Kubernetes は、Kubernetes API をベースに構築されています。この Kubernetes API のおかげで、Kubernetes クラスターとやり取りしたり、Kubernetes クラスターを調査、管理したりすることができます。kubectl や kubeadm などのツールを使用している場合でも、各ツールが Kubernetes API とやり取りして変更を適用させることができます。Kubernetes API はクラスター管理にとって重要なコンポーネントであるため、この API の内容や機能を知っておくことが不可欠です。この記事では、Kubernetes API の概要とその仕組みについて説明します。
まず、Kubernetes API の内容と、この API が Kubernetes の全体的な戦略の中で果たしている役割を見てみましょう。次に、Kubernetes API でできることと、この API でアプリケーションをデプロイおよび管理する方法について説明します。また、さまざまな API コマンドを取り上げ、Kubernetes 環境での使用例をご覧いただきます。それでは始めましょう。
Kubernetes API が使用される理由
Kubernetes API は、Kubernetes のコントロールプレーンの基盤です。この API のおかげで、Kubernetes クラスター内のプリミティブ要素を作成、変更、削除することができます。また、この API によって、クラスター内のさまざまなコンポーネント間のやり取りが可能にし、外部のコンポーネントとのやり取りが容易になります。kubectl または kubeadm を使用していた場合は、これらのコマンドラインツールから API を間接的に呼び出していました。REST 呼び出しを使用すれば API に直接アクセスすることもできます。
Kubernetes API のドキュメントは、Kubernetes の Web サイトで簡単に入手できます。また、最新バージョンの API を探して、より具体的な情報を得ることもできます。(現時点で、この API の最新版はバージョン 1.23.0 です)。さらに詳しい情報を知りたい場合は、Kubernetes GitHub リポジトリで最新の API 仕様を直接確認するか、Swagger/OpenAPI 形式でダウンロードしてください。
Kubernetes クラスターは、異なる API パスで応答する複数の API バージョンをサポートできます。クラスターがサポートする API バージョンは、次の kubectl コマンドで判断できます:
$ kubectl api-versions
前述のとおり、Kubernetes API サーバー(kube-apiserver)は、etcd、kube-scheduler、kube-controller-manager、および cloud-controller-manager とともに、コントロールプレーン内に存在します。このコントロールプレーンは通常、他のコンテナが一切デプロイされていないノードに存在します。Kubernetes は kube-apiserver を水平方向にスケールするため、デプロイするインスタンスをクラスターの要求に応じて増やすことができます。API サーバーへのリクエストによってクラスターの望ましい状態が変わると、コントロールプレーンはその変更を管理し、クラスターの実際の状態を望ましい状態に合わせて調整します。
Kubernetes API とのやり取り
ほとんどの Kubernetes ユーザーは、kubectl などのツールを使用してクラスターとやり取りします。このコマンドラインツールのインストールと構成が完了すれば、クラスター上でアクションをテスト、実行するためのコマンドを使用できるようになります。このツールでは、コマンドの後にタイプを入力し、名前やさまざまなフラグを(必要に応じて)含めることができます。いくつかの一般的なコマンドを使って、クラスターに関するどのような情報が得られるのか見てみましょう。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-master Ready control-plane,master 22h v1.23.4
kube-worker1 Ready <none> 151m v1.23.4
kube-worker2 Ready <none> 136m v1.23.4
kube-worker3 Ready <none> 67m v1.23.4
Code language: HTML, XML (xml)
このコマンドは、nodes タイプを取得する get アクションを実行します。また、kubectl を使用して、create、describe、delete などその他のアクションを実行できます。先の出力結果で確認できるように、コントロールプレーンを実行するマスターノードを構成するクラスターが 1 つ存在します。また、使用可能なワーカーノードが 3 つ存在します。単一のノードを調べるには、そのノードの名前を含めます。ここでは、get アクションと type ノードを使用して、マスターノードを調べてみましょう。
$ kubectl get node kube-master
NAME STATUS ROLES AGE VERSION
kube-master Ready control-plane,master 22h v1.23.4
Code language: JavaScript (javascript)
コマンドを実行できるその他のリソースには、Service、Pod、Deployment などがあります。クラスター内で利用できるすべてのリソースの完全なリストを表示するには、kubectl api-resources を実行してください。kubectl は便利ですが(また、API とやり取りする手段の 1 つでもあります)、この記事は kubect について学ぶためのものではないため、kubect を最大限に活用されたい方は、優れたリソースである Kubernetes のドキュメントをお読みください。
Kubernetes API と直接やり取りするには、2 つの方法があります。1 つ目のアプローチは kubectl proxy を使用すること、2 つ目は認証トークンを生成し、各リクエストでヘッダーとして渡すことです。そこで、各アプローチを実行する方法と、それぞれのアプローチを選択する理由について説明しましょう。
プロキシは、kubectl ツール内に格納されている apiserver の場所と自己署名証明書を使用します。これにより、クラスターに接続するプロセスが驚くほど簡単になります。 Kubernetes では、中間者攻撃を回避するため、クラスターへのアクセスにプロキシアクセスを使用することを推奨しています。プロキシアクセスを設定するには、次の kubectl コマンドを使用します:
$ kubectl proxy --port=8080 &
[1] 747
$ Starting to serve on 127.0.0.1:8080
これで、プロキシがローカルワークステーションで実行されます。プロキシが実行されると、ブラウザ、curl、wget などのツールを使用して、API へのアクセスや API の調査ができるようになります。上の例では、これらのコマンドをローカルプロキシアドレス(127.0.0.1:8080 など)に対して実行しています。kubectl はクラスターとのやり取りを安全に管理しています。 ![]() 最初のステップは、リクエストでヘッダーとして渡すことができるトークンの生成です。その際、リクエストの管理を容易にするために、一連の環境変数を設定します。この最初のステップでは、アクセスしたいクラスターの名前を特定します。この名前は、kubectl で使用されている config ファイルで確認するか、次のコマンドを使用して kubectl に直接リストを問い合わせます。 |
$ kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'
Cluster name Server
kubernetes https://kube-master:6443
Code language: JavaScript (javascript)
K8S_NAME. と呼ばれる変数にクラスターの名前を保存しましょう。
$ export K8S_NAME=”kubernetes”
Code language: JavaScript (javascript)
次に、クラスターの API サーバー(名前は K8S_API)のアドレスを使用して変数を作成します。この情報は、最初のリクエストから取得するか、K8S_NAME を使って次のコマンドをコピーアンドペーストして作成します。
$ K8S_API=$(kubectl config view -o
jsonpath="{.clusters[?(@.name==\"$K8S_NAME\")].cluster.server}")
Code language: JavaScript (javascript)
次のステップは、トークンを保持するシークレットの作成です。ここでも、kubectl コマンドを使用します。
$ kubectl apply -f - <<EOF
> apiVersion: v1
> kind: Secret
> metadata:
> name: default-token
> annotations:
> kubernetes.io/service-account.name: default
> type: kubernetes.io/service-account-token
> EOF
secret/default-token created
Code language: JavaScript (javascript)
トークンコントローラがシークレットにトークンを入力するまで待機する、小さなルーチンが必要です。
$ while ! kubectl describe secret default-token | grep -E '^token' >/dev/null; do
> echo "waiting for token..." >&2
> sleep 1
> done
Code language: JavaScript (javascript)
最後に、トークンの値を取得して、K8S_TOKEN と呼ばれる変数に代入します。なお、このトークンは Web アプリケーションでよく使用される標準的な Javascript Web Token(JWT)です。
$ K8S_TOKEN=$(kubectl get secret default-token -o
jsonpath='{.data.token}' | base64 --decode)
Code language: JavaScript (javascript)
このトークンを使用すると、マスターノード上の kubeapi-server に対して直接 API 呼び出しを実行できます。その際、-insecure フラグを使用して SSL 証明書の検証を回避します。
$ curl -X GET $K8S_API/api --header "Authorization: Bearer $K8S_TOKEN" --insecure
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 183 100 183 0 0 5382 0 --:--:-- --:--:-- --:--:-- 5545
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "172.16.10.8:6443"
}
]
}
Code language: PHP (php)
最初に述べたように、Kubernetes API はクラスターに関する詳細情報を取得したり、Deployment の追加や操作、Service の追加、アプリケーションのスケールアップやスケールダウンを通じてクラスターを管理したりするための基盤です。この API の真の価値は、プログラムでやり取りできることにあります。この機能を支援するために、Kubernetes は Go、Python、Java、dotnet、Javascript、Haskell といったよく使われる言語向けのクライアントライブラリを提供し、サポートしています。
Kubernetes の API Watch について
API の用途の 1 つは、クラスターで実行されているアプリケーションやリソースの現在の状態を把握することです。不安定な動作やその他の問題のトラブルシューティングを行っている場合は、API リクエストを実行して状況を監視できます。とはいえ、API コマンドを繰り返し実行して応答の変化を確認する作業は、退屈なばかりか、現実的ではなく、あまり意味がありません。Kubernetes API は、API 呼び出し上に特定のリソースの経時的な状態変化を監視することを設定できる、Watch と呼ばれる概念もサポートしています。
そこで、kubectl による Watch の実行について見てみましょう(Watch は API 自体で直接実行することもできます)。ここでは、クラスター上で Deployment を作成してスケールアップします。この Deployment のために、nginx イメージのバージョン 1 を使用します。
$ kubectl create deployment nginx --image=nginx:1
deployment.apps/nginx created
$ kubectl autoscale deployment nginx --min=5 --max=10
horizontalpodautoscaler.autoscaling/nginx autoscaled
このクラスターには、nginx アプリケーションを実行する 5 つの pod が必要です。ここでは、その Deployment で使用するイメージをバージョン 1.21 に更新します。その後、get pods アクションとリソースを使用して、更新中の Pod の状態を確認します。
$ kubectl set image deployment/nginx nginx=nginx:1.21
deployment.apps/nginx image updated
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-65895c4c4f-8x7z2 1/1 Terminating 0 6m39s
nginx-65895c4c4f-fqmhp 1/1 Running 0 6m30s
nginx-65895c4c4f-n8kf6 1/1 Running 0 6m30s
nginx-65895c4c4f-nbgng 1/1 Running 0 6m29s
nginx-65895c4c4f-qc4fh 1/1 Running 0 6m30s
nginx-f594cdf46-49k7d 0/1 ContainerCreating 0 3s
nginx-f594cdf46-7rtw4 0/1 ContainerCreating 0 2s
nginx-f594cdf46-lv2kk 0/1 ContainerCreating 0 3s
Code language: JavaScript (javascript)
実行、停止、作成など、Pod のさまざまな状態を監視できます。Kubernetes では、アプリケーションへのアクセスを維持しながら更新を実行できます。ただし、Deployment の状況を監視するには、kubectl get pods コマンドを繰り返し実行して、経時的な変化を確認する必要があります。そこで、最新の Deployment をロールバックして Watch を設定し、同じコマンドを繰り返し実行しなくてもリアルタイムで状況を監視できるようにしましょう。まず、この Deployment のロールアウト履歴をチェックします。
$ kubectl rollout history deployment/nginx
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 <none>
2 <none>
Code language: HTML, XML (xml)
この Deployment を直前のバージョンにロールバックして Watch を設定し、状況を監視できるようにしましょう。Watch フラグの -w を status パラメーターの後に追加して、Deployment が完了するまでリアルタイムで監視します。
$ kubectl rollout undo deployment/nginx --to-revision=1
deployment.apps/nginx rolled back
$ kubectl rollout status -w deployment/nginx
Waiting for deployment "nginx" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 3 out of 5 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 2 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 4 of 5 updated replicas are available...
deployment "nginx" successfully rolled out
Code language: JavaScript (javascript)
kubectl がロールアウトを確認すると、インサイトを提供します。ただし、kubectl 出力が十分な情報を提供しない場合や、この情報を別のツールに表示したい場合は、API を使って生の情報を取得できます。
先に設定したプロキシを使用すると、追加または停止された各 Pod に関するデータを大量に収集できます。API を使用するもう 1 つのメリットは、渡したパラメーターに基づいて Watch が情報を継続的に提供してくれることです。このアプリケーションに対して、別のターミナルから curl http://localhost:8080/api/v1/namespaces/default/pods?watch=1&app=nginx を実行すれば、起こっている変化を確認したり、その情報を別のツールに取り込んで詳しい分析を行ったりできます。
$ curl http: //localhost:8080/api/v1/namespaces/default/pods?watch=1&app=nginx
[1] 1236
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0--: --: -- --: --: -- --: --: --0
$ {
"type": "ADDED",
"object": {
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "nginx-f594cdf46-b8rmz",
"generateName": "nginx-f594cdf46-",
"namespace": "default",
"uid": "a2315438-4e70-485b-8de1-12d9a2f4cee0",
"resourceVersion": "115953",
"creationTimestamp": "2022-03-16T08:44:34Z",
"labels": {
"app": "nginx",
"pod-template-hash": "f594cdf46"
},
"annotations": {
"cni.projectcalico.org/containerID": "ad6ec053a52ede11a94e832afbc9f0dc4a3e2f801cdf28393b8ac70fd54cfb3e",
"cni.projectcalico.org/podIP": "10.10.130.137/32",
"cni.projectcalico.org/podIPs": "10.10.130.137/32"
},
"ownerReferences": [{
"apiVersion": "apps/v1",
"kind": "ReplicaSet",
"name": "nginx-f594cdf46",
"uid": "661d57f3-75ce-494a-8b16-001ccbae090f",
"controller": true,
"blockOwnerDeletion": true
}],
"managedFields": [{
"manager": "kube-controller-manager",
"operation": "Update",
"apiVersion": "v1",
"time": "2022-03-16T08:44:34Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:generateName": {},
"f:labels": {
".": {},
"f:app": {},
"f:pod-tem…
Code language: JavaScript (javascript)
詳細情報
Kubernetes API は、その名前が示しているように、クラスター内のあらゆるものを管理、制御、監視するためのインターフェイスです。Kubernetes の Web サイトは、この API を「Kubernetes の基礎構造」と述べています。kubectl のようなツールはクラスターを管理および表示するための簡単で使いやすい手段ですが、API に直接アクセスすれば、より広く詳しい情報にアクセスできるだけでなく、より細かな制御が可能になります。
詳細情報やテストに関する情報を知りたい方は、まず Kubernetes のドキュメントをお読みになることをお勧めします。基本的なコンセプトからこの API を最大限に活用する方法まで、あらゆる情報を入手できます。