ようし。独自のWordPressコンテナをbuildしてオーシャンのContainer Registryにpushできた。あとはk8sからpullして動作確認するだけだ。
— adachin👾SRE (@adachin0817) August 20, 2022
- インフラ構成図
さて、このブログサーバーとは別にKubernetesで運用しているwiki/WordPressコンテナ(備忘録)があります(wiki.adachin.me)。以下ブログでも書いていますが、オーシャンで運用し始めて約3年が経ちました。初期はMySQLコンテナをPodで運用していましたが、Managed Databasesに移行(ブログの方も)してからMackerel、WordPressコンテナの二台で動作しています。また、WordPressコンテナはDocker Hub公式イメージを利用していました。そこで、2020年頃にオーシャンでContainer Registryがリリースされたので、ようやく独自コンテナに移行してみました。
Container Registryとは
https://www.digitalocean.com/products/container-registry
AWSでいうECRで、コンテナ専用プライベートリポジトリになります。オーシャンは1リポジトリで500MBまでなら無料で利用できるので、今回はFreeプランにしました。通信量はかかるので、AWSとあまり変わらなそうな印象です。早速Terraformで作成してみましょう。
Terraformと準備
- do_cr.tf
1 2 3 4 |
resource "digitalocean_container_registry" "wiki_wordpress" { name = "wiki-wordpress" subscription_tier_slug = "starter" } |
- DigitalOcean Kubernetes integration
リポジトリ作成後にSettingsから DigitalOcean Kubernetes integration
で今回設定するクラスターを紐付けましょう。これによってクラスターの全てのnamespaceにSecretが追加されます。なので、手動でSecretをimagePullSecretsとしてわざわざ作成する必要はありません。楽だ…!これで準備は完了です。次は独自のWordPressをbuildしてpushしてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ kubectl get secrets NAME TYPE DATA AGE wiki-wordpress kubernetes.io/dockerconfigjson 1 1s $ kubectl describe secrets/wiki-wordpress Name: wiki-wordpress Namespace: default Labels: digitalocean.com/copy-identifier=wiki-wordpress Annotations: <none> Type: kubernetes.io/dockerconfigjson Data ==== .dockerconfigjson: 243 bytes |
Push Container Registry
- docker/prd/wiki
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ tree docker/prd/wiki docker/prd/wiki ├── Dockerfile ├── README.md ├── nginx │ ├── nginx.conf │ └── wiki.adachin.me.conf ├── php │ ├── php-fpm.conf │ ├── php.ini │ └── www.conf └── supervisor ├── app.conf └── supervisord.conf |
- Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
FROM php:7.4-fpm-alpine ENV APP_ROOT /var/www/wiki.adachin.me WORKDIR $APP_ROOT # Setup UTC+9 RUN apk --update add tzdata && \ cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/* # install packages RUN apk update && \ apk upgrade && \ apk add --update --no-cache \ autoconf \ bash \ build-base \ freetype-dev \ g++ \ gcc \ libjpeg \ libjpeg-turbo \ libjpeg-turbo-dev \ libpng \ libpng-dev \ libxml2-dev \ libxpm-dev \ libxslt-dev \ libwebp-dev \ jpeg-dev \ make \ mysql-dev \ nginx \ openssl \ supervisor \ tzdata \ vim \ yaml-dev \ zlib-dev RUN docker-php-ext-configure gd \ --with-freetype=/usr/include/ \ --with-jpeg=/usr/include/ && \ NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \ docker-php-ext-install -j${NPROC} gd && \ docker-php-ext-configure opcache --enable-opcache RUN docker-php-ext-install opcache pdo_mysql soap mysqli # nginx COPY docker/prd/wiki/nginx/wiki.adachin.me.conf /etc/nginx/conf.d/wiki.adachin.me.conf COPY docker/prd/wiki/nginx/nginx.conf /etc/nginx/nginx.conf # PHP-FPM RUN rm -f /usr/local/etc/php-fpm.conf.default RUN rm -f /usr/local/etc/php-fpm.d/zz-docker.conf RUN mkdir /var/log/php-fpm RUN chmod 777 /var/log/php-fpm COPY docker/prd/wiki/php/php-fpm.conf /usr/local/etc/php-fpm.conf COPY docker/prd/wiki/php/php.ini /usr/local/etc/php/php.ini COPY docker/prd/wiki/php/www.conf /usr/local/etc/php-fpm.d/www.conf # setting superviser COPY docker/prd/wiki/supervisor/supervisord.conf /etc/supervisord.conf COPY docker/prd/wiki/supervisor/app.conf /etc/supervisor/conf.d/app.conf RUN echo files = /etc/supervisor/conf.d/*.conf >> /etc/supervisord.conf # Service to run CMD ["/usr/bin/supervisord"] |
- supervisor/app.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[supervisord] nodaemon=true [program:nginx] command=/usr/sbin/nginx -g "daemon off;" autostart=true autorestart=true stopsignal=TERM user=root stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 [program:php-fpm] command=/usr/local/sbin/php-fpm -F autostart=true autorestart=true stopsignal=TERM user=root stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 |
元々オフィシャルイメージで利用していたのは1core 2GBで wordpress:5-php7.4-apache
でした。また、Volumeを利用して、WordPressのソースコードをマウントしています。今回はPHP7.4のAlpine OSをベースにSupervisorでNginxとphp-fpmを動作するようにしました。WordPressであればマイクロサービスのようにWebサーバーは分割しないほうが良さそうですね。ちなみにイメージの容量は431MBでした。
buildしてpushする流れは以下になります。リポジトリにpushできたらManifestファイルを変更してapplyしましょう。
- build and push
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
$ doctl registry login $ docker build -f docker/prd/wiki/Dockerfile -t wiki-wordpress:latest . [+] Building 4.0s (24/24) FINISHED => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 37B 0.1s => [internal] load .dockerignore 0.1s => => transferring context: 2B 0.1s => [internal] load metadata for docker.io/library/php:7.4-fpm-alpine 3.0s => [auth] library/php:pull token for registry-1.docker.io 0.0s => [internal] load build context 0.0s => => transferring context: 1.09kB 0.0s => [ 1/18] FROM docker.io/library/php:7.4-fpm-alpine@sha256:7e551f8b4666967229d03a1f00008ed5098d5cccbf8 0.0s => CACHED [ 2/18] WORKDIR /var/www/wiki.adachin.me 0.0s => CACHED [ 3/18] RUN apk --update add tzdata && cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime & 0.0s => CACHED [ 4/18] RUN apk update && apk upgrade && apk add --update --no-cache autoconf 0.0s => CACHED [ 5/18] RUN docker-php-ext-install pdo_mysql soap mysqli 0.0s => CACHED [ 6/18] RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/us 0.0s => CACHED [ 7/18] COPY docker/prd/wiki/nginx/wiki.adachin.me.conf /etc/nginx/conf.d/wiki.adachin.me.con 0.0s => CACHED [ 8/18] COPY docker/prd/wiki/nginx/nginx.conf /etc/nginx/nginx.conf 0.0s => CACHED [ 9/18] RUN rm -f /usr/local/etc/php-fpm.conf.default 0.0s => CACHED [10/18] RUN rm -f /usr/local/etc/php-fpm.d/zz-docker.conf 0.0s => CACHED [11/18] RUN mkdir /var/log/php-fpm 0.0s => CACHED [12/18] RUN chmod 777 /var/log/php-fpm 0.0s => CACHED [13/18] COPY docker/prd/wiki/php/php-fpm.conf /usr/local/etc/php-fpm.conf 0.0s => CACHED [14/18] COPY docker/prd/wiki/php/php.ini /usr/local/etc/php/php.ini 0.0s => [15/18] COPY docker/prd/wiki/php/www.conf /usr/local/etc/php-fpm.d/www.conf 0.0s => [16/18] COPY docker/prd/wiki/supervisor/supervisord.conf /etc/supervisord.conf 0.0s => [17/18] COPY docker/prd/wiki/supervisor/app.conf /etc/supervisor/conf.d/app.conf 0.0s => [18/18] RUN echo files = /etc/supervisor/conf.d/*.conf >> /etc/supervisord.conf 0.4s ~省略~ $ docker images |grep wordpress wiki-wordpress latest e2995c7ad7fb 3 hours ago 431MB $ docker tag wiki-wordpress registry.digitalocean.com/wiki-wordpress/wiki-wordpress $ docker push registry.digitalocean.com/wiki-wordpress/wiki-wordpress |
Fix Manifest file
- wordpress.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
--- apiVersion: apps/v1 kind: StatefulSet metadata: name: wiki-wordpress spec: serviceName: "wiki-wordpress" replicas: 1 selector: matchLabels: app: wiki-wordpress template: metadata: labels: app: wiki-wordpress spec: containers: - name: wiki-wordpress image: registry.digitalocean.com/wiki-wordpress/wiki-wordpress:latest #変更 ports: - containerPort: 80 name: wiki-wordpress volumeMounts: - name: wordpress-data mountPath: /var/www/wiki.adachin.me #ついでにディレクトリ名も変更 volumes: - name: wordpress-data persistentVolumeClaim: claimName: wordpress-volume volumeClaimTemplates: - metadata: name: wordpress-volume spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 10Gi storageClassName: do-block-storage |
19行目のimage名を今回のリポジトリ名に変更するだけになります。最後にapplyをしてコンテナを再作成します。
ちなみにハマったのは下記のようにリポジトリのリンクを間違って指定しまうとErrImagePullになってしまうので、必ずコンソールの Recent image tag:
をコピペしましょう。
ErrImagePull。ぐぬぬ。。
— adachin👾SRE (@adachin0817) August 20, 2022
- kubectl apply
1 2 3 4 5 6 7 |
$ kubectl apply -f k8s/wiki/manifests/wordpress.yaml statefulset.apps/wiki-wordpress created $ kubectl get pods NAME READY STATUS RESTARTS AGE mackerel-agent 1/1 Running 0 393d wiki-wordpress-0 1/1 Running 0 109m |
- コンテナ確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
bash-5.1# supervisorctl status all nginx RUNNING pid 9, uptime 14:15:50 php-fpm RUNNING pid 10, uptime 14:15:50 bash-5.1# cat /etc/os-release NAME="Alpine Linux" ID=alpine VERSION_ID=3.16.2 PRETTY_NAME="Alpine Linux v3.16" HOME_URL="https://alpinelinux.org/" BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues" bash-5.1# php -v PHP 7.4.30 (cli) (built: Aug 9 2022 22:40:38) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.30, Copyright (c), by Zend Technologies $ curl -I https://wiki.adachin.me HTTP/1.1 200 OK server: nginx/1.22.0 date: Mon, 22 Aug 2022 01:08:05 GMT content-type: text/html; charset=UTF-8 content-length: 152140 vary: Accept-Encoding, Cookie cache-control: max-age=3, must-revalidate last-modified: Mon, 22 Aug 2022 01:02:41 GMT |
レスポンスはどうなったのか!?
https://status.adachin.me/783273486
- 24 hours
- 1 week
切り替えた時間は本日の14時くらいです。24 hoursで確認するとあまり変わらないと思いますが、1 weekにしてみると平均約800msから約600msにレスポンスが良くなりました。さすがNginxといったところかな。
まとめ
できたわ。php-fpmのチューニングしまくってたらそもそもスペック低いの忘れてて、コンテナ落ちまくってた…
— adachin👾SRE (@adachin0817) August 21, 2022
Kubernetesの勉強も兼ねて、独自のWordPressコンテナへ移行することができました。今後はGitHubで専用のリポジトリを作成してCircleCIでソースコードを配置後、デプロイできるような仕組みを作っていきたいと思います。Trivyでコンテナ脆弱性検知やるぞーー!ってその前にKubernetes v1.21.2-do.2なのでバージョンアップしないと。。→v1.23.9-do.0にバージョンアップしたけど特に問題なかった。
- 追記
デプロイ実装しました。
[DigitalOcean][Kubernetes]WordPressコンテナをCircleCIで自動デプロイとローリングアップデートを実装してみた
- 別件
一日モニタリングしてみたところ、Topページもレスポンス良くなってた👍 pic.twitter.com/5OJAK1K0Tj
— adachin👾SRE (@adachin0817) August 19, 2022
このブログサーバーのレスポンスが改善されました。とてつもなく早くなったと思いますので、今後共ADACHIN SERVER LABOをよろしくお願いします…!(全部自分のせい)
0件のコメント