Kubernetes ECブログリレー

サーバーサイドエンジニアがPHPアプリケーションをKubernetesに移設するために学習したこと

Kubernetes ECブログリレー

この記事は EC ブログリレーの22日目の記事です。21日目は @endu によるグーペのお問い合わせフォームにreCAPTCHA v2を導入した話でした。

3月3日から始まったECブログリレーは、なんと今日で最終回です!

こんにちは、カラーミーショップ DXチームの @takapi86 です。

カラーミーショップのセキュリティやDeveloper Experience改善などを担当しております。

昨年はセキュリティ対応としてCentOS 6からのバージョンアップに合わせて、ユーザが直接触るロールで初となるメルマガ機能のKubernetes化に成功しました。

詳しくは以下のスライドをご参照ください。

今回は、普段Webアプリケーションのサーバーサイドを担当している私がどうやってKubernetesについて学んでいったかご紹介しようと思います。

Kubernetesを始める前の私の知識レベル

Kubernetesを触り始めたのは、Docker、Docker Composeを使って開発環境を構築できるレベルになってからでした。

以前、カラーミーショップの開発環境をDockerへ移行を担当した際に記事を書きましたので合わせてご覧いただけると幸いです。

カラーミーショップの開発環境をすべてDockerに移行しました

1. 動画で概要を掴む

まずはざっくり概要を掴むため、マネージドKubernetesを提供しているベンダーが公開しているYouTubeの動画を観て学習しました。

2. チュートリアルをやる

Kubernetesの公式ドキュメントにはチュートリアルが含まれているので、こちらを実施しました。

https://kubernetes.io/ja/docs/tutorials/

このチュートリアルでは、Minikubeというローカル環境でKubernetesを動かすことが出来るツールを使い、基本的な操作方法を学ぶことができました。

3. ローカルのKubernetes環境でアプリケーションを動作させる

社内にテスト用のKubernetesクラスタが用意されておりましたが、無知な状態で試すには抵抗があったので、まずはローカル上のKubernetesで環境で学習をしました。 題材となるWebアプリケーションはカラーミーショップの開発環境で使用しているロールを使いました。ここでは実践に近いマニフェストを書くことができました。

なお、Kubernetesをローカルで動作させるためのツールはMinikubeの他にいくつかありますが、ここではDocker Desktop for Macに内包されているKubernetesの機能を使いました。

理由としては、imagePullPolicyというコンテナイメージの取得に関する設定があるのですが、こちらをローカルのコンテナイメージを使うようNeverにすることで、開発環境で使っていたDocker Desktop for Macでビルドした手元のイメージをそのまま使うことができるためです。Dockerレジストリを用意する必要がなく、何度もイメージをビルドして試すにはこの環境が楽でした。

4. 社内のKubernetes環境でアプリケーションを動作させる

ここからは実際にメルマガ機能のKubernetesリプレイスに向けて必要なことを学んでいくという学習スタイルを取ることにしました。

カラーミーショップ用のKubernetesクラスタは構築済みであったっため、こちらでメルマガ機能の環境をデプロイしました。その際にいくつか課題が発生したので、それを解決するために学習を行いました。

例えば、以下のような課題がありました。

環境ごとにマニフェストを管理したい

Integration/Staging/Productionといった環境ごとにマニフェストを一つ一つ用意するのは管理が大変なので、すでに他のロールで導入事例のあるKustomizeを導入しました。こちらを使用することで環境ごとの差分を管理できるようになりました。

なお、Kustomizeについては以下の公式ドキュメントを参考に学習しました。

https://kubectl.docs.kubernetes.io/guides/introduction/kustomize/

Pod切り替え時にダウンタイムが発生しないようにしたい

Kubernetes環境を整備している中、あるときデプロイ中に502 Bad Gatewayになる瞬間があることがわかりました。 調査を進めると、Kubernetesは新しいPodに切り替わるタイミングで古いPodのプロセスにSIGTERMを送信するようになっており、NginxがSIGTERMを受け取ると処理中のリクエストも強制的に切断し終了してしまうことが原因でした。 そのため、PreStopというコンテナが終了する直前に呼び出されるフックでGraceful shutdownを行うよう設定しました。

こちらの調査と合わせてPodのライフサイクルや各Probeの設定について以下の公式ドキュメントで学習しました。

https://kubernetes.io/ja/docs/concepts/workloads/pods/pod-lifecycle/

https://kubernetes.io/ja/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

5. 本番環境として運用できるように仕上げをする

ここまでで最低限アプリケーションが動作する環境は用意できましたが、本番環境として動作させるためには以下の課題を解決する必要があり、それぞれ解決するための学習を行いました。

コンテナのセキュリティ

本番環境として運用する際の必須な知識として必ず上げられるのはセキュリティです。

セキュリティについては、IPAが公開している アプリケーションコンテナセキュリティガイド に目を通し、コンテナ・イメージなどのセキュリティ対策ができているか、一覧を作ってチェックしました。

こちらに目を通すことによってコンテナセキュリティの基準が理解できました。

ログを永続化させたい

アクセスログやPHPのエラーログなど各種ログはこれまでのVM環境ではインスタンスの中に保存しており、一部重要なログはBigQueryに転送しておりました。 Kubernetesはコンテナであるという特性上、Podの中にログを保存していてもPodが切り替わったタイミングで消えてしまうので、そのままでは永続化できません。

そのため、FluentdをSidecar方式で動作させBigQeuryに転送させるようにしました。

Kubernetesそのものの学習ではありませんが、定番の周辺ツールであるFluentdについて学習することができました。

まとめ

Kubernetesについては、以前からいつか触らなければという危機感を持ちつつ、なかなか触れる機会がなかったのですが、業務を通じて一通りアプリケーションを載せて本番環境で動作させることができるレベルになることができました。 ちなみに、本番リリースするまでにかかった期間は、着手開始してから他の業務と並行しながら2〜3ヶ月くらいでした。

Kubernetes導入したいけどできていないという方はまずは、社内システムや比較的サービス影響の少ないロールを本番稼働させるようにしてみて知見を溜めていくのはいかがでしょうか。

俺たちの戦いはこれからだ

今回Kubernetesに移設したメルマガ機能はカラーミーの中でも比較的利用者数、機能が少ないロールであったため移設の難易度はそれほど高くはありませんでした。 今後は利用者数、機能数の多いロールの移設を予定しております。 その際にパフォーマンス周りなど新たに課題が出てくると思いますが、引き続き頑張って取り組んでいきたいと思います。

また、ECブログリレーは今日で最終回ですが、EC事業部では引き続き継続してアウトプットを大切に活動をしていきます。

ご愛読ありがとうございました。

EC事業部の次回アウトプットにご期待ください。