9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

図解: Cluster APIを使ってKubernetesクラスタを作る (on Docker)

Last updated at Posted at 2020-02-04

Cluster APIを使うと何ができるのか

Cluster APIとは、クラスタ管理を宣言的APIで実現するKubernetesプロジェクトです。
Quickstartを実行することで、Cluster APIの実現機能が把握できます。

今回は、このQuickstartの流れを実機で試してみます。流れをまとめた次のような4コマ漫画を作りました。

1. 最初はManagement Clusterだけがあります。
first.png
2. Clusterを追加すると、クラスタが新規作成されますが、
中には何もありません
cluster.png
3. Machineを追加すると、マスターノードが追加されます。
machine.png
4. MachineDeploymentを追加すると、ワーカノード追加が追加されます。
last.png

以下ではこの流れに沿って、手順を実行してみます。

環境

今回は、Docker Desktop for mac v2.2.0.0 がインストールされたMacbook Proで実施しました。その他以下がインストールされています。

  • kind 1.17

Management Clusterの準備

まずは4コマ漫画の1コマ目です。Cluster APIを持つクラスタ、Management Clusterを用意します。

first.png

最小限の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.png

Cluster APIで作るためのクラスタの設定ファイルを作成します。

cluster.yaml
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でマスターノードを作成します。

machine.png

machine.yaml
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はこうなっています。

capi-quickstart.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をインストールします。

calico.png

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を使って追加します。

last.png

以下のworker.yamlファイルを作成し、Management Clusterに対しkubectl createコマンドを実行します。

worker.yaml
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を打っているのか、混乱しないように進める必要があると思いました。

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?