2024年01月22日
連載 第1回 Kubernetesの特徴と
ネイティブKubernetes vs
マネージドKubernetesの比較
DevOpsでネイティブクバネティスとマネージドクバネティス(EKS)の経験者である執筆者が、実際に運用する立場からクバネティスの主要な三つの特徴とネイティブクバネティスとマネージドクバネティスの異なるポイントを説明します。
1. Desired State (望ましい状態) 管理
クバネティスの主な特徴として、まず、クバネティスは「望ましい状態」という核心的な概念でクラスタを管理します。「望ましい状態」とは言葉から推測できるように、クラスタ内のアプリケーションとリソースをどのように動作すべきかを明示的に定義して、現在の状態がこの定義した「望ましい状態」と一致するように維持するプロセスを意味します。
この概念はクバネティスがアプリケーション及びインフラを自動的に管理し維持するための原則の一つです。例えば、突然、実行中のプロセスの一つがダウンすると、ユーザの介入が無くてもクバネティスが自動的にそのプロセスを開始して、事前に定義した「望ましい状態」を一貫して維持するという、障害への対応力が優れています。
執筆者はUnixシステムのソラリス(Solaris)の管理者でした。障害が発生すると早朝でも運用チームから電話を貰うと、問題のサーバのコンソールに1つずつ接続してコマンドで該当プロセスを再起動していました。
しかし、これからはクバネティスが代わりにその作業を行います。「望ましい状態」の管理はDevOps文化と併せてクラウドネイティブ環境でよく使われる概念です。これによりシステム管理の効率性と信頼性を向上できます。
例えば、下記のようにNGINX配布を実行します。
配布(Deployment)はアプリケーションのインスタンスを管理するクバネティスリソースのリソースです。下記のようなkubectlコマンドを使用します。kubectlコマンドの使用法などの詳細は今後の連載の中で説明します。
1. $ (⎈ |switch-singapore-test:default) kubectl create deployment nginx –image=nginx
2. deployment.apps/nginx created
このコマンドでNGINXポッドが実行されます。‘k get pod’コマンドでポッドの現在の状況を確認できます。
ポッドとは、一つ以上のコンテナを含むクバネティスで使用する最も小さい配布の単位です。ポッドはコンテナの論理的なホストで、同じポッド内のコンテナは同じネットワークネームのスペース、IPアドレス、ポート範囲、ストレージなどを共有します。
1. $ (⎈ |switch-singapore-test:default) k get pod
2. NAME READY STATUS RESTARTS AGE
3. nginx-748c667d99-d6bb5 1/1 Running 0 2m17s
任意に障害状況を発生させてみます。
リアルタイムの変化の状態を確認するには、下記のようにコマンドを2つに分けて、最初のコマンドはポッドを削除します。ポッドを削除するコマンドは‘k delete pod’です。
1. $ (⎈ |switch-singapore-test:default) k delete pod nginx-748c667d99-d6bb5
2. pod "nginx-748c667d99-d6bb5" deleted
次のコマンドはポッドの状態の変化を-w(watch)オプションを使用してリアルタイムに確認します。下記の画面で削除されたポッドが自動的に生成されることを確認できます。
1. $ (⎈ |switch-singapore-test:nginx) k get pod -w
2. NAME READY STATUS RESTARTS AGE
3. nginx-748c667d99-d6bb5 1/1 Running 0 4m19s
4. nginx-748c667d99-d6bb5 1/1 Terminating 0 4m30s
5. nginx-748c667d99-jmb7z 0/1 Pending 0 0s
6. nginx-748c667d99-jmb7z 0/1 ContainerCreating 0 0s
7. nginx-748c667d99-d6bb5 0/1 Terminating 0 4m31s
8. nginx-748c667d99-jmb7z 1/1 Running 0 3s
名称 ‘nginx-748c667d99-d6bb5’を持つポッドが終了(Terminating)して、新しい名称 ‘nginx-748c667d99-jmb7z’のポッドが実行(Running)します。
クバネティスはポッドが終了したことを確認して自動的に新しいポッドを実行しました。即ち、クバネティスがプロセスのダウンを検知して自動的に最初の「望ましい状態」へ復旧しました。
参考までに名称 ‘nginx-748c667d99-d6bb5’はクバネティス配布リソースがnginx配布名に自動的に任意のハッシュ値を付加して作成しました。
最初に‘kubectl create deployment’ コマンドでポッドを生成します。すると、クバネティス配布は「望ましい状態」をポッドが実行状態と定義します。そのため、任意の(又はシステムの突然の障害で)ポッドを削除しても、クバネティスは「望ましい状態」のポッドの一つが実行している状態を自動的に維持するためにポッドを再起動します。
内部的にDeploymentリソースはReplicaSet Controllerという名称のコントローラを利用して常に「望ましい状態」を維持します。もし、ポッドの数を3と宣言すると、常に三つの状態をReplicaSet Controllerにより維持し、ポッドが一つの場合と同様にクバネティスは多様なコントローラを使用して常に「望ましい状態」を維持します。
担当者は事前に「望ましい状態」を定義すると、クバネティスは多様なコントローラのリソースを利用して「望ましい状態」を自動的に維持します。つまり、セルフヒーリング (Self-Healing)が可能で開発担当者と運用担当者の間のコミュニケーションが円滑になります。
2. コードを利用したリソース管理
クバネティスの全てのリソースはコードで管理します。例えば、アプリケーションをインストールする際には、以前のVM環境では下記のようにyumコマンドを使用しました。
1. yum install -y nginx
コマンドを段階別に実行するプロセスを並べて求める結果を得たいと思います。特に、特定のコマンドを順次に実行することで正常に動作します。
しかし、時間が経過すると、システムの状態が変化して、変更した事項を追跡し、管理することは難しいです。現場ではマニュアルの文書で管理しますが、現在のシステムの状態が既存のマニュアルの文書と一致していると保証できません。
クバネティス環境でも前の例のようにkubectl create deploymentコマンドを使用できますが、全てのリソースを下記のようにコードファイルを利用して生成することもできます。
1. apiVersion: apps/v1
2. kind: Deployment
3. metadata:
4. name: nginx-deployment
5. labels:
6. app: nginx
7. spec:
8. replicas: 3
9. selector:
10. matchLabels:
11. app: nginx
12. template:
13. metadata:
14. labels:
15. app: nginx
16. spec:
17. containers:
18. - name: nginx
19. image: nginx:1.14.2
20. ports:
21. - containerPort: 80
クバネティスリソースをコマンドでなくコードで管理するということは宣言型の方法で管理することを意味します。
クバネティスは宣言型の方法を用いたプラットフォームで、この「宣言型形式」とは最終状態を明示的に定義して、システムがその状態を維持するアプローチ方法です。宣言型の方法では作業を行う過程や段階を明示せず、求める結果の最終状態を定義して、システムがその結果を達成できるように誘導します。
コードでリソースを定義する際には、どのリソースが必要で、どの設定をすべきかを明確に定義します。これによりクラスタ内のリソースが一貫性を持った構成で生成されて、予想外の設定ミスやトラブルを防止し、システムの安定性を高めました。
実際、リソースを配布する前にコードを定義して、事前にチームでこれをレビューし(PR Review) 、作業中に発生する可能性がある障害を予防できます。また、同じコードを使用することができ、インフラ構成を再現するときに有用です。どの環境でも同じコードを実行すると、同じリソースが配布されるため、開発、テスト、パッケージなど多様な環境で一貫した環境を維持できます。また、バージョン管理システム(例: Git)で変更事項を追跡し、管理できます。 これにより変更の内訳を追跡して、チームメンバーと共同で変更事項を調整できます。
運用担当者は、開発担当者とは異なりコードを使用することに慣れていません。しかし、クバネティスで使用するコードは一般的なプログラミング言語と異なり、複雑でないこともメリットです。簡単なYAMLファイル文法を理解すれば使用できます。また、VSCodeなどのツールを使用すると自動生成、文法の自動チェックの機能を活用することもできて便利です。
3. 高可用性な構成(Pet vs Cattle)
ペットと家畜 (Pet vs Cattle)の概念について説明します。
ペットと家畜の考え方はインフラ管理に関連する二つのアプローチ方法がその事例です。ペットは個別的で特別な管理が必要で、名前を付けて特別な関心を持って育てます。一方、家畜は特別な名前を付けず、一般的にはタグまたは番号を使用します。前の例ではポッド名(nginx-748c667d99-d6bb5)に任意のハッシュ値を使用しました。大規模に管理できるように拡張性と柔軟性が必要です。
コンテナ基盤のオーケストレーションツールのクバネティスは家畜(Cattle)の管理方法を用います。 クバネティスはコンテナ化されたアプリケーションを標準化された方法で管理して、インフラの構成を自動化し、拡張できるように構築します。これによりアプリケーションの配布、拡張、ローリングアップデート、自動復旧などを効率的に行うことができます。
例えば、クバネティスはアプリケーション(Webサーバ)とアプリケーション(DBサーバ)がコネクションするとき、既存のVM環境で使用するIP接続の方法ではないドメイン名で接続するサービス(Service) リソースを使用します。既存で使用していたIP接続の方法は固定の(Static)値を使用しているので、DBサーバを変更すると、IPが変更されて、Webサーバの環境変数などに設定されたIPも変更する必要があります。しかし、クバネティスは動的な(Dynamic)ドメインの方法を使用しているので、IPを変更すると自動的に変更されたIPに接続されます。
これと同じくクバネティスは常に障害が発生する可能性があると想定して、障害が発生しても自動的に復旧及びサービスを持続させるため、ロードバランス、Advancedスケジューリング、Readiness/Liveness Probeなどの多様な機能をサポートします。下記はクバネティスのサービスリソースの例です。
1. $ (⎈ |switch-singapore-test:nginx) k get service
2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3. nginx ClusterIP 172.20.14.84 <none> 80/TCP,9113/TCP 23h
4.
5. # 1回目 endpoint
6. $ (⎈ |switch-singapore-test:nginx) k get endpoints
7. NAME ENDPOINTS AGE
8. nginx 10.110.1.118:9113,10.110.1.118:8080 23h
9.
10. # 2回目 endpoint
11. $ (⎈ |switch-singapore-test:nginx) k get ep
12. NAME ENDPOINTS AGE
13. nginx 10.110.23.249:9113,10.110.23.249:8080 23h
ポッド間をコネクションするときnginxという名前のサービスを利用します。このサービスは自動的に「endpoints(終点)」を生成して、ポッドのIPが変更されると自動的にこのサービスにマッピングされたIPをアップデートします。そのため、IPが変更されてもサービス名は変更が無く、既存のnginxサービス名をそのままポッド間のコネクションに使用できます。
4. ネイティブクバネティスvsマネージドクバネティスの比較
オンプレミス環境でクバネティスを使用する場合、公式配布バージョンのネイティブクバネティスを使用するか、OpenShiftやTanzuなどのベンダーのソリューションを使用します。
クラウド環境は各 CSP(Cloud Service Provider)で提供するマネージドクバネティスでEKS(Amazon Elastic Kubernetes Service)、AKS(Azure Kubernetes Service)、GKE(Google Kubernetes Engine)を主に使用します。
ネイティブクバネティスを「Vanilla Kubernetes(純粋なオープンソースのクバネティス)」とも呼びます。「Vanilla Kubernetes(純粋なオープンソースのクバネティス)」とはクバネティスの公式ディスリビューションを意味します。Vanillaは一般的に本来の状態を意味する用語です。ここではクバネティスの公式配布バージョンを他と区別するために使用します。
クバネティスはオープンソースプロジェクトでCNCF(クラウド ネイティブコンピュータ財団)により管理されます。CNCFはクバネティスの開発とメンテナンスを担当して、クバネティスの公式配布バージョンをサポートします。 この公式配布バージョンを「Vanilla Kubernetes(純粋なオープンソースのクバネティス)」と呼ぶのは、この配布バージョンがクバネティスのデフォルト構成の要素と機能を含んでいて、CNCFで提供する本来の状態を表しています。
ネイティブクバネティスとマネージドクバネティスの異なる主なポイントは、ネイティブクバネティスはインストール、アップグレード及びコントロールプレーンの管理が必要なことです。
一方、マネージドクバネティスはインストールなどに関連する一連のガイドを提供し、コントロールプレーンは直接管理します。 また、自社の他のリソースと統合されてクバネティス環境のストレージの構成やネットワークの構成がネイティブ環境と比べて容易です。
しかし、 アプリケーションを配布してサービスを安定的に運用するという面では2つのサービスはそれほど大きな差はありません。
両者はクバネティス基盤のシステムで、クバネティスに対する理解が必要でHelm、ArgoCD、Ingressなどの多様なオープンソースと巧みに連携する作業が重要です。個人的な意見ですが、2つのサービスで毎日行う作業の80%〜90%は同じです。マネージドクバネティスサービスを使用することで業務量が減るとか難易度が低くなることはありません。
例としてネイティブクバネティスではkube-system ネームスペースで多様なポッドを確認できます。
1. $ (⎈ |alooo:kube-system) k get pod
2. NAME READY STATUS RESTARTS AGE
3. calico-kube-controllers-7b9cddc446-clpc4 1/1 Running 1 (15d ago) 117d
4. calico-node-2brvj 1/1 Running 0 117d
5. (省略)
6. coredns-68868dc95b-6mj9l 1/1 Running 0 117d
7. coredns-68868dc95b-znpdb 1/1 Running 0 117d
8. dns-autoscaler-7ccd65764f-546k4 1/1 Running 0 117d
9. kube-apiserver-master1 1/1 Running 2 (117d ago) 117d
10. kube-apiserver-master2 1/1 Running 1 117d
11. kube-apiserver-master3 1/1 Running 1 117d
12. kube-controller-manager-master1 1/1 Running 44 (65m ago) 117d
13. kube-controller-manager-master2 1/1 Running 64 (64m ago) 117d
14. kube-controller-manager-master3 1/1 Running 62 (2d1h ago) 117d
15. kube-proxy-92rpp 1/1 Running 0 117d
16. (省略)
17. kube-scheduler-master1 1/1 Running 48 (25h ago) 117d
18. kube-scheduler-master2 1/1 Running 68 (65m ago) 117d
19. kube-scheduler-master3 1/1 Running 75 (64m ago) 117d
20. metrics-server-6db6c9dd4-gtz55 1/1 Running 0 111d
21. nginx-proxy-node1 1/1 Running 0 117d
22. nginx-proxy-node2 1/1 Running 0 117d
23. nginx-proxy-node3 1/1 Running 0 117d
24. nodelocaldns-4gttk 1/1 Running 4 (32d ago) 117d
25. (省略)
上記の通りEtcd、controller manager、scheduler、api-serverなどのコントロールプレーンを構成する多様なポッドを確認できます。
しかし、EKSはコントロールプレーンをAWSで直接管理するため、そのポッドを確認することはできません。実行されるポッドリストを確認すると比較的シンプルです。
1. $ (⎈ |switch-singapore-test:kube-system) k get pod
2. NAME READY STATUS RESTARTS AGE
3. aws-load-balancer-controller-7d96db6884-dh8rc 1/1 Running 0 34d
4. aws-load-balancer-controller-7d96db6884-vwttg 1/1 Running 0 34d
5. aws-node-kwqkb 1/1 Running 0 17d
6. aws-node-xvgxm 1/1 Running 0 20d
7. coredns-d9bc8f875-8wgjp 1/1 Running 0 20d
8. coredns-d9bc8f875-ml4f6 1/1 Running 0 20d
9. ebs-csi-controller-b995956fb-nbxqg 6/6 Running 0 45d
10. ebs-csi-controller-b995956fb-t2jnk 6/6 Running 0 45d
11. ebs-csi-node-47trz 3/3 Running 0 45d
12. ebs-csi-node-5ffxg 3/3 Running 0 17d
13. external-dns-5555f6796f-jtrgf 1/1 Running 0 2d17h
14. kube-proxy-6gqfl 1/1 Running 0 17d
15. kube-proxy-l95v9
コントロールプレーン管理以外の作業など、多様なオープンソースの管理作業は同じです。クバネティス運用に必須で多様なオープンソースプロジェクトリストはCNCFサイトで確認できます。
CNCFサイトでは上記の様に多数のオープンソースプロジェクトを確認できます。企業毎に環境により上記のオープンソースを巧みに組み合わせて使用します。
クバネティスを運用することはクバネティスを含め、多様なオープンソースを管理することと同じで、クバネティスだけでなく多様なオープンソースに対する理解が必要です。幸いにも、クバネティスは多くの会社で既に標準的に利用され、多くの事例があります。ドキュメントも豊富で本番稼働に適用し易い状況にあります。
以上、クバネティスの特徴とネイティブクバネティスvsマネージドクバネティスのサービスを比較しました。
- kubectl コマンドは以上のようにkubectl create{動詞} deployment{リソース} 形式です。
- ‘k get pod’ は現在のポッドの状況を確認するコマンドです。kubectlを省略してkを使用することができます。Kubectlコマンドの使用法の詳細は次項番を参考にしてください。
- 勿論、VM環境でもAnsible、Terraformなどコードでインフラを管理できます。しかし、コマンドでも可能で大半の会社のVM環境ではコマンドを使用することが一般的です。