これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
kubeadmによる管理
- 1: Linuxワーカーノードの追加
- 2: cgroupドライバーの設定
- 3: Windowsノードの追加
- 4: Windowsノードのアップグレード
- 5: kubeadmによる証明書管理
1 - Linuxワーカーノードの追加
このページでは、kubeadmクラスターにLinuxワーカーノードを追加する方法を示します。
始める前に
- ワーカーノードとして追加する各マシンに、kubeadmのインストールで要求されている、kubeadm、kubelet、コンテナランタイム等のコンポーネントがインストールされていること。
kubeadm init
で構築され、kubeadmを使用したクラスターの作成ドキュメントの手順に従った稼働中のkubeadmクラスターが存在すること。- ノードにスーパーユーザー権限でアクセスできること。
Linuxワーカーノードの追加
新たなLinuxワーカーノードをクラスターに追加するために、以下を各マシンに対して実行してください。
- SSH等の手段でマシンへ接続します。
kubeadm init
実行時に出力されたコマンドを実行します。例:
sudo kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
kubeadm joinに関する追加情報
備考:
<control-plane-host>:<control-plane-port>
にIPv6タプルを指定するには、IPv6アドレスを角括弧で囲みます。
例: [2001:db8::101]:2073
トークンが不明な場合は、コントロールプレーンノードで次のコマンドを実行すると取得できます。
# コントロールプレーンノード上で実行してください。
sudo kubeadm token list
出力は次のようになります。
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
8ewj1p.9r9hcjoqgajrj4gi 23h 2018-06-12T02:51:28Z authentication, The default bootstrap system:
signing token generated by bootstrappers:
'kubeadm init'. kubeadm:
default-node-token
デフォルトでは、トークンは24時間後に有効期限が切れます。 現在のトークンの有効期限が切れた後にクラスターにノードを参加させたい場合は、コントロールプレーンノード上で次のコマンドを実行することで、新しいトークンを生成できます。
# コントロールプレーンノード上で実行してください。
sudo kubeadm token create
このコマンドの出力は次のようになります。
5didvk.d09sbcov8ph2amjw
新たなトークンを生成しながらkubeadm joinコマンドを出力するには、次のコマンドを使用します。
sudo kubeadm token create --print-join-command
--discovery-token-ca-cert-hash
の値が不明な場合は、コントロールプレーンノード上で次のコマンドを実行することで取得できます。
# コントロールプレーンノード上で実行してください。
sudo cat /etc/kubernetes/pki/ca.crt | openssl x509 -pubkey | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
出力は次のようになります。
8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78
kubeadm join
コマンドによって以下のように出力されるはずです。
[preflight] Running pre-flight checks
... (log output of join workflow) ...
Node join complete:
* Certificate signing request sent to control-plane and response
received.
* Kubelet informed of new secure connection details.
Run 'kubectl get nodes' on control-plane to see this machine join.
数秒後、kubectl get nodes
を実行すると、出力内にこのノードが表示されるはずです(kubectl
コマンドは、コントロールプレーンノード等で実行してください)。
備考:
クラスターのノードは、通常は順番に初期化されるため、CoreDNSのPodは全て最初のコントロールプレーンノードで実行されている可能性があります。 高可用性を実現するため、新たなノードを追加した後にはkubectl -n kube-system rollout restart deployment coredns
コマンドを実行してCoreDNSのPodを再配置してください。次の項目
- Windowsワーカーノードを追加する方法を参照してください。
2 - cgroupドライバーの設定
このページでは、kubeadmクラスターのコンテナランタイムcgroupドライバーに合わせて、kubelet cgroupドライバーを設定する方法について説明します。
始める前に
Kubernetesのコンテナランタイムの要件を熟知している必要があります。
コンテナランタイムのcgroupドライバーの設定
コンテナランタイムページでは、kubeadmベースのセットアップではcgroupfs
ドライバーではなく、systemd
ドライバーが推奨されると説明されています。
このページでは、デフォルトのsystemd
ドライバーを使用して多くの異なるコンテナランタイムをセットアップする方法についての詳細も説明されています。
kubelet cgroupドライバーの設定
kubeadmでは、kubeadm init
の際にKubeletConfiguration
構造体を渡すことができます。
このKubeletConfiguration
には、kubeletのcgroupドライバーを制御するcgroupDriver
フィールドを含めることができます。
備考:
v1.22では、ユーザーがKubeletConfiguration
のcgroupDriver
フィールドを設定していない場合、kubeadm
はデフォルトでsystemd
を設定するようになりました。フィールドを明示的に設定する最小限の例です:
# kubeadm-config.yaml
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
kubernetesVersion: v1.21.0
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
このような設定ファイルは、kubeadmコマンドに渡すことができます:
kubeadm init --config kubeadm-config.yaml
備考:
Kubeadmはクラスター内の全ノードで同じKubeletConfiguration
を使用します。
KubeletConfiguration
はkube-system
名前空間下のConfigMapオブジェクトに格納されます。
サブコマンドinit
、join
、upgrade
を実行すると、kubeadmがKubeletConfiguration
を/var/lib/kubelet/config.yaml
以下にファイルとして書き込み、ローカルノードのkubeletに渡します。
cgroupfsドライバーの使用
このガイドで説明するように、cgroupfs
ドライバーをkubeadmと一緒に使用することは推奨されません。
cgroupfs
を使い続け、kubeadm upgrade
が既存のセットアップでKubeletConfiguration
cgroupドライバーを変更しないようにするには、その値を明示的に指定する必要があります。
これは、将来のバージョンのkubeadmにsystemd
ドライバーをデフォルトで適用させたくない場合に適用されます。
値を明示する方法については、後述の「kubelet ConfigMapの修正」の項を参照してください。
cgroupfs
ドライバーを使用するようにコンテナランタイムを設定したい場合は、選択したコンテナランタイムのドキュメントを参照する必要があります。
systemd
ドライバーへの移行
既存のkubeadmクラスターのcgroupドライバーをsystemd
にインプレースで変更する場合は、kubeletのアップグレードと同様の手順が必要です。
これには、以下に示す両方の手順を含める必要があります。
備考:
あるいは、クラスター内の古いノードをsystemd
ドライバーを使用する新しいノードに置き換えることも可能です。
この場合、新しいノードに参加する前に以下の最初のステップのみを実行し、古いノードを削除する前にワークロードが新しいノードに安全に移動できることを確認する必要があります。kubelet ConfigMapの修正
kubectl get cm -n kube-system | grep kubelet-config
で、kubelet ConfigMapの名前を探します。kubectl edit cm kubelet-config-x.yy -n kube-system
を呼び出します(x.yy
はKubernetesのバージョンに置き換えてください)。- 既存の
cgroupDriver
の値を修正するか、以下のような新しいフィールドを追加します。
cgroupDriver: systemd
このフィールドは、ConfigMapのkubelet:
セクションの下に存在する必要があります。
全ノードでcgroupドライバーを更新
クラスター内の各ノードについて:
- Drain the nodeを
kubectl drain <node-name> --ignore-daemonsets
を使ってドレーンします。 systemctl stop kubelet
を使用して、kubeletを停止します。- コンテナランタイムの停止。
- コンテナランタイムのcgroupドライバーを
systemd
に変更します。 var/lib/kubelet/config.yaml
にcgroupDriver: systemd
を設定します。- コンテナランタイムの開始。
systemctl start kubelet
でkubeletを起動します。- Drain the nodeを
kubectl uncordon <node-name>
を使って行います。
ワークロードが異なるノードでスケジュールするための十分な時間を確保するために、これらのステップを1つずつノード上で実行します。 プロセスが完了したら、すべてのノードとワークロードが健全であることを確認します。
3 - Windowsノードの追加
Kubernetes v1.18 [beta]
Kubernetesを使用してLinuxノードとWindowsノードを混在させて実行できるため、Linuxで実行するPodとWindowsで実行するPodを混在させることができます。このページでは、Windowsノードをクラスターに登録する方法を示します。
始める前に
作業するKubernetesサーバーは次のバージョン以降のものである必要があります: 1.17.バージョンを確認するには次のコマンドを実行してください: kubectl version
.
-
WindowsコンテナをホストするWindowsノードを構成するには、Windows Server 2019ライセンス(またはそれ以上)を取得します。 VXLAN/オーバーレイネットワークを使用している場合は、KB4489899もインストールされている必要があります。
-
コントロールプレーンにアクセスできるLinuxベースのKubernetes kubeadmクラスター(kubeadmを使用したシングルコントロールプレーンクラスターの作成を参照)
目標
- Windowsノードをクラスターに登録する
- LinuxとWindowsのPodとServiceが相互に通信できるようにネットワークを構成する
はじめに: クラスターへのWindowsノードの追加
ネットワーク構成
LinuxベースのKubernetesコントロールプレーンノードを取得したら、ネットワーキングソリューションを選択できます。このガイドでは、簡単にするためにVXLANモードでのFlannelの使用について説明します。
Flannel構成
-
FlannelのためにKubernetesコントロールプレーンを準備する
クラスター内のKubernetesコントロールプレーンでは、多少の準備が推奨されます。Flannelを使用する場合は、iptablesチェーンへのブリッジIPv4トラフィックを有効にすることをお勧めします。すべてのLinuxノードで次のコマンドを実行する必要があります:
sudo sysctl net.bridge.bridge-nf-call-iptables=1
-
Linux用のFlannelをダウンロードして構成する
最新のFlannelマニフェストをダウンロード:
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
VNIを4096、ポートを4789に設定するために、flannelマニフェストの
net-conf.json
セクションを変更します。次のようになります:net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan", "VNI" : 4096, "Port": 4789 } }
備考:
Linux上のFlannelがWindows上のFlannelと相互運用するには、VNIを4096およびポート4789に設定する必要があります。これらのフィールドの説明については、VXLANドキュメントを参照してください。備考:
L2Bridge/Host-gatewayモードを使用するには、代わりにType
の値を"host-gw"
に変更し、VNI
とPort
を省略します。 -
Flannelマニフェストを適用して検証する
Flannelの構成を適用しましょう:
kubectl apply -f kube-flannel.yml
数分後、Flannel Podネットワークがデプロイされていれば、すべてのPodが実行されていることがわかります。
kubectl get pods -n kube-system
出力結果には、実行中のLinux flannel DaemonSetが含まれているはずです:
NAMESPACE NAME READY STATUS RESTARTS AGE ... kube-system kube-flannel-ds-54954 1/1 Running 0 1m
-
Windows Flannelとkube-proxy DaemonSetを追加する
これで、Windows互換バージョンのFlannelおよびkube-proxyを追加できます。 互換性のあるバージョンのkube-proxyを確実に入手するには、イメージのタグを置換する必要があります。 次の例は、Kubernetes 1.34.0の使用方法を示していますが、 独自のデプロイに合わせてバージョンを調整する必要があります。
curl -L https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/kube-proxy.yml | sed 's/VERSION/v1.34.0/g' | kubectl apply -f - kubectl apply -f https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/flannel-overlay.yml
備考:
ホストゲートウェイを使用している場合は、代わりに https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/flannel-host-gw.yml を使用してください。
備考:
Windowsノードでイーサネット(「Ethernet0 2」など)ではなく別のインターフェースを使用している場合は、次の行を変更する必要があります:
wins cli process run --path /k/flannel/setup.exe --args "--mode=overlay --interface=Ethernet"
flannel-host-gw.yml
またはflannel-overlay.yml
ファイルで、それに応じてインターフェースを指定します。# 例 curl -L https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/flannel-overlay.yml | sed 's/Ethernet/Ethernet0 2/g' | kubectl apply -f -
Windowsワーカーノードの参加
備考:
Containers
機能をインストールし、Dockerをインストールする必要があります。
行うための指示としては、Dockerエンジンのインストール - Windowsサーバー上のエンタープライズを利用できます。備考:
Windowsセクションのすべてのコードスニペットは、 Windowsワーカーノードの(管理者)権限を持つPowerShell環境で実行されます。-
wins、kubelet、kubeadmをインストールします。
curl.exe -LO https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/kubeadm/scripts/PrepareNode.ps1 .\PrepareNode.ps1 -KubernetesVersion v1.34.0
-
kubeadm
を実行してノードに参加しますコントロールプレーンホストで
kubeadm init
を実行したときに提供されたコマンドを使用します。 このコマンドがなくなった場合、またはトークンの有効期限が切れている場合は、kubeadm token create --print-join-command
(コントロールプレーンホスト上で)を実行して新しいトークンを生成します。
インストールの確認
次のコマンドを実行して、クラスター内のWindowsノードを表示できるようになります:
kubectl get nodes -o wide
新しいノードがNotReady
状態の場合は、flannelイメージがまだダウンロード中の可能性があります。
kube-system
名前空間のflannel Podを確認することで、以前と同様に進行状況を確認できます:
kubectl -n kube-system get pods -l app=flannel
flannel Podが実行されると、ノードはReady
状態になり、ワークロードを処理できるようになります。
次の項目
4 - Windowsノードのアップグレード
Kubernetes v1.18 [beta]
このページでは、kubeadmで作られたWindowsノードをアップグレードする方法について説明します。
始める前に
Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:
作業するKubernetesサーバーは次のバージョン以降のものである必要があります: 1.17.バージョンを確認するには次のコマンドを実行してください: kubectl version
.
- 残りのkubeadmクラスターをアップグレードするプロセスを理解します。 Windowsノードをアップグレードする前にコントロールプレーンノードをアップグレードしたいと思うかもしれません。
ワーカーノードをアップグレード
kubeadmをアップグレード
-
Windowsノードから、kubeadmをアップグレードします。:
# 1.34.0を目的のバージョンに置き換えます curl.exe -Lo C:\k\kubeadm.exe https://dl.k8s.io/v1.34.0/bin/windows/amd64/kubeadm.exe
ノードをドレインする
-
Kubernetes APIにアクセスできるマシンから、 ノードをスケジュール不可としてマークして、ワークロードを削除することでノードのメンテナンスを準備します:
# <node-to-drain>をドレインするノードの名前に置き換えます kubectl drain <node-to-drain> --ignore-daemonsets
このような出力結果が表示されるはずです:
node/ip-172-31-85-18 cordoned node/ip-172-31-85-18 drained
kubeletの構成をアップグレード
-
Windowsノードから、次のコマンドを呼び出して新しいkubelet構成を同期します:
kubeadm upgrade node
kubeletをアップグレード
-
Windowsノードから、kubeletをアップグレードして再起動します:
stop-service kubelet curl.exe -Lo C:\k\kubelet.exe https://dl.k8s.io/v1.34.0/bin/windows/amd64/kubelet.exe restart-service kubelet
ノードをオンライン状態に
-
Kubernetes APIにアクセスできるマシンから、 スケジュール可能としてマークして、ノードをオンラインに戻します:
# <node-to-drain>をノードの名前に置き換えます kubectl uncordon <node-to-drain>
kube-proxyをアップグレード
-
Kubernetes APIにアクセスできるマシンから、次を実行します、 もう一度1.34.0を目的のバージョンに置き換えます:
curl -L https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/kube-proxy.yml | sed 's/VERSION/v1.34.0/g' | kubectl apply -f -
5 - kubeadmによる証明書管理
Kubernetes v1.15 [stable]
kubeadmで生成されたクライアント証明書は1年で失効します。 このページでは、kubeadmで証明書の更新を管理する方法について説明します。 また、kubeadmによる証明書管理に関連するタスクも説明します。
Kubernetesプロジェクトでは、最新のパッチリリースに速やかにアップグレードし、サポートされているKubernetesのマイナーリリースを実行していることを推奨しています。 この推奨事項に従うことで、セキュリティを維持できます。
始める前に
KubernetesにおけるPKI証明書と要件を熟知している必要があります。
kubeadmコマンドに対して、kubeadmの設定ファイルを渡す方法について熟知している必要があります。
本ページではopenssl
コマンド(手動で証明書に署名する場合に使用)の使用方法について説明しますが、他のツールで代用することもできます。
ここで紹介する手順の一部では、管理者アクセスにsudo
を使用していますが、同等のツールを使用しても構いません。
カスタム証明書の使用
デフォルトでは、kubeadmはクラスターの実行に必要なすべての証明書を生成します。 独自の証明書を提供することで、この動作をオーバーライドできます。
そのためには、--cert-dir
フラグまたはkubeadmのClusterConfiguration
のcertificatesDir
フィールドで指定された任意のディレクトリに配置する必要があります。
デフォルトは/etc/kubernetes/pki
です。
kubeadm init
を実行する前に既存の証明書と秘密鍵のペアが存在する場合、kubeadmはそれらを上書きしません。
つまり、例えば既存のCAを/etc/kubernetes/pki/ca.crt
と/etc/kubernetes/pki/ca.key
にコピーすれば、kubeadmは残りの証明書に署名する際、このCAを使用できます。
暗号化アルゴリズムの選択
kubeadmでは、公開鍵や秘密鍵を作成する際に暗号化アルゴリズムを選択できます。
設定するには、kubeadmの設定ファイルにてencryptionAlgorithm
フィールドを使用します。
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
encryptionAlgorithm: <ALGORITHM>
<ALGORITHM>
は、RSA-2048
(デフォルト)、RSA-3072
、RSA-4096
、ECDSA-P256
が選択できます。
証明書の有効期間の選択
kubeadmでは、CAおよびリーフ証明書の有効期間を選択可能です。
設定するには、kubeadmの設定ファイルにて、certificateValidityPeriod
、caCertificateValidityPeriod
フィールドを使用します。
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
certificateValidityPeriod: 8760h # デフォルト: 365日 × 24時間 = 1年
caCertificateValidityPeriod: 87600h # デフォルト: 365日 × 24時間 * 10 = 10年
フィールドの値は、Go言語のtime.Duration
の値で許容される形式に準拠しており、サポートされている最長単位はh
(時間)です。
外部CAモード
また、ca.crt
ファイルのみを提供し、ca.key
ファイルを提供しないことも可能です(これはルートCAファイルのみに有効で、他の証明書ペアには有効ではありません)。
他の証明書とkubeconfigファイルがすべて揃っている場合、kubeadmはこの状態を認識し、「外部CA」モードを有効にします。
kubeadmはディスク上のCAキーがなくても処理を進めます。
代わりに、--controllers=csrsigner
を使用してController-managerをスタンドアロンで実行し、CA証明書と鍵を指定します。
外部CAモードを使用する場合、コンポーネントの資格情報を作成する方法がいくつかあります。
手動によるコンポーネント資格情報の作成
PKI証明書とその要件には、kubeadmコンポーネントに必要な全ての資格情報を手動で作成する方法が記載されています。
本ページではopenssl
コマンド(手動で証明書を署名する場合に使用)の使用方法について説明しますが、他のツールを代用することもできます。
kubeadmによって生成されたCSRへの署名による資格情報の作成
kubeadmは、openssl
のようなツールと外部CAを使用して手動で署名可能なCSRファイルの生成ができます。
これらのCSRファイルには、kubeadmによってデプロイされるコンポーネントに必要な資格情報の全ての仕様が含まれます。
kubeadm phaseを使用したコンポーネント資格情報の自動作成
もしくは、kubeadm phaseコマンドを使用して、これらのプロセスを自動化することが可能です。
- kubeadmコントロールプレーンノードとして外部CAを用いて構築するホストに対し、アクセスします。
- 外部CAの
ca.crt
とca.key
ファイルを、ノードの/etc/kubernetes/pki
へコピーします。 kubeadm init
で使用する、config.yaml
という一時的なkubeadmの設定ファイルを準備します。 このファイルには、ClusterConfiguration.controlPlaneEndpoint
、ClusterConfiguration.certSANs
、InitConfiguration.APIEndpoint
など、証明書に含まれる可能性のある、クラスター全体またはホスト固有の関連情報が全て記載されていることを確認します。- 同じホストで
kubeadm init phase kubeconfig all --config config.yaml
およびkubeadm init phase certs all --config config.yaml
コマンドを実行します。 これにより、必要な全てのkubeconfigファイルと証明書が/etc/kubernetes/
配下およびpki
サブディレクトリ配下に作成されます。 - 作成されたファイルを調べます。
/etc/kubernetes/pki/ca.key
を削除し、/etc/kubernetes/super-admin.conf
を削除するか、安全な場所に退避します。 kubeadm join
を実行するノードでは、/etc/kubernetes/kubelet.conf
も削除します。 このファイルはkubeadm init
が実行される最初のノードでのみ必要とされます。pki/sa.*
、pki/front-proxy-ca.*
、pki/etc/ca.*
等のファイルは、コントロールプレーンノード間で共有されます。kubeadm join
を実行するノードに手動で証明書を配布するか、kubeadm init
の--upload-certs
オプションおよびkubeadm join
の--certificate-key
オプションを使用することでこれらを自動配布します。
全てのノードにて資格情報を準備した後、これらのノードをクラスターに参加させるためにkubeadm init
およびkubeadm join
を実行します。
kubeadmは/etc/kubernetes/
およびpki
サブディレクトリ配下に存在するkubeconfigと証明書を使用します。
証明書の有効期限と管理
備考:
kubeadm
は、外部CAによって署名された証明書を管理することができません。check-expiration
サブコマンドを使うと、証明書の有効期限を確認することができます。
kubeadm certs check-expiration
このような出力になります:
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Dec 30, 2020 23:36 UTC 364d no
apiserver Dec 30, 2020 23:36 UTC 364d ca no
apiserver-etcd-client Dec 30, 2020 23:36 UTC 364d etcd-ca no
apiserver-kubelet-client Dec 30, 2020 23:36 UTC 364d ca no
controller-manager.conf Dec 30, 2020 23:36 UTC 364d no
etcd-healthcheck-client Dec 30, 2020 23:36 UTC 364d etcd-ca no
etcd-peer Dec 30, 2020 23:36 UTC 364d etcd-ca no
etcd-server Dec 30, 2020 23:36 UTC 364d etcd-ca no
front-proxy-client Dec 30, 2020 23:36 UTC 364d front-proxy-ca no
scheduler.conf Dec 30, 2020 23:36 UTC 364d no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Dec 28, 2029 23:36 UTC 9y no
etcd-ca Dec 28, 2029 23:36 UTC 9y no
front-proxy-ca Dec 28, 2029 23:36 UTC 9y no
このコマンドは、/etc/kubernetes/pki
フォルダー内のクライアント証明書と、kubeadmが使用するkubeconfigファイル(admin.conf
、controller-manager.conf
、scheduler.conf
)に埋め込まれたクライアント証明書の有効期限/残余時間を表示します。
また、証明書が外部管理されている場合、kubeadmはユーザーに通知します。この場合、ユーザーは証明書の更新を手動または他のツールを使用して管理する必要があります。
kubeadmは/var/lib/kubelet/pki
配下にあるローテーション可能な証明書でkubeletの証明書の自動更新を構成するため、kubelet.conf
は上記のリストに含まれません。
期限切れのkubeletクライアント証明書を修復するには、kubeletクライアント証明書のローテーションに失敗するを参照ください。
備考:
kubeadm version 1.17より前のkubeadm init
で作成したノードでは、kubelet.conf
の内容を手動で変更しなければならないというバグが存在します。
kubeadm init
が終了したら、client-certificate-data
とclient-key-data
を置き換えて、ローテーションされたkubeletクライアント証明書を指すようにkubelet.conf
を更新してください。
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
証明書の自動更新
kubeadmはコントロールプレーンのアップグレード時にすべての証明書を更新します。
この機能は、最もシンプルなユースケースに対応するために設計されています。 証明書の更新に特別な要件がなく、Kubernetesのバージョンアップを定期的に行う場合(各アップグレードの間隔が1年未満)、kubeadmは、クラスターを最新に保ち、適切なセキュリティを確保します。
証明書の更新に関してより複雑な要求がある場合は、--certificate-renewal=false
をkubeadm upgrade apply
やkubeadm upgrade node
に渡して、デフォルトの動作から外れるようにすることができます。
手動による証明書更新
適切なコマンドラインオプションを指定してkubeadm certs renew
コマンドを実行すれば、いつでも証明書を手動で更新できます。
複数のコントロールプレーンによってクラスターが稼働している場合、全てのコントロールプレーンノード上でこのコマンドを実行する必要があります。
このコマンドは/etc/kubernetes/pki
に格納されているCA(またはfront-proxy-CA)の証明書と鍵を使用して更新を行います。
kubeadm certs renew
は、属性(Common Name、Organization、SANなど)の信頼できるソースとして、kubeadm-config
ConfigMapではなく、既存の証明書を使用します。
それでも、Kubernetesプロジェクトでは、混乱のリスクを避けるために証明書とConfigMap内の関連した値を同期したままにしておくことを推奨しています。
コマンド実行後、コントロールプレーンのPodを再起動する必要があります。
これは、現在は動的な証明書のリロードが、すべてのコンポーネントと証明書でサポートされているわけではないため、必要な作業です。
static Podはローカルkubeletによって管理され、APIサーバーによって管理されないため、kubectlで削除および再起動することはできません。
static Podを再起動するには、一時的に/etc/kubernetes/manifests/
からマニフェストファイルを削除して20秒間待ちます(KubeletConfiguration構造体のfileCheckFrequency
値を参照してください)。
マニフェストディレクトリにてマニフェストファイルが存在しなくなると、kubeletはPodを終了します。
その後ファイルを戻し、さらにfileCheckFrequency
期間後に、kubeletはPodを再作成し、コンポーネントの証明書更新を完了することができます。
kubeadm certs renew
は、特定の証明書を更新できます。
また、all
サブコマンドを用いることで全ての証明書を更新できます。
# 複数のコントロールプレーンによってクラスターが稼働している場合、このコマンドは全てのコントロールプレーン上で実行する必要があります。
kubeadm certs renew all
管理者用の証明書のコピー(オプション)
kubeadmで構築されたクラスターでは、多くの場合、kubeadmを使用したクラスターの作成の指示に従い、admin.conf
証明書が$HOME/.kube/config
へコピーされます。
このようなシステムでは、admin.conf
を更新した後に$HOME/.kube/config
の内容を更新するため、次のコマンドを実行します。
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Kubernetes certificates APIによる証明書の更新
ここでは、Kubernetes certificates APIを使用して手動で証明書更新を実行する方法について詳しく説明します。
注意:
これらは、組織の証明書インフラをkubeadmで構築されたクラスターに統合する必要があるユーザー向けの上級者向けのトピックです。 kubeadmのデフォルトの設定で満足できる場合は、代わりにkubeadmに証明書を管理させる必要があります。署名者の設定
Kubernetesの認証局は、そのままでは機能しません。 cert-managerなどの外部署名者を設定するか、組み込みの署名者を使用することができます。
ビルトインサイナーはkube-controller-manager
に含まれるものです。
ビルトインサイナーを有効にするには、--cluster-signing-cert-file
と--cluster-signing-key-file
フラグを渡す必要があります。
新しいクラスターを作成する場合は、kubeadm設定ファイルを使用します。
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
controllerManager:
extraArgs:
- name: "cluster-signing-cert-file"
value: "/etc/kubernetes/pki/ca.crt"
- name: "cluster-signing-key-file"
value: "/etc/kubernetes/pki/ca.key"
証明書署名要求(CSR)の作成
Kubernetes APIでのCSR作成については、CertificateSigningRequestの作成を参照ください。
外部CAによる証明書の更新
ここでは、外部認証局を利用して手動で証明書更新を行う方法について詳しく説明します。
外部CAとの連携を強化するために、kubeadmは証明書署名要求(CSR)を生成することもできます。 CSRとは、クライアント用の署名付き証明書をCAに要求することを表します。 kubeadmでは、通常ディスク上のCAによって署名される証明書をCSRとして生成することができます。しかし、CAはCSRとして生成することはできません。
証明書署名要求(CSR)による証明書の更新
証明書の更新は、新たなCSRを作成し外部CAで署名することで実施できます。 kubeadmによって生成されたCSRの署名についての詳細は、kubeadmによって生成された証明書署名要求(CSR)の署名セクションを参照してください。
認証局(CA)のローテーション
kubeadmは、CA証明書のローテーションや置換を標準ではサポートしていません。
CAの手動ローテーションや置換についての詳細は、CA証明書の手動ローテーションを参照してください。
署名付きkubeletサーバー証明書の有効化
デフォルトでは、kubeadmによって展開されるkubeletサーバー証明書は自己署名されています。 これは、metrics-serverのような外部サービスからkubeletへの接続がTLSで保護されないことを意味します。
新しいkubeadmクラスター内のkubeletが適切に署名されたサーバー証明書を取得するように設定するには、kubeadm init
に以下の最小限の設定を渡す必要があります。
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
serverTLSBootstrap: true
すでにクラスターを作成している場合は、以下の手順で適応させる必要があります。
kube-system
namespace中のkubelet-config
ConfigMapを探して編集します。 このConfigMap内には、kubelet
キーの値として、KubeletConfigurationに関する記述が存在します。 KubeletConfigurationの内容を編集し、serverTLSBootstrap: true
を設定します。- 各ノードで、
/var/lib/kubelet/config.yaml
にserverTLSBootstrap: true
フィールドを追加し、systemctl restart kubelet
でkubeletを再起動します。
serverTLSBootstrap: true
フィールドは、certificates.k8s.io
APIからkubeletのサーバー証明書をリクエストすることで、kubeletサーバー証明書のブートストラップを有効にします。
既知の制限事項の1つとして、これらのCSR(証明書署名要求)はkube-controller-managerのデフォルトの署名者によって自動的に承認されないことが挙げられます。
kubernetes.io/kubelet-serving
を参照してください。
これには、ユーザーまたはサードパーティのコントローラーからのアクションが必要です。
これらのCSRは、以下を使用して表示できます:
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-9wvgt 112s kubernetes.io/kubelet-serving system:node:worker-1 Pending
csr-lz97v 1m58s kubernetes.io/kubelet-serving system:node:control-plane-1 Pending
承認するためには、次のようにします:
kubectl certificate approve <CSR-name>
デフォルトでは、これらのサーバー証明書は1年後に失効します。
kubeadmはKubeletConfiguration
フィールドのrotateCertificates
をtrue
に設定します。
これは有効期限が切れる間際に、サーバー証明書のための新しいCSRセットを作成し、ローテーションを完了するために承認する必要があることを意味します。
詳しくは証明書のローテーションを参照してください。
これらのCSRを自動的に承認するためのソリューションをお探しの場合は、クラウドプロバイダーに連絡し、ノードの識別をアウトオブバンドのメカニズムで行うCSRの署名者がいるかどうか確認することをお勧めします。
サードパーティのカスタムコントローラーを使用することができます。
このようなコントローラーは、CSRのCommonNameを検証するだけでなく、要求されたIPやドメイン名も検証しなければ、安全なメカニズムとは言えません。 これにより、kubeletクライアント証明書にアクセスできる悪意のあるアクターが、任意のIPやドメイン名に対してサーバー証明書を要求するCSRを作成することを防止できます。
追加ユーザー用のkubeconfigファイルの生成
クラスターの構築中、kubeadm init
はsuper-admin.conf
内の証明書に署名し、Subject: O = system:masters, CN = kubernetes-super-admin
を設定します。
system:masters
は認可のレイヤーをバイパスする(例: RBAC)、緊急用のスーパーユーザーグループです。
admin.conf
ファイルもkubeadmによってコントロールプレーン上に作成され、Subject: O = kubeadm:cluster-admins, CN = kubernetes-admin
と設定された証明書が含まれています。
kubeadm:cluster-admins
はkubeadmが属している論理的なグループです。
RBAC(kubeadmのデフォルト)をクラスターに使用している場合、kubeadm:cluster-admins
グループはcluster-admin
ClusterRoleにバインドされます。
警告:
super-admin.conf
およびadmin.conf
ファイルを共有しないでください。
代わりに、管理者として従事するユーザーに対しても最小限のアクセス権限を作成し、緊急アクセス以外の場合にはその最小限の権限の代替手段を使用します。kubeadm kubeconfig user
コマンドを使用することで、追加ユーザー用のkubeconfigファイルを生成できます。
このコマンドは、コマンドラインフラグとkubeadm configurationオプションの組み合わせが可能です。
生成されたkubeconfigファイルはstdoutに書き込まれ、kubeadm kubeconfig user ... > somefile.conf
を使用してファイルにパイプすることができます。
--config
で使用できる設定ファイルの例:
# example.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
# kubeconfig内にて、対象の"cluster"として使用します。
clusterName: "kubernetes"
# kubeconfig内にて、このクラスターの"server"(IPもしくはDNS名)として使用します。
controlPlaneEndpoint: "some-dns-address:6443"
# クラスターCAの秘密鍵と証明書が、このローカルディレクトリからロードされます。
certificatesDir: "/etc/kubernetes/pki"
これらの設定が、目的の対象クラスターの設定と一致していることを確認します。 既存のクラスターの設定を表示するには、次のコマンドを使用します。
kubectl get cm kubeadm-config -n kube-system -o=jsonpath="{.data.ClusterConfiguration}"
次の例では、appdevs
グループに属する新しいユーザーjohndoe
に対して24時間有効な資格情報を含むkubeconfigファイルが生成されます。
kubeadm kubeconfig user --config example.yaml --org appdevs --client-name johndoe --validity-period 24h
次の例では、1週間有効な管理者の資格情報を持つkubeconfigファイルが生成されます。
kubeadm kubeconfig user --config example.yaml --client-name admin --validity-period 168h
kubeadmによって生成された証明書署名要求(CSR)の署名
kubeadm certs generate-csr
コマンドで、証明書署名要求を作成できます。
通常の証明書については、このコマンドの実行によって.csr
/.key
ファイルのペアが生成されます。
kubeconfigに埋め込まれた証明書については、このコマンドで.csr
/.conf
のペアが生成されます。このペアでは、鍵は.conf
ファイルに埋め込まれています。
CSRファイルには、CAが証明書に署名するために必要な情報が全て含まれています。 kubeadmは全ての証明書とCSRに対し、明確に定義された仕様を適用します。
証明書のデフォルトのディレクトリは/etc/kubernetes/pki
であり、kubeconfigファイルのデフォルトのディレクトリは/etc/kubernetes
です。
これらのデフォルトのディレクトリは、それぞれ--cert-dir
と--kubeconfig-dir
フラグで上書きできます。
kubeadm certs generate-csr
にカスタムオプションを渡すには、--config
フラグを使用します。
このフラグは、kubeadm init
と同様に、kubeadmの設定ファイルを受け入れます。
追加のSANやカスタムIPアドレスなどの指定については、関連の全てのkubeadmコマンドに使用するために、全て同じ設定ファイルに保存し、--config
として渡す必要があります。
備考:
このガイドでは、Kubernetesのデフォルトのディレクトリである/etc/kubernetes
を使用しています。このディレクトリにはスーパーユーザー権限が必要です。
このガイドに従って、書き込み可能なディレクトリを使用している場合(通常は--cert-dir
と--kubeconfig-dir
を指定してkubeadm
を実行します)は、sudo
コマンドを省略できます。
次に、作成したファイルを/etc/kubernetes
ディレクトリ内にコピーして、kubeadm init
もしくはkubeadm join
がこれらのファイルを検出できるようにする必要があります。
CAとサービスアカウントファイルの準備
kubeadm init
を実行する最初のコントロールプレーンノードでは、以下のコマンドを実行してください。
sudo kubeadm init phase certs ca
sudo kubeadm init phase certs etcd-ca
sudo kubeadm init phase certs front-proxy-ca
sudo kubeadm init phase certs sa
これにより、コントロールプレーンノードでkubeadmが必要とする、全ての自己署名CAファイル(証明書と鍵)とサービスアカウント(公開鍵と秘密鍵)が/etc/kubernetes/pki
および/etc/kubernetes/pki/etcd
フォルダーに作成されます。
備考:
外部CAを使用する場合、同じファイルをアウトオブバンドで作成し、最初のコントロールプレーンノードの/etc/kubernetes
へ手動でコピーする必要があります。
全ての証明書に署名した後、外部CAモードセクションの記載のように、ルートCAの鍵(ca.key
)は削除しても構いません。
2番目以降のコントロールプレーンノード(kubeadm join --control-plane
を実行します)では、上記のコマンドを実行する必要はありません。
高可用性クラスターの構築方法に応じて、最初のコントロールプレーンノードから同じファイルを手動でコピーするか、kubeadm init
の自動化された--upload-certs
機能を使用する必要があります。
CSRの生成
kubeadm certs generate-csr
コマンドは、kubeadmによって管理される全ての既知の証明書のCSRファイルを作成します。
コマンドの実行後、不要な.csr
、.conf
、または.key
ファイルを手動で削除する必要があります。
kubelet.confに対する考慮事項
このセクションはコントロールプレーンノードとワーカーノードの両方に適用されます。
ca.key
ファイルをコントロールプレーンから削除している場合(外部CAモード)、クラスターで実行中のkube-controller-managerはkubeletクライアント証明書への署名ができなくなります。
構成内にこれらの証明書へ署名するための外部の方法(外部署名者など)が存在しない場合は、このガイドで説明されているように、kubelet.conf.csr
に手動で署名できます。
なお、これにより、自動によるkubeletクライアント証明書のローテーションが無効になることに注意してください。
その場合は、証明書の有効期限が近づいたら、新しいkubelet.conf.csr
を生成し、証明書に署名してkubelet.conf
に埋め込み、kubeletを再起動する必要があります。
ca.key
ファイルがコントロールプレーンノード上に存在する場合、2番目以降のコントロールプレーンノードおよびワーカーノード(kubeadm join ...
を実行する全てのノード)では、kubelet.conf.csr
の処理をスキップできます。
これは、実行中のkube-controller-managerが新しいkubeletクライアント証明書の署名を担当するためです。
備考:
kubelet.conf.csr
ファイルは、最初のコントロールプレーンノード(最初にkubeadm init
を実行したホスト)で処理する必要があります。
これは、kubeadm
がそのノードをクラスターのブートストラップ用のノードと見なすため、事前に設定されたkubelet.conf
が必要になるためです。コントロールプレーンノード
1番目(kubeadm init
)および2番目以降(kubeadm join --control-plane
)のコントロールプレーンノードで以下のコマンドを実行し、全てのCSRファイルを生成します。
sudo kubeadm certs generate-csr
外部etcdを使用する場合は、kubeadmとetcdノードに必要なCSRファイルについて理解するために、kubeadmを使用した外部etcdのガイドを参照してください。
/etc/kubernetes/pki/etcd
配下にある他の.csr
および.key
ファイルは削除して構いません。
kubelet.confに対する考慮事項の説明に基づいて、kubelet.conf
およびkubelet.conf.csr
ファイルを保持するか削除します。
ワーカーノード
kubelet.confに対する考慮事項の説明に基づいて、オプションで以下のコマンドを実行し、kubelet.conf
およびkubelet.conf.csr
ファイルを保持します。
sudo kubeadm certs generate-csr
あるいは、ワーカーノードの手順を完全にスキップします。
全ての証明書のCSRへ署名
備考:
外部CAを使用し、openssl
用のCAのシリアル番号ファイル(.srl
)が既に存在する場合は、これらのファイルをCSRを署名するkubeadmノードにコピーできます。
コピーする.srl
ファイルは、/etc/kubernetes/pki/ca.srl
、/etc/kubernetes/pki/front-proxy-ca.srl
および/etc/kubernetes/pki/etcd/ca.srl
です。
その後、これらのファイルをCSRファイルに署名する新たなノードに移動できます。
ノード上のCAに対して.srl
ファイルが存在しない場合、以下のスクリプトはランダムな開始シリアル番号を持つ新規のSRLファイルを生成します。
.srl
ファイルの詳細については、openssl
ドキュメントの--CAserial
フラグを参照してください。
CSRファイルが存在する全てのノードで、この手順を繰り返してください。
/etc/kubernetes
ディレクトリに次のスクリプトを作成し、そのディレクトリに移動してスクリプトを実行します。
このスクリプトは、/etc/kubernetes
ツリー以下に存在する全てのCSRファイルに対する証明書ファイルを生成します。
#!/bin/bash
# 日単位で証明書の有効期間を設定
DAYS=365
# front-proxyとetcdを除いた全てのCSRファイルへ署名
find ./ -name "*.csr" | grep -v "pki/etcd" | grep -v "front-proxy" | while read -r FILE;
do
echo "* Processing ${FILE} ..."
FILE=${FILE%.*} # 拡張子を取り除く
if [ -f "./pki/ca.srl" ]; then
SERIAL_FLAG="-CAserial ./pki/ca.srl"
else
SERIAL_FLAG="-CAcreateserial"
fi
openssl x509 -req -days "${DAYS}" -CA ./pki/ca.crt -CAkey ./pki/ca.key ${SERIAL_FLAG} \
-in "${FILE}.csr" -out "${FILE}.crt"
sleep 2
done
# 全てのetcdのCSRへ署名
find ./pki/etcd -name "*.csr" | while read -r FILE;
do
echo "* Processing ${FILE} ..."
FILE=${FILE%.*} # 拡張子を取り除く
if [ -f "./pki/etcd/ca.srl" ]; then
SERIAL_FLAG=-CAserial ./pki/etcd/ca.srl
else
SERIAL_FLAG=-CAcreateserial
fi
openssl x509 -req -days "${DAYS}" -CA ./pki/etcd/ca.crt -CAkey ./pki/etcd/ca.key ${SERIAL_FLAG} \
-in "${FILE}.csr" -out "${FILE}.crt"
done
# front-proxyのCSRへ署名
echo "* Processing ./pki/front-proxy-client.csr ..."
openssl x509 -req -days "${DAYS}" -CA ./pki/front-proxy-ca.crt -CAkey ./pki/front-proxy-ca.key -CAcreateserial \
-in ./pki/front-proxy-client.csr -out ./pki/front-proxy-client.crt
kubeconfigファイルへの証明書の組み込み
CSRファイルが存在する全てのノードで、この手順を繰り返してください。
/etc/kubernetes
ディレクトリに次のスクリプトを作成し、そのディレクトリに移動してスクリプトを実行します。
このスクリプトは、前の手順でCSRファイルからkubeconfigファイル用に署名された.crt
ファイルを取得し、これらをkubeconfigファイルに組み込みます。
#!/bin/bash
CLUSTER=kubernetes
find ./ -name "*.conf" | while read -r FILE;
do
echo "* Processing ${FILE} ..."
KUBECONFIG="${FILE}" kubectl config set-cluster "${CLUSTER}" --certificate-authority ./pki/ca.crt --embed-certs
USER=$(KUBECONFIG="${FILE}" kubectl config view -o jsonpath='{.users[0].name}')
KUBECONFIG="${FILE}" kubectl config set-credentials "${USER}" --client-certificate "${FILE}.crt" --embed-certs
done
クリーンアップの実行
CSRファイルがあるすべてのノードでこの手順を実行します。
/etc/kubernetes
ディレクトリに次のスクリプトを作成し、そのディレクトリに移動してスクリプトを実行します。
#!/bin/bash
# CSRファイルのクリーンアップ
rm -f ./*.csr ./pki/*.csr ./pki/etcd/*.csr # 全てのCSRファイルを削除します。
# kubeconfigファイル内に既に埋め込まれているCRTファイルのクリーンアップ
rm -f ./*.crt
必要に応じて、.srl
ファイルを次に使用するノードへ移動させます。
必要に応じて、外部CAを使用する場合は、外部CAモードのセクションで説明されているように、/etc/kubernetes/pki/ca.key
ファイルを削除します。
kubeadmノードの初期化
CSRファイルに署名し、ノードとして使用する各ホストへ証明書を配置すると、kubeadm init
コマンドとkubeadm join
を使用してKubernetesクラスターを構築できます。
init
とjoin
の実行時、kubeadmは各ホストのローカルファイルシステムの/etc/kubernetes
ツリーで検出した既存の証明書、暗号化キー、およびkubeconfigファイルを使用します。