さくらのクラウドのLBアプライアンスでk8sのingress controllerの負荷分散をする
さくらのクラウドの LB アプライアンスを使って k8s の ingress controller の負荷分散を行います。
さくらのクラウドの LB アプライアンスは DSR の LB なので、VIP のポートと実サーバーのポートは同一である必要があります。 k8s では Pod の公開を行う際、大抵 Type が LoadBalancer や NodePort な Service リソースを作成し公開を行います。 Type LoadBalancer が利用できない(から LB アプライアンスを利用する)ので NodePort が選択肢に上がりますが、NodePort はデフォルトで 30000~32767 に割り当てられます。 LB アプライアンスの仕様上 80 か 443 にしたいですが、NodePort ではできません。
そこで、今回は hostPort を利用して公開することにします。
hostPort を利用することで、Pod をホストのIP:port
で公開できるようになります。
Pod をホストのIP:port
で公開するため、Pod が存在しないノードの hostPort にアクセスしても Pod にはアクセス出来ないということに注意が必要です。
今回は、LB アプライアンスのヘルスチェックで Pod が存在するノードだけで負荷分散するようにし、Deployment でデプロイするパターンと DaemonSet でデプロイするパターンを試してみます。
構成
- control-plane: 1 台
- node: 3 台
- ingress-controller
- ingress-nginxを利用する
- Service ではなく hostPort 80/443 で公開する
作業ログ
k8s のデプロイ
以下のディレクトリで作業を行います。 ophum/kubenetes-practice-lab: ansible/
1ansible-playbook -i 02-hosts --become -u ubuntu kubespray/cluster.yml
以降 control-plane で作業を行います。 control-plane と各 node が Ready になっていることを確認します。
1root@control-plane-01:~# kubectl get node
2NAME STATUS ROLES AGE VERSION
3control-plane-01.test02.cloud.t-inagaki.net Ready control-plane 9m42s v1.29.2
4node-01.test02.cloud.t-inagaki.net Ready <none> 8m55s v1.29.2
5node-02.test02.cloud.t-inagaki.net Ready <none> 8m56s v1.29.2
6node-03.test02.cloud.t-inagaki.net Ready <none> 8m56s v1.29.2
helm をインストールします。
参考: https://helm.sh/ja/docs/intro/install/
1curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
2sudo apt-get install apt-transport-https --yes
3echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
4sudo apt-get update
5sudo apt-get install helm
helm で ingress-nginx をインストールします。
1# helm upgrade --install ingress-nginx ingress-nginx \
2 --repo https://kubernetes.github.io/ingress-nginx \
3 --namespace ingress-nginx --create-namespace \
4 --set controller.hostPort.enabled="true"
5Release "ingress-nginx" does not exist. Installing it now.
6NAME: ingress-nginx
7LAST DEPLOYED: Fri Mar 15 17:15:19 2024
8NAMESPACE: ingress-nginx
9STATUS: deployed
10REVISION: 1
11TEST SUITE: None
12NOTES:
13The ingress-nginx controller has been installed.
14It may take a few minutes for the load balancer IP to be available.
15You can watch the status by running 'kubectl get service --namespace ingress-nginx ingress-nginx-controller --output wide --watch'
controller が動作していることを確認します。 node-03 で動作していることがわかります。
1# kubectl get pods -n ingress-nginx -o wide
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3ingress-nginx-controller-6647957864-dgdn4 1/1 Running 0 2m46s 10.233.118.130 node-03.test02.cloud.t-inagaki.net <none> <none>
curl で ingress-controller にアクセスできることを確認します。
1# curl node-03.test02.cloud.t-inagaki.net
2<html>
3<head><title>404 Not Found</title></head>
4<body>
5<center><h1>404 Not Found</h1></center>
6<hr><center>nginx</center>
7</body>
8</html>
この時点での LB アプライアンスの実サーバーのステータスはこのようになります。
手元から VIP に curl してアクセスできることを確認します。
1$ curl app.test02.cloud.t-inagaki.net
2<html>
3<head><title>404 Not Found</title></head>
4<body>
5<center><h1>404 Not Found</h1></center>
6<hr><center>nginx</center>
7</body>
8</html>
今の状態では、ingress-controller が稼働しているのが node-03 の 1Pod だけになっているので、すべてのノードで Pod を動かして負荷分散できるようにします。
デフォルト設定では ingress-controller は Deployment でデプロイされます。 これを Daemonset にすることで各ノードで動かすことができます。
1# helm upgrade --install ingress-nginx ingress-nginx \
2 --repo https://kubernetes.github.io/ingress-nginx \
3 --namespace ingress-nginx \
4 --set controller.hostPort.enabled="true" \
5 --set controller.kind="DaemonSet"
6Release "ingress-nginx" has been upgraded. Happy Helming!
7NAME: ingress-nginx
8LAST DEPLOYED: Fri Mar 15 17:26:18 2024
9NAMESPACE: ingress-nginx
10STATUS: deployed
11REVISION: 2
12TEST SUITE: None
13NOTES:
14The ingress-nginx controller has been installed.
15It may take a few minutes for the load balancer IP to be available.
16You can watch the status by running 'kubectl get service --namespace ingress-nginx ingress-nginx-controller --output wide --watch'
各ノードで Pod が動作していることが確認できました。
1# kubectl get pods -n ingress-nginx -o wide
2NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3ingress-nginx-controller-tmq6q 1/1 Running 0 22s 10.233.82.131 node-01.test02.cloud.t-inagaki.net <none> <none>
4ingress-nginx-controller-vzw2l 1/1 Running 0 22s 10.233.118.132 node-03.test02.cloud.t-inagaki.net <none> <none>
5ingress-nginx-controller-zlt8b 1/1 Running 0 22s 10.233.103.3 node-02.test02.cloud.t-inagaki.net <none> <none>
LB アプライアンスの実サーバーの状態は以下のようになりました。
Web アプリを動かして ingress でアクセスしてみる
Ingress リソースでアクセスできることを確認してみます。 今回は GitBucket を動かしてみます。
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: gitbucket
5 namespace: default
6 labels:
7 app: gitbucket
8spec:
9 replicas: 1
10 selector:
11 matchLabels:
12 app: gitbucket
13 template:
14 metadata:
15 labels:
16 app: gitbucket
17 spec:
18 containers:
19 - name: gitbucket
20 image: ghcr.io/gitbucket/gitbucket
21 command:
22 - sh
23 - -c
24 - java -jar /opt/gitbucket.war --port=8080
25 ports:
26 - name: http
27 containerPort: 8080
28 protocol: TCP
29---
30apiVersion: v1
31kind: Service
32metadata:
33 name: gitbucket
34 namespace: default
35 labels:
36 app: gitbucket
37spec:
38 selector:
39 app: gitbucket
40 ports:
41 - protocol: TCP
42 port: 80
43 targetPort: 8080
44---
45apiVersion: networking.k8s.io/v1
46kind: Ingress
47metadata:
48 name: example
49 namespace: default
50 labels:
51 app: gitbucket
52spec:
53 ingressClassName: nginx
54 rules:
55 - host: app.test02.cloud.t-inagaki.net
56 http:
57 paths:
58 - path: /
59 pathType: Prefix
60 backend:
61 service:
62 name: gitbucket
63 port:
64 number: 80
デプロイします。
1# kubectl apply -f manifest.yaml
2deployment.apps/gitbucket created
3service/gitbucket created
4ingress.networking.k8s.io/example created
稼働していることを確認します。
1# kubectl get pods
2NAME READY STATUS RESTARTS AGE
3gitbucket-57b89d5bfc-6zqk2 1/1 Running 0 46s
4# kubectl get svc
5NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
6gitbucket ClusterIP 10.233.13.13 <none> 80/TCP 7m37s
7kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 59m
8# kubectl get ing
9NAME CLASS HOSTS ADDRESS PORTS AGE
10example nginx app.test02.cloud.t-inagaki.net 80 7m39s
Ingress で指定したホスト名でブラウザでアクセスできることを確認します。
おわり
以上、さくらのクラウドの LB アプライアンスで k8s の ingress controller を冗長化する方法でした。