はじめに
今回はIngressの動作を確認したいと思います。Ingressは一言で言うとL7レイヤーのロードバランサ―です。
L4レイヤーでバランシングするLoadBalancerサービスと似ていますが、厳密にはサービスではなく、独立した「Ingress」リソースです。
なお、現時点で最新のV1.18では、まだBeta版になっています。
事前準備
Podの作成
Ingressの動作確認用に以下のPod(Deployment)を作成します。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx0
spec:
replicas: 2
selector:
matchLabels:
app: nginx-dep0
template:
metadata:
labels:
app: nginx-dep0
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
spec:
replicas: 2
selector:
matchLabels:
app: nginx-dep1
template:
metadata:
labels:
app: nginx-dep1
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx2
spec:
replicas: 2
selector:
matchLabels:
app: nginx-dep2
template:
metadata:
labels:
app: nginx-dep2
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
このマニフェストをapplyします。
$ kubectl apply -f deployment.yaml
deployment.apps/nginx0 created
deployment.apps/nginx1 created
deployment.apps/nginx2 created
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx0-8466d57dbc-cndw8 1/1 Running 0 43s 192.168.79.124 k8s-worker01 <none> <none>
nginx0-8466d57dbc-pdpxn 1/1 Running 0 43s 192.168.69.215 k8s-worker02 <none> <none>
nginx1-68d8c5cc6d-fsmt7 1/1 Running 0 43s 192.168.69.210 k8s-worker02 <none> <none>
nginx1-68d8c5cc6d-sbcwp 1/1 Running 0 43s 192.168.79.120 k8s-worker01 <none> <none>
nginx2-55f9dc64d5-lqq8w 1/1 Running 0 43s 192.168.69.214 k8s-worker02 <none> <none>
nginx2-55f9dc64d5-rr25f 1/1 Running 0 43s 192.168.79.122 k8s-worker01 <none> <none>
Podに目印をつける
動作確認用にindex.htmlファイルを作成して、それぞれ「nginx0」「nginx1」「nginx2」を記載しておきます。
「nginx1」と「nginx2」はそれぞれ下位のディレクトリ配下に作成します。
## nginx0
$ kubectl exec -it nginx0-8466d57dbc-cndw8 /bin/bash
# echo nginx0 > /usr/share/nginx/html/index.html
# exit
## nginx1
$ kubectl exec -it nginx1-68d8c5cc6d-fsmt7 /bin/bash
# mkdir /usr/share/nginx/html/path1
# echo nginx1 >/usr/share/nginx/html/path1/index.html
# exit
## nginx2
$ kubectl exec -it nginx2-55f9dc64d5-lqq8w /bin/bash
# mkdir /usr/share/nginx/html/path2
# echo nginx2 >/usr/share/nginx/html/path2/index.html
# exit
NodePortの作成
IngressのバックエンドとなるNodePortを作成します。各Pod(Deployment)に対して作成します。
---
apiVersion: v1
kind: Service
metadata:
name: node-port0
spec:
type: NodePort
ports:
- name: node-port
protocol: TCP
port: 8080
targetPort: 80
nodePort: 30010
selector:
app: nginx-dep0
---
apiVersion: v1
kind: Service
metadata:
name: node-port1
spec:
type: NodePort
ports:
- name: node-port
protocol: TCP
port: 8080
targetPort: 80
nodePort: 30011
selector:
app: nginx-dep1
---
apiVersion: v1
kind: Service
metadata:
name: node-port2
spec:
type: NodePort
ports:
- name: node-port
protocol: TCP
port: 8080
targetPort: 80
nodePort: 30012
selector:
app: nginx-dep2
このマニフェストをapplyします。
$ kubectl apply -f nodePort.yaml
service/node-port0 created
service/node-port1 created
service/node-port2 created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 48d
node-port0 NodePort 10.103.174.12 <none> 8080:30010/TCP 6s
node-port1 NodePort 10.104.244.161 <none> 8080:30011/TCP 6s
node-port2 NodePort 10.102.124.27 <none> 8080:30012/TCP 6s
Ingressリソースの作成
ここまでで準備ができましたので、Ingressを作成していきます。
Ingressを使用するには、「Ingressリソース」と「Ingressコントローラ」が必要になります。
マニフェストには、リクエストパスのリストが必要になります。パスに対してserviceNameとservicePortで定義されるバックエンドが関連づけられます。オプションでホスト名も設定できます。
また、デフォルトのバックエンドも設定しておいた方がよいでしょう。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: sample-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /path1
backend:
serviceName: node-port1
servicePort: 8080
- path: /path2
backend:
serviceName: node-port2
servicePort: 8080
backend:
serviceName: node-port0
servicePort: 8080
このマニフェストをapplyします。
$ kubectl apply -f sampleIngress.yaml
ingress.networking.k8s.io/simple-ingress created
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
sample-ingress foo.bar.com 80 10s
この時点では、「ADDRESS」は空白になっています。
Ingressコントローラのインストール
GKEだとIngressコントローラがデフォルトでデプロイされているらしいので、以降は不要になります。(未確認)
が、今回はオンプレ(しかもPC、しかもVM)ですので、Nginx Ingressを使用します。
「Docker for Mac」の手順でインストールしていきます。
※前提として、MetalLBがインストール済みである必要があります。
MetalLBのインストール手順はこちらを参照してください。
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
namespace/ingress-nginx configured
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/cloud-generic.yaml
service/ingress-nginx created
確認します。
$ kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx LoadBalancer 10.102.172.38 10.20.30.150 80:31001/TCP,443:32326/TCP 39s
$ kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-7f74f657bd-8l8c6 1/1 Running 0 21m
Ingressコントローラがインストールされると、IngressリソースのADDRESSにIPアドレスが表示されます。
$ kubectl get ingresses.
NAME HOSTS ADDRESS PORTS AGE
simple-ingress foo.bar.com 10.20.30.150 80 84m
動作確認
gatewayからリクエストを送って、レスポンスを確認します。
$ curl http://10.20.30.150/path1/index.html -H 'Host: foo.bar.com'
nginx1
$ curl http://10.20.30.150/path2/index.html -H 'Host: foo.bar.com'
nginx2
$ curl http://10.20.30.150/ -H 'Host: foo.bar.com'
nginx0
ちゃんと返ってきてますね。
まとめ
設定と動作の確認はできましたが、長年インフラの低いレイヤーしかやってませんので、L7レイヤーの動きがどうも理解できません。
ここで悩んでてもしょうがないので、先に行ってからもう一度確認してみたいと思います。