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

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

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for kikumoto kikumoto
February 11, 2020

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

Avatar for kikumoto

kikumoto

February 11, 2020
Tweet

More Decks by kikumoto

Other Decks in Technology

Transcript

  1. 自己紹介 ★ きくもと ★ Twitter: @takakiku ★ 所属: Hamee(ハミィ)株式会社 ◦

    小田原にあります! ◦ ランチセッションにGo! ★ お仕事: SRE、マネージャー ★ その他 ◦ PHPerKaigi 2020 当日スタッフ 2
  2. AWSへ移行したい 7 ELB ECS Webリクエスト処理 Apache mod_php AWS Batch Lambda

    SNS SQS SES CloudWatch Events メール受信処理 バッチ処理
  3. ログ収集 - コンテナ出力 ★ ログドライバに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 \ <略>
  4. ログ収集 - その他ログ ★ 各コンテナはdockerホスト上のディレク トリをマウント ◦ ログはホスト上に出力される ★ docker

    ホスト上で fluent-agent-chimeraを動かしている ◦ 拙作 -https://kikumoto.hatenablog.com/entry/2018/02/02/095629 ◦ fluent-agent-hydraをベース ◦ 動的に生成されるログを取り込み fluent-agent-hydraに転送 12
  5. ★ 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するスクリプト>
  6. 兄弟コンテナ ★ crondコンテナも存在 ◦ 開発環境再現の容易にするため ◦ コンテナ内からdocker runする必要 ▪ docker

    コマンドをイメージに仕込済 ▪ /var/run/docker.sock をマウント 15 docker run \ --mount \ type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \ <略>
  7. メール送信 ★ コンテナ内からメール送信 ◦ ssmtp を利用 ▪ sendmail_path = /usr/sbin/ssmtp

    -t ▪ ssmtp.conf 16 mailhub=172.30.1.1:25 FromLineOverride=yes コンテナネットワーク上で のdocker ホストのIPと MTAのポート
  8. Dockerfile ★ 3つのDockerfile ◦ つまり、3つの Docker Image 18 OSおよび言語ランタイムを インストールしたイメージ

    アプリケーションが依存する外部 ツールやライブラリ アプリケーションコードや 設定 変更の頻度を意識し た構成 通常時は最上位の イメージをビルドす るだけ。
  9. 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" \ ]
  10. 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
  11. mitamae ★ itamaeのmruby実装 ◦ ワンバイナリ(rubyランタイム不要!) ◦ itamae ▪ 構成管理ツール ▪

    Chefの簡易版みたいな感じ ◦ 採用理由 ▪ もともとChefの資産があった ▪ Dockerfileが長大になるのを避けたかった • 逆に、itamaeを知る必要あるのだけど。 21
  12. 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=.
  13. BuildKit ★ BuildKitを利用 ◦ export DOCKER_BUILDKIT=1 ◦ Dockerfile frontend experimental

    syntaxes ▪ RUN --mount=type=bind ▪ Itamaeのレシピをイメージにコピーすることなくコ ンテナにマウントして利用できる。 • 不要なDockerレイヤー削除 • COPY不要によるビルド時間短縮 23
  14. 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",
  15. 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
  16. 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
  17. コンテナの動作変更 ★ docker run の引数で動作モードを 制御 ◦ entrykit の switch

    では、引数を渡すこ とができなかった。 28 #!/bin/sh mode=$1 shift case $mode in "php") exec /usr/bin/php "$@" ;; "webapp") exec /usr/sbin/httpd -D FOREGROUND ;; *) exec /bin/bash "$@" ;; esac
  18. ピタゴラスイッチ 30 Dockerビルド AWS Systems Manager Run Command deploy script

    Appサーバ push hook push pull api exec 新コンテナ
  19. 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
  20. 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 \ ...
  21. Blue-Green Deploy ★ 無停止デプロイへの課題 ◦ コンテナを入れ替える必要 ◦ コンテナポートをEXPORTする場合は、リバ プロ側の設定を変更する必要。 ▪

    リバプロ側のリロード処理も必要。 実行タイミング調整悩ましい。 ◦ Docker Swarmとか、k8sとか大掛かりな物 を導入したくなかった。 ▪ どのみちECSを目指しているし。 34
  22. 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ですね。正しくは。 資料はそのままにしておきます。
  23. 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
  24. Blue-Green Deploy 37 リバプロ Appサーバ 旧イメージベースの コンテナ LVS 192.168.3.14 PORT

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

    80 PORT 80 新イメージベースの コンテナ PORT 80 graceful shutdown (SIGWINCH)
  26. 開発環境(ローカルマシン) ★ 同じコンテナイメージを利用 ◦ ここはまだ悩んでいる ★ docker-compose を利用 ◦ 本番構成と同じ構成になるだけ近づける

    ために、リバプロコンテナ、fluentdコンテナ など、開発環境だけのコンテナイメージも 作成 ◦ PHPソースは、ローカルディレクトリをマウ ントしてそれが動作するようにしている。 42