K8s 之微服务的定义及详细资源调用案例

什么是微服务

用控制器来完成集群的工作负载,那么应用如何暴漏出去?

需要通过微服务暴漏出去后才能被访问

  • Service是一组提供相同服务的Pod对外开放的接口。
  • 借助Service,应用可以实现服务发现和负载均衡。
  • service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)

微服务的类型

微服务类型 作用描述
ClusterIP 默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问
NodePort 将Service通过指定的Node上的端口暴露给外部,访问任意一个NodeIP:nodePort都将路由到ClusterIP
LoadBalancer 在NodePort的基础上,借助cloud provider创建一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort,此模式只能在云服务器上使用
ExternalName 将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定

创建一个微服务

1、生成控制器文件并建立控制器

sh 复制代码
[root@k8s-master ~]# kubectl create deployment test --image myapp:v1  --replicas 2 --dry-run=client -o yaml > test.yml

[root@k8s-master yaml]# kubectl apply -f test.yml

2、生成微服务yaml追加到已有yaml中(当控制器存在并运行时才可追加成功)

sh 复制代码
[root@k8s-master ~]# kubectl expose deployment test --port 80 --target-port 80 --dry-run=client -o yaml >> test.yml

3、编辑微服务的yml文件

复制代码
[root@k8s-master ~]# vim test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: test
  name: test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: test
    spec:
      containers:
      - image: myapp:v1
        name: myapp
---		#不同资源间用---隔开

apiVersion: v1
kind: Service
metadata:
  labels:
    app: test
  name: test
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: test

4、重新加载和查看微服务的信息:

sh 复制代码
[root@k8s-master ~]# kubectl apply  -f test.yaml

[root@k8s-master ~]# kubectl get services

微服务默认使用iptables调度

bash 复制代码
[root@k8s-master ~]# kubectl get services  -o wide

#可以在火墙中查看到策略信息
[root@k8s-master ~]# iptables -t nat -nL

ipvs模式

  • Service 是由 kube-proxy 组件,加上 iptables 来共同实现的
  • kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源
  • IPVS模式的service,可以使K8s集群支持更多量级的Pod

ipvs模式配置方式

1、在所有节点中安装ipvsadm

bash 复制代码
[root@k8s-master ~]# yum install ipvsadm --y

2、修改master节点的代理配置

bash 复制代码
[root@k8s-master ~]# kubectl -n kube-system edit cm kube-proxy
......
    metricsBindAddress: ""
    mode: "ipvs"	#设置kube-proxy使用ipvs模式
    nftables:
......

3 、重启pod,在pod运行时配置文件中采用默认配置,当改变配置文件后已经运行的pod状态不会变化,所以要重启pod

sh 复制代码
[root@k8s-master ~]# kubectl -n kube-system get  pods   | awk '/kube-proxy/{system("kubectl -n kube-system delete pods "$1)}'

[root@k8s-master ~]# ipvsadm -Ln

切换ipvs模式后,kube-proxy会在宿主机上添加一个虚拟网卡:kube-ipvs0,并分配所有service IP

sh 复制代码
[root@k8s-master ~]# ip a 

微服务类型详解

clusterip

特点

clusterip模式只能在集群内访问,并对集群内的pod提供健康检测和自动发现功能

1、修改yml文件

sh 复制代码
[root@k8s-master yaml]# vim clusterip.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tym
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tym
  template:
    metadata:
      labels:
        app: tym
    spec:
      containers:
      - image: myapp:v1
        name: myapp

---
apiVersion: v1
kind: Service
metadata:
  name: tym
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: tym
  type: ClusterIP

[root@k8s-master yaml]# vim clusterip.yml

2、service创建后集群DNS提供解析

sh 复制代码
[root@k8s-master metallb]# kubectl -n kube-system get svc
#查看clusterip

[root@k8s-master ~]# dig tym.default.svc.cluster.local @10.96.0.10
#查看服务的集群解析详情

集群 DNS 自动解析:

clusterip 中的特殊模式 headless

headless(无头服务)

