写在前面:如有问题,以你为准,
目前24年应届生,各位大佬轻喷,部分资料与图片来自网络
内容较长,页面右上角目录方便跳转
ingress 介绍 架构
原理
- 我们已经知道,Service对集群之外暴露服务的主要方式有两种:NodePort和LoadBalancer,但是这两种方式,都有一定的缺点: - NodePort方式的缺点是会占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就愈发明显。
- LoadBalancer的缺点是每个Service都需要一个LB,浪费,麻烦,并且需要kubernetes之外的设备的支持。
 
ingress可以解决的问题
1)动态配置服务
如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的k8s服务. 而如果用了Ingress, 只需要配置好这个服务, 当服务启动时, 会自动注册到Ingress的中, 不需要而外的操作。
2)减少不必要的端口暴露
配置过k8s的都清楚, 第一步是要关闭防火墙的, 主要原因是k8s的很多服务会以NodePort方式映射出去, 这样就相当于给宿主机打了很多孔, 既不安全也不优雅. 而Ingress可以避免这个问题, 除了Ingress自身服务可能需要映射出去, 其他服务都不要用NodePort方式。
- 基于这种现状,kubernetes提供了Ingress资源对象,Ingress只需要一个NodePort或者一个LB就可以满足暴露多个Service的需求,实现多个service的反向代理和负载均衡,工作机制大致如下图所示:
 实际上,Ingress相当于一个七层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解为Ingress里面建立了诸多映射规则,Ingress Controller通过监听这些配置规则并转化为Nginx的反向代理配置,然后对外提供服务。
实际上,Ingress相当于一个七层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解为Ingress里面建立了诸多映射规则,Ingress Controller通过监听这些配置规则并转化为Nginx的反向代理配置,然后对外提供服务。
Ingress: K8s中的一个抽象资源,给管理员提供一个暴露应用的入口定义方法
Ingress Controller: 根据Ingress生成具体的路由规则,并对Pod负载均衡器
-  - Ingress:kubernetes中的一个对象,作用是定义请求如何转发到Service的规则。将Nginx的配置抽象成一个Ingress对象,每添加一个新的服务只需写一个新的Ingress的yaml文件即可,每一个ingress就是一个nginx方向代理规则
- Ingress Controller:具体实现反向代理及负载均衡的程序,对Ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现的方式有很多,比如Nginx,Contour,Haproxy等。将新加入的Ingress转化成Nginx的配置文件并使之生效
 
- Ingress(以Nginx)的工作原理如下: - 用户编写Ingress规则,说明那个域名对应kubernetes集群中的那个Service。
- Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx的反向代理配置。
- Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新。
- 到此为止,其实真正在工作的就是一个Nginx,来实现反向代理,内部配置了用户定义的请求规则。(当然也可以是一个haproxy Controller)
 
下面图中ingress service 就是ingress资源对象,通过yaml部署,规则动态更新


架构图

流量路径
浏览器(ip:port) --> ServiceNodeport (ingress controller) --> ingress controller pod --> service( web) --> deployment pod (web)
[root@master kube-bench]# kubectl get svc,pod  -n ingress-nginxNAME                                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGEservice/ingress-nginx-controller             NodePort    10.111.123.202   <none>        80:32172/TCP,443:31755/TCP   256dservice/ingress-nginx-controller-admission   ClusterIP   10.106.250.140   <none>        443/TCP                      256dNAME                                           READY   STATUS    RESTARTS   AGEpod/ingress-nginx-controller-cf4967654-f9v7j   1/1     Running   0          45h应用场景
灰度发布/金丝雀(详解在后面)
业务域拆分
证书 CA
性能调优
 部署 Ingress Controller(nginx ingress)
部署 Ingress Controller(nginx ingress)
基于nginx服务的ingress controller根据不同的开发公司,又分为
k8s社区的ingres-nginx和nginx公司的nginx-ingress
k8s社区提供的ingress,github地址如下:https://github.com/kubernetes/ingress-nginx
官网:https://kubernetes.github.io/ingress-nginx/deploy/
nginx社区提供的ingress,github地址如下:https://github.com/nginxinc/kubernetes-ingress
| Ingress-NGINX version | Alpine Version | ||
| v1.6.4 | 3.17.0 | ||
| v1.5.1 | 3.16.2 | ||
| v1.4.0 | 3.16.2 | ||
| v1.3.1 | 3.16.2 | ||
| v1.3.0 | 3.16.0 | ||
| v1.2.1 | 3.14.6 | 
部署教程:kubernetes 部署 Ingress Controller(nginx ingress)-CSDN博客
登入 ingress controller 查看nginx配置

