K8s:Ingress

介绍

k8s 对外暴露服务(service)主要有两种方式:NotePort, LoadBalance, 此外externalIPs也可以使各类service对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持; 而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。

举个例子,现在集群有api、文件存储、前端3个service,可以通过一个ingress对象来实现图中的请求转发:

实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:

  • ingress:kubernetes中的一个对象,作用是定义请求如何转发到service的规则
  • ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx, Contour, Haproxy等等

Ingress(以Nginx为例)的工作原理如下:

  1. 用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service

  2. Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置

  3. Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新

  4. 到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则

Ingress的使用

环境搭建
1
[root@master ~]# mkdir ingress
[root@master ~]# cd ingress

[root@master ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
--2021-10-19 11:11:40--  https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.109.133, 185.199.111.133, ...
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:6635 (6.5K) [text/plain]
正在保存至: “mandatory.yaml”

[root@master ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
--2021-10-19 11:11:55--  https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.110.133, ...
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:471 [text/plain]
正在保存至: “service-nodeport.yaml”

[root@master ingress]# ls
mandatory.yaml  service-nodeport.yaml
[root@master ingress]# kubectl apply -f ./
namespace/ingress-nginx created
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
service/ingress-nginx created

[root@master ingress]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS              RESTARTS   AGE
nginx-ingress-controller-7f74f657bd-q5zwf   0/1     Running              0          16s
[root@master ingress]# kubectl get pod,svc -n ingress-nginx
NAME                                            READY   STATUS              RESTARTS   AGE
pod/nginx-ingress-controller-7f74f657bd-q5zwf   0/1     ContainerCreating   0          31s

NAME                    TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx   NodePort   10.106.103.131   <none>        80:32635/TCP,443:31777/TCP   31s
Service和Pod

创建tomcat-nginx.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: tomcat-pod
template:
metadata:
labels:
app: tomcat-pod
spec:
containers:
- name: tomcat
image: tomcat:8.5-jre10-slim
ports:
- containerPort: 8080

---

apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: None
type: ClusterIP
ports:
- port: 80
targetPort: 80

---

apiVersion: v1
kind: Service
metadata:
name: tomcat-service
namespace: dev
spec:
selector:
app: tomcat-pod
clusterIP: None
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
1
[root@master ingress]# kubectl create -f tomcat-nginx.yaml
deployment.apps/nginx-deployment created
deployment.apps/tomcat-deployment created
service/nginx-service created
service/tomcat-service created

[root@master ingress]# kubectl get pod,svc -n dev
NAME                                     READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-6696798b78-4z9h9    1/1     Running   0          3m45s
pod/nginx-deployment-6696798b78-n2ff8    1/1     Running   0          3m45s
pod/nginx-deployment-6696798b78-xbnjh    1/1     Running   0          3m45s
pod/tomcat-deployment-58467d5474-4t275   1/1     Running   0          3m45s
pod/tomcat-deployment-58467d5474-c6cst   1/1     Running   0          3m45s
pod/tomcat-deployment-58467d5474-mrpww   1/1     Running   0          3m45s

NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/nginx-service    ClusterIP   None             <none>        80/TCP         3m45s
service/tomcat-service   ClusterIP   None             <none>        8080/TCP       3m45s
HTTP代理

创建ingress-http.yaml

1
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-http
  namespace: dev
spec:
  rules:
  - host: nginx.izheyi.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service
          servicePort: 80
  - host: tomcat.izheyi.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat-service
          servicePort: 8080
1
[root@master ingress]# kubectl create -f ingress-http.yaml 
ingress.extensions/ingress-http created

[root@master ingress]# kubectl get ing ingress-http -n dev
NAME           HOSTS                                ADDRESS   PORTS   AGE
ingress-http   nginx.izheyi.com,tomcat.izheyi.com             80      5s

[root@master ingress]# kubectl describe ing ingress-http  -n dev
Name:             ingress-http
Namespace:        dev
Address:          
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host               Path  Backends
  ----               ----  --------
  nginx.izheyi.com   
                     /   nginx-service:80 (10.244.1.20:80,10.244.1.21:80,10.244.2.26:80)
  tomcat.izheyi.com  
                     /   tomcat-service:8080 (10.244.1.22:8080,10.244.2.24:8080,10.244.2.25:8080)
Annotations:
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  27s   nginx-ingress-controller  Ingress dev/ingress-http

增加Hosts

1
192.168.36.10 nginx.izheyi.com
192.168.36.10 tomcat.izheyi.com
1
[root@master ~]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.106.103.131   <none>        80:32635/TCP,443:31777/TCP   124m

HTTPS代理
  1. 创建证书

    1
    # 生成证书
    [root@master ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=izhey.com"
    Generating a 2048 bit RSA private key
    ..........................................................+++
    ..................................................................................................................................+++
    writing new private key to 'tls.key'
    -----
    
    # 创建密钥
    [root@master ~]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
    secret/tls-secret created
  1. 创建ingress-https.yaml

    1
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress-https
      namespace: dev
    spec:
      tls:
        - hosts:
          - nginx.itheima.com
          - tomcat.itheima.com
          secretName: tls-secret # 指定秘钥
      rules:
      - host: nginx.izheyi.com
        http:
          paths:
          - path: /
            backend:
              serviceName: nginx-service
              servicePort: 80
      - host: tomcat.izheyi.com
        http:
          paths:
          - path: /
            backend:
              serviceName: tomcat-service
              servicePort: 8080
    1
    [root@master ~]# kubectl create -f ingress-https.yaml
    ingress.extensions/ingress-https created
    [root@master ~]# kubectl get ing ingress-https -n dev
    NAME            HOSTS                                ADDRESS   PORTS     AGE
    ingress-https   nginx.izheyi.com,tomcat.izheyi.com             80, 443   11s
    [root@master ~]# kubectl describe ing ingress-https -n dev
    Name:             ingress-https
    Namespace:        dev
    Address:          10.106.103.131
    Default backend:  default-http-backend:80 (<none>)
    TLS:
      tls-secret terminates nginx.itheima.com,tomcat.itheima.com
    Rules:
      Host               Path  Backends
      ----               ----  --------
      nginx.izheyi.com   
                         /   nginx-service:80 (10.244.1.20:80,10.244.1.21:80,10.244.2.26:80)
      tomcat.izheyi.com  
                         /   tomcat-service:8080 (10.244.1.22:8080,10.244.2.24:8080,10.244.2.25:8080)
    Annotations:
    Events:
      Type    Reason  Age   From                      Message
      ----    ------  ----  ----                      -------
      Normal  CREATE  25s   nginx-ingress-controller  Ingress dev/ingress-https
      Normal  UPDATE  3s    nginx-ingress-controller  Ingress dev/ingress-https
    1
    [root@master ~]# kubectl get svc -n ingress-nginx
    NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx   NodePort   10.106.103.131   <none>        80:32635/TCP,443:31777/TCP   148m
  2. https://即可访问

    1
    https://nginx.izheyi.com:31777/
    
    https://tomcat.izheyi.com:31777/
唐胡璐 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
分享创造价值,您的支持将鼓励我继续前行!