Ingress简介
ingress是k8s中的一个七层的负载均衡,可以把流量路由到service。
如果没有ingress,我们可以通过外部的nginx、haproxy等也可以实现七层负载均衡,但是配置nginx比较麻烦,因为想要配置nginx的upstream必须先查询service的ip,那如果使用service的name,还要维护一个dns;如果想要换成haproxy,成本也比较高。而有了ingress,实际上就是把nginx等七层负载均衡集成到了k8s中,配置就更加简单也更加通用。
它的工作原理是ingress服务作为流量的入口,收到请求后,根据host、path等规则,匹配到对应的service和端口,然后把流量转发到service的端口,service再转发流量给pod。
参考文档:
安装Ingress Controller
本节中,我们使用helm在K8S集群中安装Ingress NGINX Controller。
参考文档:
- Set up Ingress on Minikube with the NGINX Ingress Controller
- Ingress NGINX Controller
- Ingress NGINX Controller - Installation Guide
- 使用Helm安装Ingress-nginx
官方推荐一键安装:
1 | helm upgrade --install ingress-nginx ingress-nginx \ |
因为郝同学喜欢安装指定版本,并且对配置做一些了解,因此本节使用稍微麻烦一点的方式。
1、添加chart仓库
1 | helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx |
2、导出配置,chart4.1.4 对应 app1.2.1
1 | helm search repo ingress-nginx/ingress-nginx -l |
3、修改配置
values-4.1.4.yaml按需修改,这里主要修改一下镜像:
- controller.image.registry ,改为
registry.cn-hangzhou.aliyuncs.com
- controller.image.image,改为
google_containers/nginx-ingress-controller
- controller.image.tag,保持不变
v1.2.1
- 注释掉 controller.image.digest 和 controller.image.digestChroot
4、安装ingress nginx controller
1 | kubectl create ns ingress-nginx |
5、查看安装
1 | kubectl get all -n ingress-nginx |
KS中的Ingress Controller
如果k8s集群中安装了kubesphere,那么可以直接启用kubesphere的网关,本质也是ingress nginx controller。
开启办法:admin用户登录控制台,集群设置,网关设置,启用网关。
参考文档:
配置Ingress
参考文档:
Ingress Controller配置
可以认为Ingress Controller就是一个K8S内部的Nginx。
查看 Ingress Controller 的 service 配置,找到80和433端口对应的NodePort,用于访问Nginx。
假设一个节点IP为192.168.56.102,service的80端口对应30490,443端口对应30499。
创建测试服务
1、创建测试服务(Nginx)
1 | kubectl create deployment test --image=nginx --dry-run=client -oyaml > deployment.yaml |
2、查看测试服务
1 | kubectl get pods |
创建Ingress
1、准备 minimal-ingress.yaml
1 | apiVersion: networking.k8s.io/v1 |
其中,ingressClassName可以省略,省略后会使用默认的ingressClass。
因为配置了rewrite-target,所以请求到达service时,/testpath
会被替换为/
。
2、创建ingress
1 | kubectl apply -f minimal-ingress.yaml |
3、通过ingress controller访问测试服务
1 | curl 192.168.56.102:30490/testpath |
访问链路为:ip+port(ingress) -> nginx service
多个Ingress Controller
怎样在k8s集群中配置多个Ingress Controller?
答:多个Ingress Controller的--controller-class
和--ingress-class
设置成不同的值。
如果k8s集群中存在多个Ingress Controller,哪个会生效呢?
答:在Ingress的spec中指定ingressClassName
,或者在Ingress的annotations中指定kubernetes.io/ingress.class
(即将废弃)。
如果不指定,那么将会使用默认的ingressClass,默认的ingressClass中会包含一个annotations:
1 | annotations: |
Ingress NGINX Controller的--controller-class
默认值为k8s.io/ingress-nginx
,--ingress-class
的默认值为nginx
。
参考文档:
- Ingress
- Default IngressClass
- Multiple Ingress controllers
- kubernetes部署多个ingress controller(ingress controller分组部署)实践
- 部署多个Ingress Controller
- 同一kubernetes部署多个Nginx Ingress Controller
常用Ingress配置
支持websocket
推荐方法:
1 | apiVersion: networking.k8s.io/v1 |
参考文档:
- ingress-nginx Websockets
- ingress-nginx Annotations
- Advanced Configuration with Annotations
- WebSocket support
历史方法:
1 | apiVersion: networking.k8s.io/v1 |
域名证书配置
普通域名配置证书
1、创建secret
1 | kubectl create secret tls cert \ |
1 | apiVersion: v1 |
其中,tls.crt是base64加密后的证书,tls.key是base64加密后的key。
2、ingress添加tls定义
1 | spec: |
泛域名配置证书
泛域名的证书配置方法,和普通域名的证书配置方法完全一致。
1 | spec: |
参考文档:
多个域名配置泛域名证书
多个域名使用同一个泛域名证书,建议集中配置泛域名证书。
1、域名证书配置
1 | spec: |
2、路由配置
1 | spec: |
批量修改域名证书
已知条件:
- k8s集群中,使用ingress配置了很多四级域名,例如 test0.intl.voidking.com 和 test1.intl.voidking.com
- 每个域名都有一个自己的ingress配置文件,包含tls配置
- ingress位于不同的namespace
需求:*.intl.voidking.com
域名证书过期,需要批量修改k8s中的域名证书。
1、准备脚本 patch.sh
1 |
|
2、执行脚本
1 | bash patch.sh intl.voidking.com |
前后端分离
需求描述:前端后端是两个服务,位于两个namespace,要配置ingress,使发往路由/
的流量打到前端服务,发往/api
的流量打到后端服务。
方法一:
在一个namespace中,创建一个ingress和一个externalname类型的service。在ingress中配置两个path。
方法二:
在两个namespace中,分别创建一个ingress。host相同,配置不同的path,ingress-controller会自动合并这两个配置。
设置max_client_body_size
nginx-ingress-controller有一个全局配置文件(configmap),类似于nginx中的nginx.conf,通过它可以配置一些通用配置,例如max_client_body_size。
1、编辑配置文件
1 | kubectl edit cm nginx-configuration -n ingress-nginx |
修改data部分的配置:
1 | data: |
2、重启nginx-ingress-controller
1 | kubectl rollout restart deployment nginx-ingress-controller -n ingress-nginx |
路径重写
参考文档:
- How to proxy_pass with nginx-ingress?
- ingress-resources/rewrites
- Advanced Configuration with Annotations
方法一:nginx.ingress.kubernetes.io/use-regex
1 | apiVersion: networking.k8s.io/v1 |
方法二:nginx.ingress.kubernetes.io/configuration-snippet
1 | apiVersion: networking.k8s.io/v1 |
方法三:nginx.org/rewrites
1 | apiVersion: networking.k8s.io/v1 |
查看最终的nginx配置
我们编写的ingress,实际上最终会生成nginx.conf,可以在nginx-ingress-controller中查看是否符合预期。
1 | kubectl exec -it nginx-ingress-controller-xxx -- /bin/bash |
Ingress推荐链路
LB -> Service
1 | Domain -> LB(Ingress) -> Service -> Pod |
这种链路,适用于云厂商提供的k8s集群。
在创建ingress-controller的service时,直接给这个service分配一个LB可供外部访问。
这种链路最大的优点是链路短,速度快。
LB -> Ingress
1 | Domain -> LB -> Ingress -> Service -> Pod |
这种链路,适用于云厂商提供的k8s集群。
通过云厂商提供的LB,可以配置四层或者七层负载均衡到Ingress,还可以在LB层加一些安全防护产品。
如果使用的是七层负载均衡,还可以统一配置泛域名证书。
Nginx -> Ingress
1 | Domain -> Nginx -> Ingress -> Service -> Pod |
这种链路,适用于所有k8s集群。
通过Nginx,可以配置四层或者七层负载均衡到Ingress。
如果使用的是七层负载均衡,还可以统一配置泛域名证书。