Kubernetesを触るようになってそこそこ経つんだけど、未だにわからないことのほうが圧倒的に多い。体系的にちゃんと学習する必要があるなぁということで、これまで辞書的にしか使ってこなかったこれを改めて読んでます。
で、色々試すに当たり、ローカル環境でかんたんにマルチクラスタができるものがよいなぁということで、kindを触ってみました。
詳しく知りたい方はQiitaあたりにたくさん記事があるのでそちらを見てください。あくまでも自分用メモです。
目次
インストール
前提として、Dockerが必要。Macの場合はDocker Desktopをインストールしておいて、Homebrewでかんたんにインストールできる。dockerもHomebrewでいいかもね。
$ brew install kind kubectl
$ kind version kind v0.11.1 go1.16.4 darwin/amd64
クラスタの作成(シングル)
かんたんにクラスタを作成して起動するだけならkind create cluster
でOK。
$ kind create cluster Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.21.1) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
サクッとクラスタが作られます。初回だけnodeのイメージを取得するのに時間が少しかかるみたい。
デフォルトだとクラスタ名はkindになります。
$ kind get clusters kind
kubeconfig的にはkind-kindになってますね。というか普通にkubectlが使えるようになります。
$ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kind-kind kind-kind kind-kind
nodeを見てみる。デフォルトだとcontrol-plane/worker兼用の1台だけっぽい。
$ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kind-control-plane Ready control-plane,master 8m37s v1.21.1 172.18.0.2 <none> Ubuntu 21.04 5.10.25-linuxkit containerd://1.5.2
podはこんな感じ。
$ kubectl get pod --all-namespaces -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system coredns-558bd4d5db-6w67p 1/1 Running 0 11h 10.244.0.2 kind-control-plane <none> <none> kube-system coredns-558bd4d5db-thh9z 1/1 Running 0 11h 10.244.0.4 kind-control-plane <none> <none> kube-system etcd-kind-control-plane 1/1 Running 0 11h 172.18.0.2 kind-control-plane <none> <none> kube-system kindnet-z78fn 1/1 Running 0 11h 172.18.0.2 kind-control-plane <none> <none> kube-system kube-apiserver-kind-control-plane 1/1 Running 0 11h 172.18.0.2 kind-control-plane <none> <none> kube-system kube-controller-manager-kind-control-plane 1/1 Running 0 11h 172.18.0.2 kind-control-plane <none> <none> kube-system kube-proxy-k62zn 1/1 Running 0 11h 172.18.0.2 kind-control-plane <none> <none> kube-system kube-scheduler-kind-control-plane 1/1 Running 0 11h 172.18.0.2 kind-control-plane <none> <none> local-path-storage local-path-provisioner-547f784dff-5nhpt 1/1 Running 0 11h 10.244.0.3 kind-control-plane <none>
試しにnginxのpodをあげてみます。
$ kubectl run nginx --image=nginx
$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 2m23s 10.244.0.5 kind-control-plane <none> <none>
$ kubectl exec -ti nginx -- bash root@nginx:/#
普通に使えてますね。
クラスタの削除
削除する場合はkind delete cluster
で、サクッと消えます。
$ kind delete cluster Deleting cluster "kind" ...
クラスタの作成(マルチnode)
kindの最大の特徴はマルチcontrol-plane/マルチworkerが作れること。control-plane3台、worker3台だと、こんな感じのマニフェストになります。ちなみに、nameでクラスタ名の指定ができます。
apiVersion: kind.x-k8s.io/v1alpha4 kind: Cluster name: sample nodes: - role: control-plane - role: control-plane - role: control-plane - role: worker - role: worker - role: worker
クラスタ作成時に--config
でこのマニフェストを指定します。
$ kind create cluster --config multi.yaml Creating cluster "sample" ... ✓ Ensuring node image (kindest/node:v1.21.1) 🖼 ✓ Preparing nodes 📦 📦 📦 📦 📦 📦 ✓ Configuring the external load balancer ⚖️ ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 ✓ Joining more control-plane nodes 🎮 ✓ Joining worker nodes 🚜 Set kubectl context to "kind-sample" You can now use your cluster with: kubectl cluster-info --context kind-sample Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/
nodeを見てみるとちゃんと複数立ってますね。
$ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME sample-control-plane Ready control-plane,master 8m55s v1.21.1 172.18.0.7 <none> Ubuntu 21.04 5.10.25-linuxkit containerd://1.5.2 sample-control-plane2 Ready control-plane,master 8m12s v1.21.1 172.18.0.6 <none> Ubuntu 21.04 5.10.25-linuxkit containerd://1.5.2 sample-control-plane3 Ready control-plane,master 7m18s v1.21.1 172.18.0.8 <none> Ubuntu 21.04 5.10.25-linuxkit containerd://1.5.2 sample-worker Ready <none> 7m v1.21.1 172.18.0.3 <none> Ubuntu 21.04 5.10.25-linuxkit containerd://1.5.2 sample-worker2 Ready <none> 6m59s v1.21.1 172.18.0.4 <none> Ubuntu 21.04 5.10.25-linuxkit containerd://1.5.2 sample-worker3 Ready <none> 6m59s v1.21.1 172.18.0.5 <none> Ubuntu 21.04 5.10.25-linuxkit containerd://1.5.2
dockerコマンドで見てみると、haproxyも一つ立っているのがわかる。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a9cd9e1dfecc kindest/node:v1.21.1 "/usr/local/bin/entr…" 9 minutes ago Up 9 minutes sample-worker a319976c1294 kindest/node:v1.21.1 "/usr/local/bin/entr…" 9 minutes ago Up 9 minutes 127.0.0.1:49999->6443/tcp sample-control-plane 06382bd1fe9d kindest/node:v1.21.1 "/usr/local/bin/entr…" 9 minutes ago Up 9 minutes sample-worker2 41c70051f965 kindest/node:v1.21.1 "/usr/local/bin/entr…" 9 minutes ago Up 9 minutes 127.0.0.1:50002->6443/tcp sample-control-plane3 481c1f7a9f47 kindest/haproxy:v20200708-548e36db "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 127.0.0.1:50000->6443/tcp sample-external-load-balancer 5cea2faf1a7c kindest/node:v1.21.1 "/usr/local/bin/entr…" 9 minutes ago Up 9 minutes sample-worker3 9d73f13cf90c kindest/node:v1.21.1 "/usr/local/bin/entr…" 9 minutes ago Up 9 minutes 127.0.0.1:50001->6443/tcp sample-control-plane2
こいつがapiserverへのLoad Balancerになっている。
$ docker exec -ti sample-external-load-balancer sh / # ps PID USER TIME COMMAND 1 root 0:00 haproxy -sf 8 -W -db -f /usr/local/etc/haproxy/haproxy.cfg 32 root 0:05 haproxy -sf 8 -W -db -f /usr/local/etc/haproxy/haproxy.cfg 36 root 0:00 sh 44 root 0:00 ps / # cat /usr/local/etc/haproxy/haproxy.cfg (snip) frontend control-plane bind *:6443 default_backend kube-apiservers backend kube-apiservers option httpchk GET /healthz # TODO: we should be verifying (!) server sample-control-plane sample-control-plane:6443 check check-ssl verify none resolvers docker resolve-prefer ipv4 server sample-control-plane2 sample-control-plane2:6443 check check-ssl verify none resolvers docker resolve-prefer ipv4 server sample-control-plane3 sample-control-plane3:6443 check check-ssl verify none resolvers docker resolve-prefer ipv4 / #
マルチnodeなので、deploymentを立ててみる。
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: nginx image: nginx:1.19.4 ports: - containerPort: 80
複数のnodeで起動していることがわかる。
$ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-app-58b49559b8-bwm8z 1/1 Running 0 43s 10.244.4.2 sample-worker3 <none> <none> my-app-58b49559b8-jdntf 1/1 Running 0 43s 10.244.3.2 sample-worker <none> <none> my-app-58b49559b8-vwgjc 1/1 Running 0 43s 10.244.5.2 sample-worker2 <none> <none>
ローカルPCからクラスタ内podへのネットワークアクセス
kindで作成したクラスタはdockerで構成されているので、そのままではpodへネットワークアクセスできない。extraPortmappingsを使う。
まずは1 control-plain/1 workerで試してみる。クラスタ作成用マニフェストをこんな感じで作成する。
apiVersion: kind.x-k8s.io/v1alpha4 kind: Cluster name: sample2 nodes: - role: control-plane - role: worker extraPortMappings: - containerPort: 30000 hostPort: 30000 protocol: TCP
クラスタ作成
$ kind create cluster --config sample2.yaml
podとserviceはこんな感じで。
apiVersion: v1 kind: Pod metadata: name: my-app labels: app: my-app spec: containers: - name: nginx image: nginx:1.19.2 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app type: NodePort ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 30000
curlでアクセスしてみる
$ curl localhost:30000 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> (snip)
dockerでみるとworkerのpodへport-forwardされていることがわかる。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bf8df82909a2 kindest/node:v1.21.1 "/usr/local/bin/entr…" 2 minutes ago Up 2 minutes 0.0.0.0:30000->30000/tcp sample2-worker 4756002bd30d kindest/node:v1.21.1 "/usr/local/bin/entr…" 2 minutes ago Up 2 minutes 127.0.0.1:53630->6443/tcp sample2-control-plane
うーん、nodeportの場合、マルチクラスタで同じことをやる場合にはちょっとひねりが必要な感じ。
続きは次回。