介绍
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为例)的工作原理如下:
用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service
Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
到此为止,其实真正在工作的就是一个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 | apiVersion: apps/v1 |
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
# 生成证书 [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
创建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
用
https://
即可访问1
https://nginx.izheyi.com:31777/ https://tomcat.izheyi.com:31777/