GW中にやってしまいたかったが、Kubernetes v1.24がリリースされていたのでそれのセルフインストールを試しておこうと。
いつもはAWSを使うが今回はAzureを使用。
コンテナエンジンはcontainerd、ネットワークドライバはCalicoで、kubeadmを使ってインストール。
AzureならAKSを使うのが、まあ普通かもしれない。HAではないらしいがCP(Master)がタダなのは素晴らしい。とはいえ特定ベンダのクラウド依存度を下げたいからKubernetes使うんじゃないの?という論も立たなくは無いだろう。であればIaaSのVMの上にKubernetesクラスター自作である。
環境
Control Planeノードを1台。Workerノードを2台。
VMのサイズはすべてD2as_v4(vCPU:2、RAM:8GiB)、OSはUbutnu Server 20.04 LTS -Gen2、ネットワークはSSH(22)だけ開いて作成。
Kubernetesは「Masterノード」という用語を廃止しようとしており、「Control Planeノード」に置き換え中。
v1.24から、新規構築クラスターのCPノード(今までのMasterノード)に「node-role.kubernetes.io/control-plane:NoSchedule」というtaintが追加されており、インフラ的に高インパクトかも。そもそもホスト名も、これからは「master1,2」とかじゃなく「cp1,2」とかいう時代である。
Dockershimサポート廃止も合わさり、v1.24は割と頭痛いバージョン。
CPノードを作る
まずは、containerd、kubeadmを入れるまで。
azureuser@cp:~$ sudo -i
# cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
# sudo modprobe overlay
# sudo modprobe br_netfilter
# cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
# sudo sysctl --system
# wget https://github.com/containerd/containerd/releases/download/v1.6.4/containerd-1.6.4-linux-amd64.tar.gz
# tar Cxzvf /usr/local containerd-1.6.4-linux-amd64.tar.gz
# wget https://github.com/containerd/containerd/raw/main/containerd.service
# cp containerd.service /etc/systemd/system/containerd.service
# systemctl enable --now containerd
# wget https://github.com/opencontainers/runc/releases/download/v1.1.1/runc.amd64
# install -m 755 runc.amd64 /usr/local/sbin/runc
# wget https://github.com/containernetworking/plugins/releases/download/v1.1.1/cni-plugins-linux-amd64-v1.1.1.tgz
# mkdir -p /opt/cni/bin
# tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.1.1.tgz
# mkdir /etc/containerd
# containerd config default > /etc/containerd/config.toml
# sed -i /etc/containerd/config.toml -e 's/SystemdCgroup = false/SystemdCgroup = true/'
# sudo systemctl restart containerd
# sudo apt-get update
# sudo apt-get install -y apt-transport-https ca-certificates curl
# sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
# echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# sudo apt-get update
# sudo apt-get install -y kubelet kubeadm kubectl
# sudo apt-mark hold kubelet kubeadm kubectl
kubeadm initでクラスターを作るが、ネットワークドライバをCalicoにするのでCIDRは192.168.0.0/16。
# kubeadm init --pod-network-cidr=192.168.0.0/16
(出力結果)
...
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.0.0.6:6443 --token 5bwjtd.w2c2zfagwrewgal6 \
--discovery-token-ca-cert-hash sha256:a863b41e43c6fe8e8033193b927721d4099d9abf82f3cc9d5ffdf4a68e2bae04
「kubeadm join~」のテキストはこの後のWorkerノードの追加に使うので手元にとっておく。
Calicoを導入するが、Tigera operatorを使ってインストールするとtaintのcontrol-planeを追加できないので使えない。中途半端なサポートだとOperatorというアプローチは良くない。仕方がないので、Calicoのyamlファイルをダウンロードして修正して導入する。
CIDRが192.168.0.0/16なのはデフォルトのまま変更しないで良いのだが、AzureがIP-in-IPに対応していないのでそれを無効にして、VXLANを使用する。
Switching from IP-in-IP to VXLAN
https://projectcalico.docs.tigera.io/getting-started/kubernetes/installation/config-options
あと、CPノードにcontrol-planeというtaintが追加されているので、そのtolerationを追加する。
# curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O
# vi calico.yaml
(4307行目あたり)
- name: CALICO_IPV4POOL_IPIP
value: "Never" # → "Always"から"Never"に修正。
(4310行目あたり)
- name: CALICO_IPV4POOL_VXLAN
value: "Always" # → "Never"から"Always"に修正。
(4489行目あたり)
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: node-role.kubernetes.io/control-plane # → 行追加
effect: NoSchedule # → 行追加
このファイル編集の機械化はちょっと辛いので、自動化したいなら編集済みのファイルをどこかに取っておくのかな。。
ファイル修正後、Calicoをインストール。
# export KUBECONFIG=/etc/kubernetes/admin.conf
# kubectl create -f calico.yaml
しばらくするとCalicoと、CoreDNSが起動してくる。
root@cp:~# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-75848c57cf-rbv4n 1/1 Running 0 35s
kube-system calico-node-6s5ng 1/1 Running 0 35s
kube-system coredns-6d4b75cb6d-cmnjr 1/1 Running 0 27m
kube-system coredns-6d4b75cb6d-hzdh5 1/1 Running 0 27m
kube-system etcd-cp 1/1 Running 0 27m
kube-system kube-apiserver-cp 1/1 Running 0 27m
kube-system kube-controller-manager-cp 1/1 Running 0 27m
kube-system kube-proxy-5l4h9 1/1 Running 0 27m
kube-system kube-scheduler-cp 1/1 Running 0 27m
Wrokerノードを追加する
kubeadmをインストールまでの実行するコマンドはCPノードと一緒。割愛。
kubeadm joinでクラスターに追加する。
# kubeadm join 10.0.0.6:6443 --token 5bwjtd.w2c2zfagwrewgal6 \
--discovery-token-ca-cert-hash sha256:a863b41e43c6fe8e8033193b927721d4099d9abf82f3cc9d5ffdf4a68e2bae04
2台のWorkerノードを追加してしばらく後、CPノードでノードを確認する。
root@cp:~# kubectl get node
NAME STATUS ROLES AGE VERSION
cp Ready control-plane 57m v1.24.0
wk1 Ready <none> 7m50s v1.24.0
wk2 Ready <none> 63s v1.24.0
Ingressコントローラーを追加する
とりあえず、コミュニティ提供版のNginx Ingressコントローラーで。
https://kubernetes.github.io/ingress-nginx/deploy/
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml
IngressコントローラーをhostPortで公開する。
# kubectl edit deploy -n ingress-nginx ingress-nginx-controller
(26行目ら辺)
replicas: 2 # → 1から2に修正
(92行目ら辺)
ports:
- containerPort: 80
name: http
protocol: TCP
hostPort: 80 # → 行追加
ingress-nginxをクラスターのデフォルトIngressコントローラーにする。
$ kubectl edit IngressClass nginx
(8行目ら辺)
annotations:
ingressclass.kubernetes.io/is-default-class: "true" # → 行追加
wk1、wk2でIngressコントローラーが動作しているのを確認。
root@cp:~# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-wclgf 0/1 Completed 0 6m41s 192.168.175.1 wk1 <none> <none>
ingress-nginx-admission-patch-zxgp7 0/1 Completed 1 6m41s 192.168.49.65 wk2 <none> <none>
ingress-nginx-controller-6997c4694b-84shm 1/1 Running 0 3m1s 192.168.49.66 wk2 <none> <none>
ingress-nginx-controller-6997c4694b-r9cf2 1/1 Running 0 30s 192.168.175.3 wk1 <none> <none>
Ingressの動作確認。
$ kubectl run httpd --image=httpd
$ kubectl expose pod/httpd --port=80
$ cat > httpd-ingress.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpd
spec:
rules:
- http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: httpd
port:
number: 80
EOF
$ kubectl create -f httpd-ingress.yaml
Azureでwk1とwk2の仮想マシンに80/tcpの通信を許可し、WebブラウザでそれらのPublic IPにアクセス。
良いんじゃないか。
一応、AzureのApplication Gateway経由でのIngressコントローラーアクセスも構成してみるが、WorkerノードのPublic IPをバックエンドプールに追加するのはOK。ただ、既存マシンのPrivate IPアドレス向けにリクエスト転送するやり方がわからない。。なんかちょっと癖を感じるというか、慣れないな。