什么是Ingress
阿里云称之为ingress路由!在Kubernetes集群中,主要用于接入外部请求到k8s内部,Ingress是授权入站连接到达集群服务的规则集合,为您提供七层负载均衡能力。您可以给 Ingress 配置提供外部可访问的URL、负载均衡、SSL、基于名称的虚拟主机等。
Service缺点
定义service以后,尤其是NodePort集群访问,需要经过2级转换调度,而且是4层调度,无论是iptables还是ipvs。4调度自身无法实现卸载https会话。
ingress----k8s还有一种引入集群外部流量的方式,叫ingress。基于7层调度器。利用7层pod,将外部流量引入到内部。
回顾-Service:
工作三种方式模型:
- userspace(效率低、各种空间转换)
- iptables
- ipvs (1.11版之后,部署时需要额外配置先关参数)
Service集群类型:
- ClusterIP (集群内部通信)
- NodePort (集群内外互通,工作逻辑:client-->nodeip:nodeport-->clusterip:serviceip--->podiip:containerport),可以在前面加个nginx,代理后端各个nodeport的时候,压力得到释放。
- LoadBalancer
- ExternerName
Ingress支持的调度方式
- url路径映射调度: location /aa ; location /bb。可以参考nginx。
- 主机调度:l例如server aaa; server bbb
Ingress类型:
- url映射
- 虚拟主机
Ingress-controller: (提供特定功能的pod,nginx-ingress-controller-pod):提供接入外部流量的特定pod。例如有3个节点,在这3个节点打上污点,在每个上面运行特定的daemonset pod,实现外部流量接入,为后面pod提供7层调度。众多控制器都是master节点的controllermanager的子件运行的。而ingree controller自己独立运行,通常是一组pod资源。具有7层代理功能。
支持的代理工具: nginx、Traefik、Evoy(微服务)、HAproxy
watch: Service始终watch着后端pod变化。只要pod发生变化,api-server立刻检测到
Ingress实现原理
- 正常是用service去调度后面的适配label的pods,当pods增加,因为有labels,会自动识别后端添加的pods,如果用nginx怎么实现?把nginx运行在pod里面,配置文件在pod内部。这种pod叫ingress controller随时观察着后端的pod的改变。ingress controler自己没有这种能力,借助于service去实现。所以nginx-ingress-controller后端还得建立service。这种service仅仅帮忙分类后端的pods资源。pods的配置在nignx里upstream面。service不会进行调度,仅仅分组。因此可以使用headless service,直接调度至后端pods。关键pods变化,怎么自动nginx的upstream以及其他配置,这种就通过ingress路由实现!
- ingress需要建一个前端接入层,前端有可能是虚拟主机nginx配置的server,或者是location url映射,同时也要定义一个后端upstream-server。 upstream有几个主机。通过service来获取的。
- ingress有个特点:作为资源来讲,直接通过编辑注入到nginx-ingress-controller,并保存为nginx的配置文件。而且ingress一旦发现service 后端的pods改变,ingress直接注入更新nginx配置文件,而且需要重载配置文件(traefik支持自动重载)。
实现ingress步骤(7层调度):
- 部署一个nginx-ingress-controller-pod。部署一个特殊pod。
- 给nginx-ingress-controller-pod创建前端service1。用来接入外部请求!
- 创建nginx-ingress-controller-pod后端service2,以及service关联的pods。
- 创建ingress、自动实现路由规则,自动实现service2自动注入到nginx-ingress-controller-pod规则(nginx.conf)
- 总结就是首先部署外部请求<------ingress-service<-----nginx-ingress-controller-pod<--------ingress<------service(headless、daemonset)<------pods
Ingress原理图
原理:外部负载均衡器externalLB请求调至到 nodeport 里面service服务--->调度到内部pod(ingress controller里面)----->根据ingree定义,是虚拟主机,还是url代理---->假设是主机名,一组主机名对应后端的pod资源pod1,pod2,pod3。pod怎么分组通过service进行分组。才能被ingress引用。
先安装ingress controller pod。然后定义ingress。再定义pod生成service。
动态生效:pod一变化,service就变化,service一变化,ingress就变化,ingreess一变化就注入到ingress controller里面。实时动态。
部署Ingress-Nginx
git地址:https://github.com/kubernetes/Ingress-nginx
官方网站:https://kubernetes.github.io/ingress-nginx
安装
//下载ingress-nginx yaml初始化安装模板
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.33.0/deploy/static/provider/cloud/deploy.yaml
//编辑文件修改Controller的下载地址到国内
vim deploy.yaml
containers:
- name: controller
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.33.0
imagePullPolicy: IfNotPresent
//使用kubectl apply安装
kubectl apply -f deploy.yaml
//ingress默认安装在ingress-nginx名称空间内
[root@k8s-master ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-45qcs 0/1 Completed 0 4m12s
ingress-nginx-admission-patch-z52jg 0/1 Completed 1 4m12s
ingress-nginx-controller-5858f5cdf8-kxfwm 1/1 Running 0 4m12s
通过nodeport方式暴露ingress
//官网下载所需要的yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.33.0/deploy/static/provider/baremetal/deploy.yaml
mv deploy.yaml service-nodeport.yaml
//修改Controller的下载地址到国内。同ingress-controller
//安装
kubectl apply -f service-nodeport.yaml
//查看结果
kubectl get svc -n ingress-nginx
[root@k8s-master ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.103.86.19 <none> 80:30367/TCP,443:30621/TCP 21m
ingress-nginx-controller-admission ClusterIP 10.103.210.91 <none> 443/TCP 21m
创建http的 nginx-ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress // name
spec:
rules:
- host: www.xhyan.com //domain
http:
paths:
- path: / //path
backend:
serviceName: ngx-svc //svc name
servicePort: 80 //svc port
创建的ingress规则生成对应的nginx配置嵌入到nginx-controller中
通过进入ingress controller容器中查看
//查看ingress-controllerpod名称
[root@k8s-master ingress]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-45qcs 0/1 Completed 0 101m
ingress-nginx-admission-patch-z52jg 0/1 Completed 1 101m
ingress-nginx-controller-6995cf966b-qs8rc 1/1 Running 0 80m
//进入容器
[root@k8s-master ingress]# kubectl exec -it ingress-nginx-controller-6995cf966b-qs8rc -n ingress-nginx -- /bin/bash
//容器中查看配置
bash-5.0$cat nginx.conf
创建https的 nginx-ingress
- 将申请好的https证书放在指定目录
- 通过kubectl create secret将证书加入到ingress中
//kubectl create secret将证书加入到ingress中
kubectl create tls tls-secret --key tls.key --cert tls.crt //证书名为tls-secret
//https ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress // name
spec:
tls:
- hosts:
- www.xhyan.com
secretName: tls-secret //对应kubectl create创建的tls证书名称
rules:
- host: www.xhyan.com //domain
http:
paths:
- path: / //path
backend:
serviceName: ngx-svc //svc name
servicePort: 80 //svc port
更新Ingress
假如你想要向已有的ingress中增加一个新的Host,你可以编辑和更新该ingress:
$ kubectl get ing
NAME RULE BACKEND ADDRESS
test - 178.91.123.132
foo.bar.com
/foo s1:80
$ kubectl edit ing test //使用kubectl edit更新
//这会弹出一个包含已有的yaml文件的编辑器,修改它,增加新的Host配置。
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: s1
servicePort: 80
path: /foo
- host: bar.baz.com
http:
paths:
- backend:
serviceName: s2
servicePort: 80
path: /foo
..
保存它会更新API server中的资源,会触发ingress controller重新配置loadbalancer。
$ kubectl get ing
NAME RULE BACKEND ADDRESS
test - 178.91.123.132
foo.bar.com
/foo s1:80
bar.baz.com
/foo s2:80
在一个修改过的ingress yaml文件上调用kubectl replace -f命令一样可以达到同样的效果。