Cluster APIを使うと何ができるのか
Cluster APIとは、クラスタ管理を宣言的APIで実現するKubernetesプロジェクトです。
Quickstartを実行することで、Cluster APIの実現機能が把握できます。
今回は、このQuickstartの流れを実機で試してみます。流れをまとめた次のような4コマ漫画を作りました。
1. 最初はManagement Clusterだけがあります。 |
---|
2. Cluster を追加すると、クラスタが新規作成されますが、中には何もありません。 |
3. Machine を追加すると、マスターノードが追加されます。 |
4. MachineDeployment を追加すると、ワーカノード追加が追加されます。 |
以下ではこの流れに沿って、手順を実行してみます。
環境
今回は、Docker Desktop for mac v2.2.0.0 がインストールされたMacbook Proで実施しました。その他以下がインストールされています。
-
kind
1.17
Management Clusterの準備
まずは4コマ漫画の1コマ目です。Cluster APIを持つクラスタ、Management Clusterを用意します。
最小限のKubernetesの準備
Cluster APIをインストールするには、Kubernetesクラスタが必要です。このクラスタをManagement Clusterといいます。クラスタを作る前にクラスタが必要というのは、少し手間なように感じます。でもAPIが利用できればよいので、マスターノードだけでかまいません。
ここでは、kind
というツールを使いマスターノード1台だけの最小限のクラスタを用意します。control-plane
というのは、kind
の設定でマスターノードと言う意味です。
cat > kind-cluster-with-extramounts.yaml <<EOF
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
nodes:
- role: control-plane
extraMounts:
- hostPath: /var/run/docker.sock
containerPath: /var/run/docker.sock
EOF
kind create cluster --config ./kind-cluster-with-extramounts.yaml --name clusterapi
Cluster API のインストール
Cluster APIは、設定ファイルに相当するCRD (CustomResourceDefinition)と、その設定にしたがってクラスタを作成するcontroller-managerからなります。これらを一括でインストールします。
kubectl create -f https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.2.9/cluster-api-components.yaml
namespace/capi-system created
customresourcedefinition.apiextensions.k8s.io/clusters.cluster.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/machinedeployments.cluster.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/machines.cluster.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/machinesets.cluster.x-k8s.io created
role.rbac.authorization.k8s.io/capi-leader-election-role created
clusterrole.rbac.authorization.k8s.io/capi-manager-role created
rolebinding.rbac.authorization.k8s.io/capi-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/capi-manager-rolebinding created
deployment.apps/capi-controller-manager created
次に、実際の環境に合わせたブートストラップとプロバイダをインストールします。
今回は、Dockerだけの環境を使いますので、ブートストラップにKubeadmを、プロバイダにDocker用のものを使います。
以下の専用コンポーネントをインストールします。
kubectl create -f https://github.com/kubernetes-sigs/cluster-api-bootstrap-provider-kubeadm/releases/download/v0.1.5/bootstrap-components.yaml
namespace/cabpk-system created
customresourcedefinition.apiextensions.k8s.io/kubeadmconfigs.bootstrap.cluster.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/kubeadmconfigtemplates.bootstrap.cluster.x-k8s.io created
role.rbac.authorization.k8s.io/cabpk-leader-election-role created
clusterrole.rbac.authorization.k8s.io/cabpk-manager-role created
clusterrole.rbac.authorization.k8s.io/cabpk-proxy-role created
rolebinding.rbac.authorization.k8s.io/cabpk-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/cabpk-manager-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/cabpk-proxy-rolebinding created
service/cabpk-controller-manager-metrics-service created
deployment.apps/cabpk-controller-manager created
kubectl get po -n cabpk-system
NAME READY STATUS RESTARTS AGE
cabpk-controller-manager-c58d8596f-rqczh 2/2 Running 0 7m13s
kubectl create -f https://github.com/kubernetes-sigs/cluster-api-provider-docker/releases/download/v0.2.1/provider-components.yaml
namespace/capd-system created
customresourcedefinition.apiextensions.k8s.io/dockerclusters.infrastructure.cluster.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/dockermachines.infrastructure.cluster.x-k8s.io created
customresourcedefinition.apiextensions.k8s.io/dockermachinetemplates.infrastructure.cluster.x-k8s.io created
role.rbac.authorization.k8s.io/capd-leader-election-role created
clusterrole.rbac.authorization.k8s.io/capd-manager-role created
clusterrole.rbac.authorization.k8s.io/capd-proxy-role created
rolebinding.rbac.authorization.k8s.io/capd-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/capd-manager-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/capd-proxy-rolebinding created
service/capd-controller-manager-metrics-service created
deployment.apps/capd-controller-manager created
kubectl get po -n capd-system
NAME READY STATUS RESTARTS AGE
capd-controller-manager-7cd8c765c-84j7r 2/2 Running 0 5m22s
この時点で、Docker
上にはclusterapi-control-plane
というコンテナ(Management cluster)が一つだけ動いています。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
68d711500e26 kindest/node:v1.17.0 "/usr/local/bin/entr…" 11 minutes ago Up 11 minutes 127.0.0.1:32775->6443/tcp clusterapi-control-plane
ClusterAPIを使う
Cluster APIの以下のCRDを順に作成していきます。
Cluster
Machine
MachineDeployment
Cluster
新規作成
4コマ漫画の2コマ目になります。
Cluster APIで作るためのクラスタの設定ファイルを作成します。
apiVersion: cluster.x-k8s.io/v1alpha2
kind: Cluster
metadata:
name: capi-quickstart
spec:
clusterNetwork:
pods:
cidrBlocks: ["192.168.0.0/16"]
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha2
kind: DockerCluster
name: capi-quickstart
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha2
kind: DockerCluster
metadata:
name: capi-quickstart
kubectl create -f cluster.yaml
cluster.cluster.x-k8s.io/capi-quickstart created
dockercluster.infrastructure.cluster.x-k8s.io/capi-quickstart created
kubectl get dockercluster
NAME AGE
capi-quickstart 11s
Docker
を確認してみますと、以下のようにcapi-quickstart-lb
というコンテナが起動していることがわかります。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
38d5a9338e3d nginx:1.15.12-alpine "nginx -g 'daemon of…" 48 seconds ago Up 47 seconds 80/tcp, 40319/tcp, 0.0.0.0:40319->6443/tcp capi-quickstart-lb
68d711500e26 kindest/node:v1.17.0 "/usr/local/bin/entr…" 14 minutes ago Up 14 minutes 127.0.0.1:32775->6443/tcp clusterapi-control-plane
Machine
を作る
4コマ漫画の3コマ目になります。Machine
というCRDでマスターノードを作成します。
apiVersion: cluster.x-k8s.io/v1alpha2
kind: Machine
metadata:
name: capi-quickstart-controlplane-0
labels:
cluster.x-k8s.io/control-plane: "true"
cluster.x-k8s.io/cluster-name: "capi-quickstart"
spec:
version: v1.15.3
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
kind: KubeadmConfig
name: capi-quickstart-controlplane-0
infrastructureRef:
kind: DockerMachine
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha2
name: capi-quickstart-controlplane-0
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha2
kind: DockerMachine
metadata:
name: capi-quickstart-controlplane-0
---
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
kind: KubeadmConfig
metadata:
name: capi-quickstart-controlplane-0
spec:
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
clusterConfiguration:
controllerManager:
extraArgs:
enable-hostpath-provisioner: "true"
kubectl create -f machine.yaml
machine.cluster.x-k8s.io/capi-quickstart-controlplane-0 created
dockermachine.infrastructure.cluster.x-k8s.io/capi-quickstart-controlplane-0 created
kubeadmconfig.bootstrap.cluster.x-k8s.io/capi-quickstart-controlplane-0 created
以下のようにmachineが起動されるまでにおおよそ10分かかりました。
kubectl get machines --selector cluster.x-k8s.io/control-plane
NAME PROVIDERID PHASE
capi-quickstart-controlplane-0 docker:////capi-quickstart-capi-quickstart-controlplane-0 running
Docker
でも以下のように、capi-quickstart-capi-quickstart-controlplane-0
というコンテナが起動したことがわかります。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f449784405e6 kindest/node:v1.15.3 "/usr/local/bin/entr…" About a minute ago Up About a minute 35547/tcp, 127.0.0.1:35547->6443/tcp capi-quickstart-capi-quickstart-controlplane-0
38d5a9338e3d nginx:1.15.12-alpine "nginx -g 'daemon of…" 11 minutes ago Up 11 minutes 80/tcp, 40319/tcp, 0.0.0.0:40319->6443/tcp capi-quickstart-lb
68d711500e26 kindest/node:v1.17.0 "/usr/local/bin/entr…" 25 minutes ago Up 25 minutes 127.0.0.1:32775->6443/tcp clusterapi-control-plane
作成したクラスタにアクセスするkubeconfig
を作る
kubectl
でクラスタ内に接続するために、kubeconfig
ファイルを作成します。予めcluster
作成時に以下のようなSecret
が作成されているので、そこから抜き出します。
kubectl --namespace=default get secret/capi-quickstart-kubeconfig -o json \
| jq -r .data.value \
| base64 --decode \
> ./capi-quickstart.kubeconfig
今回はMacbook上で実行したために、以下のコマンドで一部だけ変更します(cluster
の宛先と接続方法insecure-skip-tls-verify
を変更します。)
sed -i -e "s/server:.*/server: https:\/\/$(docker port capi-quickstart-lb 6443/tcp | sed "s/0.0.0.0/127.0.0.1/")/g" ./capi-quickstart.kubeconfig
# Ignore the CA, because it is not signed for 127.0.0.1
sed -i -e "s/certificate-authority-data:.*/insecure-skip-tls-verify: true/g" ./capi-quickstart.kubeconfig
生成したkubeconfig
はこうなっています。
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://127.0.0.1:40319
name: capi-quickstart
contexts:
- context:
cluster: capi-quickstart
user: kubernetes-admin
name: kubernetes-admin@capi-quickstart
current-context: kubernetes-admin@capi-quickstart
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: LS0tLS1CR...
client-key-data: LS0t...
このkubeconfig
を使ってkubectl
を実行してみます。
kubectl --kubeconfig=./capi-quickstart.kubeconfig get nodes
NAME STATUS ROLES AGE VERSION
capi-quickstart-capi-quickstart-controlplane-0 NotReady master 8m35s v1.15.3
まずはMasterノードが動いていることがわかります。ただし、状態はまだNotReady
です。クラスタ内ネットワークが構築されていないためです。
クラスタ内ネットワークを構築する
次に、ネットワークを構築します。calico
をインストールします。
kubectl --kubeconfig=./capi-quickstart.kubeconfig \
apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yaml
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
kubectl --kubeconfig=./capi-quickstart.kubeconfig \
-n kube-system patch daemonset calico-node \
--type=strategic --patch='
spec:
template:
spec:
containers:
- name: calico-node
env:
- name: FELIX_IGNORELOOSERPF
value: "true"
'
daemonset.extensions/calico-node patched
これを実行することにより、マスターノードはReady
状態となります。
Workerを追加する
4コマ漫画の最後のコマになります。ワーカーノードをMachineDeployment
を使って追加します。
以下のworker.yaml
ファイルを作成し、Management Clusterに対しkubectl create
コマンドを実行します。
apiVersion: cluster.x-k8s.io/v1alpha2
kind: MachineDeployment
metadata:
name: capi-quickstart-worker
labels:
cluster.x-k8s.io/cluster-name: capi-quickstart
# Labels beyond this point are for example purposes,
# feel free to add more or change with something more meaningful.
# Sync these values with spec.selector.matchLabels and spec.template.metadata.labels.
nodepool: nodepool-0
spec:
replicas: 1
selector:
matchLabels:
cluster.x-k8s.io/cluster-name: capi-quickstart
nodepool: nodepool-0
template:
metadata:
labels:
cluster.x-k8s.io/cluster-name: capi-quickstart
nodepool: nodepool-0
spec:
version: v1.15.3
bootstrap:
configRef:
name: capi-quickstart-worker
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
kind: KubeadmConfigTemplate
infrastructureRef:
name: capi-quickstart-worker
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha2
kind: DockerMachineTemplate
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha2
kind: DockerMachineTemplate
metadata:
name: capi-quickstart-worker
spec:
template:
spec: {}
---
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha2
kind: KubeadmConfigTemplate
metadata:
name: capi-quickstart-worker
spec:
template:
spec:
# For more information about these values,
# refer to the Kubeadm Bootstrap Provider documentation.
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
clusterConfiguration:
controllerManager:
extraArgs:
enable-hostpath-provisioner: "true"
kubectl create -f worker.yaml
machinedeployment.cluster.x-k8s.io/capi-quickstart-worker created
dockermachinetemplate.infrastructure.cluster.x-k8s.io/capi-quickstart-worker created
kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/capi-quickstart-worker created
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e6162d760dd7 kindest/node:v1.15.3 "/usr/local/bin/entr…" 2 minutes ago Up 2 minutes capi-quickstart-capi-quickstart-worker-85cbf8fd8c-mhrlz
f449784405e6 kindest/node:v1.15.3 "/usr/local/bin/entr…" 16 minutes ago Up 16 minutes 35547/tcp, 127.0.0.1:35547->6443/tcp capi-quickstart-capi-quickstart-controlplane-0
38d5a9338e3d nginx:1.15.12-alpine "nginx -g 'daemon of…" 26 minutes ago Up 26 minutes 80/tcp, 40319/tcp, 0.0.0.0:40319->6443/tcp capi-quickstart-lb
68d711500e26 kindest/node:v1.17.0 "/usr/local/bin/entr…" 40 minutes ago Up 40 minutes 127.0.0.1:32775->6443/tcp clusterapi-control-plane
kubectl --kubeconfig=./capi-quickstart.kubeconfig get nodes ✔ 1656 01:13:19
NAME STATUS ROLES AGE VERSION
capi-quickstart-capi-quickstart-controlplane-0 Ready master 20m v1.15.3
capi-quickstart-capi-quickstart-worker-85cbf8fd8c-mhrlz Ready <none> 6m30s v1.15.3
Workerを増やす
オプションで、MachineDeployment
を編集することで動的にワーカーノードを追加することができます。
以下では、1台だったワーカーノードを2台に増やします。
$ kubectl edit machinedeployment capi-quickstart-worker
以下の行を変更します。
- replica: 1
+ replica: 2
保存して終了します。Machine
が以下のように増えています。
$ kubectl get machines
NAME PROVIDERID PHASE
capi-quickstart-controlplane-0 docker:////capi-quickstart-capi-quickstart-controlplane-0 running
capi-quickstart-worker-85cbf8fd8c-mhrlz docker:////capi-quickstart-capi-quickstart-worker-85cbf8fd8c-mhrlz running
capi-quickstart-worker-85cbf8fd8c-wjk9h provisioning
Dockerコンテナを見ても、以下のように追加されます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e55a1192feeb kindest/node:v1.15.3 "/usr/local/bin/entr…" About a minute ago Up About a minute capi-quickstart-capi-quickstart-worker-85cbf8fd8c-wjk9h
e6162d760dd7 kindest/node:v1.15.3 "/usr/local/bin/entr…" 3 days ago Up 3 days capi-quickstart-capi-quickstart-worker-85cbf8fd8c-mhrlz
f449784405e6 kindest/node:v1.15.3 "/usr/local/bin/entr…" 3 days ago Up 3 days 35547/tcp, 127.0.0.1:35547->6443/tcp capi-quickstart-capi-quickstart-controlplane-0
38d5a9338e3d nginx:1.15.12-alpine "nginx -g 'daemon of…" 3 days ago Up 3 days 80/tcp, 40319/tcp, 0.0.0.0:40319->6443/tcp capi-quickstart-lb
68d711500e26 kindest/node:v1.17.0 "/usr/local/bin/entr…" 3 days ago Up 3 days 127.0.0.1:32775->6443/tcp clusterapi-control-plane
kubectl get nodes
コマンドでも確認できます。
$ kubectl --kubeconfig=./capi-quickstart.kubeconfig get nodes
NAME STATUS ROLES AGE VERSION
capi-quickstart-capi-quickstart-controlplane-0 Ready master 3d22h v1.15.3
capi-quickstart-capi-quickstart-worker-85cbf8fd8c-mhrlz Ready <none> 3d22h v1.15.3
capi-quickstart-capi-quickstart-worker-85cbf8fd8c-wjk9h Ready <none> 3m8s v1.15.3
上記のように、capi-quickstart-capi-quickstart-worker-85cbf8fd8c-xxxxx
の名前のノードが2台に増えたことが確認できました。
まとめ
Cluster APIを使ってManagement ClusterからKubernetesクラスタを作ってみました。
宣言的APIで動的にワーカーノードを追加することができ、kind
よりも柔軟性が高いと感じました。
ただし、Kubeadm
の設定があまり隠蔽されないため、YAMLファイルを書く行数はkind
より多くなっていると思います。
注意点として、頻繁にkubectl
を実行するのですが、今自分がManagement Clusterにkubectl
を打っているのか、はたまた作成後のKubernetesクラスタにkubectl
を打っているのか、混乱しないように進める必要があると思いました。