对于无头 Services 并不会分配 Cluster IP,kube-proxy不会处理它们, 而且平台也不会为它们进行负载均衡和路由,集群访问通过dns解析直接指向到业务pod上的IP,所有的调度有dns单独完成

bash 复制代码
[root@k8s-master ~]# vim clusterip-head.yml.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tym
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tym
  template:
    metadata:
      labels:
        app: tym
    spec:
      containers:
      - image: myapp:v1
        name: myapp

---
apiVersion: v1
kind: Service
metadata:
  name: tym
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: tym
  type: ClusterIP
  clusterIP: None	#无头模式


[root@k8s-master ~]# kubectl apply -f clusterip-head.yml.yaml

查看服务的集群解析:

sh 复制代码
[root@k8s-master yaml]# dig tym.default.svc.cluster.local @10.96.0.10

效果演示:

创建一个pod,在容器内直接访问微服务,查看解析之后返回的结果

sh 复制代码
[root@k8s-master ~]# kubectl run test --image busyboxplus -it
......
/ # curl tym

nodeport

通过ipvs暴漏端口从而使外部主机通过master节点的对外ip:来访问pod业务

nodeport 在集群节点上绑定端口,一个端口对应一个服务

nodeport默认端口是30000-32767,超出会报错

如果需要配置默认范围外的端口号,需要修改k8s的配置文件

1、编辑k8s的配置文件

