Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
PHPシステムをコンテナで動かすための取組みのすべて
kikumoto
February 11, 2020
Technology
1
2.7k
PHPシステムをコンテナで動かすための取組みのすべて
kikumoto
February 11, 2020
Tweet
Share
More Decks by kikumoto
See All by kikumoto
kikumoto
1
760
kikumoto
0
690
Other Decks in Technology
See All in Technology
oyakata2438
0
420
shirayanagiryuji
1
2.2k
ganariya
0
390
opdavies
0
1.6k
kraj
0
5.4k
chaspy
3
1.2k
keiya01
22
8.9k
mukai21
2
610
k1low
1
620
hisaichi5518
0
210
asamihirai
0
170
siroemk
0
280
Featured
See All Featured
chrislema
173
14k
pedronauck
652
110k
malarkey
393
60k
morganepeng
17
1.1k
yeseniaperezcruz
302
31k
ammeep
656
54k
roundedbygravity
241
21k
cromwellryan
101
5.9k
smashingmag
283
47k
keathley
18
650
tanoku
258
24k
lauravandoore
437
28k
Transcript
PHPシステムを コンテナで 動かすための 取り組みのすべて PHPerKaigi 2020 2020/02/11 きくもと (@takakiku)
自己紹介 ★ きくもと ★ Twitter: @takakiku ★ 所属: Hamee(ハミィ)株式会社 ◦
小田原にあります! ◦ ランチセッションにGo! ★ お仕事: SRE、マネージャー ★ その他 ◦ PHPerKaigi 2020 当日スタッフ 2
話すこと、話さないこと ★ PHPコンテナを動かす際に実際に 取り組んだことを話します。 ◦ 基本泥臭い話しばかりです。 ◦ 「正しい」とは限らない。 ★ PHP成分はほんの僅かです。
★ Dockerそのものや、各種ツールの 細かい説明はしません。 3
❖ 背景 ❖ システムの動作まわり ❖ Docker Image ❖ CI/CD ❖
開発環境 4 Agenda
❖ 背景 ❖ システムの動作まわり ❖ Docker Image ❖ CI/CD ❖
開発環境 5 Agenda
こんなシステムがありまして 6 ロードバランサ リバプロ RDBMS Appサーバ Apache mod_php モノリスなPHPコード (コードベースは1つ)
Webリクエスト処理 プロセス メール受信処理 プロセス バッチ処理 プロセス
AWSへ移行したい 7 ELB ECS Webリクエスト処理 Apache mod_php AWS Batch Lambda
SNS SQS SES CloudWatch Events メール受信処理 バッチ処理
その前に、、、 ★ コンテナ化しないと ★ 既存環境でコンテナ化された状態で 動作させて、実績を作っておきたい ★ AWSでの移行イメージを持ちやすい 状態にしたい 8
❖ 背景 ❖ システムの動作まわり ❖ Docker Image ❖ CI/CD ❖
開発環境 9 Agenda
話すシステムのイメージ 10 10 ロードバランサ リバプロ RDBMS Appサーバ Webリクエスト処理 コンテナ メール受信処理
コンテナ バッチ処理 コンテナ Apache mod_php 共通 Docker Image
ログ収集 - コンテナ出力 ★ ログドライバに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 \ <略>
ログ収集 - その他ログ ★ 各コンテナはdockerホスト上のディレク トリをマウント ◦ ログはホスト上に出力される ★ docker
ホスト上で fluent-agent-chimeraを動かしている ◦ 拙作 -https://kikumoto.hatenablog.com/entry/2018/02/02/095629 ◦ fluent-agent-hydraをベース ◦ 動的に生成されるログを取り込み fluent-agent-hydraに転送 12
システム起動まわり ★ systemdな環境 ★ システム起動時にコンテナ(Webリク エスト処理)を起動したい。 ★ コンテナ起動前に、fluentdがPORTを LISTENしている必要。 13
★ 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するスクリプト>
兄弟コンテナ ★ crondコンテナも存在 ◦ 開発環境再現の容易にするため ◦ コンテナ内からdocker runする必要 ▪ docker
コマンドをイメージに仕込済 ▪ /var/run/docker.sock をマウント 15 docker run \ --mount \ type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \ <略>
メール送信 ★ コンテナ内からメール送信 ◦ ssmtp を利用 ▪ sendmail_path = /usr/sbin/ssmtp
-t ▪ ssmtp.conf 16 mailhub=172.30.1.1:25 FromLineOverride=yes コンテナネットワーク上で のdocker ホストのIPと MTAのポート
❖ 背景 ❖ システムの動作まわり ❖ Docker Image ❖ CI/CD ❖
開発環境 17 Agenda
Dockerfile ★ 3つのDockerfile ◦ つまり、3つの Docker Image 18 OSおよび言語ランタイムを インストールしたイメージ
アプリケーションが依存する外部 ツールやライブラリ アプリケーションコードや 設定 変更の頻度を意識し た構成 通常時は最上位の イメージをビルドす るだけ。
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" \ ]
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
mitamae ★ itamaeのmruby実装 ◦ ワンバイナリ(rubyランタイム不要!) ◦ itamae ▪ 構成管理ツール ▪
Chefの簡易版みたいな感じ ◦ 採用理由 ▪ もともとChefの資産があった ▪ Dockerfileが長大になるのを避けたかった • 逆に、itamaeを知る必要あるのだけど。 21
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=.
BuildKit ★ BuildKitを利用 ◦ export DOCKER_BUILDKIT=1 ◦ Dockerfile frontend experimental
syntaxes ▪ RUN --mount=type=bind ▪ Itamaeのレシピをイメージにコピーすることなくコ ンテナにマウントして利用できる。 • 不要なDockerレイヤー削除 • COPY不要によるビルド時間短縮 23
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",
entrykit ★ entrykitを利用 ◦ https:/ /github.com/progrium/entrykit ◦ 起動時にテンプレートおよび環境変数 からファイル生成したり、事前コマンド の実行とか、引数に応じて実行プロセ
スを変えるとか。 ◦ 今回は、テンプレートからのファイル生 成用途 25
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
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
コンテナの動作変更 ★ 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
❖ 背景 ❖ システムの動作まわり ❖ Docker Image ❖ CI/CD ❖
開発環境 29 Agenda
ピタゴラスイッチ 30 Dockerビルド AWS Systems Manager Run Command deploy script
Appサーバ push hook push pull api exec 新コンテナ
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
AWS Systems Manager ★ オンプレマシンもAWSの仕組みで 管理できる(雑) ◦ agentを動かして、登録。 32
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 \ ...
Blue-Green Deploy ★ 無停止デプロイへの課題 ◦ コンテナを入れ替える必要 ◦ コンテナポートをEXPORTする場合は、リバ プロ側の設定を変更する必要。 ▪
リバプロ側のリロード処理も必要。 実行タイミング調整悩ましい。 ◦ Docker Swarmとか、k8sとか大掛かりな物 を導入したくなかった。 ▪ どのみちECSを目指しているし。 34
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ですね。正しくは。 資料はそのままにしておきます。
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
Blue-Green Deploy 37 リバプロ Appサーバ 旧イメージベースの コンテナ LVS 192.168.3.14 PORT
80 PORT 80 新イメージベースの コンテナ PORT 80 起動確認
Blue-Green Deploy 38 リバプロ Appサーバ 旧イメージベースの コンテナ LVS 192.168.3.14 PORT
80 PORT 80 新イメージベースの コンテナ PORT 80
Blue-Green Deploy 39 リバプロ Appサーバ 旧イメージベースの コンテナ LVS 192.168.3.14 PORT
80 PORT 80 新イメージベースの コンテナ PORT 80
Blue-Green Deploy 40 リバプロ Appサーバ 旧イメージベースの コンテナ LVS 192.168.3.14 PORT
80 PORT 80 新イメージベースの コンテナ PORT 80 graceful shutdown (SIGWINCH)
❖ 背景 ❖ システムの動作まわり ❖ Docker Image ❖ CI/CD ❖
開発環境 41 Agenda
開発環境(ローカルマシン) ★ 同じコンテナイメージを利用 ◦ ここはまだ悩んでいる ★ docker-compose を利用 ◦ 本番構成と同じ構成になるだけ近づける
ために、リバプロコンテナ、fluentdコンテナ など、開発環境だけのコンテナイメージも 作成 ◦ PHPソースは、ローカルディレクトリをマウ ントしてそれが動作するようにしている。 42
開発環境(ローカルマシン) ★ メールは、mailcatcherを利用して、実 際には送信されないように ◦ これもコンテナなので、実際にノーマルな MTAがインストールされたコンテナに差し 替えることで、実際に送信できるようにもし ている。 43
まとめ 44
★ PHPコンテナを動かす際に実際に取 り組んだことを話しました。 ◦ ひたすら泥臭く実装した感じです。 ◦ AWS環境移行時のイメージが具体化さ せるということはできた。 ★ 何か参考にでもなれば幸いです。
45
ご清聴ありがとうご ざいました。 46