k8s部署-44-带你深入学习ingress-nginx(终)

网友投稿 834 2022-11-04

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

k8s部署-44-带你深入学习ingress-nginx(终)

4访问控制

我们之前学了如何使用ingress-nginx来进行多节点配置,如何代理4层协议,如何配置https,那么我们还剩下一个,那就是访问控制,本文来详细实操一下。

1、session保持;

在同一段时间,长期访问同一个后端服务,不要进行轮训;那么我们首先来准备下环境吧。为了做测试,我们要实现的是,经过同一个域名,访问两个使用不同镜像的后端服务,就是我们要采用金丝雀部署的方式,来看看吧。

[root@node1 ~]# kubectl get podNAME READY STATUS RESTARTS AGEnginx-ds-q2pjt 1/1 Running 35 26dnginx-ds-zc5qt 1/1 Running 40 32dspringboot-web-demo-5c9446ffbf-qvq69 1/1 Running 1 15h[root@node1 ~]#

可以看到我们现在运行了一个pod,使用的镜像如下:

[root@node1 ~]# kubectl get pod springboot-web-demo-5c9446ffbf-qvq69 -o yaml | grep image f:image: {} f:imagePullPolicy: {} - image: registry.cn-beijing.aliyuncs.com/yunweijia0909/springboot-web:v1 imagePullPolicy: IfNotPresent image: registry.cn-beijing.aliyuncs.com/yunweijia0909/springboot-web:v1 imageID: registry.cn-beijing.aliyuncs.com/yunweijia0909/springboot-web@sha256:1953bfa3859e02f7f8ab10e5b69a0505c738f2d05040be6222e63c2971e8b45d[root@node1 ~]#

然后我们再次创建个同样域名的pod,使用不同的镜像来看看;

[root@node1 ~]# cd namespace/[root@node1 namespace]# mkdir control[root@node1 namespace]# cd control/[root@node1 control]# [root@node1 control]# vim control-ceshi.yaml #deployapiVersion: apps/v1kind: Deploymentmetadata: name: springboot-web-demo-newspec: selector: matchLabels: app: springboot-web-demo replicas: 1 template: metadata: labels: app: springboot-web-demo spec: containers: - name: springboot-web-demo image: registry.cn-beijing.aliyuncs.com/yunweijia0909/tomcat:jre8-openjdk ports: - containerPort: 8080---#serviceapiVersion: v1kind: Servicemetadata: name: springboot-web-demospec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: springboot-web-demo type: ClusterIP---#ingressapiVersion: extensions/v1beta1kind: Ingressmetadata: name: springboot-web-demospec: rules: - host: springboot.yunweijia.com http: paths: - backend: serviceName: springboot-web-demo servicePort: 80 path: [root@node1 control]# [root@node1 control]#

可以看到我们使用了同样的域名,但是镜像不一样,当然了,我们使用的配置https,还是和上文是一样的,如下(只需要执行一个就行,因为域名是一样的):

[root@node1 control]# cat web-demo-ingress.yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: name: springboot.yunweijia.comspec: rules: - host: springboot.yunweijia.com http: paths: - backend:          serviceName: springboot-web-demo servicePort: 80 path: / tls: - hosts: - springboot.yunweijia.com secretName: yunweijia-tls[root@node1 control]#

看下访问结果哈,一直按着刷新;

会在这两个界面中来回切换,说明我们的环境就搞定了。(不要在意我的404 ,上次镜像搞崩了,一直没修复。)

环境搞定之后,我们就该做session保持了,操作的对象是ingress-nginx;

[root@node1 control]# vim ingress-session.yaml apiVersion: extensions/v1beta1kind: Ingressmetadata: annotations: nginx.ingress.kubernetes.io/affinity: cookie nginx.ingress.kubernetes.io/session-cookie-hash: sha1 nginx.ingress.kubernetes.io/session-cookie-name: route name: springboot-web-demospec: rules: - host: springboot.yunweijia.com http: paths: - backend: serviceName: springboot-web-demo servicePort: 80 path: / tls: - hosts: - springboot.yunweijia.com secretName: yunweijia-tls[root@node1 control]#

然后我们再次浏览器刷新的时候,会发现他一直保持在一个界面,这个时候我们看看他的session是什么样子的;

只要是同一个cookie就会一直保持在同一个界面中,除非你关闭浏览器再次打开,这样子你的cookie就换了,那么有可能就不是这个后台程序了。

2、流量控制

比如说当我们有两个服务,我们再升级的时候,升了一个,想切10%的流量到我们的新服务上,验证下有没有问题,那么我们应该如何来做呢?

[root@node1 control]# cd ../tls/[root@node1 tls]#  kubectl create secret tls yunweijia-tls --key yunweijia.key --cert yunweijia.crt -n canary

上面这步不太理解的,看一下前面的文章。

PS:该项操作,需要在较新的ingress-nginx版本上才有的哈,如果版本太老了,可能不支持,可以更新一下image,替换版本为0.23.0之后方可;