sh 复制代码
[root@k8s-master ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
......
- --service-node-port-range=30000-40000
......

2、编辑 nodeport 控制器的 yml 文件

sh 复制代码
[root@k8s-master yaml]# vim nodeport.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tym
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nodeport
  template:
    metadata:
      labels:
        app: nodeport
    spec:
      containers:
      - image: myapp:v1
        name: myapp

---
apiVersion: v1
kind: Service
metadata:
  name: nodeport
spec:
  ports:
  - port: 80
    protocol: TCP
    nodePort: 33333
  selector:
    app: nodeport
  type: NodePort

[root@k8s-master yaml]# kubectl apply -f nodeport.yml

效果演示:

sh 复制代码
[root@k8s-master yaml]# kubectl get services nodeport

loadbalancer

云平台会为我们分配vip并实现访问,如果是裸金属主机那么需要metallb来实现ip的分配

loadbalancer 微服务的访问过程:

LoadBalancer模式适用云平台,裸金属环境需要安装metallb提供支持

bash 复制代码
[root@k8s-master ~]# vim timinglee.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: loadbalancer
spec:
  replicas: 2
  selector:
    matchLabels:
      app: loadbalancer
  template:
    metadata:
      labels:
        app: loadbalancer
    spec:
      containers:
      - image: myapp:v1
        name: myapp

---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: loadbalancer
  type: LoadBalancer


[root@k8s-master yaml]# kubectl apply -f loadbalancer.yml

默认无法分配外部访问IP
[root@k8s2 service]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP        4d1h
myapp        LoadBalancer   10.107.23.134   <pending>     80:32537/TCP   4s

metalLB

官网:https://metallb.universe.tf/installation/

MetalLB是一个负载均衡器,专门解决裸金属Kubernetes集群中无法使用LoadBalancer类型服务的问题。

它有两个主要功能:地址分配,为LoadBalancer Service分配lP地

址;外部声明,让集群外的网络知道这个地址的存在;为LoadBalancer分配vip

部署方式

1、设置ipvs模式

sh 复制代码
[root@k8s-master ~]# kubectl edit cm -n kube-system kube-proxy
...
  strictARP: true
...
mode: "ipvs"
...

2、将修改的配置生效

sh 复制代码
[root@k8s-master ~]# kubectl -n kube-system get pods | awk '/kube-proxy/{system("kubectl -n kube-system delete pods "$1)}'

3、下载部署文件

sh 复制代码
[root@k8s2 metallb ~]# wget https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml

4、修改metallb部署文件内容

sh 复制代码
[root@k8s-master ~]# vim metallb-native.yaml
......
image: metallb/controller:v0.14.8
......
image: metallb/speaker:v0.14.8
......

5、上传镜像到harbor仓库

sh 复制代码
[root@k8s-master metallb]# docker tag quay.io/metallb/controller:v0.14.8 reg.tym.org/metallb/controller:v0.14.8
[root@k8s-master metallb]# docker tag quay.io/metallb/speaker:v0.14.8 reg.tym.org/metallb/speaker:v0.14.8

[root@k8s-master metallb]# docker push reg.tym.org/metallb/controller:v0.14.8
[root@k8s-master metallb]# docker push reg.tym.org/metallb/speaker:v0.14.8

6、部署服务

启用metallb服务:

bash 复制代码
[root@k8s-metallb ~]# kubectl apply -f metallb-native.yaml

[root@k8s-master ~]# kubectl -n metallb-system get pods

配置分配地址段:

sh 复制代码
[root@k8s-master ~]# vim configmap.yml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool				#地址池名称
  namespace: metallb-system
spec:
  addresses:
  - 172.25.254.50-172.25.254.99	#修改为自己本地地址段

---		#两个不同的kind中间必须加分割
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool					#使用的地址池 

重新加载文件:

sh 复制代码
[root@k8s-master ~]# kubectl apply -f configmap.yml

查看服务信息:

sh 复制代码
[root@k8s-master ~]# kubectl get services

#通过分配地址从集群外访问服务

sh 复制代码
[root@reg ~]# curl  172.25.254.51

externalname

  • 开启services后,不会被分配IP,而是用dns解析CNAME固定域名来解决ip变化问题
  • 一般应用于外部业务和pod沟通或外部业务迁移到pod内时
  • 在应用向集群迁移过程中,externalname在过度阶段就可以起作用了
  • 集群外的资源迁移到集群时,在迁移的过程中ip可能会变化,但是域名+dns解析能完美解决此问题
sh 复制代码
[root@k8s-master ~]# vim externalname.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: externalname
spec:
  replicas: 2
  selector:
    matchLabels:
      app: externalname
  template:
    metadata:
      labels:
        app: externalname
    spec:
      containers:
      - image: myapp:v1
        name: myapp

---
apiVersion: v1
kind: Service
metadata:
  name: externalname
spec:
  selector:
    app: externalname
  type: ExternalName
  externalName: www.tym.org


[root@k8s-master yaml]# kubectl apply -f externalname.yml

[root@k8s-master ~]# kubectl get services

Ingress-nginx

官网:

https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters

ingress-nginx 功能

  • 一种全局的、为了代理不同后端 Service 而设置的负载均衡服务,支持7层
  • Ingress由两部分组成:Ingress controller和Ingress服务
  • Ingress Controller 会根据你定义的 Ingress 对象,提供对应的代理能力
  • 业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller

部署 ingress

下载部署文件

bash 复制代码
[root@k8s-master ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/baremetal/deploy.yaml

上传ingress所需镜像到harbor

bash 复制代码
[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/controller:v1.11.2 reg.tym.org/ingress-nginx/controller:v1.11.2
[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3 reg.tym.org/ingress-nginx/kube-webhook-certgen:v1.4.3

[root@k8s-master ~]# docker push reg.tym.org/ingress-nginx/controller:v1.11.2
[root@k8s-master ~]# docker push reg.tym.org/ingress-nginx/kube-webhook-certgen:v1.4.3

安装ingress

1、修改配置文件

sh 复制代码
[root@k8s-master ~]# vim deploy.yaml
...
	image: ingress-nginx/controller:v1.11.2
...
	image: ingress-nginx/kube-webhook-certgen:v1.4.3
...
	image: ingress-nginx/kube-webhook-certgen:v1.4.3
...

2、安装ingress-nginx

sh 复制代码
[root@k8s-master ingress]# kubectl apply -f deploy.yaml

3、查看ingress-nginx状态

sh 复制代码
[root@k8s-master ~]# kubectl -n ingress-nginx get pods

[root@k8s-master ~]# kubectl -n ingress-nginx get svc

4、修改微服务为loadbalancer

sh 复制代码
[root@k8s-master ~]# kubectl -n ingress-nginx edit svc ingress-nginx-controller
...
   type: LoadBalancer
  ...

5、查看其服务状态

sh 复制代码
[root@k8s-master ingress]# kubectl -n ingress-nginx get svc

在ingress-nginx-controller中看到的对外IP就是ingress最终对外开放的 ip

测试ingress

1、生成 yaml 文件

sh 复制代码
[root@k8s-master ~]# kubectl create ingress myappv1 --class nginx --rule='/=myappv1:80' --dry-run=client -o yaml > ingress1.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myappv1
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: myappv1	#该名称为已建立好的服务名称
            port:
              number: 80
        path: /
        pathType: Prefix
#Exact(精确匹配);ImplementationSpecific(特定实现);Prefix(前缀匹配);Regular expression(正则表达式匹配)

2、建立控制器

sh 复制代码
[root@k8s-master yaml]# kubectl apply -f ingress.yml

3、访问测试

sh 复制代码
[root@k8s-master yaml]# curl 172.25.254.50
#172.25.254.50为ingress对外IP地址

ingress必须和输出的service资源处于同一namespace

如果 ingress-nginx 的 yml 文件内的服务不存在,则会访问失败

ingress 的高级用法

基于路径的访问

1、建立用于测试的控制器myapp1,myappv2

生成 yml 文件:

bash 复制代码
[root@k8s-master yaml]# kubectl create deployment myappv1 --image myapp:v1 --dry-run=client -o yaml > myappv1.yaml

[root@k8s-master yaml]# kubectl expose deployment myappv1 --port 80 --target-port 80 --dry-run=client -o yaml >> myappv1.yaml

编辑 yml 文件:

sh 复制代码
[root@k8s-master yaml]# vim myappv1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myappv1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myappv1
  template:
    metadata:
      labels:
        app: myappv1
    spec:
      containers:
      - image: myapp:v1
        name: myappv1

---
apiVersion: v1
kind: Service
metadata:
  name: myappv1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myappv1

按照以上方法再次建立v2的版本

建立并运行两个微服务:

sh 复制代码
[root@k8s-master yaml]# kubectl apply -f myappv1.yml

[root@k8s-master yaml]# kubectl apply -f myappv2.yml

2、建立ingress的yaml 文件

bash 复制代码
[root@k8s-master yaml]# vim ingress1.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /	#访问路径后加任何内容都被定向到/
  name: ingress1
spec:
  ingressClassName: nginx
  rules:
  - host: www.tym.org
    http:
      paths:
      - backend:
          service:
            name: myapp-v1
            port:
              number: 80
        path: /v1
        pathType: Prefix

      - backend:
          service:
            name: myapp-v2
            port:
              number: 80
        path: /v2
        pathType: Prefix

3、运行ingress服务

sh 复制代码
[root@k8s-master yaml]# kubectl apply -f ingress1.yml

4、添加本地解析

sh 复制代码
[root@k8s-master yaml]# vim /etc/hosts
...
172.25.254.50 www.tym.org

5、查看服务的详细信息

sh 复制代码
[root@k8s-master yaml]# kubectl describe ingress ingress1

6、测试

sh 复制代码
[root@k8s-master yaml]# curl www.tym.org/v2

基于域名的访问

1、在测试主机中设定解析

sh 复制代码
[root@k8s-master yaml]# vim /etc/hosts

2、建立基于域名的yaml文件

sh 复制代码
[root@k8s-master yaml]# vim ingress3.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: ingresss
spec:
  ingressClassName: nginx
  rules:
  - host: myappv1.tym.org
    http:
      paths:
      - backend:
          service:
            name: myappv1
            port:
              number: 80
        path: /
        pathType: Prefix
  - host: myappv2.tym.org
    http:
      paths:
      - backend:
          service:
            name: myappv2
            port:
              number: 80
        path: /
        pathType: Prefix

3、利用文件资源清单建立ingress

sh 复制代码
[root@k8s-master yaml]# kubectl apply -f ingress3.yml

4、查看其ingress的详细信息

sh 复制代码
[root@k8s-master yaml]# kubectl describe ingress

5、访问测试

sh 复制代码
[root@k8s-master yaml]# curl myappv1.tym.org

[root@k8s-master yaml]# curl myappv2.tym.org

建立tls加密

1、建立证书

sh 复制代码
[root@k8s-master yaml]# openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -subj "/CN=nginxsvc/O=nginxsvc" -out tls.crt

2、建立加密资源类型secret

sh 复制代码
[root@k8s-master yaml]# kubectl create secret tls web-tls-secret --key tls.key --cert tls.crt

[root@k8s-master app]# kubectl get secrets

secret通常在kubernetes中存放敏感数据,他并不是一种加密方式

3、建立资源清单基于tls认证的yml文件

bash 复制代码
[root@k8s-master yaml]# vim ingress4.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: ingresss
spec:
  tls:
  - hosts:
    - myappv1-tls.tym.org
    - myappv2-tls.tym.org
    secretName: web-tls-secret	#当通过以上域名访问时,自动定位至加密资源secret
  ingressClassName: nginx
  rules:
  - host: myappv1-tls.tym.org
    http:
      paths:
      - backend:
          service:
            name: myappv1
            port:
              number: 80
        path: /
        pathType: Prefix
  - host: myappv2-tls.tym.org
    http:
      paths:
      - backend:
          service:
            name: myappv2
            port:
              number: 80
        path: /
        pathType: Prefix

[root@k8s-master yaml]# kubectl apply -f ingress4.yml

4、测试

在测试主机内添加域名解析;通过浏览器进行访问测试

建立auth认证

1、建立认证文件

bash 复制代码
[root@k8s-master yaml]# dnf install httpd-tools -y
#下载安装认证工具

[root@k8s-master yaml]# htpasswd -cm auth lee
#创建认证用户

[root@k8s-master app]# cat auth

2、建立认证类型资源secret

sh 复制代码
[root@k8s-master app]# kubectl create secret generic auth-web --from-file auth

root@k8s-master app]# kubectl describe secrets auth-web

3、建立资源清单基于用户认证的yaml文件

bash 复制代码
[root@k8s-master yaml]# vim ingress5.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic	#认证类型
    nginx.ingress.kubernetes.io/auth-secret: auth-web	#认证资源的名称
    nginx.ingress.kubernetes.io/auth-realme: "Please input username and passsword"
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: myappv1
            port:
              number: 80
        path: /
        pathType: Prefix
    host: www.tym.org

[root@k8s-master app]# kubectl apply -f ingress4.yml

4、测试

sh 复制代码
[root@k8s-master yaml]# curl -k https://www.tym.org

[root@reg ~]# curl -k https://www.tym.org -u tym:123

rewrite重定向

1、创建资源清单文件基于默认访问的文件到hostname.html上

sh 复制代码
[root@k8s-master yaml]# vim ingress6.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/app-port: /hostname.html	#默认访问至该文件
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: myappv1
            port:
              number: 80
        path: /
        pathType: Prefix
    host: www.tym.org

[root@k8s-master yaml]# kubectl apply -f ingress6.yml

2、测试

sh 复制代码
[root@k8s-master yaml]# curl www.tym.org
解决重定向路径问题

1、创建资源清单文件

sh 复制代码
[root@k8s-master yaml]# vim ingress6.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"	#开启正则表达式
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: myappv1
            port:
              number: 80
        path: /
        pathType: Prefix
      - backend:
          service:
            name: myappv1
            port:
              number: 80
        path: /tym(/|$)(.*)	#正则表达式匹配/tym/,/tym/a
        pathType: ImplementationSpecific	#匹配类型为正则表达式
    host: www.tym.org

[root@k8s-master yaml]# kubectl apply -f ingress6.yml

2、测试

sh 复制代码
[root@k8s-master yaml]# curl www.tym.org/aa

[root@k8s-master yaml]# curl www.tym.org/aa/aa

[root@k8s-master yaml]# curl www.tym.org/aa/aa/fdsfd

Canary 金丝雀发布

金丝雀发布简介

基于 Ingress-nginx 的一种发布方式

金丝雀发布(Canary Release)也称为灰度发布,是一种软件发布策略。

主要目的是在将新版本的软件全面推广到生产环境之前,先在一小部分用户或服务器上进行测试和验证,以降低因新版本引入重大问题而对整个系统造成的影响。

是一种Pod的发布方式。金丝雀发布采取先添加、再删除的方式,保证Pod的总量不低于期望值。并且在更新部分Pod后,暂停更新,当确认新Pod版本运行正常后再进行其他版本的Pod的更新。

Canary 发布方式

其中header和weiht中的最多

基于header(http包头)灰度发布

  • 通过Annotaion扩展
  • 创建灰度ingress,配置灰度头部key以及value
  • 灰度流量验证完毕后,切换正式ingress到新版本
  • 在做升级时可以通过控制器做滚动更新,默认25%利用header可以使升级更为平滑,通过key 和vule 测试新的业务体系是否有问题。

示例

1、建立版本为1的ingress(旧版本)

sh 复制代码
[root@k8s-master yaml]# vim ingress7.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myappv1-canary
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: myappv1
            port:
              number: 80
        path: /
        pathType: Prefix

[root@k8s-master yaml]# kubectl apply -f ingress7.yml

2、建立版本为2的ingress(新版本)

sh 复制代码
[root@k8s-master yaml]# vim ingress8.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myappv2-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "version"	#设定其包头的键
    nginx.ingress.kubernetes.io/canary-by-header-value: "2"	#设定其包头的值
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: myappv2
            port:
              number: 80
        path: /
        pathType: Prefix

[root@k8s-master yaml]# kubectl apply -f ingress7.yml

3、测试

sh 复制代码
[root@k8s-master yaml]# curl 172.25.254.50

[root@k8s-master yaml]# curl -H "version:2" 172.25.254.50

基于权重的灰度发布

  • 通过Annotaion拓展
  • 创建灰度ingress,配置灰度权重以及总权重
  • 灰度流量验证完毕后,切换正式ingress到新版本

示例

1、创建基于权重的灰度发布

bash 复制代码
[root@k8s-master yml]# vim ingress8.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myappv2-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"	#设定其发布新版的权重,如果总权重为100,则发布的新版占百分之十
    nginx.ingress.kubernetes.io/canary-by-weight-total: "100"	#设定其总权重
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - backend:
          service:
            name: myappv2
            port:
              number: 80
        path: /
        pathType: Prefix

[root@k8s-master yml]# kubectl apply -f ingress8.yml

2、编写一个脚本进行测试其灰度发布的情况

sh 复制代码
[root@reg ~]# vim check_ingress.sh
#!/bin/bash
v1=0
v2=0

for (( i=0; i<100; i++))
do
    response=`curl -s 172.25.254.50 |grep -c v1`

    v1=`expr $v1 + $response`
    v2=`expr $v2 + 1 - $response`

done
echo "v1:$v1, v2:$v2"

观察其发布的情况

当发布权重为10时:

当发布权重为40时:

相关推荐
赴前尘2 小时前
Go 微服务框架排行榜(按 GitHub Star 排序)
微服务·golang·github
能不能别报错2 小时前
K8s学习笔记(十六) 探针(Probe)
笔记·学习·kubernetes
能不能别报错4 小时前
K8s学习笔记(十四) DaemonSet
笔记·学习·kubernetes
火星MARK5 小时前
k8s面试题
容器·面试·kubernetes
赵渝强老师6 小时前
【赵渝强老师】Docker容器的资源管理机制
linux·docker·容器·kubernetes
能不能别报错8 小时前
K8s学习笔记(十五) pause容器与init容器
笔记·学习·kubernetes
稚辉君.MCA_P8_Java8 小时前
kafka解决了什么问题?mmap 和sendfile
java·spring boot·分布式·kafka·kubernetes
乄bluefox8 小时前
保姆级docker部署nacos集群
java·docker·容器
每天进步一点_JL8 小时前
Docker 是什么?
后端·docker·容器
一叶飘零_sweeeet9 小时前
从 0 到 1 掌控云原生部署:Java 项目的 Docker 容器化与 K8s 集群实战指南
docker·云原生·kubernetes·项目部署