确认[Kubernetes]的ingress功能是否正常

首先

这次我想要确认一下Ingress的运作。Ingress可以简单说是L7层的负载均衡器。
虽然与在L4层进行负载均衡的LoadBalancer服务相似,但严格来说,Ingress并不是一个服务,而是一个独立的”Ingress”资源。
值得注意的是,在当前最新的V1.18版本中,它仍然是一个Beta版。

kubernetes.io改名为Ingress。

准备之前的事项

创建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
---

我会申请这个宣言。

$ 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

我将应用此宣言。

$ 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进行定义的。还可以选择性地设置主机名。另外,最好也设置一个默认的后端。

Ingress资源 -> Ingress规则、默认的后端

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

我会提交这个宣言书。

$ 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控制器默认部署,所以以后不再需要(未确认)。
但是,这次是在本地部署(而且是在个人电脑上,而且是虚拟机),所以我们将使用Nginx Ingress。

NGINX入口控制器 -> 安装指南

请按照「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

我会确认。 (Wǒ huì .)

$ 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

你回答得很好嘛。 (Nǐ dé .)

总结

我已经确认了设置和操作,但由于多年来只做过低层次的基础结构,对L7层的运作还不太理解。
在这里纠结也没有意义,所以我打算先继续前进,然后再重新确认一次。

bannerAds