前回の Kubernetes の ヘルスチェック の続きなります。僕の思う Kubernetes のうれしい機能の1つがセルフヒーリング(自己回復)です。今回は、セルフヒーリング(自己回復)を実現する ReplicaSet を紹介します。
最新では、マイクロソフトの「Build 2019」で Kubernetes の Pod レベルでサーバーレスを実現するフレークワーク(Kubernetes-based Event-Driven Autoscaling(KEDA))をレッドハットと共同で開発したオープンソースプロジェクトとして発表されたようです。
セルフヒーリング(自己回復)
Kubernetes はセルフヒーリング(自己回復)するシステムです。望ましい状態を常に継続させます。どういうことかというと、nginx コンテナが3つ動作しているのが望ましい状態としてマニフェストファイルを定義してデプロイを実行すると、Kubernetes は常に nginx コンテナが3つ動作している状態を継続します。
ここで重要なことは、”3つ動作しているのが望ましい状態”、つまり望ましい状態を ”宣言的設定” するということです。宣言的設定(Infrastructure as Code)については、こちらで紹介しています。
ReplicaSetの目的
A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods.
ReplicaSetの目的は、いつでも実行されているレプリカポッドの安定したセットを維持することです。そのため、指定された数の同一のPodの可用性を保証するためによく使用されます。
レプリカを作成する理由
理由といっても、ReplicaSet の目的そのままですね。上の例で言うと、なぜ nginx を3つも動作させる必要があるのか、を考えると次のような理由があるかと思います。
冗長性
インスタンスを複数動かすと、障害を許容できます。
スケール
インスタンスを複数動かすと、多くの多くのリクエストを受け付けられてます。
シャーディング
異なるコンテナのレプリカを動かすと、異なる種類の処理を同時に受け付けられます。
どれもプロダクション環境下では、求められる要件だと思いますし、運営側としても実現できれば安心してサービスを提供できます。
Pod と ReplicaSet の関連付け
プログラミングにおいて疎結合(分離)であることは重要だとされています。僕が紹介している「はじめての ASP.NET Core 作りながら学習」の ASP.NET Core でも MVC が採用されています。
疎結合であること
Kubernetes においても 疎結合(分離)であることが重要であるという考えのもと、設計されています。この設計思想を前提とすると、ReplicaSet と Pod の関係が、 ReplicaSet は Pod を管理はするが、所有はしないというのは自然です。
では ReplicaSet と Pod をどう関連付けているか?答えは Label です。ReplicaSet は管理すべき Pod の集合体を Label クエリにより識別します。後で ReplicaSet をデプロイして確認してみましょう。
ReplicaSet をデプロイ
まずは、前回デプロイした kuard Pod を削除します。
1 2 3 4 |
# 前回のマニフェストファイルがローカルにある場合 kubectl delete -f .\kuard-pod-deploy.yaml # 前回のマニフェストファイルがローカルにない場合 kubectl delete pod/kuard |
マニフェスト作成
spec.selector.matchLaels と spec.template.metadata.labels を一致させる必要があります。
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 |
apiVersion: apps/v1 kind: ReplicaSet metadata: name: kuard-rs spec: replicas: 2 selector: matchLabels: app: kuard version: "1" template: metadata: labels: app: kuard version: "1" spec: containers: - image: gcr.io/kuar-demo/kuard-amd64:1 name: kuard-container livenessProbe: httpGet: path: healthy port: 8080 initialDelaySeconds: 5 timeoutSeconds: 1 periodSeconds: 10 failureThreshold: 3 ports: - containerPort: 8080 name: http protocol: TCP |
デプロイ
1 2 3 4 5 6 7 8 |
# マニフェストファイルから ReplicaSet をデプロイします。 kubectl apply -f .\kuard-replicaset-deploy.yaml replicaset.apps "kuard-rs" created # Pod のレプリカが2つ作成されていることを確認します。 kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE kuard-rs-6t4nr 1/1 Running 0 10s 10.1.0.27 docker-for-desktop kuard-rs-b4q9c 1/1 Running 0 10s 10.1.0.26 docker-for-desktop |
Pod を検索
Pod から ReplicaSet を調べる
1 2 3 4 5 6 7 8 9 |
kubectl get pod/kuard-rs-6t4nr -o yaml ・・・ ownerReferences: - apiVersion: extensions/v1beta1 blockOwnerDeletion: true controller: true kind: ReplicaSet name: kuard-rs ・・・ |
ReplicaSet に関連する Pod を調べる
1 2 3 4 |
kubectl get pod -l app=kuard NAME READY STATUS RESTARTS AGE kuard-rs-6t4nr 1/1 Running 0 32m kuard-rs-b4q9c 1/1 Running 0 32m |
Pod を削除
セルフヒーリング(自己回復)を試してみましょう。
1 2 3 4 5 6 7 |
kubectl delete pod/kuard-rs-b4q9c pod "kuard-rs-b4q9c" deleted # kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE kuard-rs-6t4nr 1/1 Running 0 58m 10.1.0.27 docker-for-desktop kuard-rs-mrhn7 1/1 Running 0 7s 10.1.0.28 docker-for-desktop |
(」゚ロ゚)」オオオオ セルフヒーリング。AGE が 7s となっているのが削除後に作成された Pod ですね。
ラベルの切り替え
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# ReplicaSet と Pod の関連付けに作成した app ラベルを削除します。 # Label値の最後に -(ダッシュ)を付けると削除されます。 kubectl label pod/kuard-rs-mrhn7 "app-" # Pod 一覧を取得します。 # kuard-rs-mrhn7 が RepolicaSet の管理対象から外れて、 # 望ましい状態を維持するために Pod が生成されています。 kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE kuard-rs-6t4nr 1/1 Running 1 23h 10.1.0.29 docker-for-desktop kuard-rs-krvq2 1/1 Running 0 15s 10.1.0.33 docker-for-desktop kuard-rs-mrhn7 1/1 Running 1 22h 10.1.0.30 docker-for-desktop # ReplicaSet の管理対象から外れたか確認するために、Pod を削除します。 kubectl delete pod/kuard-rs-mrhn7 # Pod 一覧を取得します。 kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE kuard-rs-6t4nr 1/1 Running 1 23h 10.1.0.29 docker-for-desktop kuard-rs-krvq2 1/1 Running 0 4m 10.1.0.33 docker-for-desktop |
障害時の調査
前回、紹介したヘルスチェックを Pod に設定した場合は、動作に問題があると自動的に再起動されます。しかし、ヘルスチェックが不十分だと再起動されない可能性があります(僕はローカル環境での作業が主なので経験したことがないですが)。
そんな時は動作していない Pod の代わりの Pod レプリカを作成して望ましい状態の Pod 数にすると同時に、動作しなくなった Pod を調査したいため、動作していない Pod は起動したままにしておきたいと考えるのは、エンジニアとして当然だと思います。それは、ラベルの切り替え(削除)で出来そうですね。
Horizontal Pod Autoscalers (HPA)
複製された Pod のCPU使用率に応じて ReplicaSet を自動スケーリングすることも可能です。
まとめ
今回は Kubernetes のうれしいと思う機能の1つがセルフヒーリング(自己回復)を紹介しました。
- 望ましい状態を維持
- Pod と ReplicaSet の関連付けは Label で実現
- 自動スケーリング
セルフヒーリング(自己回復)はやはり魅力的です。それに望ましい状態を維持(調整ループ)、Pod と ReplicaSet の関連付け(疎結合)、自動スケーリングなど、一流モノからは色々学ぶことが多くて勉強になります。因みに、今回はルフヒーリング(自己回復)に注目しましたが、ReplicaSet は、複数の Pod にトラフィックを分散する Service のロードバランサと組み合わせて使用することが通常です。この辺りは Service、Deployment で理解を深めていければと思います。
おすすめ書籍
1.6,5 のバージョンで解説(リポジトリ、注釈は翻訳時の最新1.9で更新)されています。バージョンは少し古いですが、初心者の入門書(おえるべきポイントはしっかり網羅されてる)としては、途中で挫折しない適度なボリューム(本の厚さ)で、とっかかりとしては良い本になっています。
僕は「入門 Kubernetes」⇒「Kubernetes完全ガイド」(現在進行形)という進み方をしていますが、より本番環境を想定した方法を学べます。特にWeb 系だと、https で使用する Ingress リソースなどもしっかり説明してくれています。「入門 Kubernetes」には、詳しい説明がなかったので個人的にはすごく助かっています。
コンテナオーケストレーションプラットフォームである Kubernetes を学ぶときには、どうしても Docker の知識が必要となってきます。それをまとめているのが、この本です。途中で挫折しない適度なボリューム(本の厚さ)で、とっかかりとしては良い本になっています。