プロダクト開発のための Kubernetes 入門
Wantedly のバックエンドシステムは全て AWS 上に構築された Kubernetes クラスタの上で動いています。 新しいコードをデプロイしたり、開発用クラスタで rails c
を実行したりなど日常の業務はインフラチームの助けを借りずにできるようになっています。 この章では、プロダクト開発に必要となる知識の説明をします。Kubernetes の基本的な概念、Wantedly における Kubernetes の構成、そしてその内製CLIである kube
コマンドの概要を説明します。
Kubernetes とは?
Kubernetes における代表的な Object の階層構造と役割(機能) を知ることが重要です。より詳しくは公式ドキュメントのKubernetesとは何か?を参照してください。
Object とは
Kubernetes の管理下にあるレイヤのリソース(Container, Network, Storage, etc…)を抽象化したものを指します。詳細は公式ドキュメントのKubernetesオブジェクトを理解するを参照してください。また、少し古いですがKubernetes道場 Advent Calendar 2018 - Qiitaの記事群も図解が多めでわかりやすいです。
Object には spec(仕様)と state(状態)が存在しています。Kubernetes の根本的なコンセプトとして Reconciliation Loop によって Object で宣言された spec(desired state) に操作対象リソースの state を近づけるというものがあります。例えば Pod を 2 つ立てておいてくださいと spec に書いている状態で Pod が 1 つになってしまった(state)ら自動的にもう一台 Pod を立てるということを勝手にやってくれます。詳細はKubernetes のしくみ やさしく学ぶ 内部構造とアーキテクチャーを参照してください。
よく聞く主な Object の役割(機能)
Namespace
Kubernetes 上のリソースを分類するための名前空間
操作権限の境界
Object のグルーピング
ClusterRole(Binding) とか一部の Object 以外は必ずどこかの Namespace に所属している
Object の作成時に Namespace を指定しなかった場合は
default
Namespace が指定される
Wantedly においてはマイクロサービスごとに Namespace を作っている
e.g. wantedly/yashima-rails リポジトリ -
yashima-rails
namespace
Pod
Kubernetes におけるアプリケーションの最小構成単位
コンテナの集まり
1 つの Pod に N 個の Container が含まれる
e.g. rails server などアプリケーションサーバ, nginx や envoy などの reverse proxy をひとまとめに扱う
Node
VM もしくは物理マシンに対応
Wantedly においては AWS 上の EC2 インスタンス
Node 上には複数の Pod がデプロイされる
ReplicaSet
Pod の管理
指定した数の Pod の複製・維持
例えば Pod を 2 台起動して欲しいと宣言しておくと、1 台 Pod が終了してもその直後に勝手に 1 台 Pod を起動して 2 台構成を維持してくれる
これを逆手にとって Pod を強制的に再起動したいときは Pod を delete することで消えた分の数の Pod が自動的に立ち上がる
ただこの場合 Pod の台数を維持できなくなる瞬間が存在する(Rolling Update ではないので 1 台構成とかだったらサービスダウンする)ので、複数台構成になっている前提
Deployment/ReplicaSet で管理された Pod を完全に削除したいという場合は Deployment/ReplicaSet を削除する
Deployment
ReplicaSet の世代管理
Pod の Rolling Update
以前の ReplicaSet までの Rollback
CronJob
指定した時刻に Job を起動する
Job
Pod を起動して指定された One Shot なコマンドを実行する
Service
Pod への通信を管理する
Pod に対する L4(TCP/IP) Load Balancer
Pod に対して通信しようと思ったら Service を追加しなければならない
Ingress
Pod(Service) への通信を管理する
Pod(Service) に対する L7(HTTP) Load Balancer
URL 上の Path でルーティングを切り替えるとかはこのレイヤでないと出来ない
この Object が実際に操作するのは Cloud Provider の Load Balancer が多い(Wantedly では ALB)
他にも Kubernetes 内の Object も操作できる(e.g. nginx-ingress-controller とか)
Object の階層構造
Wantedly での Kunbernetes 構成
以下の3種類のクラスタが存在します。
Production
ユーザからのアクセスを受ける、いわゆる本番環境です。
QA
本番デプロイ前の動作確認用クラスタです。
QAテスターチームが日常的に利用しています。社内のビジネスチームが動作確認のために利用することもあります。
原則として、本番環境と同じバージョンのコードが動いている状態を保ちます。
モバイルアプリ・Web フロントエンドエンジニアは普段ローカルから QA につないで開発しています。
Sandbox
開発用クラスタです。
バックエンドエンジニアが本番に近い環境でアプリケーションを動かしたいときに利用しています。
デプロイについて
Wantedly の Kubernetes クラスタ上で動いているアプリケーションは全て、Rolling update という Strategy でデプロイされます。これは動いているアプリケーション徐々に入れ替えていく方式で、古いアプリと新しいアプリが同時に動作する時間が存在することになります。 なので、Pull request を作るときには「バックエンドとフロントエンドの変更を分ける」「DB スキーマ変更とアプリケーション変更は分ける」などを意識することが重要になります。
より詳しくはリリース・デプロイ戦略の章を参照してください。
環境変数・dotenv について
The Twelve-Factor App の III. Config で、アプリケーションの設定値はコード上に記述せず環境変数にセットすることが推奨されています。 Wantedly の Kubernetes クラスタでは Secret を利用し環境変数を管理しています。 各 Namespace に dotenv
という Secret を作成し、そこに設定値を格納して環境変数に展開しています。 dotenv
への環境変数の設定などは、後述する kube コマンドを介して行われます。
kube コマンド
kube
は Wantedly の Kubernetes クラスタのリソースを操作するためのユーティリティです。 詳しくは kube - Wantedly Engineering Handbook を参照してください。
話を聞きに行きたい
もっと知りたい
最終更新