これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
ベストプラクティス
- 1: 複数のゾーンで動かす
- 2: 大規模クラスターの構築
- 3: ノードのセットアップの検証
- 4: PKI証明書とその要件
1 - 複数のゾーンで動かす
This page describes how to run a cluster in multiple zones.
始めに
Kubernetes 1.2より、複数のゾーンにおいて単一のクラスターを運用するサポートが追加されました(GCEでは単純に"ゾーン",AWSは"アベイラビリティゾーン"と呼びますが、ここでは"ゾーン"とします)。 これは、より範囲の広いCluster Federationの軽量バージョンです(以前は"Ubernetes"の愛称で言及されていました)。 完全なCluster Federationでは、異なるリージョンやクラウドプロバイダー(あるいはオンプレミスデータセンター)内の独立したKubernetesクラスターをまとめることが可能になります。しかしながら、多くのユーザーは単に1つのクラウドプロバイダーの複数のゾーンでより可用性の高いKubernetesクラスターを運用したいと考えており、バージョン1.2におけるマルチゾーンサポート(以前は"Ubernetes Lite"の愛称で使用されていました)ではこれが可能になります。
マルチゾーンサポートは故意に限定されています: 1つのKubernetesクラスターは複数のゾーンで運用することができますが、同じリージョン(あるいはクラウドプロバイダー)のみです。現在はGCEとAWSのみが自動的にサポートされています(他のクラウドプロバイダーやベアメタル環境においても、単にノードやボリュームに追加する適切なラベルを用意して同様のサポートを追加することは容易ではありますが)。
機能性
ノードが開始された時、kubeletは自動的にそれらにゾーン情報を付したラベルを追加します。
Kubernetesはレプリケーションコントローラーやサービス内のPodをシングルゾーンクラスターにおけるノードにデプロイします(障害の影響を減らすため)。マルチゾーンクラスターでは、このデプロイの挙動はゾーンを跨いで拡張されます(障害の影響を減らすため)(これはSelectorSpreadPriority
によって可能になります)。これはベストエフォートな配置であり、つまりもしクラスターのゾーンが異種である(例:異なる数のノード,異なるタイプのノードや異なるPodのリソース要件)場合、これはゾーンを跨いだPodのデプロイを完璧に防ぐことができます。必要であれば、同種のゾーン(同一の数及びタイプのノード)を利用して不平等なデプロイの可能性を減らすことができます。
永続ボリュームが作成されると、PersistentVolumeLabel
アドミッションコントローラーがそれらにゾーンラベルを付与します。スケジューラーはVolumeZonePredicate
を通じて与えられたボリュームを請求するPodがそのボリュームと同じゾーンにのみ配置されることを保証します、これはボリュームはゾーンを跨いでアタッチすることができないためです。
制限
マルチゾーンサポートにはいくつか重要な制限があります:
-
異なるゾーンはネットワーク内においてお互いに近接して位置していることが想定されているため、いかなるzone-aware routingも行われません。特に、トラフィックはゾーンを跨いだサービスを通じて行き来するため(サービスをサポートするいくつかのPodがクライアントと同じゾーンに存在していても)、これは追加のレイテンシやコストを生むかもしれません。
-
Volume zone-affinityは
PersistentVolume
と共に動作し、例えばPodのスペックにおいてEBSボリュームを直接指定しても動作しません。 -
クラスターはクラウドやリージョンを跨げません(この機能はフルフェデレーションサポートが必要です)。
*ノードは複数のゾーンに存在しますが、kube-upは現在デフォルトではシングルマスターノードでビルドします。サービスは高可用性でありゾーンの障害に耐えることができますが、コントロールプレーンは単一のゾーンに配置されます。高可用性コントロールプレーンを必要とするユーザーは高可用性の説明を参照してください。
ボリュームの制限
以下の制限はtopology-aware volume bindingに記載されています。
-
動的なプロビジョニングを使用する際のStatefulSetボリュームゾーンのデプロイは、現在Podのアフィニティあるいはアンチアフィニティと互換性がありません。
-
StatefulSetの名前がダッシュ("-")を含む場合、ボリュームゾーンのデプロイはゾーンを跨いだストレージの均一な分配を提供しない可能性があります。
-
DeploymentやPodのスペックにおいて複数のPVCを指定すると、StorageClassは特定の1つのゾーンに割り当てる必要があります、あるいはPVは特定のゾーンに静的にプロビジョンされる必要があります。もう一つの解決方法として、StatefulSetを使用すると、レプリカに対する全てのボリュームが同じゾーンにプロビジョンされます。
全体の流れ
GCEとAWSの両方にマルチゾーンのクラスターをセットアップし使用する手順について説明します。そのために、フルクラスターを用意し(MULTIZONE=true
と指定する)、kube-up
を再び実行して追加のゾーンにノードを追加します(KUBE_USE_EXISTING_MASTER=true
と指定する)。
クラスターの立ち上げ
通常と同様にクラスターを作成します、しかし複数のゾーンを管理するためにMULTIZONEをクラスターに設定します。ノードをus-central1-aに作成します。
GCE:
curl -sS https://get.k8s.io | MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a NUM_NODES=3 bash
AWS:
curl -sS https://get.k8s.io | MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a NUM_NODES=3 bash
このステップは通常と同様にクラスターを立ち上げ、1つのゾーンで動作しています(しかし、MULTIZONE=true
によりマルチゾーン能力は有効になっています)。
ノードはラベルが付与される
ノードを見てください。それらがゾーン情報と共にラベルされているのが分かります。
それら全ては今のところus-central1-a
(GCE)あるいはus-west-2a
(AWS)にあります。ラベルはtopology.kubernetes.io/region
がリージョンに、topology.kubernetes.io/zone
はゾーンに付けられています:
kubectl get nodes --show-labels
結果は以下のようになります:
NAME STATUS ROLES AGE VERSION LABELS
kubernetes-master Ready,SchedulingDisabled <none> 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-1,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-87j9 Ready <none> 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready <none> 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready <none> 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
2つ目のゾーンにさらにノードを追加
それでは、現存のマスターを再利用し、現存のクラスターの異なるゾーン(us-central1-bかus-west-2b)にもう1つのノードのセットを追加しましょう。
kube-upを再び実行します.しかしKUBE_USE_EXISTING_MASTER=true
を指定することでkube-upは新しいマスターを作成せず、代わりに以前作成したものを再利用します。
GCE:
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-b NUM_NODES=3 kubernetes/cluster/kube-up.sh
AWSではマスターの内部IPアドレスに加えて追加のサブネット用のネットワークCIDRを指定する必要があります:
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2b NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.1.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
ノードをもう1度見てください。更なる3つのノードがus-central1-bに起動し、タグ付けられているはずです:
kubectl get nodes --show-labels
結果は以下のようになります:
NAME STATUS ROLES AGE VERSION LABELS
kubernetes-master Ready,SchedulingDisabled <none> 16m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-1,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master
kubernetes-minion-281d Ready <none> 2m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-87j9 Ready <none> 16m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9
kubernetes-minion-9vlv Ready <none> 16m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-a12q Ready <none> 17m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-a12q
kubernetes-minion-pp2f Ready <none> 2m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-pp2f
kubernetes-minion-wf8i Ready <none> 2m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-wf8i
ボリュームのアフィニティ
動的ボリュームを使用してボリュームを作成します(PersistentVolumeのみがゾーンアフィニティに対してサポートされています):
kubectl apply -f - <<EOF
{
"apiVersion": "v1",
"kind": "PersistentVolumeClaim",
"metadata": {
"name": "claim1",
"annotations": {
"volume.alpha.kubernetes.io/storage-class": "foo"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "5Gi"
}
}
}
}
EOF
それでは、KubernetesがPVが作成されたゾーン及びリージョンを自動的にラベルしているか確認しましょう。
kubectl get pv --show-labels
結果は以下のようになります:
NAME CAPACITY ACCESSMODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE LABELS
pv-gce-mj4gm 5Gi RWO Retain Bound default/claim1 manual 46s topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a
では永続ボリュームクレームを使用するPodを作成します。 GCE PD / AWS EBSボリュームはゾーンを跨いでアタッチできないため、これはこのPodがボリュームと同じゾーンにのみ作成されることを意味します:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: claim1
EOF
一般的にゾーンを跨いだアタッチはクラウドプロバイダーによって許可されていないため、Podは自動的にボリュームと同じゾーンに作成されることに注意してください:
kubectl describe pod mypod | grep Node
Node: kubernetes-minion-9vlv/10.240.0.5
ノードのラベルをチェックします:
kubectl get node kubernetes-minion-9vlv --show-labels
NAME STATUS AGE VERSION LABELS
kubernetes-minion-9vlv Ready 22m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
Podがゾーンをまたがって配置される
レプリケーションコントローラーやサービス内のPodは自動的にゾーンに跨いでデプロイされます。まず、3つ目のゾーンに更なるノードを立ち上げましょう:
GCE:
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-f NUM_NODES=3 kubernetes/cluster/kube-up.sh
AWS:
KUBE_USE_EXISTING_MASTER=true MULTIZONE=true KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2c NUM_NODES=3 KUBE_SUBNET_CIDR=172.20.2.0/24 MASTER_INTERNAL_IP=172.20.0.9 kubernetes/cluster/kube-up.sh
3つのゾーンにノードがあることを確認します:
kubectl get nodes --show-labels
シンプルなWebアプリケーションを動作する、3つのRCを持つguestbook-goの例を作成します:
find kubernetes/examples/guestbook-go/ -name '*.json' | xargs -I {} kubectl apply -f {}
Podは3つの全てのゾーンにデプロイされているはずです:
kubectl describe pod -l app=guestbook | grep Node
Node: kubernetes-minion-9vlv/10.240.0.5
Node: kubernetes-minion-281d/10.240.0.8
Node: kubernetes-minion-olsh/10.240.0.11
kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels
NAME STATUS ROLES AGE VERSION LABELS
kubernetes-minion-9vlv Ready <none> 34m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
kubernetes-minion-281d Ready <none> 20m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d
kubernetes-minion-olsh Ready <none> 3m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,topology.kubernetes.io/region=us-central1,topology.kubernetes.io/zone=us-central1-f,kubernetes.io/hostname=kubernetes-minion-olsh
ロードバランサーはクラスター内の全てのゾーンにデプロイされています; guestbook-goの例は負荷分散サービスのサンプルを含みます:
kubectl describe service guestbook | grep LoadBalancer.Ingress
結果は以下のようになります:
LoadBalancer Ingress: 130.211.126.21
IPの上に設定します:
export IP=130.211.126.21
IPをcurlを通じて探索します:
curl -s http://${IP}:3000/env | grep HOSTNAME
結果は以下のようになります:
"HOSTNAME": "guestbook-44sep",
再び、複数回探索します:
(for i in `seq 20`; do curl -s http://${IP}:3000/env | grep HOSTNAME; done) | sort | uniq
結果は以下のようになります:
"HOSTNAME": "guestbook-44sep",
"HOSTNAME": "guestbook-hum5n",
"HOSTNAME": "guestbook-ppm40",
ロードバランサーは、たとえPodが複数のゾーンに存在していても、全てのPodをターゲットします。
クラスターの停止
終了したら、クリーンアップします:
GCE:
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-f kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=gce KUBE_USE_EXISTING_MASTER=true KUBE_GCE_ZONE=us-central1-b kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=gce KUBE_GCE_ZONE=us-central1-a kubernetes/cluster/kube-down.sh
AWS:
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2c kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2b kubernetes/cluster/kube-down.sh
KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a kubernetes/cluster/kube-down.sh
2 - 大規模クラスターの構築
クラスターはKubernetesのエージェントが動作する(物理もしくは仮想の)ノードの集合で、コントロールプレーンによって管理されます。 Kubernetes v1.23 では、最大5000ノードから構成されるクラスターをサポートします。 具体的には、Kubernetesは次の基準を 全て 満たす構成に対して適用できるように設計されています。
- 1ノードにつきPodが110個以上存在しない
- 5000ノード以上存在しない
- Podの総数が150000個以上存在しない
- コンテナの総数が300000個以上存在しない
ノードを追加したり削除したりすることによって、クラスターをスケールできます。 これを行う方法は、クラスターがどのようにデプロイされたかに依存します。
クラウドプロバイダーのリソースクォータ
クラウドプロバイダーのクォータの問題に遭遇することを避けるため、多数のノードを使ったクラスターを作成するときには次のようなことを考慮してください。
- 次のようなクラウドリソースの増加をリクエストする
- コンピューターインスタンス
- CPU
- ストレージボリューム
- 使用中のIPアドレス
- パケットフィルタリングのルールセット
- ロードバランサーの数
- ネットワークサブネット
- ログストリーム
- クラウドプロバイダーによる新しいインスタンスの作成に対するレート制限のため、バッチで新しいノードを立ち上げるようなクラスターのスケーリング操作を通すためには、バッチ間ですこし休止を入れます。
コントロールプレーンのコンポーネント
大きなクラスターでは、十分な計算とその他のリソースを持ったコントロールプレーンが必要になります。
特に故障ゾーンあたり1つまたは2つのコントロールプレーンインスタンスを動かす場合、最初に垂直方向にインスタンスをスケールし、垂直方向のスケーリングの効果が低下するポイントに達したら水平方向にスケールします。
フォールトトレランスを備えるために、1つの故障ゾーンに対して最低1インスタンスを動かすべきです。 Kubernetesノードは、同一故障ゾーン内のコントロールプレーンエンドポイントに対して自動的にトラフィックが向かないようにします。 しかし、クラウドプロバイダーはこれを実現するための独自の機構を持っているかもしれません。
例えばマネージドなロードバランサーを使うと、故障ゾーン A にあるkubeletやPodから発生したトラフィックを、同じく故障ゾーン A にあるコントロールプレーンホストに対してのみ送るように設定します。もし1つのコントロールプレーンホストまたは故障ゾーン A のエンドポイントがオフラインになった場合、ゾーン A にあるノードについてすべてのコントロールプレーンのトラフィックはゾーンを跨いで送信されます。それぞれのゾーンで複数のコントロールプレーンホストを動作させることは、結果としてほとんどありません。
etcdストレージ
大きなクラスターの性能を向上させるために、他の専用のetcdインスタンスにイベントオブジェクトを保存できます。
クラスターを作るときに、(カスタムツールを使って)以下のようなことができます。
- 追加のetcdインスタンスを起動または設定する
- イベントを保存するためにAPIサーバを設定する
大きなクラスターのためにetcdを設定・管理する詳細については、Operating etcd clusters for Kubernetesまたはkubeadmを使用した高可用性etcdクラスターの作成を見てください。
アドオンのリソース
Kubernetesのリソース制限は、メモリリークの影響やPodやコンテナが他のコンポーネントに与える他の影響を最小化することに役立ちます。 これらのリソース制限は、アプリケーションのワークロードに適用するのと同様に、アドオンのリソースにも適用されます。
例えば、ロギングコンポーネントに対してCPUやメモリ制限を設定できます。
...
containers:
- name: fluentd-cloud-logging
image: fluent/fluentd-kubernetes-daemonset:v1
resources:
limits:
cpu: 100m
memory: 200Mi
アドオンのデフォルト制限は、アドオンを小~中規模のKubernetesクラスターで動作させたときの経験から得られたデータに基づきます。 大規模のクラスターで動作させる場合は、アドオンはデフォルト制限よりも多くのリソースを消費することが多いです。 これらの値を調整せずに大規模のクラスターをデプロイした場合、メモリー制限に達し続けるため、アドオンが継続的に停止されるかもしれません。 あるいは、CPUのタイムスライス制限により性能がでない状態で動作するかもしれません。
クラスターのアドオンのリソース制限に遭遇しないために、多くのノードで構成されるクラスターを構築する場合は次のことを考慮します。
- いくつかのアドオンは垂直方向にスケールします - クラスターに1つのレプリカ、もしくは故障ゾーン全体にサービングされるものがあります。このようなアドオンでは、クラスターをスケールアウトしたときにリクエストと制限を増やす必要があります。
- 数多くのアドオンは、水平方向にスケールします - より多くのPod数を動作させることで性能を向上できます - ただし、とても大きなクラスターではCPUやメモリの制限も少し引き上げる必要があるかもしれません。VerticalPodAutoscalerは、提案されたリクエストや制限の数値を提供する
_recommender_
モードで動作可能です。 - いくつかのアドオンはDaemonSetによって制御され、1ノードに1つ複製される形で動作します: 例えばノードレベルのログアグリゲーターです。水平方向にスケールするアドオンの場合と同様に、CPUやメモリ制限を少し引き上げる必要があるかもしれません。
次の項目
VerticalPodAutoscaler
は、リソースのリクエストやPodの制限についての管理を手助けするためにクラスターへデプロイ可能なカスタムリソースです。
VerticalPodAutoscaler
やクラスターで致命的なアドオンを含むクラスターコンポーネントをスケールする方法についてさらに知りたい場合はVertical Pod Autoscalerをご覧ください。
cluster autoscalerは、クラスターで要求されるリソース水準を満たす正確なノード数で動作できるよう、いくつかのクラウドプロバイダーと統合されています。
addon resizerは、クラスターのスケールが変化したときにアドオンの自動的なリサイズをお手伝いします。
3 - ノードのセットアップの検証
ノード適合テスト
ノード適合テスト は、システムの検証とノードに対する機能テストを提供するコンテナ型のテストフレームワークです。このテストは、ノードがKubernetesの最小要件を満たしているかどうかを検証するもので、テストに合格したノードはKubernetesクラスタに参加する資格があることになります。
制約
Kubernetesのバージョン1.5ではノード適合テストには以下の制約があります:
- ノード適合テストはコンテナのランタイムとしてDockerのみをサポートします。
ノードの前提条件
適合テストを実行するにはノードは通常のKubernetesノードと同じ前提条件を満たしている必要があります。 最低でもノードに以下のデーモンがインストールされている必要があります:
- コンテナランタイム (Docker)
- Kubelet
ノード適合テストの実行
ノード適合テストを実行するには、以下の手順に従います:
- Kubeletをlocalhostに指定します(
--api-servers="http://localhost:8080"
)、 このテストフレームワークはKubeletのテストにローカルマスターを起動するため、Kubeletをローカルホストに設定します(--api-servers="http://localhost:8080"
)。他にも配慮するべきKubeletフラグがいくつかあります:
--pod-cidr
:kubenet
を利用している場合は、Kubeletに任意のCIDR(例:--pod-cidr=10.180.0.0/24
)を指定する必要があります。--cloud-provider
:--cloud-provider=gce
を指定している場合は、テストを実行する前にこのフラグを取り除いてください。
- 以下のコマンドでノード適合テストを実行します:
# $CONFIG_DIRはKubeletのPodのマニフェストパスです。
# $LOG_DIRはテスト出力のパスです。
sudo docker run -it --rm --privileged --net=host \
-v /:/rootfs -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
k8s.gcr.io/node-test:0.2
他アーキテクチャ向けのノード適合テストの実行
Kubernetesは他のアーキテクチャ用のノード適合テストのdockerイメージを提供しています:
Arch | Image |
---|---|
amd64 | node-test-amd64 |
arm | node-test-arm |
arm64 | node-test-arm64 |
選択したテストの実行
特定のテストを実行するには、環境変数FOCUS
を実行したいテストの正規表現で上書きします。
sudo docker run -it --rm --privileged --net=host \
-v /:/rootfs:ro -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
-e FOCUS=MirrorPod \ # MirrorPodテストのみを実行します
k8s.gcr.io/node-test:0.2
特定のテストをスキップするには、環境変数SKIP
をスキップしたいテストの正規表現で上書きします。
sudo docker run -it --rm --privileged --net=host \
-v /:/rootfs:ro -v $CONFIG_DIR:$CONFIG_DIR -v $LOG_DIR:/var/result \
-e SKIP=MirrorPod \ # MirrorPodテスト以外のすべてのノード適合テストを実行します
k8s.gcr.io/node-test:0.2
ノード適合テストは、node e2e testのコンテナ化されたバージョンです。 デフォルトでは、すべての適合テストが実行されます。
理論的には、コンテナを構成し必要なボリュームを適切にマウントすれば、どのノードのe2eテストも実行できます。しかし、不適合テストを実行するためにはより複雑な設定が必要となるため、適合テストのみを実行することを強く推奨します。
注意事項
- このテストでは、ノード適合テストイメージや機能テストで使用されるコンテナのイメージなど、いくつかのdockerイメージがノード上に残ります。
- このテストでは、ノード上にデッドコンテナが残ります。これらのコンテナは機能テスト中に作成されます。
4 - PKI証明書とその要件
Kubernetesでは、TLS認証のためにPKI証明書が必要です。 kubeadmでKubernetesをインストールする場合、必要な証明書は自動で生成されます。 自身で証明書を作成することも可能です。例えば、秘密鍵をAPIサーバーに保持しないことで、管理をよりセキュアにする場合が挙げられます。 本ページでは、クラスターに必要な証明書について説明します。
クラスタではどのように証明書が使われているのか
Kubernetesは下記の用途でPKIを必要とします:
- kubeletがAPIサーバーの認証をするためのクライアント証明書
- APIサーバーのエンドポイント用サーバー証明書
- クラスターの管理者がAPIサーバーの認証を行うためのクライアント証明書
- APIサーバーがkubeletと通信するためのクライアント証明書
- APIサーバーがetcdと通信するためのクライアント証明書
- controller managerがAPIサーバーと通信するためのクライアント証明書およびkubeconfig
- スケジューラーがAPIサーバーと通信するためのクライアント証明書およびkubeconfig
- front-proxy用のクライアント証明書およびサーバー証明書
front-proxy
証明書は、Kubernetes APIの拡張をサポートするためにkube-proxyを実行する場合のみ必要です。
さらに、etcdはクライアントおよびピア間の認証に相互TLS通信を実装しています。
証明書の保存場所
kubeadmを使用してKubernetesをインストールする場合、証明書は/etc/kubernetes/pki
に保存されます。このドキュメントの全てのパスは、そのディレクトリの相対パスを表します。
手動で証明書を設定する
kubeadmで証明書を生成したくない場合は、下記の方法のいずれかで手動で生成可能です。
単一ルート認証局
管理者によりコントロールされた、単一ルート認証局の作成が可能です。このルート認証局は複数の中間認証局を作る事が可能で、作成はKubernetes自身に委ねます。
必要な認証局:
パス | デフォルトCN | 説明 |
---|---|---|
ca.crt,key | kubernetes-ca | Kubernetes全体の認証局 |
etcd/ca.crt,key | etcd-ca | etcd用 |
front-proxy-ca.crt,key | kubernetes-front-proxy-ca | front-end proxy用 |
上記の認証局に加えて、サービスアカウント管理用に公開鍵/秘密鍵のペア(sa.key
とsa.pub
)を取得する事が必要です。
全ての証明書
CAの秘密鍵をクラスターにコピーしたくない場合、自身で全ての証明書を作成できます。
必要な証明書:
デフォルトCN | 親認証局 | 組織 | 種類 | ホスト名 (SAN) |
---|---|---|---|---|
kube-etcd | etcd-ca | server, client | <hostname> , <Host_IP> , localhost , 127.0.0.1 |
|
kube-etcd-peer | etcd-ca | server, client | <hostname> , <Host_IP> , localhost , 127.0.0.1 |
|
kube-etcd-healthcheck-client | etcd-ca | client | ||
kube-apiserver-etcd-client | etcd-ca | system:masters | client | |
kube-apiserver | kubernetes-ca | server | <hostname> , <Host_IP> , <advertise_IP> , [1] |
|
kube-apiserver-kubelet-client | kubernetes-ca | system:masters | client | |
front-proxy-client | kubernetes-front-proxy-ca | client |
[1]: クラスターに接続するIPおよびDNS名( kubeadmを使用する場合と同様、ロードバランサーのIPおよびDNS名、kubernetes
、kubernetes.default
、kubernetes.default.svc
、kubernetes.default.svc.cluster
、kubernetes.default.svc.cluster.local
)
kind
は下記のx509の鍵用途のタイプにマッピングされます:
種類 | 鍵の用途 |
---|---|
server | digital signature, key encipherment, server auth |
client | digital signature, key encipherment, client auth |
kubeadm利用者のみ:
- 秘密鍵なしでCA証明書をクラスターにコピーするシナリオは、kubeadmドキュメントの外部認証局の項目で言及されています。
- kubeadmでPKIを生成すると、
kube-etcd
、kube-etcd-peer
およびkube-etcd-healthcheck-client
証明書は外部etcdを利用するケースでは生成されない事に留意してください。
証明書のパス
証明書は推奨パスに配置するべきです(kubeadmを使用する場合と同様)。 パスは場所に関係なく与えられた引数で特定されます。
デフォルトCN | 鍵の推奨パス | 証明書の推奨パス | コマンド | 鍵を指定する引数 | 証明書を指定する引数 |
---|---|---|---|---|---|
etcd-ca | etcd/ca.key | etcd/ca.crt | kube-apiserver | --etcd-cafile | |
kube-apiserver-etcd-client | apiserver-etcd-client.key | apiserver-etcd-client.crt | kube-apiserver | --etcd-keyfile | --etcd-certfile |
kubernetes-ca | ca.key | ca.crt | kube-apiserver | --client-ca-file | |
kubernetes-ca | ca.key | ca.crt | kube-controller-manager | --cluster-signing-key-file | --client-ca-file, --root-ca-file, --cluster-signing-cert-file |
kube-apiserver | apiserver.key | apiserver.crt | kube-apiserver | --tls-private-key-file | --tls-cert-file |
kube-apiserver-kubelet-client | apiserver-kubelet-client.key | apiserver-kubelet-client.crt | kube-apiserver | --kubelet-client-key | --kubelet-client-certificate |
front-proxy-ca | front-proxy-ca.key | front-proxy-ca.crt | kube-apiserver | --requestheader-client-ca-file | |
front-proxy-ca | front-proxy-ca.key | front-proxy-ca.crt | kube-controller-manager | --requestheader-client-ca-file | |
front-proxy-client | front-proxy-client.key | front-proxy-client.crt | kube-apiserver | --proxy-client-key-file | --proxy-client-cert-file |
etcd-ca | etcd/ca.key | etcd/ca.crt | etcd | --trusted-ca-file, --peer-trusted-ca-file | |
kube-etcd | etcd/server.key | etcd/server.crt | etcd | --key-file | --cert-file |
kube-etcd-peer | etcd/peer.key | etcd/peer.crt | etcd | --peer-key-file | --peer-cert-file |
etcd-ca | etcd/ca.crt | etcdctl | --cacert | ||
kube-etcd-healthcheck-client | etcd/healthcheck-client.key | etcd/healthcheck-client.crt | etcdctl | --key | --cert |
サービスアカウント用の鍵ペアについても同様です。
秘密鍵のパス | 公開鍵のパス | コマンド | 引数 |
---|---|---|---|
sa.key | kube-controller-manager | service-account-private | |
sa.pub | kube-apiserver | service-account-key |
ユーザアカウント用に証明書を設定する
管理者アカウントおよびサービスアカウントは手動で設定しなければなりません。
ファイル名 | クレデンシャル名 | デフォルトCN | 組織 |
---|---|---|---|
admin.conf | default-admin | kubernetes-admin | system:masters |
kubelet.conf | default-auth | system:node:<nodeName> (see note) |
system:nodes |
controller-manager.conf | default-controller-manager | system:kube-controller-manager | |
scheduler.conf | default-scheduler | system:kube-scheduler |
kubelet.conf
における<nodeName>
の値は必ずAPIサーバーに登録されたkubeletのノード名と一致しなければなりません。詳細は、Node Authorizationを参照してください。
-
各コンフィグ毎に、CN名と組織を指定してx509証明書と鍵ペアを生成してください。
-
以下のように、各コンフィグで
kubectl
を実行してください。
KUBECONFIG=<filename> kubectl config set-cluster default-cluster --server=https://<host ip>:6443 --certificate-authority <path-to-kubernetes-ca> --embed-certs
KUBECONFIG=<filename> kubectl config set-credentials <credential-name> --client-key <path-to-key>.pem --client-certificate <path-to-cert>.pem --embed-certs
KUBECONFIG=<filename> kubectl config set-context default-system --cluster default-cluster --user <credential-name>
KUBECONFIG=<filename> kubectl config use-context default-system
これらのファイルは以下のように利用されます:
ファイル名 | コマンド | コメント |
---|---|---|
admin.conf | kubectl | クラスターの管理者設定用 |
kubelet.conf | kubelet | クラスターの各ノードに1つ必要です。 |
controller-manager.conf | kube-controller-manager | manifests/kube-controller-manager.yaml のマニフェストファイルに追記する必要があります。 |
scheduler.conf | kube-scheduler | manifests/kube-scheduler.yaml のマニフェストファイルに追記する必要があります。 |