かんたんすぎる
Kubernetesの動作確認環境として, 簡単にクラスタを用意できるkindを使ってみた.
やったことのまとめ
kind
をMacにインストールしたkind
でKubernetes
クラスタを作成, 削除したkind
で作ったクラスタにIngress Controller
をデプロイした
つかうもの
- macOS Mojave 10.14
- Docker Desktop for Mac
- Version 2.5.0.0
- Docker version 19.03.13
- インストール済み
- anyenv 1.1.1
- インストール済み
- goenv 2.0.0beta11
- インストール済み
- go version go1.15.5 darwin/amd64
- 今回入れる
- kind v0.9.0 go1.15.5 darwin/amd64
- 今回入れる
- kubectl Client Version: v1.19.3
- インストール済み
やったこと
kindってなに
kind
1はDocker
コンテナをNode
として動かすことでローカル環境でKubernetes
クラスタを動作させるツール.
今までローカルでの動作確認にはDocker Desktop
で作れるKuberentes
クラスタを使ってたんだけど,
この前Kubernetes
v1.20以降はDocker
がNode
のコンテナランタイムとして非推奨2になるとのお知らせが出ていた.
Docker Desktop
のKubernetes
クラスタはDocker
をコンテナランタイムとして使っているので, そのうち使えなくなるかも…
# Docker Desktopで立てたKubernetesクラスタのコンテナランタイムはDocker
$ kubectl get nodes -o wide --context=docker-desktop
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
docker-desktop Ready master 33d v1.19.3 192.168.65.3 <none> Docker Desktop 5.4.39-linuxkit docker://19.3.13
ということで, これを機にローカルでの動作確認用Kubernetes
クラスタはkind
で作ることにした.
(kind
ではNode
でcontainerd
3をランタイムとして使っているので問題ないらしい)
Goの更新
(Go
の最新版がインストールされている環境なら飛ばしてOK)
kind
のクイックスタート4によるとGo
の最新版を使ってね!とのことなのでせっかくだし新しいGo
(1.15)をインストールする.
$ go version
go version go1.14.6 darwin/amd64
# goenvを更新
$ anyenv install goenv
anyenv: /Users/uzimihsr/.anyenv/envs/goenv already exists
Reinstallation keeps versions directories
continue with installation? (y/N) y
...
Install goenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session.
# シェルを再起動
$ exec $SHELL -l
# インストール可能なバージョンの一覧を確認
$ goenv install -l | grep 1.15
1.15.0
1.15beta1
1.15rc2
1.15.1
1.15.2
1.15.3
1.15.4
1.15.5
# Go 1.15.5をインストール
$ goenv install 1.15.5
Downloading go1.15.5.darwin-amd64.tar.gz...
-> https://golang.org/dl/go1.15.5.darwin-amd64.tar.gz
Installing Go Darwin 64bit 1.15.5...
Installed Go Darwin 64bit 1.15.5 to /Users/uzimihsr/.anyenv/envs/goenv/versions/1.15.5
# このMacで常にGo 1.15.5を使うようにする
$ goenv global 1.15.5
$ goenv rehash
# 確認
$ goenv versions
1.12.9
1.13.0
1.14.6
* 1.15.5 (set by /Users/uzimihsr/.anyenv/envs/goenv/version)
$ go version
go version go1.15.5 darwin/amd64
$ echo $GOPATH
/Users/uzimihsr/go/1.15.5
OK.
kindのインストール
次にkind
をインストールする.
といってもgo get
で入るのでインストール自体は1行で終わっちゃう.
クッソかんたん.
# kindのインストール
$ GO111MODULE="on" go get sigs.k8s.io/kind@v0.9.0
# $GOPATH/bin/kindに入っている
$ which kind
/Users/uzimihsr/go/1.15.5/bin/kind
# 動作確認
$ kind version
kind v0.9.0 go1.15.5 darwin/amd64
クラスタの起動
いよいよKubernetes
クラスタを起動する.
…これもコマンド1発でできる.
めっちゃかんたん.
# Kubernetesクラスタ(kind-kind)の作成
$ kind create cluster
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.19.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/
kubectl
のcontext
が勝手に切り替わるので, すぐにクラスタの操作もできる.
# kubectlのcontextが自動で変更されている
$ kubectl config view --minify
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://127.0.0.1:63917
name: kind-kind
contexts:
- context:
cluster: kind-kind
user: kind-kind
name: kind-kind
current-context: kind-kind
kind: Config
preferences: {}
users:
- name: kind-kind
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
# うまく切り替わっていない場合もkindコマンドから有効なkubeconfigを取得可能
$ kind get kubeconfig --name kind
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ...
server: https://127.0.0.1:63917
name: kind-kind
contexts:
- context:
cluster: kind-kind
user: kind-kind
name: kind-kind
current-context: kind-kind
kind: Config
preferences: {}
users:
- name: kind-kind
user:
client-certificate-data: ...
client-key-data: ...
# 動作確認
$ kubectl cluster-info --context kind-kind
Kubernetes master is running at https://127.0.0.1:63917
KubeDNS is running at https://127.0.0.1:63917/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
実際にNode
用のコンテナが起動していることも確認できる.
# Nodeが1つ作成されている(コンテナランタイムがcontainerd!)
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kind-control-plane Ready master 19m v1.19.1 172.19.0.2 <none> Ubuntu Groovy Gorilla (development branch) 5.4.39-linuxkit containerd://1.4.0
# Nodeとして動いているコンテナ
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
24117f8d397f kindest/node:v1.19.1 "/usr/local/bin/entr…" 21 minutes ago Up 20 minutes 127.0.0.1:63917->6443/tcp kind-control-plane
ちゃんとPod
も動く. すごい.
# Podも作れる
$ kubectl run nginx --image=nginx
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 37s 10.244.0.5 kind-control-plane <none> <none>
# Podの動作確認
$ kubectl run busybox --image=busybox --restart=Never --rm -it -- wget -O- 10.244.0.5:80
Connecting to 10.244.0.5:80 (10.244.0.5:80)
writing to stdout
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100% |********************************| 612 0:00:00 ETA
written to stdout
pod "busybox" deleted
Ingressの設定
簡単なPod
やJob
の動作確認だけならこれでも良いんだけど,
クラスタ外からの動作確認がしたい場合は追加でIngress
の設定が必要なので試してみる.
まずは新たなクラスタを設定ファイル5を使って作成する.extraPortMappings
とnode-labels
が設定されていることが重要らしい.
# kindのクラスタ設定ファイルの作成
$ vim config.yaml
# 新規クラスタ(kind-ingress-enabled)の起動
$ kind create cluster --name ingress-enabled --config config.yaml
Creating cluster "ingress-enabled" ...
✓ Ensuring node image (kindest/node:v1.19.1) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-ingress-enabled"
You can now use your cluster with:
kubectl cluster-info --context kind-ingress-enabled
Thanks for using kind! 😊
作ったばかりのクラスタ(kind-ingress-enabled)にIngress Controller
をデプロイする6.
今回はNGINX Ingress Controller
7を使用する.
# NGINX Ingress Controllerのデプロイ
$ kubectl apply --context kind-ingress-enabled -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
# 起動確認
$ kubectl wait --context kind-ingress-enabled --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
pod/ingress-nginx-controller-6df69bd4f7-57bkk condition met
これでこのクラスタでIngress
を使う準備ができた.
最後にサンプルアプリ8を動かして, Ingress
の動作を確認する.
# サンプルアプリ(Pod, Service, Ingress)のデプロイ
$ kubectl apply -f https://kind.sigs.k8s.io/examples/ingress/usage.yaml
pod/foo-app created
service/foo-service created
pod/bar-app created
service/bar-service created
Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.networking.k8s.io/example-ingress created
# リクエストに対してそれぞれfoo, barを返すPodとそれに対応したService
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/bar-app 1/1 Running 0 33s
pod/foo-app 1/1 Running 0 33s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/bar-service ClusterIP 10.96.251.3 <none> 5678/TCP 33s
service/foo-service ClusterIP 10.96.170.161 <none> 5678/TCP 33s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16m
# /foo, /barへのトラフィックをそれぞれのServiceに振り分けるIngress
$ kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> * localhost 80 16m
$ kubectl describe ingress example-ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
Name: example-ingress
Namespace: default
Address: localhost
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
*
/foo foo-service:5678 10.244.0.10:5678)
/bar bar-service:5678 10.244.0.9:5678)
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 17m (x2 over 17m) nginx-ingress-controller Scheduled for sync
# クラスタ外から叩いて動作確認
$ curl localhost/foo
foo
$ curl localhost/bar
bar
やったぜ.
kind
で立てたクラスタでもIngress
を使ってクラスタ外からアクセスすることができた.
クラスタの削除
最後にクラスタをお掃除する.
これもコマンド1発なのでめちゃくちゃ簡単.
# 削除前の状態
$ kind get clusters
ingress-enabled
kind
# Node用のコンテナが2クラスタぶん存在する
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d5c5aa156df9 kindest/node:v1.19.1 "/usr/local/bin/entr…" 23 hours ago Up 23 hours 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 127.0.0.1:57487->6443/tcp ingress-enabled-control-plane
24117f8d397f kindest/node:v1.19.1 "/usr/local/bin/entr…" 24 hours ago Up 24 hours 127.0.0.1:63917->6443/tcp kind-control-plane
# クラスタの削除
$ kind delete cluster --name kind
Deleting cluster "kind" ...
# 一括削除も可能
$ kind delete clusters --all
Deleted clusters: ["ingress-enabled"]
# Nodeのコンテナがすべて消えている
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# kubeconfigの設定も勝手に消えている(残っているのは別途作成したDocker DesktopとMinikubeの設定のみ)
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://kubernetes.docker.internal:6443
name: docker-desktop
- cluster:
certificate-authority: /Users/uzimihsr/.minikube/ca.crt
server: https://192.168.99.110:8443
name: minikube
contexts:
- context:
cluster: docker-desktop
user: docker-desktop
name: docker-desktop
- context:
cluster: minikube
user: minikube
name: minikube
current-context: ""
kind: Config
preferences: {}
users:
- name: docker-desktop
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: minikube
user:
client-certificate: /Users/uzimihsr/.minikube/client.crt
client-key: /Users/uzimihsr/.minikube/client.key
…こんなに簡単でいいのか?
おわり
kind
を使ったKubernetes
クラスタの作成, Ingress Controller
のデプロイ, クラスタの削除を一通り試してみた.
Ingress
対応だけちょっと面倒だけどそれもほぼコピペでできるし,
基本はコマンド1行でクラスタが簡単に作れるのがすごい. 便利すぎる.