原理
https://www.bilibili.com/video/BV1r64y1m72f/?spm_id_from=333.337.search-card.all.click&vd_source=d649e016cd28e49d35879f17f8ba6892多进程管理,ingress-nginx-controller 是在pod 里面,但是外部还有一个ingress-nginx-controller进程来通过kubernetes api 管理这些pod,并对这些pod写入ingress 配置
reload 流程
部署 Service和Dployment
apiVersion: apps/v1kind: Deploymentmetadata:name: nginx-deploymentnamespace: studyspec:replicas: 3selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80---apiVersion: apps/v1kind: Deploymentmetadata:name: tomcat-deploymentnamespace: studyspec:replicas: 3selector:matchLabels:app: tomcat-podtemplate:metadata:labels:app: tomcat-podspec:containers:- name: tomcatimage: tomcat:8.0.52ports:- containerPort: 8080---apiVersion: v1kind: Servicemetadata:name: nginx-servicenamespace: studyspec:selector:app: nginx-podclusterIP: Nonetype: ClusterIPports:- port: 80targetPort: 80---apiVersion: v1kind: Servicemetadata:name: tomcat-servicenamespace: studyspec:selector:app: tomcat-podclusterIP: Nonetype: ClusterIPports:- port: 8080targetPort: 8080[root@master k8s]# kubectl apply -f ms.yamldeployment.apps/nginx-deployment createddeployment.apps/tomcat-deployment createdservice/nginx-service createdservice/tomcat-service created[root@master k8s]# kubectl get deploy,svc -n studyNAME                                READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/nginx-deployment    3/3     3            3           69sdeployment.apps/tomcat-deployment   3/3     3            3           69sNAME                     TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGEservice/nginx-service    ClusterIP   None         <none>        80/TCP     69sservice/tomcat-service   ClusterIP   None         <none>        8080/TCP   69singress yaml 详解
[root@master k8s]# kubectl get ingressclasses.networking.k8s.ioNAME    CONTROLLER             PARAMETERS   AGEnginx   k8s.io/ingress-nginx   <none>       32mapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: ingress-httpnamespace: studyspec:ingressClassName: nginx # (1.20开始使用)# defaultBackend: 处理不匹配的请求的后端,如果没有指定任何规则# 则必须指定默认后端如果没有设置默认后端处理请求不匹配任何规则将由入口控制器决定# service:# name: nginx-service# port:#  number: 80# tls: # 指定https 密钥证书# - hosts: # 指定使用该密钥的规则# - nginx.xudaxian.com# - tomcat.xudaxian.com# secretName: tls-secret # 指定秘钥rules: # 规则指定请求匹配规则,每一个规则都是<[]Object>- host: www.snj.com #指定匹配域名,默认端口为80,443http:paths:- path: / # 这里的路径指的host访问的路径,不同路径可以绑定不同的servicepathType: Prefix # 匹配规则,Prefix 前缀匹配 it.nginx.com/* 都可以匹配到backend: # 后端的serviceservice:name: nginx-service # 绑定 serviceport:number: 80 # 指定service 端口- host: tomcat.snj.comhttp:paths:- path: /pathType: Prefixbackend:service:name: tomcat-serviceport:number: 8080Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个完成。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。
Exact:精确匹配 URL 路径,且区分大小写。
ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。
[root@master k8s]# kubectl get ing -n studyNAME           CLASS    HOSTS                          ADDRESS   PORTS   AGEingress-http   <none>   nginx.snj.com,tomcat.snj.com             80      12m[root@master k8s]# kubectl get ingress -n  study -o wideNAME           CLASS   HOSTS                          ADDRESS   PORTS   AGEingress-http   nginx   nginx.snj.com,tomcat.snj.com             80      28s[root@master k8s]# kubectl describe ingress -n  studyName:             ingress-httpLabels:           <none>Namespace:        studyAddress:         Ingress Class:    nginxDefault backend:  <default>Rules:Host            Path  Backends----            ----  --------nginx.snj.com  /   nginx-service:80 (10.244.104.28:80,10.244.166.153:80,10.244.166.155:80)tomcat.snj.com /   tomcat-service:80 (10.244.104.29:8080,10.244.104.34:8080,10.244.166.154:8080)Annotations:      <none>Events:Type    Reason  Age   From                      Message----    ------  ----  ----                      -------Normal  Sync    33s   nginx-ingress-controller  Scheduled for sync# 有上面这个Normal 则绑定成功测试(http实现)
[root@master k8s]# kubectl describe svc -n ingress-nginx ingress-nginx-controllerName:                     ingress-nginx-controllerNamespace:                ingress-nginxLabels:                   app.kubernetes.io/component=controllerapp.kubernetes.io/instance=ingress-nginxapp.kubernetes.io/name=ingress-nginxapp.kubernetes.io/part-of=ingress-nginxapp.kubernetes.io/version=1.6.4Annotations:              <none>Selector:                 app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginxType:                     NodePortIP Family Policy:         SingleStackIP Families:              IPv4IP:                       10.111.123.202IPs:                      10.111.123.202Port:                     http  80/TCPTargetPort:               http/TCPNodePort:                 http  32172/TCPEndpoints:                192.168.100.51:80 # 外部访问ingress的IP地址Port:                     https  443/TCPTargetPort:               https/TCPNodePort:                 https  31755/TCPEndpoints:                192.168.100.51:443 # 外部访问ingress的IP地址Session Affinity:         NoneExternal Traffic Policy:  LocalEvents:                   <none>出现的问题:集群内部都能也可以从自己的地址访问到ingress,hosts对应写自身地址
因为搭建ingress-nginx的service的时候,会向ipvs写入规则(访问ip为自身地址)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port           Forward Weight ActiveConn InActConnTCP  192.168.100.53:31755 rr-> 192.168.100.51:443           Masq    1      0          0        TCP  192.168.100.53:32172 rr-> 192.168.100.51:80            Masq    1      0          0  但是外部不能通过master物理地址访问到ingress,外部要通过ingress pod 部署到的node的物理地址来访问
192.168.100.51 nginx.snj.com192.168.100.51 tomcat.snj.com[root@master k8s]# kubectl get svc  -n ingress-nginxNAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGEingress-nginx-controller             NodePort    10.102.42.91    <none>        80:32310/TCP,443:30777/TCP   4m29singress-nginx-controller-admission   ClusterIP   10.96.129.195   <none>        443/TCP                      4m29s# http端口为 32310 https端口为 30777https 实现(ingress 证书)
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=xudaxian.com"[root@master k8s]# ls | grep tlstls.crttls.key[root@master k8s]# kubectl create secret tls tls-secret --key tls.key --cert tls.crtsecret/tls-secret created[root@master k8s]# kubectl get pod,svc,deploy -n studyNAME                                     READY   STATUS    RESTARTS   AGEpod/nginx-deployment-6bb9d9f778-6dnhh    1/1     Running   0          86mpod/nginx-deployment-6bb9d9f778-nfzk4    1/1     Running   0          86mpod/nginx-deployment-6bb9d9f778-rl7nr    1/1     Running   0          86mpod/tomcat-deployment-84748d94d5-dgmvh   1/1     Running   0          86mpod/tomcat-deployment-84748d94d5-nczhr   1/1     Running   0          86mpod/tomcat-deployment-84748d94d5-qbp59   1/1     Running   0          86mNAME                     TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGEservice/nginx-service    ClusterIP   None         <none>        80/TCP     86mservice/tomcat-service   ClusterIP   None         <none>        8080/TCP   86mNAME                                READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/nginx-deployment    3/3     3            3           86mdeployment.apps/tomcat-deployment   3/3     3            3           86mapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: ingress-httpnamespace: studyspec:ingressClassName: nginx # (1.20开始使用)tls: # 指定https 密钥证书- hosts: # 指定使用该密钥的规则- nginx.xudaxian.com- tomcat.xudaxian.comsecretName: tls-secret # 指定秘钥           rules: # 规则指定请求匹配规则,每一个规则都是<[]Object>- host: nginx.snj.com #指定匹配域名,默认端口为80,443http:paths:- path: / # 这里的路径指的host访问的路径,不同路径可以绑定不同的servicepathType: Prefixbackend: #后端的serviceservice:name: nginx-service # 绑定 serviceport:number: 80 # 指定service 端口- host: tomcat.snj.comhttp:paths:- path: /pathType: Prefixbackend:service:name: tomcat-serviceport:number: 8080             [root@master k8s]# kubectl apply -f ingress.yamlingress.networking.k8s.io/ingress-http created[root@master k8s]# kubectl get ing -n studyNAME           CLASS   HOSTS                        ADDRESS   PORTS     AGEingress-http   nginx   www.snj.com,tomcat.snj.com             80, 443   8s[root@master k8s]# kubectl describe ing -n studyName:             ingress-httpLabels:           <none>Namespace:        studyAddress:         Ingress Class:    nginxDefault backend:  <default>TLS:tls-secret terminates nginx.xudaxian.com,tomcat.xudaxian.comRules:Host            Path  Backends----            ----  --------www.snj.com    /   nginx-service:80 (10.244.104.38:80,10.244.166.165:80,10.244.166.166:80)tomcat.snj.com /   tomcat-service:8080 (10.244.104.39:8080,10.244.104.40:8080,10.244.166.167:8080)Annotations:      <none>Events:Type    Reason  Age   From                      Message----    ------  ----  ----                      -------Normal  Sync    38s   nginx-ingress-controller  Scheduled for sync[root@master k8s]# kubectl get svc -n ingress-nginxNAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGEingress-nginx-controller             NodePort    10.111.123.202   <none>        80:32172/TCP,443:31755/TCP   92mingress-nginx-controller-admission   ClusterIP   10.106.250.140   <none>        443/TCP                      92m
# 访问端口 443:31755/TCPcurl -k https://nginx.snj.com:31755
单域名多路径

