Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPシステムをコンテナで動かすための取組みのすべて

kikumoto
February 11, 2020

 PHPシステムをコンテナで動かすための取組みのすべて

kikumoto

February 11, 2020
Tweet

More Decks by kikumoto

Other Decks in Technology

Transcript

  1. PHPシステムを
    コンテナで
    動かすための
    取り組みのすべて
    PHPerKaigi 2020
    2020/02/11
    きくもと
    (@takakiku)

    View Slide

  2. 自己紹介
    ★ きくもと
    ★ Twitter: @takakiku
    ★ 所属: Hamee(ハミィ)株式会社
    ○ 小田原にあります!
    ○ ランチセッションにGo!
    ★ お仕事: SRE、マネージャー
    ★ その他
    ○ PHPerKaigi 2020 当日スタッフ
    2

    View Slide

  3. 話すこと、話さないこと
    ★ PHPコンテナを動かす際に実際に
    取り組んだことを話します。
    ○ 基本泥臭い話しばかりです。
    ○ 「正しい」とは限らない。
    ★ PHP成分はほんの僅かです。
    ★ Dockerそのものや、各種ツールの
    細かい説明はしません。
    3

    View Slide

  4. ❖ 背景
    ❖ システムの動作まわり
    ❖ Docker Image
    ❖ CI/CD
    ❖ 開発環境
    4
    Agenda

    View Slide

  5. ❖ 背景
    ❖ システムの動作まわり
    ❖ Docker Image
    ❖ CI/CD
    ❖ 開発環境
    5
    Agenda

    View Slide

  6. こんなシステムがありまして
    6
    ロードバランサ
    リバプロ
    RDBMS
    Appサーバ
    Apache
    mod_php
    モノリスなPHPコード
    (コードベースは1つ)
    Webリクエスト処理
    プロセス
    メール受信処理
    プロセス
    バッチ処理
    プロセス

    View Slide

  7. AWSへ移行したい
    7
    ELB
    ECS
    Webリクエスト処理
    Apache
    mod_php
    AWS Batch
    Lambda
    SNS
    SQS
    SES
    CloudWatch
    Events
    メール受信処理
    バッチ処理

    View Slide

  8. その前に、、、
    ★ コンテナ化しないと
    ★ 既存環境でコンテナ化された状態で
    動作させて、実績を作っておきたい
    ★ AWSでの移行イメージを持ちやすい
    状態にしたい
    8

    View Slide

  9. ❖ 背景
    ❖ システムの動作まわり
    ❖ Docker Image
    ❖ CI/CD
    ❖ 開発環境
    9
    Agenda

    View Slide

  10. 話すシステムのイメージ
    10
    10
    ロードバランサ
    リバプロ
    RDBMS
    Appサーバ
    Webリクエスト処理
    コンテナ
    メール受信処理
    コンテナ
    バッチ処理
    コンテナ
    Apache
    mod_php
    共通
    Docker Image

    View Slide

  11. ログ収集 - コンテナ出力
    ★ ログドライバにfluentdを指定
    ★ dockerホスト上でfluent-agent-hydra
    を動かしている
    ○ https:/
    /github.com/fujiwara/fluent-agent-hydra
    ○ Kayac @fujiwara さん作成
    ○ Go 実装(docker ホストにruby不要)
    11
    docker run \
    --log-driver=fluentd \
    --log-opt fluentd-address=localhost:24224 \
    <略>

    View Slide

  12. ログ収集 - その他ログ
    ★ 各コンテナはdockerホスト上のディレク
    トリをマウント
    ○ ログはホスト上に出力される
    ★ docker ホスト上で
    fluent-agent-chimeraを動かしている
    ○ 拙作 -https://kikumoto.hatenablog.com/entry/2018/02/02/095629
    ○ fluent-agent-hydraをベース
    ○ 動的に生成されるログを取り込み
    fluent-agent-hydraに転送
    12

    View Slide

  13. システム起動まわり
    ★ systemdな環境
    ★ システム起動時にコンテナ(Webリク
    エスト処理)を起動したい。
    ★ コンテナ起動前に、fluentdがPORTを
    LISTENしている必要。
    13

    View Slide

  14. ★ Unit ファイル
    システム起動まわり
    14
    [Unit]
    After=fluent-agent-hydra.service docker.service
    Wants=fluent-agent-hydra.service docker.service
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=<24224ポートがLISTENされるまで待つスクリプト>
    ExecStart=<docker run するスクリプト>
    ExecStop=<Apacheをgraceful shutdownするスクリプト>

    View Slide

  15. 兄弟コンテナ
    ★ crondコンテナも存在
    ○ 開発環境再現の容易にするため
    ○ コンテナ内からdocker runする必要
    ■ docker コマンドをイメージに仕込済
    ■ /var/run/docker.sock をマウント
    15
    docker run \
    --mount \
    type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
    <略>

    View Slide

  16. メール送信
    ★ コンテナ内からメール送信
    ○ ssmtp を利用
    ■ sendmail_path = /usr/sbin/ssmtp -t
    ■ ssmtp.conf
    16
    mailhub=172.30.1.1:25
    FromLineOverride=yes
    コンテナネットワーク上で
    のdocker ホストのIPと
    MTAのポート

    View Slide

  17. ❖ 背景
    ❖ システムの動作まわり
    ❖ Docker Image
    ❖ CI/CD
    ❖ 開発環境
    17
    Agenda

    View Slide

  18. Dockerfile
    ★ 3つのDockerfile
    ○ つまり、3つの Docker Image
    18
    OSおよび言語ランタイムを
    インストールしたイメージ
    アプリケーションが依存する外部
    ツールやライブラリ
    アプリケーションコードや
    設定
    変更の頻度を意識し
    た構成
    通常時は最上位の
    イメージをビルドす
    るだけ。

    View Slide

  19. Dockerfile
    19
    # syntax = docker/dockerfile:experimental
    FROM hamee/hoge_appenv:1.0.1
    MAINTAINER Takahiro.Kikumoto
    WORKDIR /root
    RUN --mount=type=bind,target=. \
    mitamae local ./docker/itamae/recipe.rb && \
    rm -rf /var/cache/yum/* && \
    yum clean all
    EXPOSE 80
    ENTRYPOINT [\
    "render", \
    "/path/to/hogeapp/config.ini", \
    "/etc/ssmtp/ssmtp.conf", \
    "--", \
    "/usr/local/bin/start.sh" \
    ]

    View Slide

  20. Dockerfile
    20
    # syntax = docker/dockerfile:experimental
    FROM hamee/hoge_appenv:1.0.1
    MAINTAINER Takahiro.Kikumoto
    WORKDIR /root
    RUN --mount=type=bind,target=. \
    mitamae local ./docker/itamae/recipe.rb && \
    rm -rf /var/cache/yum/* && \
    yum clean all
    EXPOSE 80
    ENTRYPOINT [\
    "render", \
    "/path/to/hogeapp/config.ini", \
    "/etc/ssmtp/ssmtp.conf", \
    "--", \
    "/usr/local/bin/start.sh" \
    ]
    mitamae local ./docker/itamae/recipe.rb

    View Slide

  21. mitamae
    ★ itamaeのmruby実装
    ○ ワンバイナリ(rubyランタイム不要!)
    ○ itamae
    ■ 構成管理ツール
    ■ Chefの簡易版みたいな感じ
    ○ 採用理由
    ■ もともとChefの資産があった
    ■ Dockerfileが長大になるのを避けたかった
    ● 逆に、itamaeを知る必要あるのだけど。
    21

    View Slide

  22. Dockerfile
    22
    # syntax = docker/dockerfile:experimental
    FROM hamee/hoge_appenv:1.0.1
    MAINTAINER Takahiro.Kikumoto
    WORKDIR /root
    RUN --mount=type=bind,target=. \
    mitamae local ./docker/itamae/recipe.rb && \
    rm -rf /var/cache/yum/* && \
    yum clean all
    EXPOSE 80
    ENTRYPOINT [\
    "render", \
    "/path/to/hogeapp/config.ini", \
    "/etc/ssmtp/ssmtp.conf", \
    "--", \
    "/usr/local/bin/start.sh" \
    ]
    # syntax = docker/dockerfile:experimental
    RUN --mount=type=bind,target=.

    View Slide

  23. BuildKit
    ★ BuildKitを利用
    ○ export DOCKER_BUILDKIT=1
    ○ Dockerfile frontend experimental syntaxes
    ■ RUN --mount=type=bind
    ■ Itamaeのレシピをイメージにコピーすることなくコ
    ンテナにマウントして利用できる。
    ● 不要なDockerレイヤー削除
    ● COPY不要によるビルド時間短縮
    23

    View Slide

  24. Dockerfile
    24
    # syntax = docker/dockerfile:experimental
    FROM hamee/hoge_appenv:1.0.1
    MAINTAINER Takahiro.Kikumoto
    WORKDIR /root
    RUN --mount=type=bind,target=. \
    mitamae local ./docker/itamae/recipe.rb && \
    rm -rf /var/cache/yum/* && \
    yum clean all
    EXPOSE 80
    ENTRYPOINT [\
    "render", \
    "/path/to/hogeapp/config.ini", \
    "/etc/ssmtp/ssmtp.conf", \
    "--", \
    "/usr/local/bin/start.sh" \
    ]
    "render", \
    "/path/to/hogeapp/config.ini", \
    "/etc/ssmtp/ssmtp.conf",

    View Slide

  25. entrykit
    ★ entrykitを利用
    ○ https:/
    /github.com/progrium/entrykit
    ○ 起動時にテンプレートおよび環境変数
    からファイル生成したり、事前コマンド
    の実行とか、引数に応じて実行プロセ
    スを変えるとか。
    ○ 今回は、テンプレートからのファイル生
    成用途
    25

    View Slide

  26. entrykit
    26
    mailhub={{ var "SMTP_ADDR" | default "localhost"
    }}:{{ var "SMTP_PORT" | default "25" }}
    /etc/ssmtp/ssmtp.conf.tmpl
    Docker run \
    --env-file=env.txt
    SMTP_ADDR=172.30.1.1
    SMTP_PORT=25
    env.txt
    mailhub=172.30.1.1:25
    /etc/ssmtp/ssmtp.conf

    View Slide

  27. Dockerfile
    27
    # syntax = docker/dockerfile:experimental
    FROM hamee/hoge_appenv:1.0.1
    MAINTAINER Takahiro.Kikumoto
    WORKDIR /root
    RUN --mount=type=bind,target=. \
    mitamae local ./docker/itamae/recipe.rb && \
    rm -rf /var/cache/yum/* && \
    yum clean all
    EXPOSE 80
    ENTRYPOINT [\
    "render", \
    "/path/to/hogeapp/config.ini", \
    "/etc/ssmtp/ssmtp.conf", \
    "--", \
    "/usr/local/bin/start.sh" \
    ]
    /usr/local/bin/start.sh

    View Slide

  28. コンテナの動作変更
    ★ docker run の引数で動作モードを
    制御
    ○ entrykit の switch では、引数を渡すこ
    とができなかった。
    28
    #!/bin/sh
    mode=$1
    shift
    case $mode in
    "php")
    exec /usr/bin/php "[email protected]"
    ;;
    "webapp")
    exec /usr/sbin/httpd -D FOREGROUND
    ;;
    *)
    exec /bin/bash "[email protected]"
    ;;
    esac

    View Slide

  29. ❖ 背景
    ❖ システムの動作まわり
    ❖ Docker Image
    ❖ CI/CD
    ❖ 開発環境
    29
    Agenda

    View Slide

  30. ピタゴラスイッチ
    30
    Dockerビルド
    AWS Systems
    Manager
    Run Command
    deploy script
    Appサーバ
    push hook
    push
    pull
    api
    exec
    新コンテナ

    View Slide

  31. CircleCIでのポイント
    ★ BuildKit利用、mountも。
    ○ docker executor
    ■ dockerのバージョンは新しい
    ● BuildKitはサポートしているバージョン
    ■ mountができない。
    ○ machine executor
    ■ デフォルトイメージでは、dockerのバージョン
    が古い
    ■ ubuntu-1604:201903-01 を使用
    ● https://circleci.com/docs/ja/2.0/configuration-reference/#machine
    31

    View Slide

  32. AWS Systems Manager
    ★ オンプレマシンもAWSの仕組みで
    管理できる(雑)
    ○ agentを動かして、登録。
    32

    View Slide

  33. AWS Systems Manager
    ★ Run Command
    ○ 管理サーバ上でスクリプトを実行可能。
    ○ 対象をタグで一括指定。
    ○ CircleCIから以下を実行している。
    33
    aws ssm send-command \
    --document-name "Our-Deploy" \
    --parameters "{\"tag\":[\"$VERSION\"]}" \
    --timeout-seconds 600 \
    --max-concurrency "50" \
    --targets Key=tag:Deployable,Values=Yes \
    Key=tag:Environment,Values=Staging \
    ...

    View Slide

  34. Blue-Green Deploy
    ★ 無停止デプロイへの課題
    ○ コンテナを入れ替える必要
    ○ コンテナポートをEXPORTする場合は、リバ
    プロ側の設定を変更する必要。
    ■ リバプロ側のリロード処理も必要。
    実行タイミング調整悩ましい。
    ○ Docker Swarmとか、k8sとか大掛かりな物
    を導入したくなかった。
    ■ どのみちECSを目指しているし。
    34

    View Slide

  35. Blue-Green Deploy
    ★ LVSを採用
    ○ Linux Virtual Server
    ○ L4 Load Balancer
    ○ LVSが外向けにPORT (80) をLISTEN
    ○ パケットの転送先にコンテナを指定
    ○ 新コンテナ起動後、health checkしてOKな
    ら、LVSに組み込む。
    ○ 古いコンテナはLVSから外して、graceful
    shutdown。
    35
    Ask The Speaer でのご指摘。
    同時に新旧混在があるので、これは
    Rolling Updateですね。正しくは。
    資料はそのままにしておきます。

    View Slide

  36. Blue-Green Deploy
    36
    リバプロ
    Appサーバ
    旧イメージベースの
    コンテナ
    LVS
    upstream backend {
    server 192.168.3.14;
    server 192.168.3.15;
    ...
    }
    192.168.3.14
    PORT 80
    PORT 80

    View Slide

  37. Blue-Green Deploy
    37
    リバプロ
    Appサーバ
    旧イメージベースの
    コンテナ
    LVS
    192.168.3.14
    PORT 80
    PORT 80
    新イメージベースの
    コンテナ
    PORT 80
    起動確認

    View Slide

  38. Blue-Green Deploy
    38
    リバプロ
    Appサーバ
    旧イメージベースの
    コンテナ
    LVS
    192.168.3.14
    PORT 80
    PORT 80
    新イメージベースの
    コンテナ
    PORT 80

    View Slide

  39. Blue-Green Deploy
    39
    リバプロ
    Appサーバ
    旧イメージベースの
    コンテナ
    LVS
    192.168.3.14
    PORT 80
    PORT 80
    新イメージベースの
    コンテナ
    PORT 80

    View Slide

  40. Blue-Green Deploy
    40
    リバプロ
    Appサーバ
    旧イメージベースの
    コンテナ
    LVS
    192.168.3.14
    PORT 80
    PORT 80
    新イメージベースの
    コンテナ
    PORT 80
    graceful shutdown
    (SIGWINCH)

    View Slide

  41. ❖ 背景
    ❖ システムの動作まわり
    ❖ Docker Image
    ❖ CI/CD
    ❖ 開発環境
    41
    Agenda

    View Slide

  42. 開発環境(ローカルマシン)
    ★ 同じコンテナイメージを利用
    ○ ここはまだ悩んでいる
    ★ docker-compose を利用
    ○ 本番構成と同じ構成になるだけ近づける
    ために、リバプロコンテナ、fluentdコンテナ
    など、開発環境だけのコンテナイメージも
    作成
    ○ PHPソースは、ローカルディレクトリをマウ
    ントしてそれが動作するようにしている。
    42

    View Slide

  43. 開発環境(ローカルマシン)
    ★ メールは、mailcatcherを利用して、実
    際には送信されないように
    ○ これもコンテナなので、実際にノーマルな
    MTAがインストールされたコンテナに差し
    替えることで、実際に送信できるようにもし
    ている。
    43

    View Slide

  44. まとめ
    44

    View Slide

  45. ★ PHPコンテナを動かす際に実際に取
    り組んだことを話しました。
    ○ ひたすら泥臭く実装した感じです。
    ○ AWS環境移行時のイメージが具体化さ
    せるということはできた。
    ★ 何か参考にでもなれば幸いです。
    45

    View Slide

  46. ご清聴ありがとうご
    ざいました。
    46

    View Slide