kubeadmを使用したクラスターの作成

ベストプラクティスに準拠した実用最小限のKubernetesクラスターを作成します。 実際、kubeadmを使用すれば、Kubernetes Conformance testsに通るクラスターをセットアップすることができます。 kubeadmは、ブートストラップトークンやクラスターのアップグレードなどのその他のクラスターのライフサイクルの機能もサポートします。

kubeadmツールは、次のようなときに適しています。

  • 新しいユーザーが初めてKubernetesを試すためのシンプルな方法が必要なとき。
  • 既存のユーザーがクラスターのセットアップを自動化し、アプリケーションをテストする方法が必要なとき。
  • より大きなスコープで、他のエコシステムやインストーラーツールのビルディングブロックが必要なとき。

kubeadmは、ラップトップ、クラウドのサーバー群、Raspberry Piなどの様々なマシンにインストールして使えます。クラウドとオンプレミスのどちらにデプロイする場合でも、kubeadmはAnsibleやTerraformなどのプロビジョニングシステムに統合できます。

始める前に

このガイドを進めるには、以下の環境が必要です。

  • UbuntuやCentOSなど、deb/rpmパッケージと互換性のあるLinux OSが動作している1台以上のマシンがあること。
  • マシンごとに2GiB以上のRAMが搭載されていること。それ以下の場合、アプリ実行用のメモリがほとんど残りません。
  • コントロールプレーンノードとして使用するマシンには、最低でも2CPU以上あること。
  • クラスター内の全マシン間に完全なネットワーク接続があること。パブリックネットワークとプライベートネットワークのいずれでも使えます。

また、新しいクラスターで使いたいKubernetesのバージョンをデプロイできるバージョンのkubeadmを使用する必要もあります。

Kubernetesのバージョンとバージョンスキューポリシーは、kubeadmにもKubernetes全体と同じように当てはまります。 Kubernetesとkubeadmがサポートするバージョンを理解するには、上記のポリシーを確認してください。このページは、Kubernetes v1.33向けに書かれています。

kubeadmツールの全体の機能の状態は、一般利用可能(GA)です。一部のサブ機能はまだ活発に開発が行われています。クラスター作成の実装は、ツールの進化に伴ってわずかに変わるかもしれませんが、全体の実装は非常に安定しているはずです。

目的

  • シングルコントロールプレーンのKubernetesクラスターをインストールします
  • クラスター上にPodネットワークをインストールして、Podがお互いに通信できるようにします

手順

ホストの準備

コンポーネントのインストール

コンテナランタイムと、kubeadmを全てのホストにインストールしてください。 インストールの詳細やその他の準備については、kubeadmのインストールを読んでください。

ネットワークの設定

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による証明書管理を参照してください。

必要なコンテナイメージの準備

このステップは任意で、kubeadm initおよびkubeadm join実行時にregistry.k8s.ioに存在するデフォルトのコンテナイメージをダウンロードしない場合のみ行います。

kubeadmは、ノードにインターネット接続がない状態でクラスターを構築する際に、必要なイメージを事前に取得するのに役立つコマンドがあります。 詳細は、インターネット接続無しでのkubeadmの稼働を参照してください。

kubeadmはカスタムイメージリポジトリから必要なイメージを使用することもできます。 詳細はカスタムイメージの使用を参照してください。

コントロールプレーンノードの初期化

コントロールプレーンノードとは、etcd(クラスターのデータベース)やAPIサーバー(kubectlコマンドラインツールが通信する相手)などのコントロールプレーンのコンポーネントが実行されるマシンです。

  1. (推奨)シングルコントロールプレーンのkubeadmクラスターを高可用性クラスターにアップグレードする予定がある場合、--control-plane-endpointを指定して、すべてのコントロールプレーンノードとエンドポイントを共有する必要があります。 エンドポイントにはDNS名やロードバランサーのIPアドレスが使用できます。
  2. Podネットワークアドオンを選んで、kubeadm initに引数を渡す必要があるかどうか確認してください。 選んだサードパーティのプロバイダーによっては、--pod-network-cidrをプロバイダー固有の値に設定する必要がある場合があります。 詳しくは、Podネットワークアドオンのインストールを参照してください。
  3. (オプション)kubeadmは既知のエンドポイントの一覧を用いて、コンテナランタイムの検出を試みます。 異なるコンテナランタイムを使用する場合やプロビジョニングするノードに2つ以上のランタイムがインストールされている場合、kubeadm--cri-socket引数を指定してください。 詳しくは、ランタイムのインストールを参照してください。

コントロールプレーンノードを初期化するには、次のコマンドを実行します。

kubeadm init <args>

apiserver-advertise-addressとControlPlaneEndpointに関する検討