[root@node1 control]# mkdir canary[root@node1 control]# cd canary/[root@node1 canary]# vim web-canary-a.yaml #deployapiVersion: apps/v1kind: Deploymentmetadata: name: web-canary-a namespace: canaryspec: strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate selector: matchLabels: app: web-canary-a replicas: 1 template: metadata: labels: app: web-canary-a spec: containers: - name: web-canary-a image: registry.cn-beijing.aliyuncs.com/yunweijia0909/springboot-web:v1 ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 8080 initialDelaySeconds: 20 periodSeconds: 10 failureThreshold: 3 successThreshold: 1 timeoutSeconds: 5 readinessProbe: httpGet: path: /hello?name=test port: 8080 scheme: HTTP initialDelaySeconds: 20 periodSeconds: 10 failureThreshold: 1 successThreshold: 1 timeoutSeconds: 5---#serviceapiVersion: v1kind: Servicemetadata: name: web-canary-a namespace: canaryspec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: web-canary-a type: ClusterIP[root@node1 canary]# vim web-canary-b.yaml #deployapiVersion: apps/v1kind: Deploymentmetadata: name: web-canary-b namespace: canaryspec: strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate selector: matchLabels: app: web-canary-b replicas: 1 template: metadata: labels: app: web-canary-b spec: containers: - name: web-canary-b image: registry.cn-beijing.aliyuncs.com/yunweijia0909/tomcat:jre8-openjdk ports:        - containerPort: 8080---#serviceapiVersion: v1kind: Servicemetadata: name: web-canary-b namespace: canaryspec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: web-canary-b type: ClusterIP[root@node1 canary]#

可以看到我们写了两个yaml文件,我们下来运行一下;

[root@node1 canary]# kubectl create ns canarynamespace/canary created[root@node1 canary]# kubectl apply -f web-canary-a.yaml deployment.apps/web-canary-a createdservice/web-canary-a created[root@node1 canary]# kubectl apply -f web-canary-b.yaml deployment.apps/web-canary-b createdservice/web-canary-b created[root@node1 canary]#

然后我们还需要准备一个ingress的yaml文件;

[root@node1 canary]# vim ingress-common.yaml #ingressapiVersion: extensions/v1beta1kind: Ingressmetadata: name: web-canary-a namespace: canaryspec: rules: - host: canary.yunweijia.com http: paths: - path: backend: serviceName: web-canary-a servicePort: 80 tls: - hosts: - canary.yunweijia.com secretName: yunweijia-tls[root@node1 canary]# [root@node1 canary]# kubectl apply -f ingress-common.yaml ingress.extensions/web-canary-a created[root@node1 canary]#

然后我们访问验证一下试试;(需要先添加hosts文件哈,自行添加,不演示了哈)

接着我们需要上线canary-b;

[root@node1 canary]# cat ingress-weight.yaml #ingressapiVersion: extensions/v1beta1kind: Ingressmetadata: name: web-canary-b namespace: canary annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "10"spec: rules: - host: canary.yunweijia.com http: paths: - path: backend: serviceName: web-canary-b servicePort: 80 tls: - hosts: - canary.yunweijia.com secretName: yunweijia-tls[root@node1 canary]# kubectl apply -f ingress-weight.yaml ingress.extensions/web-canary-b created[root@node1 canary]#

然后我们再次访问验证下,发现只有10%的流量切到了canary-b上;这就是我们实现的流量控制。这个10%可以根据自己的需要自行调节。我们可以写个脚本测试下:

while sleep 0.2; do curl -k https://canary.yunweijia.com/hello?name=yunweijia && echo "";done

等待一段时间之后,发现如下图:

基本控制在了十分之一的访问切换。

3、控制访问

还有一种情况是,替换完了之后并不想让其他人来访问,只想让指定的人来访问,这个时候我们如何来做呢?

可以通过控制cookie的方式来实现;

[root@node1 canary]# cat ingress-cookie.yaml #ingressapiVersion: extensions/v1beta1kind: Ingressmetadata: name: web-canary-b namespace: canary annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-cookie: "web-canary"spec: rules: - host: canary.yunweijia.com http: paths: - path: backend: serviceName: web-canary-b servicePort: 80[root@node1 canary]#

我们让其生效;

[root@node1 canary]# kubectl apply -f ingress-cookie.yaml

当我们再次访问的时候,会发现全部访问的都是canary-a了,如下图:

那么我们如何来canary-b的服务呢?需要指定一个cookie,当你浏览器访问的时候,添加如下:

然后我们再来访问的话,就变成了canary-b的服务了;

4、请求头控制

还有一种方式是通过请求头来控制访问哪个服务,我们继续来测试下;

[root@node1 canary]# cat ingress-header.yaml #ingressapiVersion: extensions/v1beta1kind: Ingressmetadata: name: web-canary-b namespace: canary annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "web-canary"spec: rules: - host: canary.yunweijia.com http: paths: - path: backend: serviceName: web-canary-b servicePort: 80[root@node1 canary]#

我们使其生效一下;

[root@node1 canary]# kubectl apply -f ingress-header.yaml ingress.extensions/web-canary-b created[root@node1 canary]#

然后我们继续浏览器访问,这个时候我们依旧会一直访问canary-a的服务,我们如何访问到canary-b的服务呢,是不是需要添加请求头啊;

curl -H "web-canary: always" -k https://canary.yunweijia.com/hello?name=yunweijia && echo ""

5、组合控制

上面我们介绍了三种方式,是可以组合到一块的哈,优先级如下:

header > cookie > weight

如下:

#ingressapiVersion: extensions/v1beta1kind: Ingressmetadata: name: web-canary-b namespace: canary annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "web-canary" nginx.ingress.kubernetes.io/canary-by-cookie: "web-canary" nginx.ingress.kubernetes.io/canary-weight: "90"spec: rules: - host: canary.yunweijia.com http: paths: - path: / backend: serviceName: web-canary-b servicePort: 80

至此,本文结束,下一篇咱们继续进行ingress-nginx的深入学习哈。

往期推荐如何将不同linux服务器的目录内容进行双向同步linux 虚拟化linux下普通用户如何免密执行sudo命令呢

上一篇:软件测试培训之压力测试和负载测试的区别
下一篇:软件测试培训之测试人员解决问题的8种职业能力
相关文章

 发表评论

暂时没有评论,来抢沙发吧~