こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
前回Helmを使ってMetalLBをデプロイ。LoadBalancerを使える環境を構築し、実際に使ってみました。
今回はIngress-nginxをこの環境にデプロイし、使ってみたいと思います。
用語
Ingressとは?
Ingressはクラスター外からクラスター内ServiceへのHTTPとHTTPSのルートを公開します。トラフィックのルーティングはIngressリソース上で定義されるルールによって制御されます。
Ingress-nginxとは?
おそらく様々な種類のあるIngressの中の1つの種類という認識でいいかと思います。
他にもHAProxy IngressとかIstio Ingress等様々ありそうです。
構築イメージ
今回構築する環境は以下となります。ingress-nginx namespace上にingressに必要な環境をHelmを使ってデプロイ。wp namespace上にあったWordpress用のLoadbalancerを削除し、新しくClusterIPをデプロイ。さらにIngressを同namespaceにデプロイし、デプロイ時にWordpressのClusterIPと紐づけることでIngress経由でWordpressにアクセスしたいと思います。
構築
Ingress-nginxをHelmを作ってデプロイ
以下のサイトを参考に環境を作っていきます。
まず、ingress-nginx namespaceを作成します。
root@k8s-master:~# kubectl create ns ingress-nginx
namespace/ingress-nginx created
root@k8s-master:~# kubectl get ns
NAME STATUS AGE
default Active 21d
ingress-nginx Active 5s
kube-node-lease Active 21d
kube-public Active 21d
kube-system Active 21d
metal-lb Active 135m
observability Active 7d7h
wp Active 135m
上記Webサイトに記載されているコマンドを実行してデプロイします。NOTEより下に色々書かれていますが、いったん気にしないで問題ありません。
root@k8s-master:~# helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
Release "ingress-nginx" does not exist. Installing it now.
NAME: ingress-nginx
LAST DEPLOYED: Sat Jul 1 16:16:50 2023
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller'
An example Ingress that makes use of the controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: foo
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- pathType: Prefix
backend:
service:
name: exampleService
port:
number: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- www.example.com
secretName: example-tls
If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls
helm lsでデプロイされているか確認します。
root@k8s-master:~# helm ls -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
ingress-nginx ingress-nginx 1 2023-07-01 16:16:50.572819104 +0000 UTC deployed ingress-nginx-4.7.1 1.8.1
metallb metal-lb 1 2023-07-01 14:01:52.7948106 +0000 UTC deployed metallb-0.13.10 v0.13.10
nginx-ingress namespaceのpodやserviceを確認します。
デプロイに問題はなさそうに見えます。LoadBalancerがデプロイされていることから、Ingress環境を作る前段階としてMetalLB環境を作っておく必要がありそうです。
※最も回避する方法もありそうではありますが。
root@k8s-master:~# kubectl get pod,svc -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-controller-5fcb5746fc-96lhp 1/1 Running 0 78s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 10.111.144.184 192.168.2.46 80:32147/TCP,443:31546/TCP 78s
service/ingress-nginx-controller-admission ClusterIP 10.96.215.248 <none> 443/TCP 78s
WordpressのLoadbalancerを削除しClusterIPを用意する
以下のコマンドを実行して既にデプロイされていたWordpressのLoadBalancerを削除しました。
root@k8s-master:~/yaml/wp# kubectl delete -f wordpress-loadbalancer.yaml
service "wordpress-loadbalancer" deleted
次にIngressと連携するためのClusterIPのデプロイをしていきます。
今回用意したyamlは以下となります。
apiVersion: v1
kind: Service
metadata:
name: wordpress-clusterip
namespace: wp
spec:
selector:
app: wordpress
type: ClusterIP
ports:
- name: wordpress
port: 80
protocol: TCP
targetPort: 80
デプロイします。
root@k8s-master:~/yaml/wp# kubectl apply -f wordpress-clusterip.yaml
service/wordpress-clusterip created
ingressをデプロイする
以下のyamlを用意しました。アクセスしたいpod(ClusterIP)と同じnamespace上にデプロイされるように気を付けましょう。pathに"/"に指定していることから、IPアドレス後に何も入力をしないとWorpressのClusterIPに処理を投げるような処理を行います。
PythonのDjangoをやっている方であれば、あれのurls.pyをイメージいただけると近いのかと思います。またJavaのSprinBootをやっている方であればRestControllerが近いように感じます。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wp-pod-ingress
namespace: wp
spec:
ingressClassName: "nginx"
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wordpress-clusterip
port:
number: 80
デプロイします。
root@k8s-master:~/yaml/ingress# kubectl apply -f wp-pod-ingress.yaml
ingress.networking.k8s.io/wp-pod-ingress created
実行結果を確認します。ingressにあたっているIPアドレスは後で接続確認で使用します。
root@k8s-master:~/yaml/ingress# kubectl get pod,svc,ingress -n wp -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/mysql-pod 1/1 Running 0 170m 172.16.69.207 k8s-worker02 <none> <none>
pod/wordpress-pod 1/1 Running 0 170m 172.16.39.209 k8s-worker03 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/mysql-clusterip ClusterIP 10.96.152.58 <none> 3306/TCP 170m app=mysql
service/wordpress-clusterip ClusterIP 10.104.178.189 <none> 80/TCP 30m app=wordpress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/wp-pod-ingress nginx * 192.168.2.46 80 6m45s
root@k8s-master:~/yaml/ingress# kubectl describe ingress -n wp wp-pod-ingress
Name: wp-pod-ingress
Labels: <none>
Namespace: wp
Address: 192.168.2.46
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
*
/ wordpress-clusterip:80 (172.16.39.209:80)
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 2m29s (x2 over 3m14s) nginx-ingress-controller Scheduled for sync