ベストプラクティスに準拠した実用最小限のKubernetesクラスターを作成します。
実際、kubeadmを使用すれば、Kubernetes Conformance testsに通るクラスターをセットアップすることができます。
kubeadmは、ブートストラップトークンやクラスターのアップグレードなどのその他のクラスターのライフサイクルの機能もサポートします。
kubeadmツールは、次のようなときに適しています。
kubeadmは、ラップトップ、クラウドのサーバー群、Raspberry Piなどの様々なマシンにインストールして使えます。クラウドとオンプレミスのどちらにデプロイする場合でも、kubeadmはAnsibleやTerraformなどのプロビジョニングシステムに統合できます。
このガイドを進めるには、以下の環境が必要です。
また、新しいクラスターで使いたいKubernetesのバージョンをデプロイできるバージョンのkubeadmを使用する必要もあります。
Kubernetesのバージョンとバージョンスキューポリシーは、kubeadmにもKubernetes全体と同じように当てはまります。
Kubernetesとkubeadmがサポートするバージョンを理解するには、上記のポリシーを確認してください。このページは、Kubernetes v1.35向けに書かれています。
kubeadmツールの全体の機能の状態は、一般利用可能(GA)です。一部のサブ機能はまだ活発に開発が行われています。クラスター作成の実装は、ツールの進化に伴ってわずかに変わるかもしれませんが、全体の実装は非常に安定しているはずです。
kubeadm alpha以下のすべてのコマンドは、定義通り、アルファレベルでサポートされています。コンテナランタイムと、kubeadmを全てのホストにインストールしてください。 インストールの詳細やその他の準備については、kubeadmのインストールを読んでください。
すでにkubeadmがインストール済みである場合は、kubeadmのアップグレード手順についてはLinuxノードのアップグレードの最初の2ステップを確認してください。
アップグレード中、kubeletはクラッシュループによってkubeadmの指示を待つため、数秒ごとに再起動します。 このクラッシュループは想定内の正常な動作です。 コントロールプレーンの初期化が完了すれば、kubeletは正常に動作します。
kubeadmは他のKubernetesコンポーネントと同様に、ホスト上のデフォルトゲートウェイとなっているネットワークインターフェースと関連づけられた利用可能なIPアドレスを探索します。 このIPアドレスは、コンポーネントによるアドバタイズや受信に使用されます。
Linuxのホスト上でこのIPを確認するには次のようにします:
ip route show # "default via"で始まる行を探してください。
Kubernetesコンポーネントはカスタムネットワークインターフェースをオプションとして受け入れないため、カスタム構成を必要とする全てのコンポーネントのインスタンスにカスタムIPアドレスをフラグとして渡す必要があります。
initおよびjoinで作成されたコントロールプレーンに対してAPIサーバーのアドバタイズアドレスを設定するには、--apiserver-advertise-addressフラグを使用します。
このオプションは、可能であればkubeadm APIにおいてInitConfiguration.localAPIEndpointおよびJoinConfiguration.controlPlane.localAPIEndpointとして設定するのが望ましいです。
全てのノード上のkubeletに対して、--node-ipオプションはkubeadmの設定ファイル(InitConfigurationまたはJoinConfiguration)の.nodeRegistration.kubeletExtraArgsにて指定することができます。
デュアルスタックについては、kubeadmによるデュアルスタックのサポートを参照してください。
コントロールプレーンのコンポーネントに割り当てたIPアドレスは、X.509証明書のSubject Alternative Nameフィールドの一部になります。 これらのIPアドレスを変更するには、新しい証明書に署名し、影響を受けるコンポーネントを再起動する必要があります。 これにより、証明書ファイルの変更が反映されます。 詳細は、kubeadmによる証明書管理を参照してください。
ip routeのようなコマンドを使用できます。
また、オペレーティングシステムによってはより高レベルなネットワーク管理ツールが提供される場合もあります。
ノードのデフォルトゲートウェイがパブリックアドレスの場合、ノードやクラスターを保護するためにパケットフィルタリングなどのセキュリティ対策を行う必要があります。このステップは任意で、kubeadm initおよびkubeadm join実行時にregistry.k8s.ioに存在するデフォルトのコンテナイメージをダウンロードしない場合のみ行います。
kubeadmは、ノードにインターネット接続がない状態でクラスターを構築する際に、必要なイメージを事前に取得するのに役立つコマンドがあります。 詳細は、インターネット接続無しでのkubeadmの稼働を参照してください。
kubeadmはカスタムイメージリポジトリから必要なイメージを使用することもできます。 詳細はカスタムイメージの使用を参照してください。
コントロールプレーンノードとは、etcd(クラスターのデータベース)やAPIサーバー(kubectlコマンドラインツールが通信する相手)などのコントロールプレーンのコンポーネントが実行されるマシンです。
kubeadmクラスターを高可用性クラスターにアップグレードする予定がある場合、--control-plane-endpointを指定して、すべてのコントロールプレーンノードとエンドポイントを共有する必要があります。
エンドポイントにはDNS名やロードバランサーのIPアドレスが使用できます。kubeadm initに引数を渡す必要があるかどうか確認してください。
選んだサードパーティのプロバイダーによっては、--pod-network-cidrをプロバイダー固有の値に設定する必要がある場合があります。
詳しくは、Podネットワークアドオンのインストールを参照してください。kubeadmは既知のエンドポイントの一覧を用いて、コンテナランタイムの検出を試みます。
異なるコンテナランタイムを使用する場合やプロビジョニングするノードに2つ以上のランタイムがインストールされている場合、kubeadmに--cri-socket引数を指定してください。
詳しくは、ランタイムのインストールを参照してください。コントロールプレーンノードを初期化するには、次のコマンドを実行します。
kubeadm init <args>
--apiserver-advertise-addressは、特定のコントロールプレーンノードのAPIサーバーがアドバタイズするアドレスを設定するために使用できます。
一方--control-plane-endpointは、すべてのコントロールプレーンノード共有のエンドポイントを設定するために使用できます。
--control-plane-endpointはIPアドレスと、IPアドレスへマッピングできるDNS名を使用できます。利用可能なソリューションをそうしたマッピングの観点から評価するには、ネットワーク管理者に相談してください。
以下にマッピングの例を示します。
192.168.0.102 cluster-endpoint
ここでは、192.168.0.102がこのノードのIPアドレスであり、cluster-endpointがこのIPアドレスへとマッピングされるカスタムDNS名です。
このように設定することで、--control-plane-endpoint=cluster-endpointをkubeadm initに渡せるようになり、kubeadm joinにも同じDNS名を渡せます。
後でcluster-endpointを修正して、高可用性が必要なシナリオでロードバランサーのアドレスを指すようにすることができます。
kubeadmでは、--control-plane-endpointを渡さずに構築したシングルコントロールプレーンのクラスターを高可用性クラスターに切り替えることはサポートされていません。
kubeadm initの引数のより詳細な情報は、kubeadmリファレンスガイドを参照してください。
kubeadm initを設定ファイルにて設定するには、設定ファイルのドキュメントを参照してください。
コントロールプレーンコンポーネントやetcdサーバーのliveness probeへのオプションのIPv6の割り当てなど、コントロールプレーンのコンポーネントをカスタマイズしたい場合は、カスタムの引数に示されている方法で各コンポーネントに追加の引数を与えてください。
既存のクラスターの再設定を行う場合は、kubeadmクラスターの再設定を参照してください。
kubeadm initを再び実行する場合は、初めにクラスターの破棄を行う必要があります。
もし異なるアーキテクチャのノードをクラスターにjoinさせたい場合は、デプロイしたDaemonSetがそのアーキテクチャ向けのコンテナイメージをサポートしているか確認してください。
初めにkubeadm initは、マシンがKubernetesを実行する準備ができているかを確認するための、一連の事前チェックを行います。
これらの事前チェックは、エラー発生時には警告を表示して終了します。
次に、kubeadm initはクラスターのコントロールプレーンのコンポーネントをダウンロードしてインストールします。
これには数分掛かるかもしれません。
これらが終了すると以下が出力されます。
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a Pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
kubectlをroot以外のユーザーでも実行できるようにするには、次のコマンドを実行します。これらのコマンドは、kubeadm initの出力の中にも書かれています。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
rootユーザーの場合は、代わりに次のコマンドを実行します。
export KUBECONFIG=/etc/kubernetes/admin.conf
kubeadm initによって生成されたkubeconfigファイルのadmin.confは、Subject: O = kubeadm:cluster-admins, CN = kubernetes-admin
の証明書を内包しています。
kubeadm:cluster-adminsグループは、ビルトインのClusterRoleであるcluster-adminと紐づいています。
admin.confは誰とも共有しないでください。
kubeadm initは、別のkubeconfigファイルであるsuper-admin.confも生成します。
これは、Subject: O = system:masters, CN = kubernetes-super-adminの証明書を内包しています。
system:mastersは認可のレイヤー(例: RBAC)をバイパスする、緊急用のスーパーユーザーグループです。
super-admin.confは誰とも共有しないでください。
このファイルは安全な場所に退避させることを推奨します。
追加ユーザーへkubeconfigファイルを生成するためにkubeadm kubeconfig userを実行するには、追加ユーザのためのkubeconfigファイルの生成を参照してください。
kubeadm initが出力したkubeadm joinコマンドをメモしておいてください。クラスターにノードを追加するために、このコマンドが必要です。
トークンは、コントロールプレーンノードと追加ノードの間の相互認証に使用します。ここに含まれるトークンには秘密の情報が含まれます。
このトークンを知っていれば、誰でもクラスターに認証済みノードを追加できてしまうため、取り扱いには注意してください。
kubeadm tokenコマンドを使用すると、これらのトークンの一覧、作成、削除ができます。
詳しくはkubeadmリファレンスガイドを参照してください。
このセクションには、ネットワークのセットアップとデプロイの順序に関する重要な情報が書かれています。 先に進む前に以下のすべてのアドバイスを熟読してください。
Pod同士が通信できるようにするには、Container Network Interface(CNI)をベースとするPodネットワークアドオンをデプロイしなければなりません。 ネットワークアドオンをインストールする前には、Cluster DNS(CoreDNS)は起動しません。
kubeadm initの実行時に--pod-network-cidrにそのCIDRを指定し、ネットワークプラグインのYAMLでは代わりにそのCIDRを使用してください)。kubeadmはRBAC(role based access control)の使用を強制します。
PodネットワークプラグインがRBACをサポートしており、またそのデプロイに使用するマニフェストもRBACをサポートしていることを確認してください。CNIを使用するKubernetes Podネットワークを提供する外部のプロジェクトがいくつかあります。一部のプロジェクトでは、ネットワークポリシーもサポートしています。
Kubernetesのネットワークモデルを実装したアドオンの一覧も確認してください。
Kubernetesでサポートされているネットワークアドオンの非網羅的な一覧については、アドオンのインストールのページを参照してください。 Podネットワークアドオンをインストールするには、コントロールプレーンノード上またはkubeconfigクレデンシャルを持っているノード上で、次のコマンドを実行します。
kubectl apply -f <add-on.yaml>
インストールできるPodネットワークは、クラスターごとに1つだけです。
Podネットワークがインストールされたら、kubectl get pods --all-namespacesの出力結果でCoreDNS PodがRunning状態であることをチェックすることで、ネットワークが動作していることを確認できます。そして、一度CoreDNS Podが動作すれば、続けてノードを追加できます。
ネットワークやCoreDNSがRunning状態にならない場合は、kubeadmのトラブルシューティングガイドをチェックしてください。
デフォルトでは、kubeadmはNodeRestrictionという、ノード登録時にkubeletが自己適用するラベルを制限するアドミッションコントローラーを有効化します。
このアドミッションコントローラーのドキュメントでは、kubeletの--node-labelsオプションで使用できるラベルについて説明しています。
node-role.kubernetes.io/control-planeは上記のような制限されたラベルであり、ノード作成後に特権クライアントを使用してkubeadmがマニュアルで適用します。
これを手動で行うには、kubeadm管理の/etc/kubernetes/admin.confのような特権kubeconfigを使用していることを確認し、kubectl labelコマンドを使用してください。
デフォルトでは、セキュリティ上の理由により、クラスターはコントロールプレーンノードにPodをスケジューリングしません。 たとえば、開発用のKubernetesシングルマシンのクラスターなどで、Podをコントロールプレーンノードにスケジューリングしたい場合は、次のコマンドを実行します。
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
出力は次のようになります。
node "test-01" untainted
...
このコマンドは、コントロールプレーンノードを含むすべてのノードからnode-role.kubernetes.io/control-plane:NoSchedule taintを削除します。
その結果、スケジューラーはどこにでもPodをスケジューリングできるようになります。
さらに、以下のコマンドを実行することでコントロールプレーンノードからnode.kubernetes.io/exclude-from-external-load-balancersラベルを削除できます。
このラベルは、バックエンドサーバーの一覧からコントロールプレーンノードを除外するものです。
kubectl label nodes --all node.kubernetes.io/exclude-from-external-load-balancers-
コントロールプレーンノードの追加によって高可用性kubeadmクラスターを構築する手順は、kubeadmを使用した高可用性クラスターの作成を参照してください。
ワーカーノードは、ワークロード(コンテナやPodなど)が実行される場所です。
kubeadm joinコマンドを使用したLinux、Windowsワーカーノードの追加方法は、以下のページを参照してください。
他のコンピューター(例: ラップトップ)上のkubectlがクラスターと通信できるようにするためには、次のようにして管理者のkubeconfigファイルをコントロールプレーンノードから対象のコンピューター上にコピーする必要があります。
scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf get nodes
上の例では、rootユーザーに対するSSH接続が有効であることを仮定しています。
そうでない場合は、admin.confファイルを他のユーザーからアクセスできるようにコピーした上で、代わりにそのユーザーを使ってscpしてください。
admin.confファイルはユーザーにクラスターに対する スーパーユーザー の権限を与えます。
そのため、このファイルは慎重に使用しなければなりません。
通常のユーザーには、明示的に許可した権限を持つユニークなクレデンシャルを生成することを推奨します。
これには、kubeadm kubeconfig user --client-name <CN>コマンドが使えます。
このコマンドを実行すると、KubeConfigファイルがSTDOUTに出力されるため、ファイルに保存してユーザーに配布します。
その後、kubectl create (cluster)rolebindingコマンドを使って権限を付与します。
クラスターの外部からAPIサーバーに接続したいときは、次のようにkubectl proxyコマンドが使えます。
scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy
これで、ローカルのhttp://localhost:8001/api/v1からAPIサーバーにアクセスできるようになります。
テストのためにクラスターに破棄可能なサーバーを使用した場合、サーバーのスイッチをオフにすれば、以降のクリーンアップの作業は必要ありません。
クラスターのローカルの設定を削除するには、kubectl config delete-clusterを実行します。
しかし、よりきれいにクラスターのプロビジョンをもとに戻したい場合は、初めにノードのdrainを行い、ノードが空になっていることを確認した後、ノードの設定を削除する必要があります。
適切なクレデンシャルを使用してコントロールプレーンノードに指示を出します。次のコマンドを実行してください。
kubectl drain <node name> --delete-emptydir-data --force --ignore-daemonsets
ノードを削除する前に、kubeadmによってインストールされた状態をリセットします。
kubeadm reset
リセットプロセスでは、iptablesのルールやIPVS tablesのリセットやクリーンアップは行われません。 iptablesをリセットしたい場合は、次のように手動でコマンドを実行する必要があります。
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
IPVS tablesをリセットしたい場合は、次のコマンドを実行する必要があります。
ipvsadm -C
ノードを削除します。
kubectl delete node <node name>
クラスターのセットアップを最初から始めたいときは、kubeadm initやkubeadm joinを適切な引数を付けて実行すればいいだけです。
コントロールホスト上でkubeadm resetを実行すると、ベストエフォートでのクリーンアップが実行できます。
このサブコマンドとオプションに関するより詳しい情報は、kubeadm resetリファレンスドキュメントを読んでください。
kubeadmは、kubeadmが管理するコンポーネントに対してバージョンの差異を許容しますが、kubeadmのバージョンをコントロールプレーンのコンポーネント、kube-proxy、kubeletと一致させることを推奨します。
kubeadmは、kubeadmと同じバージョンか、1つ前のバージョンのKubernetesコンポーネントで使用できます。
Kubernetesのバージョンはkubeadm initの--kubernetes-version、もしくは--configを使用する場合のClusterConfiguration.kubernetesVersionフィールドで指定できます。
このオプションはkube-apiserver、kube-controller-manager、kube-scheduler、kube-proxyのバージョンを制御します。
例:
kubernetesVersionは、1.35または1.34でなければならないKubernetesのバージョンと同様に、kubeadmは、kubeadmと同じバージョン、もしくは3つ前までのバージョンをkubeletに使用できます。
例:
kubeadmによって管理されている既存のノードまたはクラスター全体を、kubeadmコマンドが操作するには一定の制限が存在します。
新たなノードをクラスターに参加させる場合、kubeadm joinを実行するkubeadmのバイナリは、kubeadm initによるクラスター構築、もしくはkubeadm upgradeによるノードのアップグレードのいずれかに使用されたkubeadmの最新バージョンと一致している必要があります。
同様の制限はkubeadm upgradeを除く他のkubeadmのコマンドにも適用されます。
kubeadm joinの例:
kubeadm initによるクラスター構築で使用したkubeadmのバージョン: 1.35アップグレードするノードでは、そのノードの管理に使用しているkubeadmのバージョンと同じマイナーバージョン、もしくはマイナーバージョンが1つ新しいkubeadmを使用する必要があります。
kubeadm upgradeの例:
異なるKubernetesコンポーネント間のバージョン差異についてさらに学ぶには、バージョンスキューポリシーを参照してください。
ここで作られたクラスターは、1つのコントロールプレーンノードと、その上で動作する1つのetcdデータベースしか持ちません。 つまり、コントロールプレーンノードが故障した場合、クラスターのデータは失われ、クラスターを最初から作り直す必要がある可能性があります。
対処方法:
定期的にetcdをバックアップする。
kubeadmが設定するetcdのデータディレクトリは、コントロールプレーンノードの/var/lib/etcdにあります。
複数のコントロールプレーンノードを使用する。 高可用性トポロジーのオプションでは、より高い可用性を提供するクラスターのトポロジーの選択について説明しています。
kubeadmのdeb/rpmパッケージおよびバイナリは、multi-platform proposalに従い、amd64、arm(32ビット)、arm64、ppc64le、およびs390x向けにビルドされています。
マルチプラットフォームのコントロールプレーンおよびアドオン用のコンテナイメージも、v1.12からサポートされています。
すべてのプラットフォーム向けのソリューションを提供しているネットワークプロバイダーは一部のみです。それぞれのプロバイダーが選択したプラットフォームをサポートしているかどうかを確認するには、前述のネットワークプロバイダーのリストを参照してください。
kubeadmに関する問題が起きたときは、トラブルシューティングドキュメントを確認してください。
kubeadmを使用したクラスターをアップグレードする方法について、kubeadmクラスターをアップグレードするを参照する。kubeadmの高度な利用方法についてkubeadmリファレンスドキュメントで学ぶ。kubectlについてさらに学ぶ。