访问时跳转指定地址
不使用域名,使用ip
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: ingress-v1namespace: studyspec:ingressClassName: "nginx"rules:- http:paths:- path: /pathType: Prefixbackend:service:name: v1-serviceport:number: 80[root@master canary]# curl 10.111.123.202v1-pod限流操作
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: rate-ingressnamespace: defaultannotations: # https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rate-limitingkubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/backend-protocol: "HTTP" nginx.ingress.kubernetes.io/limit-rps: "1" # 限流spec:rules:- host: nginx.xudaxian.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svcport:number: 80基于 Cookie 的会话保持技术
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: rate-ingressnamespace: defaultannotations: # https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rate-limitingkubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/backend-protocol: "HTTP" nginx.ingress.kubernetes.io/affinity: "cookie"spec:rules:- host: nginx.xudaxian.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svcport:number: 80其他示例
出现问题
IngressClass
kubectl logs -n ingress-nginx ingress-nginx-controller-cf4967654-fkwcl# 进行排错# 比如出现一下错误# W0102 12:51:07.374785       7 controller.go:278] ignoring ingress nginx-ingress in study based on annotation : ingress does not contain a valid IngressClass# 说明没有配置 ingress classI0102 13:53:52.597216       7 main.go:100] "successfully validated configuration, accepting" ingress="study/nginx-ingress"I0102 13:53:52.604268       7 store.go:433] "Found valid IngressClass" ingress="study/nginx-ingress" ingressclass="nginx"I0102 13:53:52.614011       7 event.go:285] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"study", Name:"nginx-ingress", UID:"0f72d9c8-4b9c-4dee-afec-e5a7d213323e", APIVersion:"networking.k8s.io/v1", ResourceVersion:"8126946", FieldPath:""}): type: 'Normal' reason: 'Sync' Scheduled for syncI0102 13:53:53.128640       7 controller.go:188] "Configuration changes detected, backend reload required"I0102 13:53:53.246681       7 controller.go:205] "Backend successfully reloaded"I0102 13:53:53.254908       7 event.go:285] Event(v1.ObjectReference{Kind:"Pod", Namespace:"ingress-nginx", Name:"ingress-nginx-controller-cf4967654-fkwcl", UID:"a50e3220-3928-4fac-bdd6-b5fe5409be00", APIVersion:"v1", ResourceVersion:"8047653", FieldPath:""}): type: 'Normal' reason: 'RELOAD' NGINX reload triggered due to a change in configurationI0102 13:54:14.813365       7 status.go:300] "updating Ingress status" namespace="study" ingress="nginx-ingress" currentValue=[] newValue=[{IP:10.111.123.202 Hostname: Ports:[]}]I0102 13:54:14.817935       7 event.go:285] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"study", Name:"nginx-ingress", UID:"0f72d9c8-4b9c-4dee-afec-e5a7d213323e", APIVersion:"networking.k8s.io/v1", ResourceVersion:"8126996", FieldPath:""}): type: 'Normal' reason: 'Sync' Scheduled for sync[root@master k8s]# kubectl get ingress -n studyNAME            CLASS   HOSTS   ADDRESS          PORTS   AGEnginx-ingress   nginx   *       10.111.123.202   80      65smaster 访问问题
因为master没有ingress-nginx-controller控制器
外部不能通过master物理地址访问到ingress,外部要通过ingress pod 部署到的node的物理地址来访问
灰度发布/蓝绿发布/金丝雀发布
概述
以前使用 Kubernetes 的 Service 配合 Deployment 进行金丝雀的部署,原理如下所示:
- 但是,也是有缺点的,就是不能自定义灰度逻辑,如:指定用户进行灰度(新功能只让 VIP 先体验一个月,一个月之后再将新功能解锁,让所有用户都体验到)。
- Ingress 金丝雀发布的原理如下所示:
canary - 监绿和灰度发布而社区版本
service - 蓝绿和灰度发布云端版本(阿里云)
基于Request Headerf的流量切分,适用于灰度发布及AB测试
基于Cookie的流量切分,适用于灰度发布及AB测试
环境:已经部署了一个old nginx的ingress以及后端的deployment service资源
现在部署完了new nginx 的deployment service资源,要部署一个实现蓝绿发布的ingress(同一个host 域名)
环境部署
deployment service
部署 v1 deployment service 和 v2 deployment service
apiVersion: v1kind: Namespacemetadata:name: study---apiVersion: apps/v1kind: Deploymentmetadata:name: v1-deploymentlabels:app: v1-deploymentnamespace: studyspec:replicas: 2selector:matchLabels:app: v1-podtemplate:metadata:name: nginxlabels:app: v1-podspec:initContainers:- name: busyboximage: busybox:1.30imagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","echo v2-pod > /app/index.html;"]volumeMounts:- mountPath: /appname: appcontainers:- name: nginximage: nginx:1.17.1imagePullPolicy: IfNotPresentports:- containerPort: 80resources:requests:cpu: 100mmemory: 100Milimits:cpu: 250mmemory: 500MivolumeMounts:- name: appmountPath: /usr/share/nginx/html            volumes:- name: appemptyDir: {}      restartPolicy: Always---apiVersion: v1kind: Servicemetadata:name: v1-servicenamespace: studyspec:selector:app: v1-podtype: ClusterIPports:- name: nginxprotocol: TCPport: 80targetPort: 80---apiVersion: apps/v1kind: Deploymentmetadata:name: v2-deploymentlabels:app: v2-deploymentnamespace: studyspec:replicas: 3selector:matchLabels:app: v2-podtemplate:metadata:name: v2-podlabels:app: v2-podspec:initContainers:- name: busyboximage: busybox:1.30imagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","echo v2-pod > /app/index.html;"]volumeMounts:- mountPath: /appname: appcontainers:- name: nginximage: nginx:1.17.2imagePullPolicy: IfNotPresentports:- containerPort: 80resources:requests:cpu: 100mmemory: 100Milimits:cpu: 250mmemory: 500MivolumeMounts:- name: appmountPath: /usr/share/nginx/htmlvolumes:- name: appemptyDir: {}restartPolicy: Always---apiVersion: v1kind: Servicemetadata:name: v2-servicenamespace: studyspec:selector:app: v2-podtype: ClusterIPports:- name: nginxprotocol: TCPport: 80targetPort: 80v1-ingress
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: ingress-v1namespace: defaultspec:ingressClassName: "nginx"rules:- host: nginx.xudaxian.comhttp:paths:- path: /pathType: Prefixbackend:service:name: v1-serviceport:number: 80检查
[root@master canary]# kubectl get deploy,svc,pod,ing -n studyNAME                            READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/v1-deployment   2/2     2            2           9m1sdeployment.apps/v2-deployment   3/3     3            3           9m1sNAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGEservice/v1-service   ClusterIP   10.100.50.208   <none>        80/TCP    9m1sservice/v2-service   ClusterIP   10.107.230.80   <none>        80/TCP    9m1sNAME                                 READY   STATUS    RESTARTS   AGEpod/v1-deployment-7c455c58d8-6njc2   1/1     Running   0          9m1spod/v1-deployment-7c455c58d8-ngkq2   1/1     Running   0          9m1spod/v2-deployment-bc9fc6679-6lgjf    1/1     Running   0          9m1spod/v2-deployment-bc9fc6679-n8b49    1/1     Running   0          9m1spod/v2-deployment-bc9fc6679-p86ln    1/1     Running   0          9m1sNAME                                   CLASS   HOSTS           ADDRESS          PORTS   AGEingress.networking.k8s.io/ingress-v1   nginx   nginx.snj.com   10.111.123.202   80      83s[root@ip-15 ~]# curl nginx.snj.comv1-podv2-ingress
基于 Header 的流量切分
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: v2-ingress-canary-headernamespace: studyannotations:nginx.ingress.kubernetes.io/canary: "true" # 开启金丝雀nginx.ingress.kubernetes.io/canary-by-header: "Region" # 基于请求头# 如果 请求头 Region = always ,就路由到金丝雀版本;如果 Region = never ,就永远不会路由到金丝雀版本。# canary-by-header-value 默认 是always和 nervernginx.ingress.kubernetes.io/canary-by-header-value: "sz" # 自定义值# 如果 请求头 Region = sz ,就路由到金丝雀版本;如果 Region != sz ,就永远不会路由到金丝雀版本。# nginx.ingress.kubernetes.io/canary-by-header-pattern: "sh|sz"# 如果 请求头 Region = sh 或 Region = sz ,就路由到金丝雀版本;如果 Region != sz 并且 Region != sz ,就永远不会路由到金丝雀版本。spec:ingressClassName: "nginx"rules:- host: nginx.snj.comhttp:paths:- path: /pathType: Prefixbackend:service:name: v2-serviceport:number: 80[root@ip-15 ~]# curl nginx.snj.comv1-pod[root@ip-15 ~]# curl -H "Region: sz" nginx.snj.comv2-pod
# 此时进行测试,如负载等测试,如果没问题即可直接根据下面的完全上线新版本基于 Cookie 的流量切分
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: ingress-canary-cookienamespace: studyannotations:nginx.ingress.kubernetes.io/canary: "true" # 开启金丝雀nginx.ingress.kubernetes.io/canary-by-cookie: "vip"# 如果 cookie 是 vip = always ,就会路由到到金丝雀版本# 如果 cookie 是 vip = never ,就永远不会路由到金丝雀的版本。spec:ingressClassName: "nginx"rules:- host: nginx.snj.comhttp:paths:- path: /pathType: Prefixbackend:service:name: v2-serviceport:number: 80[root@ip-15 ~]# curl nginx.snj.comv1-pod[root@ip-15 ~]# curl --cookie "vip=always" nginx.snj.comv2-pod# 此时进行测试,如负载等测试,如果没问题即可直接根据下面的完全上线新版本基于服务权重的流量切分
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: ingress-canary-weightnamespace: studyannotations:nginx.ingress.kubernetes.io/canary: "true" # 开启金丝雀nginx.ingress.kubernetes.io/canary-weight: "10" # 基于服务权重spec:ingressClassName: "nginx"rules:- host: nginx.snj.comhttp:paths:- path: /pathType: Prefixbackend:service:name: v2-serviceport:number: 80[root@master canary]# kubectl get deploy,svc,pod,ing -n studyNAME                            READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/v1-deployment   2/2     2            2           28mdeployment.apps/v2-deployment   3/3     3            3           28mNAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGEservice/v1-service   ClusterIP   10.107.153.174   <none>        80/TCP    28mservice/v2-service   ClusterIP   10.97.36.128     <none>        80/TCP    28mNAME                                 READY   STATUS    RESTARTS   AGEpod/v1-deployment-7c455c58d8-68k9r   1/1     Running   0          28mpod/v1-deployment-7c455c58d8-kdmgl   1/1     Running   0          28mpod/v2-deployment-568ff74948-cs6dr   1/1     Running   0          28mpod/v2-deployment-568ff74948-ptsdx   1/1     Running   0          28mpod/v2-deployment-568ff74948-rpql8   1/1     Running   0          28mNAME                                              CLASS   HOSTS           ADDRESS          PORTS   AGEingress.networking.k8s.io/ingress-canary-weight   nginx   nginx.snj.com   10.111.123.202   80      30singress.networking.k8s.io/ingress-v1              nginx   nginx.snj.com   10.111.123.202   80      27m[root@ip-15 ~]# for i in {1..10}; do curl nginx.snj.com; done;v1-podv1-podv1-podv1-podv1-podv2-podv1-podv1-podv1-podv1-pod完全上线新版本
改ingress的后端service
[root@master canary]# kubectl edit ingress -n study ingress-v1ingress.networking.k8s.io/ingress-v1 edited- backend:service:name: v2-serviceport:number: 80改service标签选择器
直接就老版本的service的标签选择器指向新版本的deploy的标签

首先在网络中使用的http协议进行传输,http协议是一个明文传输协议
此时为了安全,我们就需要使用https加密传输协议,但是需要对 ingress 进行证书配置


















