これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
ベストプラクティス
- 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 - 大規模クラスタの構築
サポート
At v1.22, Kubernetes supports clusters with up to 5000 nodes. More specifically, we support configurations that meet all of the following criteria:
- No more than 110 pods per node
- No more than 5000 nodes
- No more than 150000 total pods
- No more than 300000 total containers
構築
A cluster is a set of nodes (physical or virtual machines) running Kubernetes agents, managed by a "master" (the cluster-level control plane).
Normally the number of nodes in a cluster is controlled by the value NUM_NODES
in the platform-specific config-default.sh
file (for example, see GCE's config-default.sh
).
Simply changing that value to something very large, however, may cause the setup script to fail for many cloud providers. A GCE deployment, for example, will run in to quota issues and fail to bring the cluster up.
When setting up a large Kubernetes cluster, the following issues must be considered.
クォータの問題
To avoid running into cloud provider quota issues, when creating a cluster with many nodes, consider:
- Increase the quota for things like CPU, IPs, etc.
- In GCE, for example, you'll want to increase the quota for:
- CPUs
- VM instances
- Total persistent disk reserved
- In-use IP addresses
- Firewall Rules
- Forwarding rules
- Routes
- Target pools
- In GCE, for example, you'll want to increase the quota for:
- Gating the setup script so that it brings up new node VMs in smaller batches with waits in between, because some cloud providers rate limit the creation of VMs.
Etcdのストレージ
To improve performance of large clusters, we store events in a separate dedicated etcd instance.
When creating a cluster, existing salt scripts:
- start and configure additional etcd instance
- configure api-server to use it for storing events
マスターのサイズと構成要素
On GCE/Google Kubernetes Engine, and AWS, kube-up
automatically configures the proper VM size for your master depending on the number of nodes
in your cluster. On other providers, you will need to configure it manually. For reference, the sizes we use on GCE are
- 1-5 nodes: n1-standard-1
- 6-10 nodes: n1-standard-2
- 11-100 nodes: n1-standard-4
- 101-250 nodes: n1-standard-8
- 251-500 nodes: n1-standard-16
- more than 500 nodes: n1-standard-32
And the sizes we use on AWS are
- 1-5 nodes: m3.medium
- 6-10 nodes: m3.large
- 11-100 nodes: m3.xlarge
- 101-250 nodes: m3.2xlarge
- 251-500 nodes: c4.4xlarge
- more than 500 nodes: c4.8xlarge
On Google Kubernetes Engine, the size of the master node adjusts automatically based on the size of your cluster. For more information, see this blog post.
On AWS, master node sizes are currently set at cluster startup time and do not change, even if you later scale your cluster up or down by manually removing or adding nodes or using a cluster autoscaler.
アドオンのリソース
To prevent memory leaks or other resource issues in cluster addons from consuming all the resources available on a node, Kubernetes sets resource limits on addon containers to limit the CPU and Memory resources they can consume (See PR #10653 and #10778).
For example:
containers:
- name: fluentd-cloud-logging
image: k8s.gcr.io/fluentd-gcp:1.16
resources:
limits:
cpu: 100m
memory: 200Mi
Except for Heapster, these limits are static and are based on data we collected from addons running on 4-node clusters (see #10335). The addons consume a lot more resources when running on large deployment clusters (see #5880). So, if a large cluster is deployed without adjusting these values, the addons may continuously get killed because they keep hitting the limits.
To avoid running into cluster addon resource issues, when creating a cluster with many nodes, consider the following:
- Scale memory and CPU limits for each of the following addons, if used, as you scale up the size of cluster (there is one replica of each handling the entire cluster so memory and CPU usage tends to grow proportionally with size/load on cluster):
- Scale number of replicas for the following addons, if used, along with the size of cluster (there are multiple replicas of each so increasing replicas should help handle increased load, but, since load per replica also increases slightly, also consider increasing CPU/memory limits):
- Increase memory and CPU limits slightly for each of the following addons, if used, along with the size of cluster (there is one replica per node but CPU/memory usage increases slightly along with cluster load/size as well):
Heapster's resource limits are set dynamically based on the initial size of your cluster (see #16185 and #22940). If you find that Heapster is running out of resources, you should adjust the formulas that compute heapster memory request (see those PRs for details).
For directions on how to detect if addon containers are hitting resource limits, see the Troubleshooting section of Compute Resources.
少数のノードの起動の失敗を許容する
For various reasons (see #18969 for more details) running
kube-up.sh
with a very large NUM_NODES
may fail due to a very small number of nodes not coming up properly.
Currently you have two choices: restart the cluster (kube-down.sh
and then kube-up.sh
again), or before
running kube-up.sh
set the environment variable ALLOWED_NOTREADY_NODES
to whatever value you feel comfortable
with. This will allow kube-up.sh
to succeed with fewer than NUM_NODES
coming up. Depending on the
reason for the failure, those additional nodes may join later or the cluster may remain at a size of
NUM_NODES - ALLOWED_NOTREADY_NODES
.
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 | 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 のマニフェストファイルに追記する必要があります。 |