これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
kubeadmを使ってクラスターを構築する
1 - kubeadmのインストール

このページではkubeadmコマンドをインストールする方法を示します。このインストール処理実行後にkubeadmを使用してクラスターを作成する方法については、kubeadmを使用したシングルマスタークラスターの作成を参照してください。
始める前に
- 次のいずれかが動作しているマシンが必要です
- Ubuntu 16.04+
- Debian 9+
- CentOS 7
- Red Hat Enterprise Linux (RHEL) 7
- Fedora 25+
- HypriotOS v1.0.1+
- Container Linux (tested with 1800.6.0)
- 1台あたり2GB以上のメモリ(2GBの場合、アプリ用のスペースはほとんどありません)
- 2コア以上のCPU
- クラスター内のすべてのマシン間で通信可能なネットワーク(パブリックネットワークでもプライベートネットワークでも構いません)
- ユニークなhostname、MACアドレス、とproduct_uuidが各ノードに必要です。詳細はここを参照してください。
- マシン内の特定のポートが開いていること。詳細はここを参照してください。
- Swapがオフであること。kubeletが正常に動作するためにはswapは必ずオフでなければなりません。
MACアドレスとproduct_uuidが全てのノードでユニークであることの検証
- ネットワークインターフェースのMACアドレスは
ip linkもしくはifconfig -aコマンドで取得できます。 - product_uuidは
sudo cat /sys/class/dmi/id/product_uuidコマンドで確認できます。
ハードウェアデバイスではユニークなアドレスが割り当てられる可能性が非常に高いですが、VMでは同じになることがあります。Kubernetesはこれらの値を使用して、クラスター内のノードを一意に識別します。これらの値が各ノードに固有ではない場合、インストール処理が失敗することもあります。
ネットワークアダプタの確認
複数のネットワークアダプターがあり、Kubernetesコンポーネントにデフォルトで到達できない場合、IPルートを追加して、Kubernetesクラスターのアドレスが適切なアダプターを経由するように設定することをお勧めします。
必須ポートの確認
Kubernetesのコンポーネントが互いに通信するためには、これらの必要なポートが開いている必要があります。 netcatなどのツールを使用することで、下記のようにポートが開いているかどうかを確認することが可能です。
nc 127.0.0.1 6443 -zv -w 2
使用するPodネットワークプラグインによっては、特定のポートを開く必要がある場合もあります。 これらは各Podネットワークプラグインによって異なるため、どのようなポートが必要かについては、プラグインのドキュメントを参照してください。
ランタイムのインストール
Podのコンテナを実行するために、Kubernetesはコンテナランタイムを使用します。
デフォルトでは、Kubernetesは選択されたコンテナランタイムと通信するためにContainer Runtime Interface (CRI)を使用します。
ランタイムを指定しない場合、kubeadmはよく知られたUnixドメインソケットのリストをスキャンすることで、インストールされたコンテナランタイムの検出を試みます。 次の表がコンテナランタイムと関連するソケットのパスリストです。
| ランタイム | Unixドメインソケットのパス |
|---|---|
| Docker | /var/run/docker.sock |
| containerd | /run/containerd/containerd.sock |
| CRI-O | /var/run/crio/crio.sock |
Dockerとcontainerdの両方が同時に検出された場合、Dockerが優先されます。Docker 18.09にはcontainerdが同梱されており、両方が検出可能であるため、この仕様が必要です。他の2つ以上のランタイムが検出された場合、kubeadmは適切なエラーメッセージで終了します。
kubeletは、組み込まれたdockershimCRIを通してDockerと連携します。
詳細は、コンテナランタイムを参照してください。
kubeadm、kubelet、kubectlのインストール
以下のパッケージをマシン上にインストールしてください
kubeadm: クラスターを起動するコマンドです。kubelet: クラスター内のすべてのマシンで実行されるコンポーネントです。 Podやコンテナの起動などを行います。kubectl: クラスターにアクセスするためのコマンドラインツールです。
kubeadmはkubeletやkubectlをインストールまたは管理しないため、kubeadmにインストールするKubernetesコントロールプレーンのバージョンと一致させる必要があります。そうしないと、予期しないバグのある動作につながる可能性のあるバージョン差異(version skew)が発生するリスクがあります。ただし、kubeletとコントロールプレーン間のマイナーバージョン差異(minor version skew)は_1つ_サポートされていますが、kubeletバージョンがAPIサーバーのバージョンを超えることはできません。たとえば、1.7.0を実行するkubeletは1.8.0 APIサーバーと完全に互換性がありますが、その逆はできません。
kubectlのインストールに関する詳細情報は、kubectlのインストールおよびセットアップを参照してください。
警告:
これらの手順はシステムアップグレードによるすべてのKubernetesパッケージの更新を除きます。これはkubeadmとKubernetesがアップグレードにおける特別な注意を必要とするからです。バージョン差異(version skew)に関しては下記を参照してください。
- Kubernetes Kubernetesバージョンとバージョンスキューサポートポリシー
- Kubeadm-specific バージョン互換ポリシー
aptのパッケージ一覧を更新し、Kubernetesのaptリポジトリーを利用するのに必要なパッケージをインストールします:sudo apt-get update # apt-transport-httpsはダミーパッケージの可能性があります。その場合、そのパッケージはスキップできます sudo apt-get install -y apt-transport-https ca-certificates curl gpgKubernetesパッケージリポジトリーの公開署名キーをダウンロードします。すべてのリポジトリーに同じ署名キーが使用されるため、URL内のバージョンは無視できます:
# `/etc/apt/keyrings`フォルダーが存在しない場合は、curlコマンドの前に作成する必要があります。下記の備考を参照してください。 # sudo mkdir -p -m 755 /etc/apt/keyrings curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.36/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
備考:
Debian 12とUbuntu 22.04より古いリリースでは、/etc/apt/keyringsフォルダーはデフォルトでは存在しないため、curlコマンドの前に作成する必要があります。適切なKubernetes
aptリポジトリーを追加します。このリポジトリーには、Kubernetes 1.36用のパッケージのみがあることに注意してください。他のKubernetesマイナーバージョンの場合は、目的のマイナーバージョンに一致するようにURL内のKubernetesマイナーバージョンを変更する必要があります(インストールする予定のKubernetesバージョンのドキュメントも読んでください):# これにより、/etc/apt/sources.list.d/kubernetes.listにある既存の設定が上書きされます echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.36/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.listaptのパッケージ一覧を更新し、kubelet、kubeadm、kubectlをインストールします。そしてバージョンを固定します:sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
# SELinuxをpermissiveモードに設定する(効果的に無効化する)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
Note:
setenforce 0およびsed ...を実行することによりSELinuxをpermissiveモードに設定し、効果的に無効化できます。 これはコンテナがホストのファイルシステムにアクセスするために必要です。例えば、Podのネットワークに必要とされます。 kubeletにおけるSELinuxのサポートが改善されるまでは、これを実行しなければなりません。
CNIプラグインをインストールする(ほとんどのPodのネットワークに必要です):
CNI_VERSION="v0.8.2"
ARCH="amd64"
mkdir -p /opt/cni/bin
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-${ARCH}-${CNI_VERSION}.tgz" | tar -C /opt/cni/bin -xz
crictlをインストールする (kubeadm / Kubelet Container Runtime Interface (CRI)に必要です)
CRICTL_VERSION="v1.22.0"
ARCH="amd64"
curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz" | sudo tar -C $DOWNLOAD_DIR -xz
kubeadm、kubelet、kubectlをインストールしkubeletをsystemd serviceに登録します:
RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)"
ARCH="amd64"
mkdir -p /opt/bin
cd /opt/bin
curl -L --remote-name-all https://dl.k8s.io/release/${RELEASE}/bin/linux/${ARCH}/{kubeadm,kubelet,kubectl}
chmod +x {kubeadm,kubelet,kubectl}
curl -sSL "https://raw.githubusercontent.com/kubernetes/kubernetes/${RELEASE}/build/debs/kubelet.service" | sed "s:/usr/bin:/opt/bin:g" > /etc/systemd/system/kubelet.service
mkdir -p /etc/systemd/system/kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/kubernetes/${RELEASE}/build/debs/10-kubeadm.conf" | sed "s:/usr/bin:/opt/bin:g" > /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
kubeletを有効化し起動します:
systemctl enable --now kubelet
kubeadmが何をすべきか指示するまで、kubeletはクラッシュループで数秒ごとに再起動します。
コントロールプレーンノードのkubeletによって使用されるcgroupドライバーの設定
Dockerを使用した場合、kubeadmは自動的にkubelet向けのcgroupドライバーを検出し、それを実行時に/var/lib/kubelet/kubeadm-flags.envファイルに設定します。
もしあなたが異なるCRIを使用している場合、/etc/default/kubelet(CentOS、RHEL、Fedoraでは/etc/sysconfig/kubelet)ファイル内のcgroup-driverの値を以下のように変更する必要があります。
KUBELET_EXTRA_ARGS=--cgroup-driver=<value>
このファイルは、kubeletの追加のユーザー定義引数を取得するために、kubeadm initおよびkubeadm joinによって使用されます。
CRIのcgroupドライバーがcgroupfsでない場合にのみそれを行う必要があることに注意してください。なぜなら、これはすでにkubeletのデフォルト値であるためです。
kubeletをリスタートする方法:
systemctl daemon-reload
systemctl restart kubelet
CRI-Oやcontainerdといった他のコンテナランタイムのcgroup driverは実行中に自動的に検出されます。
トラブルシュート
kubeadmで問題が発生した場合は、トラブルシューティングを参照してください。
次の項目
2 - kubeadmのトラブルシューティング
どのプログラムでもそうですが、kubeadmのインストールや実行でエラーが発生することがあります。このページでは、一般的な失敗例をいくつか挙げ、問題を理解して解決するための手順を示しています。
本ページに問題が記載されていない場合は、以下の手順を行ってください:
問題がkubeadmのバグによるものと思った場合:
- github.com/kubernetes/kubeadmにアクセスして、既存のIssueを探してください。
- Issueがない場合は、テンプレートにしたがって新しくIssueを立ててください。
kubeadmがどのように動作するかわからない場合は、Slackの#kubeadmチャンネルで質問するか、StackOverflowで質問をあげてください。その際は、他の方が助けを出しやすいように
#kubernetesや#kubeadmといったタグをつけてください。
RBACがないため、v1.18ノードをv1.17クラスターに結合できない
v1.18では、同名のノードが既に存在する場合にクラスター内のノードに参加しないようにする機能を追加しました。これには、ブートストラップトークンユーザーがNodeオブジェクトをGETできるようにRBACを追加する必要がありました。
しかし、これによりv1.18のkubeadm joinがkubeadm v1.17で作成したクラスターに参加できないという問題が発生します。
この問題を回避するには、次の2つの方法があります。
kubeadm v1.18を用いて、コントロールプレーンノード上で
kubeadm init phase bootstrap-tokenを実行します。 これには、ブートストラップトークンの残りのパーミッションも同様に有効にすることに注意してください。kubectl apply -f ...を使って以下のRBACを手動で適用します。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kubeadm:get-nodes
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubeadm:get-nodes
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubeadm:get-nodes
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers:kubeadm:default-node-token
インストール中にebtablesもしくは他の似たような実行プログラムが見つからない
kubeadm initの実行中に以下のような警告が表示された場合は、以降に記載するやり方を行ってください。
[preflight] WARNING: ebtables not found in system path
[preflight] WARNING: ethtool not found in system path
このような場合、ノード上にebtables, ethtoolなどの実行ファイルがない可能性があります。これらをインストールするには、以下のコマンドを実行します。
- Ubuntu/Debianユーザーは、
apt install ebtables ethtoolを実行してください。 - CentOS/Fedoraユーザーは、
yum install ebtables ethtoolを実行してください。
インストール中にkubeadmがコントロールプレーンを待ち続けて止まる
以下のを出力した後にkubeadm initが止まる場合は、kubeadm initを実行してください:
[apiclient] Created API client, waiting for the control plane to become ready
これはいくつかの問題が原因となっている可能性があります。最も一般的なのは:
ネットワーク接続の問題が挙げられます。続行する前に、お使いのマシンがネットワークに完全に接続されていることを確認してください。
kubeletのデフォルトのcgroupドライバーの設定がDockerで使用されているものとは異なっている場合も考えられます。 システムログファイル(例:
/var/log/message)をチェックするか、journalctl -u kubeletの出力を調べてください:error: failed to run Kubelet: failed to create kubelet: misconfiguration: kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs"以上のようなエラーが現れていた場合、cgroupドライバーの問題を解決するには、以下の2つの方法があります:
ここの指示に従ってDockerを再度インストールします。
Dockerのcgroupドライバーに合わせてkubeletの設定を手動で変更します。その際は、マスターノード上でkubeletが使用するcgroupドライバーを設定するを参照してください。
- control plane Dockerコンテナがクラッシュループしたり、ハングしたりしています。これは
docker psを実行し、docker logsを実行して各コンテナを調査することで確認できます。
管理コンテナを削除する時にkubeadmが止まる
Dockerが停止して、Kubernetesで管理されているコンテナを削除しないと、以下のようなことが起こる可能性があります:
sudo kubeadm reset
[preflight] Running pre-flight checks
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Removing kubernetes-managed containers
(block)
考えられる解決策は、Dockerサービスを再起動してからkubeadm resetを再実行することです:
sudo systemctl restart docker.service
sudo kubeadm reset
dockerのログを調べるのも有効な場合があります:
journalctl -u docker
Podの状態がRunContainerError、CrashLoopBackOff、またはErrorとなる
kubeadm initの直後には、これらの状態ではPodは存在しないはずです。
kubeadm initの 直後 にこれらの状態のいずれかにPodがある場合は、kubeadmのリポジトリにIssueを立ててください。ネットワークソリューションをデプロイするまではcoredns(またはkube-dns)はPending状態でなければなりません。- ネットワークソリューションをデプロイしても
coredns(またはkube-dns)に何も起こらない場合にRunContainerError、CrashLoopBackOff、Error`の状態でPodが表示された場合は、インストールしたPodネットワークソリューションが壊れている可能性が高いです。より多くのRBACの特権を付与するか、新しいバージョンを使用する必要があるかもしれません。PodネットワークプロバイダーのイシュートラッカーにIssueを出して、そこで問題をトリアージしてください。 - 1.12.1よりも古いバージョンのDockerをインストールした場合は、
systemdでdockerdを起動する際にMountFlags=slaveオプションを削除してdockerを再起動してください。マウントフラグは/usr/lib/systemd/system/docker.serviceで確認できます。MountFlagsはKubernetesがマウントしたボリュームに干渉し、PodsをCrashLoopBackOff状態にすることがあります。このエラーは、Kubernetesがvar/run/secrets/kubernetes.io/serviceaccountファイルを見つけられない場合に発生します。
coredns(もしくはkube-dns)がPending状態でスタックする
kubeadmはネットワークプロバイダーに依存しないため、管理者は選択したPodネットワークソリューションをインストールをする必要があります。CoreDNSを完全にデプロイする前にPodネットワークをインストールする必要があります。したがって、ネットワークがセットアップされる前の Pending状態になります。
HostPortサービスが動かない
HostPortとHostIPの機能は、ご使用のPodネットワークプロバイダーによって利用可能です。Podネットワークソリューションの作者に連絡して、HostPortとHostIP機能が利用可能かどうかを確認してください。
Calico、Canal、FlannelのCNIプロバイダーは、HostPortをサポートしていることが確認されています。
詳細については、[CNI portmap documentation] (https://github.com/containernetworking/plugins/blob/master/plugins/meta/portmap/README.md) を参照してください。
ネットワークプロバイダーが portmap CNI プラグインをサポートしていない場合は、NodePortサービスを使用するか、HostNetwork=trueを使用してください。
サービスIP経由でPodにアクセスすることができない
多くのネットワークアドオンは、PodがサービスIPを介して自分自身にアクセスできるようにするヘアピンモードを有効にしていません。これはCNIに関連する問題です。ヘアピンモードのサポート状況については、ネットワークアドオンプロバイダーにお問い合わせください。
VirtualBoxを使用している場合(直接またはVagrant経由)は、
hostname -iがルーティング可能なIPアドレスを返すことを確認する必要があります。デフォルトでは、最初のインターフェースはルーティング可能でないホスト専用のネットワークに接続されています。これを回避するには/etc/hostsを修正する必要があります。例としてはこのVagrantfileを参照してください。
TLS証明書のエラー
以下のエラーは、証明書の不一致の可能性を示しています。
# kubectl get pods
Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
HOME/.kube/configファイルに有効な証明書が含まれていることを確認し、必要に応じて証明書を再生成します。kubeconfigファイル内の証明書はbase64でエンコードされています。証明書をデコードするにはbase64 --decodeコマンドを、証明書情報を表示するにはopenssl x509 -text -nooutコマンドを用いてください。環境変数
KUBECONFIGの設定を解除するには以下のコマンドを実行するか:unset KUBECONFIG設定をデフォルトの
KUBECONFIGの場所に設定します:export KUBECONFIG=/etc/kubernetes/admin.confもう一つの回避策は、既存の
kubeconfigを"admin"ユーザーに上書きすることです:mv $HOME/.kube $HOME/.kube.bak mkdir $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
Vagrant内でPodネットワークとしてflannelを使用する時のデフォルトNIC
以下のエラーは、Podネットワークに何か問題があったことを示している可能性を示しています:
Error from server (NotFound): the server could not find the requested resource
Vagrant内のPodネットワークとしてflannelを使用している場合は、flannelのデフォルトのインターフェース名を指定する必要があります。
Vagrantは通常、2つのインターフェースを全てのVMに割り当てます。1つ目は全てのホストにIPアドレス
10.0.2.15が割り当てられており、NATされる外部トラフィックのためのものです。これは、ホストの最初のインターフェースをデフォルトにしているflannelの問題につながるかもしれません。これは、すべてのホストが同じパブリックIPアドレスを持っていると考えます。これを防ぐには、2番目のインターフェースが選択されるように
--iface eth1フラグをflannelに渡してください。
公開されていないIPがコンテナに使われている
状況によっては、kubectl logsやkubectl runコマンドが以下のようなエラーを返すことがあります:
Error from server: Get https://10.19.0.41:10250/containerLogs/default/mysql-ddc65b868-glc5m/mysql: dial tcp 10.19.0.41:10250: getsockopt: no route to host
これには、おそらくマシンプロバイダーのポリシーによって、一見同じサブネット上の他のIPと通信できないIPをKubernetesが使用している可能性があります。
DigitalOceanはパブリックIPとプライベートIPを
eth0に割り当てていますが、kubeletはパブリックIPではなく、ノードのInternalIPとして後者を選択します。ifconfigではエイリアスIPアドレスが表示されないため、ifconfigの代わりにip addr showを使用してこのシナリオをチェックしてください。あるいは、DigitalOcean専用のAPIエンドポイントを使用して、ドロップレットからアンカーIPを取得することもできます:curl http://169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address回避策としては、
--node-ipを使ってどのIPを使うかをkubeletに伝えることです。DigitalOceanを使用する場合、オプションのプライベートネットワークを使用したい場合は、パブリックIP(eth0に割り当てられている)かプライベートIP(eth1に割り当てられている)のどちらかを指定します。これにはkubeadmNodeRegistrationOptions構造体のKubeletExtraArgsセクション が利用できます。kubeletを再起動してください:systemctl daemon-reload systemctl restart kubelet
corednsのPodがCrashLoopBackOffもしくはError状態になる
SELinuxを実行しているノードで古いバージョンのDockerを使用している場合、coredns Podが起動しないということが起きるかもしれません。この問題を解決するには、以下のオプションのいずれかを試してみてください:
新しいDockerのバージョンにアップグレードする。
corednsを変更して、allowPrivilegeEscalationをtrueに設定:
kubectl -n kube-system get deployment coredns -o yaml | \
sed 's/allowPrivilegeEscalation: false/allowPrivilegeEscalation: true/g' | \
kubectl apply -f -
CoreDNSにCrashLoopBackOffが発生する別の原因は、KubernetesにデプロイされたCoreDNS Podがループを検出したときに発生します。CoreDNSがループを検出して終了するたびに、KubernetesがCoreDNS Podを再起動しようとするのを避けるために、いくつかの回避策が用意されています。
警告:
SELinuxを無効にするかallowPrivilegeEscalationをtrueに設定すると、クラスターのセキュリティが損なわれる可能性があります。etcdのpodが継続的に再起動する
以下のエラーが発生した場合は:
rpc error: code = 2 desc = oci runtime error: exec failed: container_linux.go:247: starting container process caused "process_linux.go:110: decoding init error from pipe caused \"read parent: connection reset by peer\""
この問題は、CentOS 7をDocker 1.13.1.84で実行した場合に表示されます。このバージョンのDockerでは、kubeletがetcdコンテナに実行されないようにすることができます。
この問題を回避するには、以下のいずれかのオプションを選択します:
- 1.13.1-75のような以前のバージョンのDockerにロールバックする
yum downgrade docker-1.13.1-75.git8633870.el7.centos.x86_64 docker-client-1.13.1-75.git8633870.el7.centos.x86_64 docker-common-1.13.1-75.git8633870.el7.centos.x86_64
- 18.06のような最新の推奨バージョンをインストールする:
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce-18.06.1.ce-3.el7.x86_64
コンマで区切られた値のリストを--component-extra-argsフラグ内の引数に渡すことができない
-component-extra-argsのようなkubeadm initフラグを使うと、kube-apiserverのようなコントロールプレーンコンポーネントにカスタム引数を渡すことができます。しかし、このメカニズムは値の解析に使われる基本的な型 (mapStringString) のために制限されています。
もし、--apiserver-extra-args "enable-admission plugins=LimitRanger,NamespaceExists"のようにカンマで区切られた複数の値をサポートする引数を渡した場合、このフラグはflag: malformed pair, expect string=stringで失敗します。これは--apiserver-extra-argsの引数リストがkey=valueのペアを期待しており、この場合NamespacesExistsは値を欠いたキーとみなされるためです。
別の方法として、key=valueのペアを以下のように分離してみることもできます:
--apiserver-extra-args "enable-admission-plugins=LimitRanger,enable-admission-plugins=NamespaceExists"しかし、この場合は、キーenable-admission-pluginsはNamespaceExistsの値しか持ちません。既知の回避策としては、kubeadm設定ファイルを使用することが挙げられます。
cloud-controller-managerによってノードが初期化される前にkube-proxyがスケジューリングされる
クラウドプロバイダーのシナリオでは、クラウドコントローラーマネージャがノードアドレスを初期化する前に、kube-proxyが新しいワーカーノードでスケジューリングされてしまうことがあります。これにより、kube-proxyがノードのIPアドレスを正しく拾えず、ロードバランサを管理するプロキシ機能に悪影響を及ぼします。
kube-proxy Podsでは以下のようなエラーが発生します:
server.go:610] Failed to retrieve node IP: host IP unknown; known addresses: []
proxier.go:340] invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP
既知の解決策は、初期のガード条件が緩和されるまで他のノードから離しておき、条件に関係なくコントロールプレーンノード上でスケジューリングできるように、キューブプロキシDaemonSetにパッチを当てることです:
kubectl -n kube-system patch ds kube-proxy -p='{ "spec": { "template": { "spec": { "tolerations": [ { "key": "CriticalAddonsOnly", "operator": "Exists" }, { "effect": "NoSchedule", "key": "node-role.kubernetes.io/master" } ] } } } }'
Tこの問題のトラッキング問題はこちら。
kubeadmの設定をマーシャリングする際、NodeRegistration.Taintsフィールドが省略される
注意: このIssueは、kubeadmタイプをマーシャルするツール(YAML設定ファイルなど)にのみ適用されます。これはkubeadm API v1beta2で修正される予定です。
デフォルトでは、kubeadmはコントロールプレーンノードにnode-role.kubernetes.io/master:NoScheduleのテイントを適用します。kubeadmがコントロールプレーンノードに影響を与えないようにし、InitConfiguration.NodeRegistration.Taintsを空のスライスに設定すると、マーシャリング時にこのフィールドは省略されます。フィールドが省略された場合、kubeadmはデフォルトのテイントを適用します。
少なくとも2つの回避策があります:
空のスライスの代わりに
node-role.kubernetes.io/master:PreferNoScheduleテイントを使用します。他のノードに容量がない限り、Podsはマスター上でスケジュールされます。kubeadm init終了後のテイントの除去:
kubectl taint nodes NODE_NAME node-role.kubernetes.io/master:NoSchedule-
ノード{#usr-mounted-read-only}に/usrが読み取り専用でマウントされる
Fedora CoreOSなどのLinuxディストリビューションでは、ディレクトリ/usrが読み取り専用のファイルシステムとしてマウントされます。 flex-volumeサポートでは、kubeletやkube-controller-managerのようなKubernetesコンポーネントはデフォルトで/usr/libexec/kubernetes/kubelet-plugins/volume/exec/のパスを使用していますが、この機能を動作させるためにはflex-volumeディレクトリは 書き込み可能 な状態でなければなりません。
この問題を回避するには、kubeadm設定ファイルを使用してflex-volumeディレクトリを設定します。
プライマリコントロールプレーンノード(kubeadm initで作成されたもの)上で、--configで以下のファイルを渡します:
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
controllerManager:
extraArgs:
flex-volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
ノードをジョインするには:
apiVersion: kubeadm.k8s.io/v1beta2
kind: JoinConfiguration
nodeRegistration:
kubeletExtraArgs:
volume-plugin-dir: "/opt/libexec/kubernetes/kubelet-plugins/volume/exec/"
あるいは、/usrマウントを書き込み可能にするために /etc/fstabを変更することもできますが、これはLinuxディストリビューションの設計原理を変更していることに注意してください。
kubeadm upgrade planがcontext deadline exceededエラーメッセージを表示する
このエラーメッセージは、外部etcdを実行している場合にkubeadmでKubernetesクラスターをアップグレードする際に表示されます。これは致命的なバグではなく、古いバージョンのkubeadmが外部etcdクラスターのバージョンチェックを行うために発生します。kubeadm upgrade apply ...で進めることができます。
この問題はバージョン1.19で修正されます。
3 - 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.36向けに書かれています。
kubeadmツールの全体の機能の状態は、一般利用可能(GA)です。一部のサブ機能はまだ活発に開発が行われています。クラスター作成の実装は、ツールの進化に伴ってわずかに変わるかもしれませんが、全体の実装は非常に安定しているはずです。
備考:
kubeadm alpha以下のすべてのコマンドは、定義通り、アルファレベルでサポートされています。目的
- シングルコントロールプレーンのKubernetesクラスターをインストールします
- クラスター上にPodネットワークをインストールして、Podがお互いに通信できるようにします
手順
ホストの準備
コンポーネントのインストール
コンテナランタイムと、kubeadmを全てのホストにインストールしてください。 インストールの詳細やその他の準備については、kubeadmのインストールを読んでください。
備考:
すでにkubeadmがインストール済みである場合は、kubeadmのアップグレード手順についてはLinuxノードのアップグレードの最初の2ステップを確認してください。
アップグレード中、kubeletはクラッシュループによってkubeadmの指示を待つため、数秒ごとに再起動します。 このクラッシュループは想定内の正常な動作です。 コントロールプレーンの初期化が完了すれば、kubeletは正常に動作します。
ネットワークの設定
kubeadmは他のKubernetesコンポーネントと同様に、ホスト上のデフォルトゲートウェイとなっているネットワークインターフェースと関連づけられた利用可能なIPアドレスを探索します。 このIPアドレスは、コンポーネントによるアドバタイズや受信に使用されます。
Linuxのホスト上でこのIPを確認するには次のようにします:
ip route show # "default via"で始まる行を探してください。
備考:
2つ以上のデフォルトゲートウェイがホスト上に存在する場合、Kubernetesコンポーネントは、適切なグローバルユニキャストIPアドレスを持つ最初に検出したゲートウェイを使用しようとします。 この選択を行う際、ゲートウェイの正確な順序は、オペレーティングシステムやカーネルのバージョンにより異なる場合があります。Kubernetesコンポーネントはカスタムネットワークインターフェースをオプションとして受け入れないため、カスタム構成を必要とする全てのコンポーネントのインスタンスにカスタムIPアドレスをフラグとして渡す必要があります。
備考:
ホストにデフォルトゲートウェイが存在せず、カスタムIPがKubernetesコンポーネントに渡されない場合、コンポーネントはエラーで終了する可能性があります。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による証明書管理を参照してください。
警告:
Kubernetesプロジェクトは、このアプローチ(全てのコンポーネントのインスタンスにカスタムIPアドレスを設定すること)を推奨していません。 代わりに、Kubernetesメンテナーはホストネットワークを設定することを推奨しています。 これにより、KubernetesコンポーネントがデフォルトゲートウェイのIPを自動検出し使用できるようになります。 Linuxノード上では、ネットワーク設定にip routeのようなコマンドを使用できます。
また、オペレーティングシステムによってはより高レベルなネットワーク管理ツールが提供される場合もあります。
ノードのデフォルトゲートウェイがパブリックアドレスの場合、ノードやクラスターを保護するためにパケットフィルタリングなどのセキュリティ対策を行う必要があります。必要なコンテナイメージの準備
このステップは任意で、kubeadm initおよびkubeadm join実行時にregistry.k8s.ioに存在するデフォルトのコンテナイメージをダウンロードしない場合のみ行います。
kubeadmは、ノードにインターネット接続がない状態でクラスターを構築する際に、必要なイメージを事前に取得するのに役立つコマンドがあります。 詳細は、インターネット接続無しでのkubeadmの稼働を参照してください。
kubeadmはカスタムイメージリポジトリから必要なイメージを使用することもできます。 詳細はカスタムイメージの使用を参照してください。
コントロールプレーンノードの初期化
コントロールプレーンノードとは、etcd(クラスターのデータベース)やAPIサーバー(kubectlコマンドラインツールが通信する相手)などのコントロールプレーンのコンポーネントが実行されるマシンです。
- (推奨)シングルコントロールプレーンの
kubeadmクラスターを高可用性クラスターにアップグレードする予定がある場合、--control-plane-endpointを指定して、すべてのコントロールプレーンノードとエンドポイントを共有する必要があります。 エンドポイントにはDNS名やロードバランサーのIPアドレスが使用できます。 - Podネットワークアドオンを選んで、
kubeadm initに引数を渡す必要があるかどうか確認してください。 選んだサードパーティのプロバイダーによっては、--pod-network-cidrをプロバイダー固有の値に設定する必要がある場合があります。 詳しくは、Podネットワークアドオンのインストールを参照してください。 - (オプション)
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-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ネットワークアドオンのインストール
注意:
このセクションには、ネットワークのセットアップとデプロイの順序に関する重要な情報が書かれています。 先に進む前に以下のすべてのアドバイスを熟読してください。
Pod同士が通信できるようにするには、Container Network Interface(CNI)をベースとするPodネットワークアドオンをデプロイしなければなりません。 ネットワークアドオンをインストールする前には、Cluster DNS(CoreDNS)は起動しません。
- Podネットワークがホストネットワークと決して重ならないように気をつけてください。
もし重なると、様々な問題が起こってしまう可能性があります(ネットワークプラグインが優先するPodネットワークとホストのネットワークの一部が衝突することが分かった場合、適切な代わりのCIDRを考える必要があります。そして、
kubeadm initの実行時に--pod-network-cidrにそのCIDRを指定し、ネットワークプラグインのYAMLでは代わりにそのCIDRを使用してください)。 - デフォルトでは、
kubeadmはRBAC(role based access control)の使用を強制します。 PodネットワークプラグインがRBACをサポートしており、またそのデプロイに使用するマニフェストもRBACをサポートしていることを確認してください。 - クラスターでIPv6を使用したい場合、デュアルスタック、IPv6のみのシングルスタックのネットワークのいずれであっても、PodネットワークプラグインがIPv6をサポートしていることを確認してください。 IPv6のサポートは、CNIのv0.6.0で追加されました。
備考:
kubeadmはCNIに依存すべきではないため、CNIプロバイダーの検証は現在e2eテストの範囲外です。 CNIプラグインに関する問題を見つけた場合、kubeadmやKubernetesではなく、そのCNIプラグインの課題管理システムへ問題を報告してください。CNIを使用するKubernetes Podネットワークを提供する外部のプロジェクトがいくつかあります。一部のプロジェクトでは、ネットワークポリシーもサポートしています。
Kubernetesのネットワークモデルを実装したアドオンの一覧も確認してください。
Kubernetesでサポートされているネットワークアドオンの非網羅的な一覧については、アドオンのインストールのページを参照してください。 Podネットワークアドオンをインストールするには、コントロールプレーンノード上またはkubeconfigクレデンシャルを持っているノード上で、次のコマンドを実行します。
kubectl apply -f <add-on.yaml>
備考:
WindowsをサポートするCNIプラグインは少数です。 詳細とセットアップ手順は、Windowsワーカーノードの追加を参照してください。インストールできる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サーバーを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 initやkubeadm 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.36
kubernetesVersionは、1.36または1.35でなければならない
kubeletに対するkubeadmのバージョンの差異
Kubernetesのバージョンと同様に、kubeadmは、kubeadmと同じバージョン、もしくは3つ前までのバージョンをkubeletに使用できます。
例:
- kubeadmのバージョン: 1.36
- ホスト上のkubeletのバージョンは、1.36、1.35、1.34、もしくは1.33でなければならない
kubeadmに対するkubeadmのバージョンの差異
kubeadmによって管理されている既存のノードまたはクラスター全体を、kubeadmコマンドが操作するには一定の制限が存在します。
新たなノードをクラスターに参加させる場合、kubeadm joinを実行するkubeadmのバイナリは、kubeadm initによるクラスター構築、もしくはkubeadm upgradeによるノードのアップグレードのいずれかに使用されたkubeadmの最新バージョンと一致している必要があります。
同様の制限はkubeadm upgradeを除く他のkubeadmのコマンドにも適用されます。
kubeadm joinの例:
kubeadm initによるクラスター構築で使用したkubeadmのバージョン: 1.36- 参加するノードは、1.36のバージョンのkubeadmバイナリを使用しなければならない
アップグレードするノードでは、そのノードの管理に使用しているkubeadmのバージョンと同じマイナーバージョン、もしくはマイナーバージョンが1つ新しいkubeadmを使用する必要があります。
kubeadm upgradeの例:
- クラスター構築またはノードのアップグレードに使用されたkubeadmのバージョン: 1.35
- ノードのアップグレードで使用するkubeadmのバージョンは、1.35または1.36でなければならない
異なる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に関する問題が起きたときは、トラブルシューティングドキュメントを確認してください。
次の項目
- Sonobuoyを使用してクラスターが適切に動作しているか検証する。
kubeadmを使用したクラスターをアップグレードする方法について、kubeadmクラスターをアップグレードするを参照する。kubeadmの高度な利用方法についてkubeadmリファレンスドキュメントで学ぶ。- Kubernetesのコンセプトや
kubectlについてさらに学ぶ。 - Podネットワークアドオンのより完全なリストをクラスターのネットワークで確認する。
- ロギング、モニタリング、ネットワークポリシー、仮想化、Kubernetesクラスターの制御のためのツールなど、その他のアドオンについて、アドオンのリストで確認する。
- クラスターイベントやPod内で実行中のアプリケーションから送られるログをクラスターがハンドリングする方法を設定する。関係する要素の概要を理解するために、ロギングのアーキテクチャを読む。
フィードバック
- バグを見つけた場合は、kubeadm GitHub issue trackerで報告してください。
- サポートを受けたい場合は、#kubeadm Slackチャンネルを訪ねてください。
- General SIG Cluster Lifecycle development Slackチャンネル: #sig-cluster-lifecycle
- SIG Cluster Lifecycle SIG information
- SIG Cluster Lifecycleメーリングリスト: kubernetes-sig-cluster-lifecycle
4 - kubeadmを使ったコントロールプレーンの設定のカスタマイズ
Kubernetes 1.12 [stable]kubeadmのClusterConfigurationオブジェクトはAPIServer、ControllerManager、およびSchedulerのようなコントロールプレーンの構成要素に渡されたデフォルトのフラグを上書きすることができる extraArgsの項目があります。
その構成要素は次の項目で定義されています。
apiServercontrollerManagerscheduler
extraArgs の項目は キー: 値 のペアです。コントロールプレーンの構成要素のフラグを上書きするには:
- 設定内容に適切な項目を追加
- フラグを追加して項目を上書き
--config <任意の設定YAMLファイル>でkubeadm initを実行
各設定項目のより詳細な情報はAPIリファレンスのページを参照してください。
備考:
kubeadm config print init-defaultsを実行し、選択したファイルに出力を保存することで、デフォルト値でClusterConfigurationオブジェクトを生成できます。APIServerフラグ
詳細はkube-apiserverのリファレンスドキュメントを参照してください。
使用例:
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.16.0
apiServer:
extraArgs:
advertise-address: 192.168.0.103
anonymous-auth: "false"
enable-admission-plugins: AlwaysPullImages,DefaultStorageClass
audit-log-path: /home/johndoe/audit.log
ControllerManagerフラグ
詳細はkube-controller-managerのリファレンスドキュメントを参照してください。
使用例:
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.16.0
controllerManager:
extraArgs:
cluster-signing-key-file: /home/johndoe/keys/ca.key
bind-address: 0.0.0.0
deployment-controller-sync-period: "50"
Schedulerフラグ
詳細はkube-schedulerのリファレンスドキュメントを参照してください。
使用例:
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.16.0
scheduler:
extraArgs:
bind-address: 0.0.0.0
config: /home/johndoe/schedconfig.yaml
kubeconfig: /home/johndoe/kubeconfig.yaml
5 - 高可用性トポロジーのためのオプション
このページでは、高可用性(HA)Kubernetesクラスターのトポロジーを設定するための2つのオプションについて説明します。
HAクラスターは次の方法で設定できます。
- 積層コントロールプレーンノードを使用する方法。こちらの場合、etcdノードはコントロールプレーンノードと同じ場所で動作します。
- 外部のetcdノードを使用する方法。こちらの場合、etcdがコントロールプレーンとは分離されたノードで動作します。
HAクラスターをセットアップする前に、各トポロジーの利点と欠点について注意深く考慮する必要があります。
備考:
kubeadmは、etcdクラスターを静的にブートストラップします。 詳細については、etcdクラスタリングガイドをご覧ください。積層etcdトポロジー
積層HAクラスターは、コントロールプレーンのコンポーネントを実行する、kubeadmで管理されたノードで構成されるクラスターの上に、etcdにより提供される分散データストレージクラスターがあるようなトポロジーです。
各コントロールプレーンノードは、kube-apiserver、kube-scheduler、およびkube-controller-managerを実行します。kube-apiserver はロードバランサーを用いてワーカーノードに公開されます。
各コントロールプレーンノードはローカルのetcdメンバーを作り、このetcdメンバーはそのノードのkube-apiserverとだけ通信します。ローカルのkube-controller-managerとkube-schedulerのインスタンスも同様です。
このトポロジーは、同じノード上のコントロールプレーンとetcdのメンバーを結合します。外部のetcdノードを使用するクラスターよりはセットアップがシンプルで、レプリケーションの管理もシンプルです。
しかし、積層クラスターには、結合による故障のリスクがあります。1つのノードがダウンすると、etcdメンバーとコントロールプレーンのインスタンスの両方が失われ、冗長性が損なわれます。より多くのコントロールプレーンノードを追加することで、このリスクは緩和できます。
そのため、HAクラスターのためには、最低でも3台の積層コントロールプレーンノードを実行しなければなりません。
これがkubeadmのデフォルトのトポロジーです。kubeadm initやkubeadm join --control-placeを実行すると、ローカルのetcdメンバーがコントロールプレーンノード上に自動的に作成されます。
外部のetcdトポロジー
外部のetcdを持つHAクラスターは、コントロールプレーンコンポーネントを実行するノードで構成されるクラスターの外部に、etcdにより提供される分散データストレージクラスターがあるようなトポロジーです。
積層etcdトポロジーと同様に、外部のetcdトポロジーにおける各コントロールプレーンノードは、kube-apiserver、kube-scheduler、およびkube-controller-managerのインスタンスを実行します。そして、kube-apiserverは、ロードバランサーを使用してワーカーノードに公開されます。しかし、etcdメンバーは異なるホスト上で動作しており、各etcdホストは各コントロールプレーンノードのkube-api-serverと通信します。
このトポロジーは、コントロールプレーンとetcdメンバーを疎結合にします。そのため、コントロールプレーンインスタンスまたはetcdメンバーを失うことによる影響は少なく、積層HAトポロジーほどクラスターの冗長性に影響しないHAセットアップが実現します。
しかし、このトポロジーでは積層HAトポロジーの2倍の数のホストを必要とします。このトポロジーのHAクラスターのためには、最低でもコントロールプレーンのために3台のホストが、etcdノードのために3台のホストがそれぞれ必要です。
次の項目
6 - kubeadmを使用した高可用性クラスターの作成
このページでは、kubeadmを使用して、高可用性クラスターを作成する、2つの異なるアプローチを説明します:
- 積層コントロールプレーンノードを使う方法。こちらのアプローチは、必要なインフラストラクチャーが少ないです。etcdのメンバーと、コントロールプレーンノードは同じ場所に置かれます。
- 外部のetcdクラスターを使う方法。こちらのアプローチには、より多くのインフラストラクチャーが必要です。コントロールプレーンノードと、etcdのメンバーは分離されます。
先へ進む前に、どちらのアプローチがアプリケーションの要件と、環境に適合するか、慎重に検討してください。こちらの比較が、それぞれの利点/欠点について概説しています。
高可用性クラスターの作成で問題が発生した場合は、kueadmのissue trackerでフィードバックを提供してください。
高可用性クラスターのアップグレードも参照してください。
注意:
このページはクラウド上でクラスターを構築することには対応していません。ここで説明されているどちらのアプローチも、クラウド上で、LoadBalancerタイプのServiceオブジェクトや、動的なPersistentVolumeを利用して動かすことはできません。始める前に
どちらの方法でも、以下のインフラストラクチャーが必要です:
- master用に、kubeadmの最小要件を満たす3台のマシン
- worker用に、kubeadmの最小要件を満たす3台のマシン
- クラスター内のすべてのマシン間がフルにネットワーク接続可能であること(パブリック、もしくはプライベートネットワーク)
- すべてのマシンにおいて、sudo権限
- あるデバイスから、システム内のすべてのノードに対しSSH接続できること
kubeadmとkubeletがすべてのマシンにインストールされていること。kubectlは任意です。
外部etcdクラスターには、以下も必要です:
- etcdメンバー用に、追加で3台のマシン
両手順における最初のステップ
kube-apiserver用にロードバランサーを作成
備考:
ロードバランサーには多くの設定項目があります。以下の例は、一選択肢に過ぎません。あなたのクラスター要件には、異なった設定が必要かもしれません。DNSで解決される名前で、kube-apiserver用ロードバランサーを作成する。
クラウド環境では、コントロールプレーンノードをTCPフォワーディングロードバランサーの後ろに置かなければなりません。このロードバランサーはターゲットリストに含まれる、すべての健全なコントロールプレーンノードにトラフィックを分配します。apiserverへのヘルスチェックはkube-apiserverがリッスンするポート(デフォルト値:
:6443)に対する、TCPチェックです。クラウド環境では、IPアドレスを直接使うことは推奨されません。
ロードバランサーは、apiserverポートで、全てのコントロールプレーンノードと通信できなければなりません。また、リスニングポートに対する流入トラフィックも許可されていなければなりません。
ロードバランサーのアドレスは、常にkubeadmの
ControlPlaneEndpointのアドレスと一致することを確認してください。詳細はOptions for Software Load Balancingをご覧ください。
ロードバランサーに、最初のコントロールプレーンノードを追加し、接続をテストする:
nc -v LOAD_BALANCER_IP PORT- apiserverはまだ動いていないので、接続の拒否は想定通りです。しかし、タイムアウトしたのであれば、ロードバランサーはコントロールプレーンノードと通信できなかったことを意味します。もし、タイムアウトが起きたら、コントロールプレーンノードと通信できるように、ロードバランサーを再設定してください。
残りのコントロールプレーンノードを、ロードバランサーのターゲットグループに追加します。
積層コントロールプレーンとetcdノード
最初のコントロールプレーンノードの手順
最初のコントロールプレーンノードを初期化します:
sudo kubeadm init --control-plane-endpoint "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" --upload-certs--kubernetes-versionフラグで使用するKubernetesのバージョンを設定できます。kubeadm、kubelet、kubectl、Kubernetesのバージョンを一致させることが推奨されます。--control-plane-endpointフラグは、ロードバランサーのIPアドレスまたはDNS名と、ポートが設定される必要があります。--upload-certsフラグは全てのコントロールプレーンノードで共有する必要がある証明書をクラスターにアップロードするために使用されます。代わりに、コントロールプレーンノード間で手動あるいは自動化ツールを使用して証明書をコピーしたい場合は、このフラグを削除し、以下の証明書の手動配布のセクションを参照してください。
備考:
kubeadm initの--configフラグと--certificate-keyフラグは混在させることはできないため、kubeadm configurationを使用する場合はcertificateKeyフィールドを適切な場所に追加する必要があります(InitConfigurationとJoinConfiguration: controlPlaneの配下)。備考:
いくつかのCNIネットワークプラグインはPodのIPのCIDRの指定など追加の設定を必要としますが、必要としないプラグインもあります。CNIネットワークドキュメントを参照してください。PodにCIDRを設定するには、ClusterConfigurationのnetworkingオブジェクトにpodSubnet: 192.168.0.0/16フィールドを設定してください。- このような出力がされます:
... You can now join any number of control-plane node by running the following command on each as a root: kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07 Please note that the certificate-key gives access to cluster sensitive data, keep it secret! As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use kubeadm init phase upload-certs to reload certs afterward. Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866この出力をテキストファイルにコピーします。あとで、他のコントロールプレーンノードとワーカーノードをクラスターに参加させる際に必要です。
--upload-certsフラグをkubeadm initで使用すると、プライマリコントロールプレーンの証明書が暗号化されて、kubeadm-certsSecretにアップロードされます。証明書を再アップロードして新しい復号キーを生成するには、すでにクラスターに参加しているコントロールプレーンノードで次のコマンドを使用します:
sudo kubeadm init phase upload-certs --upload-certs- また、後で
joinで使用できるように、init中にカスタムした--certificate-keyを指定することもできます。このようなキーを生成するには、次のコマンドを使用します:
kubeadm alpha certs certificate-key備考:
`kubeadm-certs`のSecretと復号キーは2時間で期限切れとなります。注意:
コマンド出力に記載されているように、証明書キーはクラスターの機密データへのアクセスを提供します。秘密にしてください!使用するCNIプラグインを適用します:
こちらの手順に従いCNIプロバイダーをインストールします。該当する場合は、kubeadmの設定で指定されたPodのCIDRに対応していることを確認してください。Weave Netを使用する場合の例:
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"以下のコマンドを入力し、コンポーネントのPodが起動するのを確認します:
kubectl get pod -n kube-system -w
残りのコントロールプレーンノードの手順
備考:
kubeadmバージョン1.15以降、複数のコントロールプレーンノードを並行してクラスターに参加させることができます。 このバージョンの前は、最初のノードの初期化が完了した後でのみ、新しいコントロールプレーンノードを順番にクラスターに参加させる必要があります。追加のコントロールプレーンノード毎に、以下の手順を行います。
kubeadm initを最初のノードで実行した際に取得したjoinコマンドを使って、新しく追加するコントロールプレーンノードでkubeadm joinを開始します。このようなコマンドになるはずです:sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07--control-planeフラグによって、kubeadm joinの実行は新しいコントロールプレーンを作成します。-certificate-key ...を指定したキーを使って、クラスターのkubeadm-certsSecretからダウンロードされたコントロールプレーンの証明書が復号されます。
外部のetcdノード
外部のetcdノードを使ったクラスターの設定は、積層etcdの場合と似ていますが、最初にetcdを設定し、kubeadmの設定ファイルにetcdの情報を渡す必要があります。
etcdクラスターの構築
こちらの手順にしたがって、etcdクラスターを構築してください。
こちらの手順にしたがって、SSHを構築してください。
以下のファイルをクラスター内の任意のetcdノードから最初のコントロールプレーンノードにコピーしてください:
export CONTROL_PLANE="ubuntu@10.0.0.7" scp /etc/kubernetes/pki/etcd/ca.crt "${CONTROL_PLANE}": scp /etc/kubernetes/pki/apiserver-etcd-client.crt "${CONTROL_PLANE}": scp /etc/kubernetes/pki/apiserver-etcd-client.key "${CONTROL_PLANE}":CONTROL_PLANEの値を、最初のコントロールプレーンノードのuser@hostで置き換えます。
最初のコントロールプレーンノードの構築
以下の内容で、
kubeadm-config.yamlという名前の設定ファイルを作成します:apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: stable controlPlaneEndpoint: "LOAD_BALANCER_DNS:LOAD_BALANCER_PORT" etcd: external: endpoints: - https://ETCD_0_IP:2379 - https://ETCD_1_IP:2379 - https://ETCD_2_IP:2379 caFile: /etc/kubernetes/pki/etcd/ca.crt certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key備考:
ここで、積層etcdと外部etcdの違いは、外部etcdの構成では`etcd`の`external`オブジェクトにetcdのエンドポイントが記述された設定ファイルが必要です。積層etcdトポロジーの場合、これは自動で管理されます。テンプレート内の以下の変数を、クラスターに合わせて適切な値に置き換えます:
LOAD_BALANCER_DNSLOAD_BALANCER_PORTETCD_0_IPETCD_1_IPETCD_2_IP
以下の手順は、積層etcdの構築と同様です。
sudo kubeadm init --config kubeadm-config.yaml --upload-certsをこのノードで実行します。表示されたjoinコマンドを、あとで使うためにテキストファイルに書き込みます。
使用するCNIプラグインを適用します。以下はWeave CNIの場合です:
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
残りのコントロールプレーンノードの手順
手順は、積層etcd構築の場合と同じです:
- 最初のコントロールプレーンノードが完全に初期化されているのを確認します。
- テキストファイルに保存したjoinコマンドを使って、それぞれのコントロールプレーンノードをクラスターへ参加させます。コントロールプレーンノードは1台ずつクラスターへ参加させるのを推奨します。
--certificate-keyで指定する復号キーは、デフォルトで2時間で期限切れになることを忘れないでください。
コントロールプレーン起動後の共通タスク
workerのインストール
kubeadm initコマンドから返されたコマンドを利用して、workerノードをクラスターに参加させることが可能です。
sudo kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
証明書の手動配布
--upload-certsフラグを指定してkubeadm initを実行しない場合、プライマリコントロールプレーンノードから他のコントロールプレーンノードへ証明書を手動でコピーする必要があります。
コピーを行うには多くの方法があります。次の例ではsshとscpを使用しています。
1台のマシンから全てのノードをコントロールしたいのであれば、SSHが必要です。
システム内の全ての他のノードにアクセスできるメインデバイスで、ssh-agentを有効にします
eval $(ssh-agent)SSHの秘密鍵を、セッションに追加します:
ssh-add ~/.ssh/path_to_private_key正常に接続できることを確認するために、ノード間でSSHします。
ノードにSSHする際は、必ず
-Aフラグをつけます:ssh -A 10.0.0.7ノードでsudoするときは、SSHフォワーディングが動くように、環境変数を引き継ぎます:
sudo -E -s
全てのノードでSSHを設定したら、
kubeadm initを実行した後、最初のコントロールノードプレーンノードで次のスクリプトを実行します。このスクリプトは、最初のコントロールプレーンノードから残りのコントロールプレーンノードへ証明書ファイルをコピーします:次の例の、
CONTROL_PLANE_IPSを他のコントロールプレーンノードのIPアドレスに置き換えます。USER=ubuntu # 環境に合わせる CONTROL_PLANE_IPS="10.0.0.7 10.0.0.8" for host in ${CONTROL_PLANE_IPS}; do scp /etc/kubernetes/pki/ca.crt "${USER}"@$host: scp /etc/kubernetes/pki/ca.key "${USER}"@$host: scp /etc/kubernetes/pki/sa.key "${USER}"@$host: scp /etc/kubernetes/pki/sa.pub "${USER}"@$host: scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host: scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host: scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt # 外部のetcdノード使用時はこちらのコマンドを実行 scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key done注意:
上のリストにある証明書だけをコピーしてください。kubeadmが、参加するコントロールプレーンノード用に、残りの証明書と必要なSANの生成を行います。間違って全ての証明書をコピーしてしまったら、必要なSANがないため、追加ノードの作成は失敗するかもしれません。次に、クラスターに参加させる残りの各コントロールプレーンノードで
kubeadm joinを実行する前に次のスクリプトを実行する必要があります。このスクリプトは、前の手順でコピーした証明書をホームディレクトリから/etc/kubernetes/pkiへ移動します:USER=ubuntu # 環境に合わせる mkdir -p /etc/kubernetes/pki/etcd mv /home/${USER}/ca.crt /etc/kubernetes/pki/ mv /home/${USER}/ca.key /etc/kubernetes/pki/ mv /home/${USER}/sa.pub /etc/kubernetes/pki/ mv /home/${USER}/sa.key /etc/kubernetes/pki/ mv /home/${USER}/front-proxy-ca.crt /etc/kubernetes/pki/ mv /home/${USER}/front-proxy-ca.key /etc/kubernetes/pki/ mv /home/${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt # 外部のetcdノード使用時はこちらのコマンドを実行 mv /home/${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
7 - kubeadmを使用した高可用性etcdクラスターの作成
kubeadmはデフォルトで、各コントロールプレーンノード上でローカルのetcdインスタンスを実行します。 また、コントロールプレーンノードとは別のホスト上にetcdインスタンスを構築し、外部etcdクラスターとして扱うこともできます。 これら2つのアプローチの違いについては高可用性トポロジーのためのオプションを参照してください。
このタスクでは、kubeadmによるKubernetesクラスター作成時に使用できる、3メンバー構成の高可用性外部etcdクラスターを構築する手順を説明します。
始める前に
- 3台のホストが、TCPポート2379および2380を介して相互に通信できる必要があります。このドキュメントでは、これらがデフォルトポートであることを前提としていますが、kubeadmの設定ファイルで変更することもできます。
- 各ホストには、systemdおよびbash互換シェルがインストールされている必要があります。
- 各ホストに、コンテナランタイム、kubelet、およびkubeadmをインストールしておく必要があります。
- 各ホストはKubernetesコンテナイメージレジストリ(
registry.k8s.io)にアクセスできるか、kubeadm config images list/pullを使用して必要なetcdイメージを一覧表示または取得できる必要があります。このガイドでは、kubeletによって管理されるStatic Podとしてetcdインスタンスを構築します。 - ホスト間でファイルをコピーするための仕組みが必要です。たとえば、
sshやscpを利用できます。
クラスターの構築
一般的な方法では、1つのノードですべての証明書を生成し、他のノードには必要なファイルだけを配布します。
備考:
kubeadmには、以下で説明する証明書の生成に必要な暗号処理機能がすべて備わっています。この例では、他の暗号化ツールは必要ありません。備考:
以下の例ではIPv4アドレスを使用していますが、kubeadm、kubelet、etcdでIPv6アドレスを使用するように設定することもできます。 デュアルスタックはKubernetesの一部の機能ではサポートされていますが、etcdではサポートされていません。 Kubernetesのデュアルスタックのサポートについて詳しくは、kubeadmによるデュアルスタックのサポートを参照してください。etcdのサービスマネージャーとしてkubeletを設定します。
etcdを先に作成するため、kubeadmが提供するkubeletユニットファイルよりも優先順位の高い新しいユニットファイルを作成し、サービスの優先順位を上書きする必要があります。備考:
etcdを実行するすべてのホストでこの設定を行う必要があります。cat << EOF > /etc/systemd/system/kubelet.service.d/kubelet.conf # "systemd"をコンテナランタイムのcgroupドライバーに置き換えます。kubeletのデフォルト値は"cgroupfs"です。 # 別のコンテナランタイムを使用する場合は、必要に応じて"containerRuntimeEndpoint"の値を置き換えます。 # apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration authentication: anonymous: enabled: false webhook: enabled: false authorization: mode: AlwaysAllow cgroupDriver: systemd address: 127.0.0.1 containerRuntimeEndpoint: unix:///var/run/containerd/containerd.sock staticPodPath: /etc/kubernetes/manifests EOF cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf [Service] ExecStart= ExecStart=/usr/bin/kubelet --config=/etc/systemd/system/kubelet.service.d/kubelet.conf Restart=always EOF systemctl daemon-reload systemctl restart kubeletkubeletのステータスを確認し、実行中であることを確かめます。
systemctl status kubeletkubeadmの設定ファイルを作成します。
以下のスクリプトを使用して、etcdメンバーを実行する各ホスト用にkubeadm設定ファイルを1つずつ生成します。
# HOST0、HOST1、HOST2を各ホストのIPアドレスに変更します export HOST0=10.0.0.6 export HOST1=10.0.0.7 export HOST2=10.0.0.8 # NAME0、NAME1、NAME2を各ホストのホスト名に変更します export NAME0="infra0" export NAME1="infra1" export NAME2="infra2" # 他のホストに配置するファイルを格納する一時ディレクトリを作成します mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/ /tmp/${HOST2}/ HOSTS=(${HOST0} ${HOST1} ${HOST2}) NAMES=(${NAME0} ${NAME1} ${NAME2}) for i in "${!HOSTS[@]}"; do HOST=${HOSTS[$i]} NAME=${NAMES[$i]} cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml --- apiVersion: "kubeadm.k8s.io/v1beta4" kind: InitConfiguration nodeRegistration: name: ${NAME} localAPIEndpoint: advertiseAddress: ${HOST} --- apiVersion: "kubeadm.k8s.io/v1beta4" kind: ClusterConfiguration etcd: local: serverCertSANs: - "${HOST}" peerCertSANs: - "${HOST}" extraArgs: - name: initial-cluster value: ${NAMES[0]}=https://${HOSTS[0]}:2380,${NAMES[1]}=https://${HOSTS[1]}:2380,${NAMES[2]}=https://${HOSTS[2]}:2380 - name: initial-cluster-state value: new - name: name value: ${NAME} - name: listen-peer-urls value: https://${HOST}:2380 - name: listen-client-urls value: https://${HOST}:2379 - name: advertise-client-urls value: https://${HOST}:2379 - name: initial-advertise-peer-urls value: https://${HOST}:2380 EOF done認証局を生成します。
すでにCAがある場合は、そのCAの
crtファイルとkeyファイルを/etc/kubernetes/pki/etcd/ca.crtと/etc/kubernetes/pki/etcd/ca.keyにコピーするだけです。 これらのファイルをコピーしたら、次の手順「各メンバーの証明書を作成します」に進みます。まだCAがない場合は、kubeadmの設定ファイルを生成した
$HOST0上で次のコマンドを実行します。kubeadm init phase certs etcd-caこれにより、次の2つのファイルが作成されます。
/etc/kubernetes/pki/etcd/ca.crt/etc/kubernetes/pki/etcd/ca.key
各メンバーの証明書を作成します。
kubeadm init phase certs etcd-server --config=/tmp/${HOST2}/kubeadmcfg.yaml kubeadm init phase certs etcd-peer --config=/tmp/${HOST2}/kubeadmcfg.yaml kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST2}/kubeadmcfg.yaml kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST2}/kubeadmcfg.yaml cp -R /etc/kubernetes/pki /tmp/${HOST2}/ # 再利用できない証明書を削除します find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete kubeadm init phase certs etcd-server --config=/tmp/${HOST1}/kubeadmcfg.yaml kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml cp -R /etc/kubernetes/pki /tmp/${HOST1}/ find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml # HOST0用の証明書のため、移動する必要はありません # このホストの外部にコピーすべきでない証明書を削除します find /tmp/${HOST2} -name ca.key -type f -delete find /tmp/${HOST1} -name ca.key -type f -delete証明書とkubeadmの設定ファイルをコピーします。
生成した証明書を、それぞれのホストへ移動します。
USER=ubuntu HOST=${HOST1} scp -r /tmp/${HOST}/* ${USER}@${HOST}: ssh ${USER}@${HOST} USER@HOST $ sudo -Es root@HOST $ chown -R root:root pki root@HOST $ mv pki /etc/kubernetes/必要なファイルがすべて存在することを確認します。
$HOST0上に必要なファイルの完全な一覧は次のとおりです。/tmp/${HOST0} └── kubeadmcfg.yaml --- /etc/kubernetes/pki ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key └── etcd ├── ca.crt ├── ca.key ├── healthcheck-client.crt ├── healthcheck-client.key ├── peer.crt ├── peer.key ├── server.crt └── server.key$HOST1上では次のとおりです。$HOME └── kubeadmcfg.yaml --- /etc/kubernetes/pki ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key └── etcd ├── ca.crt ├── healthcheck-client.crt ├── healthcheck-client.key ├── peer.crt ├── peer.key ├── server.crt └── server.key$HOST2上では次のとおりです。$HOME └── kubeadmcfg.yaml --- /etc/kubernetes/pki ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key └── etcd ├── ca.crt ├── healthcheck-client.crt ├── healthcheck-client.key ├── peer.crt ├── peer.key ├── server.crt └── server.keyStatic Podマニフェストを作成します。
証明書と設定ファイルの準備が整ったため、マニフェストを作成します。 各ホストで
kubeadmコマンドを実行し、etcd用のStatic Podマニフェストを生成します。root@HOST0 $ kubeadm init phase etcd local --config=/tmp/${HOST0}/kubeadmcfg.yaml root@HOST1 $ kubeadm init phase etcd local --config=$HOME/kubeadmcfg.yaml root@HOST2 $ kubeadm init phase etcd local --config=$HOME/kubeadmcfg.yamlオプション: クラスターの健全性を確認します。
etcdctlを利用できない場合は、コンテナイメージ内でこのツールを実行できます。 その場合はKubernetes経由ではなく、crictl runなどのツールを使用してコンテナランタイムから直接実行します。ETCDCTL_API=3 etcdctl \ --cert /etc/kubernetes/pki/etcd/peer.crt \ --key /etc/kubernetes/pki/etcd/peer.key \ --cacert /etc/kubernetes/pki/etcd/ca.crt \ --endpoints https://${HOST0}:2379 endpoint health ... https://[HOST0 IP]:2379 is healthy: successfully committed proposal: took = 16.283339ms https://[HOST1 IP]:2379 is healthy: successfully committed proposal: took = 19.44402ms https://[HOST2 IP]:2379 is healthy: successfully committed proposal: took = 35.926451ms${HOST0}を、確認対象ホストのIPアドレスに設定します。
次の項目
稼働中の3つのメンバーで構成されるetcdクラスターを用意できたら、kubeadmで外部etcdを使用する方法による高可用性コントロールプレーンの構築に進むことができます。
8 - kubeadmを使用したクラスター内の各kubeletの設定
Kubernetes 1.11 [stable]kubeadm CLIツールのライフサイクルは、Kubernetesクラスター内の各ノード上で稼働するデーモンであるkubeletから分離しています。kubeadm CLIツールはKubernetesを初期化またはアップグレードする際にユーザーによって実行されます。一方で、kubeletは常にバックグラウンドで稼働しています。
kubeletはデーモンのため、何らかのinitシステムやサービスマネージャーで管理する必要があります。DEBパッケージやRPMパッケージからkubeletをインストールすると、systemdはkubeletを管理するように設定されます。代わりに別のサービスマネージャーを使用することもできますが、手動で設定する必要があります。
いくつかのkubeletの設定は、クラスターに含まれる全てのkubeletで同一である必要があります。一方で、特定のマシンの異なる特性(OS、ストレージ、ネットワークなど)に対応するために、kubeletごとに設定が必要なものもあります。手動で設定を管理することも可能ですが、kubeadmは一元的な設定管理のためのKubeletConfigurationAPIを提供しています。
Kubeletの設定パターン
以下のセクションでは、kubeadmを使用したkubeletの設定パターンについて説明します。これは手動で各Nodeの設定を管理するよりも簡易に行うことができます。
各kubeletにクラスターレベルの設定を配布
kubeadm initおよびkubeadm joinコマンドを使用すると、kubeletにデフォルト値を設定することができます。興味深い例として、異なるCRIランタイムを使用したり、Serviceが使用するデフォルトのサブネットを設定したりすることができます。
Serviceが使用するデフォルトのサブネットとして10.96.0.0/12を設定する必要がある場合は、--service-cidrパラメーターを渡します。
kubeadm init --service-cidr 10.96.0.0/12
これによってServiceの仮想IPはこのサブネットから割り当てられるようになりました。また、--cluster-dnsフラグを使用し、kubeletが用いるDNSアドレスを設定する必要もあります。この設定はクラスター内の全てのマネージャーとNode上で同一である必要があります。kubeletは、kubeletのComponentConfigと呼ばれる、バージョン管理と構造化されたAPIオブジェクトを提供します。これはkubelet内のほとんどのパラメーターを設定し、その設定をクラスター内で稼働中の各kubeletへ適用することを可能にします。以下の例のように、キャメルケースのキーに値のリストとしてクラスターDNS IPアドレスなどのフラグを指定することができます。
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDNS:
- 10.96.0.10
ComponentConfigの詳細については、このセクションをご覧ください
インスタンス固有の設定内容を適用
いくつかのホストでは、ハードウェア、オペレーティングシステム、ネットワーク、その他ホスト固有のパラメーターの違いのため、特定のkubeletの設定を必要とします。以下にいくつかの例を示します。
- DNS解決ファイルへのパスは
--resolv-confフラグで指定することができますが、オペレーティングシステムやsystemd-resolvedを使用するかどうかによって異なる場合があります。このパスに誤りがある場合、そのNode上でのDNS解決は失敗します。 - クラウドプロバイダーを使用していない場合、Node APIオブジェクト
.metadata.nameはデフォルトでマシンのホスト名に設定されます。異なるNode名を指定する必要がある場合には、--hostname-overrideフラグによってこの挙動を書き換えることができます。 - 現在のところ、kubletはCRIランタイムが使用するcgroupドライバーを自動で検知することができませんが、kubeletの稼働を保証するためには、
--cgroup-driverの値はCRIランタイムが使用するcgroupドライバーに一致していなければなりません。 - クラスターが使用するCRIランタイムによっては、異なるフラグを指定する必要があるかもしれません。例えば、Dockerを使用している場合には、
--network-plugin=cniのようなフラグを指定する必要があります。外部のランタイムを使用している場合には、--container-runtime=remoteと指定し、--container-runtime-endpoint=<path>のようにCRIエンドポイントを指定する必要があります。
これらのフラグは、systemdなどのサービスマネージャー内のkubeletの設定によって指定することができます。
kubeadmを使用したkubeletの設定
kubeadm ... --config some-config-file.yamlのように、カスタムのKubeletConfigurationAPIオブジェクトを設定ファイルを介して渡すことで、kubeadmによって起動されるkubeletに設定を反映することができます。
kubeadm config print init-defaults --component-configs KubeletConfigurationを実行することによって、この構造体の全てのデフォルト値を確認することができます。
また、各フィールドの詳細については、kubelet ComponentConfigに関するAPIリファレンスを参照してください。
kubeadm init実行時の流れ
kubeadm initを実行した場合、kubeletの設定は/var/lib/kubelet/config.yamlに格納され、クラスターのConfigMapにもアップロードされます。ConfigMapはkubelet-config-1.Xという名前で、Xは初期化するKubernetesのマイナーバージョンを表します。またこの設定ファイルは、クラスター内の全てのkubeletのために、クラスター全体設定の基準と共に/etc/kubernetes/kubelet.confにも書き込まれます。この設定ファイルは、kubeletがAPIサーバと通信するためのクライアント証明書を指し示します。これは、各kubeletにクラスターレベルの設定を配布することの必要性を示しています。
二つ目のパターンである、インスタンス固有の設定内容を適用するために、kubeadmは環境ファイルを/var/lib/kubelet/kubeadm-flags.envへ書き出します。このファイルは以下のように、kubelet起動時に渡されるフラグのリストを含んでいます。
KUBELET_KUBEADM_ARGS="--flag1=value1 --flag2=value2 ..."
kubelet起動時に渡されるフラグに加えて、このファイルはcgroupドライバーや異なるCRIランタイムソケットを使用するかどうか(--cri-socket)といった動的なパラメーターも含みます。
これら二つのファイルがディスク上に格納されると、systemdを使用している場合、kubeadmは以下の二つのコマンドを実行します。
systemctl daemon-reload && systemctl restart kubelet
リロードと再起動に成功すると、通常のkubeadm initのワークフローが続きます。
kubeadm join実行時の流れ
kubeadm joinを実行した場合、kubeadmはBootstrap Token証明書を使用してTLS bootstrapを行い、ConfigMapkubelet-config-1.Xをダウンロードするために必要なクレデンシャルを取得し、/var/lib/kubelet/config.yamlへ書き込みます。動的な環境ファイルは、kubeadm initの場合と全く同様の方法で生成されます。
次に、kubeadmは、kubeletに新たな設定を読み込むために、以下の二つのコマンドを実行します。
systemctl daemon-reload && systemctl restart kubelet
kubeletが新たな設定を読み込むと、kubeadmは、KubeConfigファイル/etc/kubernetes/bootstrap-kubelet.confを書き込みます。これは、CA証明書とBootstrap Tokenを含みます。これらはkubeletがTLS Bootstrapを行い/etc/kubernetes/kubelet.confに格納されるユニークなクレデンシャルを取得するために使用されます。ファイルが書き込まれると、kubeletはTLS Bootstrapを終了します。
kubelet用のsystemdファイル
kubeadmには、systemdがどのようにkubeletを実行するかを指定した設定ファイルが同梱されています。
kubeadm CLIコマンドは決してこのsystemdファイルには触れないことに注意してください。
kubeadmのDEBパッケージまたはRPMパッケージによってインストールされたこの設定ファイルは、/etc/systemd/system/kubelet.service.d/10-kubeadm.confに書き込まれ、systemdで使用されます。基本的なkubelet.service(RPM用または、 DEB用)を拡張します。
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf
--kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generate at runtime, populating
the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably,
# the user should use the .NodeRegistration.KubeletExtraArgs object in the configuration files instead.
# KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
このファイルは、kubeadmがkubelet用に管理する全ファイルが置かれるデフォルトの場所を指定します。
- TLS Bootstrapに使用するKubeConfigファイルは
/etc/kubernetes/bootstrap-kubelet.confですが、/etc/kubernetes/kubelet.confが存在しない場合にのみ使用します。 - ユニークなkublet識別子を含むKubeConfigファイルは
/etc/kubernetes/kubelet.confです。 - kubeletのComponentConfigを含むファイルは
/var/lib/kubelet/config.yamlです。 KUBELET_KUBEADM_ARGSを含む動的な環境ファイルは/var/lib/kubelet/kubeadm-flags.envから取得します。KUBELET_EXTRA_ARGSによるユーザー定義のフラグの上書きを格納できるファイルは/etc/default/kubelet(DEBの場合)、または/etc/sysconfig/kubelet(RPMの場合)から取得します。KUBELET_EXTRA_ARGSはフラグの連なりの最後に位置し、優先度が最も高いです。
Kubernetesバイナリとパッケージの内容
Kubernetesに同梱されるDEB、RPMのパッケージは以下の通りです。
| パッケージ名 | 説明 |
|---|---|
kubeadm | /usr/bin/kubeadmCLIツールと、kubelet用のsystemdファイルをインストールします。 |
kubelet | kubeletバイナリを/usr/binに、CNIバイナリを/opt/cni/binにインストールします。 |
kubectl | /usr/bin/kubectlバイナリをインストールします。 |
cri-tools | /usr/bin/crictlバイナリをcri-tools gitリポジトリからインストールします。 |
9 - kubeadmによるデュアルスタックのサポート
Kubernetes v1.23 [stable]Kubernetesクラスターにはデュアルスタックネットワークが含まれています。つまりクラスターネットワークではいずれかのアドレスファミリーを使用することができます。 クラスターでは、コントロールプレーンはIPv4アドレスとIPv6アドレスの両方を、単一のPodまたはServiceに割り当てることができます。
始める前に
kubeadmのインストールの手順に従って、kubeadmツールをインストールしておく必要があります。
ノードとして使用したいサーバーごとに、IPv6フォワーディングが許可されていることを確認してください。
Linuxでは、各サーバーでrootユーザーとしてsysctl -w net.ipv6.conf.all.forwarding=1を実行することで設定できます。
使用するにはIPv4およびIPv6アドレス範囲が必要です。
クラスター運用者は、通常はIPv4にはプライベートアドレス範囲を使用します。
IPv6では、通常は運用者が割り当てたアドレス範囲を使用して、2000::/3の範囲内からグローバルユニキャストアドレスブロックを選択します。
クラスターのIPアドレス範囲をパブリックインターネットにルーティングする必要はありません。
IPアドレス割り当てのサイズは、実行する予定のPodとServiceの数に適している必要があります。
備考:
kubeadm upgradeコマンドを使用して既存のクラスターをアップグレードする場合、kubeadmはPodのIPアドレス範囲("クラスターCIDR")やクラスターのServiceのアドレス範囲("Service CIDR")の変更をサポートしません。デュアルスタッククラスターの作成
kubeadm initを使用してデュアルスタッククラスターを作成するには、以下の例のようにコマンドライン引数を渡します:
# これらのアドレス範囲は例です
kubeadm init --pod-network-cidr=10.244.0.0/16,2001:db8:42:0::/56 --service-cidr=10.96.0.0/16,2001:db8:42:1::/112
わかりやすいように、主要なデュアルスタックコントロールプレーンノードのkubeadm構成ファイルkubeadm-config.yamlの例を示します。
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
networking:
podSubnet: 10.244.0.0/16,2001:db8:42:0::/56
serviceSubnet: 10.96.0.0/16,2001:db8:42:1::/112
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: "10.100.0.1"
bindPort: 6443
nodeRegistration:
kubeletExtraArgs:
- name: "node-ip"
value: "10.100.0.2,fd00:1:2:3::2
InitConfigurationのadvertiseAddressは、APIサーバーがリッスンしていることをアドバタイズするIPアドレスを指定します。
advertiseAddressの値はkubeadm initの--apiserver-advertise-addressフラグに相当します。
kubeadmを実行してデュアルスタックコントロールプレーンノードを初期化します:
kubeadm init --config=kubeadm-config.yaml
kube-controller-managerフラグ--node-cidr-mask-size-ipv4|--node-cidr-mask-size-ipv6はデフォルト値で設定されます。
IPv4/IPv6デュアルスタックの設定を参照してください。
備考:
--apiserver-advertise-addressフラグはデュアルスタックをサポートしません。デュアルスタッククラスターへのノード参加
ノードを参加させる前に、そのノードにIPv6ルーティングが可能なネットワークインターフェースがあり、IPv6フォワーディングが許可されていることを確認してください。
以下は、ワーカーノードをクラスターに参加させるためのkubeadm構成ファイルkubeadm-config.yamlの例です。
apiVersion: kubeadm.k8s.io/v1beta4
kind: JoinConfiguration
discovery:
bootstrapToken:
apiServerEndpoint: 10.100.0.1:6443
token: "clvldh.vjjwg16ucnhp94qr"
caCertHashes:
- "sha256:a4863cde706cfc580a439f842cc65d5ef112b7b2be31628513a9881cf0d9fe0e"
# 上記の認証情報をクラスターの実際のトークンとCA証明書に一致するように変更
nodeRegistration:
kubeletExtraArgs:
- name: "node-ip"
value: "10.100.0.2,fd00:1:2:3::3"
また以下は、別のコントロールプレーンノードをクラスターに参加させるためのkubeadm構成ファイルkubeadm-config.yamlの例です。
apiVersion: kubeadm.k8s.io/v1beta4
kind: JoinConfiguration
controlPlane:
localAPIEndpoint:
advertiseAddress: "10.100.0.2"
bindPort: 6443
discovery:
bootstrapToken:
apiServerEndpoint: 10.100.0.1:6443
token: "clvldh.vjjwg16ucnhp94qr"
caCertHashes:
- "sha256:a4863cde706cfc580a439f842cc65d5ef112b7b2be31628513a9881cf0d9fe0e"
# 上記の認証情報をクラスターの実際のトークンとCA証明書に一致するように変更
nodeRegistration:
kubeletExtraArgs:
- name: "node-ip"
value: "10.100.0.2,fd00:1:2:3::4"
JoinConfiguration.controlPlaneのadvertiseAddressは、APIサーバーがリッスンしていることをアドバタイズするIPアドレスを指定します。
advertiseAddressの値はkubeadm joinの--apiserver-advertise-addressフラグに相当します。
kubeadm join --config=kubeadm-config.yaml
シングルスタッククラスターの作成
備考:
デュアルスタックのサポートは、デュアルスタックアドレスを使用する必要があるという意味ではありません。 デュアルスタックネットワーク機能が有効になっているシングルスタッククラスターをデプロイすることができます。よりわかりやすいように、シングルスタックコントロールプレーンノードのkubeadm構成ファイルkubeadm-config.yamlの例を示します。
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/16
次の項目
- IPv4/IPv6デュアルスタックの検証
- デュアルスタッククラスターネットワークについて読む
- kubeadm構成形式についてもっと詳しく知る
10 - コントロールプレーンをセルフホストするようにkubernetesクラスターを構成する
コントロールプレーンのセルフホスティング
kubeadmを使用すると、セルフホスト型のKubernetesコントロールプレーンを実験的に作成できます。これはAPIサーバー、コントローラーマネージャー、スケジューラーなどの主要コンポーネントは、静的ファイルを介してkubeletで構成されたstatic podsではなく、Kubernetes APIを介して構成されたDaemonSet podsとして実行されることを意味します。
セルフホスト型クラスターを作成する場合はkubeadm alpha selfhosting pivotを参照してください。
警告
注意:
この機能により、クラスターがサポートされていない状態になり、kubeadmがクラスターを管理できなくなります。これにはkubeadm upgradeが含まれます。1.8以降のセルフホスティングには、いくつかの重要な制限があります。特に、セルフホスト型クラスターは、手動の介入なしにコントロールプレーンのNode再起動から回復することはできません。
デフォルトでは、セルフホスト型のコントロールプレーンのPodは、
hostPathボリュームからロードされた資格情報に依存しています。最初の作成を除いて、これらの資格情報はkubeadmによって管理されません。コントロールプレーンのセルフホストされた部分にはetcdが含まれていませんが、etcdは静的Podとして実行されます。
プロセス
セルフホスティングのブートストラッププロセスは、kubeadm design documentに記載されています。
要約すると、kubeadm alpha selfhostingは次のように機能します。
静的コントロールプレーンのブートストラップが起動し、正常になるのを待ちます。これは
kubeadm initのセルフホスティングを使用しないプロセスと同じです。静的コントロールプレーンのPodのマニフェストを使用して、セルフホスト型コントロールプレーンを実行する一連のDaemonSetのマニフェストを構築します。また、必要に応じてこれらのマニフェストを変更します。たとえば、シークレット用の新しいボリュームを追加します。
kube-systemのネームスペースにDaemonSetを作成し、Podの結果が起動されるのを待ちます。セルフホスト型のPodが操作可能になると、関連する静的Podが削除され、kubeadmは次のコンポーネントのインストールに進みます。これによりkubeletがトリガーされて静的Podが停止します。
元の静的なコントロールプレーンが停止すると、新しいセルフホスト型コントロールプレーンはリスニングポートにバインドしてアクティブになります。