--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-endpointkubeadm 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が出力したkubeadm joinコマンドをメモしておいてください。クラスターにノードを追加するために、このコマンドが必要です。

トークンは、コントロールプレーンノードと追加ノードの間の相互認証に使用します。ここに含まれるトークンには秘密の情報が含まれます。 このトークンを知っていれば、誰でもクラスターに認証済みノードを追加できてしまうため、取り扱いには注意してください。 kubeadm tokenコマンドを使用すると、これらのトークンの一覧、作成、削除ができます。 詳しくはkubeadmリファレンスガイドを参照してください。

Podネットワークアドオンのインストール

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

(オプション)APIサーバーをlocalhostへプロキシする

クラスターの外部から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 initkubeadm joinを適切な引数を付けて実行すればいいだけです。

コントロールプレーンのクリーンアップ

コントロールホスト上でkubeadm resetを実行すると、ベストエフォートでのクリーンアップが実行できます。

このサブコマンドとオプションに関するより詳しい情報は、kubeadm resetリファレンスドキュメントを読んでください。

バージョンスキューポリシー

kubeadmは、kubeadmが管理するコンポーネントに対してバージョンの差異を許容しますが、kubeadmのバージョンをコントロールプレーンのコンポーネント、kube-proxy、kubeletと一致させることを推奨します。

Kubernetesのバージョンに対するkubeadmのバージョンの差異

kubeadmは、kubeadmと同じバージョンか、1つ前のバージョンのKubernetesコンポーネントで使用できます。 Kubernetesのバージョンはkubeadm init--kubernetes-version、もしくは--configを使用する場合のClusterConfiguration.kubernetesVersionフィールドで指定できます。 このオプションはkube-apiserver、kube-controller-manager、kube-scheduler、kube-proxyのバージョンを制御します。

例:

  • kubeadmのバージョン: 1.33
  • kubernetesVersionは、1.33または1.32でなければならない

kubeletに対するkubeadmのバージョンの差異

Kubernetesのバージョンと同様に、kubeadmは、kubeadmと同じバージョン、もしくは3つ前までのバージョンをkubeletに使用できます。

例:

  • kubeadmのバージョン: 1.33
  • ホスト上のkubeletのバージョンは、1.33、1.32、1.31、もしくは1.30でなければならない

kubeadmに対するkubeadmのバージョンの差異

kubeadmによって管理されている既存のノードまたはクラスター全体を、kubeadmコマンドが操作するには一定の制限が存在します。

新たなノードをクラスターに参加させる場合、kubeadm joinを実行するkubeadmのバイナリは、kubeadm initによるクラスター構築、もしくはkubeadm upgradeによるノードのアップグレードのいずれかに使用されたkubeadmの最新バージョンと一致している必要があります。 同様の制限はkubeadm upgradeを除く他のkubeadmのコマンドにも適用されます。

kubeadm joinの例:

  • kubeadm initによるクラスター構築で使用したkubeadmのバージョン: 1.33
  • 参加するノードは、1.33のバージョンのkubeadmバイナリを使用しなければならない

アップグレードするノードでは、そのノードの管理に使用しているkubeadmのバージョンと同じマイナーバージョン、もしくはマイナーバージョンが1つ新しいkubeadmを使用する必要があります。

kubeadm upgradeの例:

  • クラスター構築またはノードのアップグレードに使用されたkubeadmのバージョン: 1.32
  • ノードのアップグレードで使用するkubeadmのバージョンは、1.32または1.33でなければならない

異なるKubernetesコンポーネント間のバージョン差異についてさらに学ぶには、バージョンスキューポリシーを参照してください。

制限事項

クラスターの弾力性

ここで作られたクラスターは、1つのコントロールプレーンノードと、その上で動作する1つのetcdデータベースしか持ちません。 つまり、コントロールプレーンノードが故障した場合、クラスターのデータは失われ、クラスターを最初から作り直す必要がある可能性があります。

対処方法:

プラットフォームの互換性

kubeadmのdeb/rpmパッケージおよびバイナリは、multi-platform proposalに従い、amd64、arm(32ビット)、arm64、ppc64le、およびs390x向けにビルドされています。

マルチプラットフォームのコントロールプレーンおよびアドオン用のコンテナイメージも、v1.12からサポートされています。

すべてのプラットフォーム向けのソリューションを提供しているネットワークプロバイダーは一部のみです。それぞれのプロバイダーが選択したプラットフォームをサポートしているかどうかを確認するには、前述のネットワークプロバイダーのリストを参照してください。

トラブルシューティング

kubeadmに関する問題が起きたときは、トラブルシューティングドキュメントを確認してください。

次の項目

フィードバック