Kubernetes资源管理之Ingress
1、概述
Service是四层调度器,无论是Iptable还是ipvs,都是工作在TCP/IP协议栈上。在生产环境中,提供的站点多为HTTPS请求,而后端多为HTTP服务
1.1、Service调度网络的缺陷:
基本的Service模式如下图,如果使用工作在四层的Service作为调度器,证书应该放置在何处?会话应该如何保持?https证书如何卸载?

1.2、解决缺陷的方案
1.2.1、解决方案一:
可以在集群中增加一个独立的Pod作为七层代理使用,比如Nginx。如下图

上述方式,用户在集群外发起请求后,通过LoadBanacer转发至K8s集群中的节点,节点上NodePort接收到请求,将服务转发至七层代理的Service,Service收到后将请求转发至七层代理Nginx,Nginx进行证书卸载再将请求转发至后端的Service,Service再转发至后端服务器。为了实现一个功能,增加了4层转发,效率极差。
1.2.2、解决方案二:
在节点上运行的容器可以使用自己的虚拟网络,但也可以共享宿主机的网络名称空间,如果使用宿主机的网络就相当于将端口直接监听在宿主机上。因此,在方案一的基础上,将Nginx Pod直接运行为共享模式。

此方案中,因为Nginx Pod运行为共享模式,因此在节点上只能运行一个服务,客户端访问也只能访问这一个节点,则会出现单点。
1.2.3、解决方案三:
为了防止出现单点,可以使用K8s中的DamonSet控制器,来在每一个节点上创建一个代理Pod。

上述这种方式就是Ingress Controller,详细调用方式如下图:

- ingress:K8s中的一个抽象资源,给管理员提供一个暴露应用的入口定义方法。
- ingress Controller:根据ingress生成具体的路由规则,为集群提供全局的负载均衡能力。ingress Controller本质上是一个DaemonSet的Pod,因此实现的方式有多种,可以基于Nginx、Haproxy等实现负载均衡。
2、Ingress使用流程
Ingress Crontroller通过与K8s API交互,动态感知集群中Ingress规则变化,根据规则生成Nginx配置,应用到管理的Nginx Pod中,然后热加载生效。
2.1、部署ingress crontroller
在K8s官网选择适合的Crontroller,https://kubernetes.io/zh/docs/concepts/services-networking/ingress-controllers/
$ kubectl apply -f ingress-controller.yaml$ kubectl get pods -n ingress-nginx -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-ingress-controller-k9c8k 1/1 Running 0 11m 10.211.55.103 k8s-slave2 <none> <none>nginx-ingress-controller-x2mpw 1/1 Running 0 11m 10.211.55.102 k8s-slave1 <none> <none>
2.2、创建基于HTTP转发的ingress规则
- 创建规则之前先准备一组deployment的Pod和关联的service资源
$ kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/webdepoyment-78cff8f5f7-2jc52 1/1 Running 0 3h20m
pod/webdepoyment-78cff8f5f7-2xhgc 1/1 Running 0 3h20m
pod/webdepoyment-78cff8f5f7-cdt8l 1/1 Running 0 3h20m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/web-service NodePort 10.105.144.52 <none> 80:30080/TCP 3h20m
- 创建的规则为使用web.test.com域名转发到web-service中。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webingress
spec:
rules:
- host: web.test.com # 域名
http:
paths:
- path: / # 转发规则,nginx中的location
pathType: Prefix
backend: # 后端服务
service:
name: web-service # service名称
port:
number: 80 # 监听端口
- 查看ingress规则
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
webingress <none> web.test.com 80 8s
- 添加hosts文件
# 在client上绑定hosts文件
10.211.55.102 web.test.com
10.211.55.103 web.test.com
使用浏览器访问web.test.com即可。
2.3、创建基于HTTPs的Ingress规则
准备证书文件,可以自建证书或者申请权威证书。
将证书保存到K8s集群secret中。
$ kubectl create secret tls web-test-com --cert=web.test.com.pem --key=web.test.com-key.pem
secret/web-test-com created
$ kubectl get secret
NAME TYPE DATA AGE
default-token-hx8bm kubernetes.io/service-account-token 3 5h51m
web-test-com kubernetes.io/tls 2 11s
- 创建Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webingress
spec:
tls: # 添加此段配置
- hosts:
- web.test.com # 域名
secretName: web-test-com # 指定secret名称
rules:
- host: web.test.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
- 查看ingress规则
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
webingress <none> web.test.com 80, 443 19m
# PORTS处可以看到多监听了443端口。
