k8s的service

一、Service简介

1.服务发现与负载均衡资源(Service & Ingress)

这类资源决定了如何访问运行中的应用。

  • Service(服务) :为一组 Pod 提供固定的访问入口和负载均衡。它主要有四种类型:ClusterIP (集群内部访问)、NodePort (节点端口映射,通过节点 IP+端口访问)、LoadBalancer (对接云厂商负载均衡器)和 Headless(用于 StatefulSet 的稳定 DNS)。

  • Ingress(入口) :管理集群外部访问集群内服务的七层(HTTP/HTTPS)路由 。例如,根据域名 api.example.com 路由到 api-service,根据路径 /web 路由到 web-service

2.理解标签与service中的endpoint

建立一个service

bash 复制代码
[root@k8s-master ~]# mkdir service/
[root@k8s-master ~]# cd service/
[root@k8s-master service]# kubectl create service  clusterip  --tcp 80:80 testservice --dry-run=client -o yaml >> testservice.yaml
[root@k8s-master service]# vim testservice.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
    app: testservice
  name: testservice
spec:
  ports:
  - name: webport
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: webserver
  type: ClusterIP

[root@k8s-master service]# kubectl apply -f testservice.yml 
service/testservice created
[root@k8s-master service]# kubectl get svc
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   13d
testservice   ClusterIP   10.100.99.225   <none>        80/TCP    4s

[root@k8s-master service]# kubectl describe svc testservice

建立pod并测试pod是否可以被testservice暴漏

bash 复制代码
[root@k8s-master service]# kubectl run  webserver --image myapp:v1 --dry-run=client -o yaml > webserver.yml
[root@k8s-master service]# vim webserver.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: myapp:v1
    name: webserver
[root@k8s-master service]# kubectl get pods -o wide;kubectl describe service testservice 

由于标签没有匹配上,所以此时并没有被暴露

更改标签然后观察

bash 复制代码
[root@k8s-master service]# kubectl label pods webserver app=webserver
pod/webserver labeled
[root@k8s-master service]# kubectl describe service testservice 
[root@k8s-master service]# curl 10.100.99.225
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

3.利用service暴漏控制器

监控

bash 复制代码
[root@k8s-master service]# watch -n 1 "kubectl describe svc webservice ; kubectl get deploy --show-labels;kubectl get pods -o wide --show-labels "

生成控制器和service的组合yam

bash 复制代码
[root@k8s-master service]# kubectl create service  clusterip  --tcp 80:80 webservice --dry-run=client -o yaml >> webservice.yaml
[root@k8s-master service]# kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml >>webservice.yaml
[root@k8s-master service]# vim webservice.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: webservice
  name: webservice
spec:
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: webcluster
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

生成控制器和service

bash 复制代码
[root@k8s-master service]# kubectl apply -f webservice.yaml
#测试
[root@k8s-master service]# curl 10.100.140.222
[root@k8s-master service]# curl 10.100.140.222/hostname.html
[root@k8s-master service]# curl 10.100.140.222/hostname.html

二、service的ipvs模式

  • Service 是由 kube-proxy 组件,加上 iptables 来共同实现的

  • kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源

  • IPVS模式的service,可以使K8s集群支持更多量级的Pod

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

1.在所有节点中安装ipvsadm工具

bash 复制代码
[root@k8s-master service]# for name in 100 10 20 200
> do
> ssh -l root 172.25.254.$name "dnf install ipvsadm -y"
> done

2.配置集群中的kube-proxy

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

bash 复制代码
[root@k8s-master service]# kubectl -n kube-system edit cm kube-proxy
59     mode: "ipvs"
[root@k8s-master service]#  kubectl -n kube-system get pods
kube-proxy-n7zrb                          1/1     Running   1 (28h ago)   8d
kube-proxy-pq7qn                          1/1     Running   0             8d
kube-proxy-r6zc7                          1/1     Running   1 (28h ago)   8d
[root@k8s-master service]#  kubectl -n kube-system get pods |awk '/proxy/{system("kubectl -n kube-system delete pods "$1)}'
pod "kube-proxy-n7zrb" deleted from kube-system namespace
pod "kube-proxy-pq7qn" deleted from kube-system namespace
pod "kube-proxy-r6zc7" deleted from kube-system namespace

3.效果

bash 复制代码
[root@k8s-master service]# ipvsadm -Ln

三、Service的类型

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

1.ClusterIP

yaml文件内容

bash 复制代码
[root@k8s-master service]# vim webservice.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: webservice
  name: webservice
spec:
  ports:
  - name: webport
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: webcluster
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

[root@k8s-master service]# kubectl apply -f webservice.yaml 

集群内部解析

注意:集群内部通常使用service的解析名称进行通信地址的指定,因为资源的ip会变但是名字不会

bash 复制代码
[root@k8s-master service]# kubectl -n kube-system get svc
NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                  AGE
calico-typha   ClusterIP   10.97.97.73   <none>        5473/TCP                 28h
kube-dns       ClusterIP   10.96.0.10    <none>        53/UDP,53/TCP,9153/TCP   13d
[root@k8s-master service]# dig webservice.default.svc.cluster.local @10.96.0.10

clusterIP的headless模式

当设定此模式,那么service不会被分配一个ip而是直接把endpoints上的ip直接通过dns裸漏

bash 复制代码
[root@k8s-master service]# vim webservice.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: webservice
  name: webservice
spec:
  ports:
  - name: webport
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: webcluster
  type: ClusterIP
  clusterIP: None     ##加上这条
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

[root@k8s-master service]# kubectl apply -f webservice.yaml
bash 复制代码
#查看解析
[root@k8s-master service]# dig webservice.default.svc.cluster.local @10.96.0.10

2.nodePort模式

nodePort的yaml文件内容

bash 复制代码
[root@k8s-master service]# vim webservice.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: webservice
  name: webservice
spec:
  ports:
  - name: webport
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30001        #指定端口,如不写可以从30000~32767之间随机分
  selector:
    app: webcluster
  type: NodePort        #NodePort模式
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp
[root@k8s-master service]# kubectl apply -f webservice.yaml 

查看策略与访问测试

bash 复制代码
[root@k8s-master service]# ipvsadm -Ln
TCP  172.25.254.100:30001 rr
  -> 10.224.36.78:80              Masq    1      0          0         
  -> 10.224.169.157:80            Masq    1      0          0 
TCP  10.244.0.0:30001 rr
  -> 10.224.36.78:80              Masq    1      0          0         
  -> 10.224.169.157:80            Masq    1      0          0
[root@k8s-master service]# curl 172.25.254.100:30001
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master service]# curl 172.25.254.100:30001/hostname.html
webcluster-77c87d9946-tg8qr
[root@k8s-master service]# curl 172.25.254.100:30001/hostname.html
webcluster-77c87d9946-kjc9n

端口破限

默认端口范围30000~32767

bash 复制代码
[root@k8s-master service]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
42     - --service-node-port-range=30000-50000
[root@k8s-master service]# kubectl -n kube-system delete pods  all
[root@k8s-master service]# vim webservice.yaml
nodePort: 44444
 
[root@k8s-master service]# kubectl apply -f webservice.yaml

3.loadbalancer

loadbalancer的yaml文件内容

bash 复制代码
[root@k8s-master service]# cp webservice.yaml loadbalancer.yml 
[root@k8s-master service]# vim loadbalancer.yml 
apiVersion: v1
kind: Service
metadata:
  labels:
    app: webservice
  name: webservice
spec:
  ports:
  - name: webport
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: webcluster
  type: LoadBalancer        #指定LoadBalancer模式
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp
[root@k8s-master service]# kubectl apply -f loadbalancer.yml
[root@k8s-master metaLLB]# kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP        13d
webservice   LoadBalancer   10.102.221.3   <none>     80:43957/TCP   3m59s

构建metalLB

bash 复制代码
[root@k8s-master service]# tar zxf metallb-v0.16.1.tar.gz
[root@k8s-master service]# cd metaLLB/
[root@k8s-master metaLLB]# ls
1-metallb-native.yaml  2-metallb-confmap.yml  metallb-v0.16.1.tar

#镜像推入harbor仓库
[root@k8s-master metaLLB]# docker load  -i metallb-v0.16.1.tar
[root@k8s-master metaLLB]# docker tag quay.io/metallb/controller:v0.16.1 reg.timinglee.org/metallb/controller:v0.16.1
[root@k8s-master metaLLB]# docker tag quay.io/metallb/speaker:v0.16.1 reg.timinglee.org/metallb/speaker:v0.16.1
[root@k8s-master metaLLB]# docker push  reg.timinglee.org/metallb/controller:v0.16.1
[root@k8s-master metaLLB]# docker push reg.timinglee.org/metallb/speaker:v0.16.1


#更新proxy
[root@k8s-master mateLLB]# kubectl edit configmap -n kube-system kube-proxy
59     mode: "ipvs"
60     ipvs:
61       strictARP: true
[root@k8s-master metaLLB]#  kubectl -n kube-system get pods |awk '/proxy/{system("kubectl -n kube-system delete pods "$1)}'


#修改配置文件的镜像位置
[root@k8s-master metaLLB]# vim 1-metallb-native.yaml
[root@k8s-master metaLLB]# grep image: 1-metallb-native.yaml
1-metallb-native.yaml:        image: metallb/controller:v0.16.1
1-metallb-native.yaml:        image: metallb/speaker:v0.16.1

#设定获取ip范围
[root@k8s-master metaLLB]# vim 2-metallb-confmap.yml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 172.25.254.50-172.25.254.99
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool

验证

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

#等待1的配置加载完成
[root@k8s-master metaLLB]# kubectl apply -f 2-metallb-confmap.yml
[root@k8s-master metaLLB]# kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1      <none>          443/TCP        13d
webservice   LoadBalancer   10.102.221.3   172.25.254.50   80:43957/TCP   26m

4.extrnalname

bash 复制代码
[root@k8s-master service]# kubectl create svc externalname externalname --external-name='www.timinglee.org'  --dry-run=client -o yaml > externalname.yaml 
[root@k8s-master service]# vim externalname.yaml 
apiVersion: v1
kind: Service
metadata:
  labels:
    app: externalname
  name: externalname
spec:
  externalName: www.timinglee.org
  selector:
    app: externalname
  type: ExternalName

[root@k8s-master service]# kubectl apply -f externalname.yaml 
[root@k8s-master service]# kubectl get svc
NAME           TYPE           CLUSTER-IP   EXTERNAL-IP         PORT(S)   AGE
externalname   ExternalName   <none>       www.timinglee.org   <none>    39s
kubernetes     ClusterIP      10.96.0.1    <none>              443/TCP   13d

四、ingress七层代理

1.ingress的部署

下载deploy文件

bash 复制代码
[root@k8s-master service]# tar zxf ingress.1.15.1.tar.gz
[root@k8s-master service]# cd ingress-v1.15.1
[root@k8s-master ingress-v1.15.1]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/baremetal/deploy.yaml

准备ingress所需镜像

bash 复制代码
[root@k8s-master ingress-v1.5.1]# docker load  -i ingress-v1.15.1.tar
[root@k8s-master ingress-v1.5.1]# docker tag registry.k8s.io/ingress-nginx/controller:v1.15.1  reg.timinglee.org/ingress-nginx/controller:v1.15.1
[root@k8s-master ingress-v1.5.1]# docker push  reg.timinglee.org/ingress-nginx/controller:v1.15.1

[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9 reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.6.9
[root@k8s-master ~]# docker push  reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.6.9

更改deploy.yaml

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim deploy.yaml
444:        image: ingress-nginx/controller:v1.15.1
547:        image: ingress-nginx/kube-webhook-certgen:v1.6.9
603:        image: ingress-nginx/kube-webhook-certgen:v1.6.9
365   		type: LoadBalancer
[root@k8s-master ingress-v1.5.1]# kubectl apply -f deploy.yaml
[root@k8s-master ingress-v1.5.1]# kubectl get -n ingress-nginx svc
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.111.155.83   172.25.254.51   80:30805/TCP,443:32333/TCP   7d1h
ingress-nginx-controller-admission   ClusterIP      10.101.96.196   <none>          443/TCP                      7d1h

2.ingress功能的基本实现

pathtype:ImplementationSpecific(通配符匹配)| Exact(完全匹配)| Prefix(前缀匹配)

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

建立ingress代理的微服务

bash 复制代码
[root@k8s-master ingress-v1.5.1]# kubectl create deployment myappv1 --image myapp:v1 --replicas 2 --dry-run=client -o yaml > myappv1.yaml
[root@k8s-master ingress-v1.5.1]# kubectl create service clusterip servicev1 --tcp 80:80 --dry-run=client -o yaml  >> myappv1.yaml

[root@k8s-master ingress-v1.5.1]# vim myappv1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myappv1
  name: myappv1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myappv1
  template:
    metadata:
      labels:
        app: myappv1
    spec:
      containers:
      - image: myapp:v1
        name: myapp
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: servicev1
  name: servicev1
spec:
  ports:
  - name: serviceportv1
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myappv1
  type: ClusterIP


#同样方式建立myappv2
[root@k8s-master ingress-v1.5.1]# kubectl apply -f myappv1.yaml 
[root@k8s-master ingress-v1.5.1]# kubectl apply -f myappv2.yaml

建立ingress

bash 复制代码
[root@k8s-master ingress-v1.5.1]# kubectl create ingress  ingress1 --class nginx --rule "*/=servicev1:80" --dry-run=client -o yaml > 1-ingress.yml

[root@k8s-master ingress-v1.5.1]# vim 1-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /v1
        pathType: Prefix

      - backend:
          service:
            name: servicev2
            port:
              number: 80
[root@k8s-master ingress-v1.5.1]# kubectl apply -f 1-ingress.yml 
[root@k8s-master ingress-v1.5.1]# kubectl describe  ingress ingress1

测试

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim /etc/hosts
172.25.254.51 www.timinglee.org
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/v1
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl www.timinglee.org/v2
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

3.基于域名的访问

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim 2-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: 'myapp1.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /
        pathType: Prefix
  - host: 'myapp2.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev2
            port:
              number: 80
        path: /
        pathType: Prefix
[root@k8s-master ingress-v1.5.1]# kubectl apply -f 2-ingress.yml 

测试

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim /etc/hosts
172.25.254.51 www.timinglee.org myapp1.timinglee.org myapp2.timinglee.org
[root@k8s-master ingress-v1.5.1]# curl myapp1.timinglee.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ingress-v1.5.1]# curl myapp2.timinglee.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

4.基于动静分离的方式

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim 3-ingress.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /index.html
spec:
  ingressClassName: nginx
  rules:
  - host: www.timinglee.org
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /php
        pathType: ImplementationSpecific

      - backend:
          service:
            name: servicev2
            port:
              number: 80
        path: /static
        pathType: ImplementationSpecific

5.tls加密访问

bash 复制代码
 [root@k8s-master ingress-v1.5.1]# openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -subj "/CN=nginxsvc/O=nginxsvc" -out tls.crt
[root@k8s-master ingress-v1.5.1]# kubectl create secret tls  web-tls-secret --key tls.key --cert tls.crt
[root@k8s-master ingress-v1.5.1]# vim 4-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - www.timinglee.org
    secretName: web-tls-secret
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /
        pathType: Prefix

6.auth认证

生成认证文件并注入集群中

bash 复制代码
[root@k8s-master ingress-v1.5.1]# dnf install httpd-tools -y
[root@k8s-master ingress-v1.5.1]# htpasswd -cm auth admin
#注入集群
[root@k8s-master ingress-v1.5.1]# kubectl create secret generic web-auth --from-file auth

在ingress中配置auth认证

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim 5-ingress.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: web-auth
    nginx.ingress.kubernetes.io/auth-realm: "Please input username and password"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /v1
        pathType: Prefix

7.ingress中的网页重写

利用网页从写定义默认发布文

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim 6-ingress.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /
        pathType: Prefix
      - backend:
          service:
            name: servicev2
            port:
              number: 80
        path: /lee/(.*)
        pathType: ImplementationSpecific
[root@k8s-master ingress-v1.5.1]# kubectl apply -f 6-ingress.yml

利用正侧表达式从定向网页

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim 7-ingress.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /
        pathType: Prefix
      - backend:
          service:
            name: servicev2
            port:
              number: 80
        path: /lee/(.*)
        pathType: ImplementationSpecific

五、金丝雀发布(cannary)

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

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

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

1.基于headr的灰度发布

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim cannary-header.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
spec:
  ingressClassName: nginx
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /
        pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress2
  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:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev2
            port:
              number: 80
        path: /
        pathType: Prefix

2.基于权重的灰度发布

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim cannary-weight.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress1
  annotations:
spec:
  ingressClassName: nginx
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev1
            port:
              number: 80
        path: /
        pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress2
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "50"
    nginx.ingress.kubernetes.io/canary-weight-total: "100"
spec:
  ingressClassName: nginx
  rules:
  - host: 'www.timinglee.org'
    http:
      paths:
      - backend:
          service:
            name: servicev2
            port:
              number: 80
        path: /
        pathType: Prefix
[root@k8s-master ingress-v1.5.1]# kubectl apply -f cannary-weight.yml 

编写测试脚本

bash 复制代码
[root@k8s-master ingress-v1.5.1]# vim check_cannary.sh 
#!/bin/bash
v1=0
v2=0

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

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

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

[root@k8s-master ingress-v1.5.1]# sh check_cannary.sh 
v1:52, v2:48
相关推荐
starzy19901 小时前
虚拟化解决方案全景:软件虚拟化、硬件虚拟化与 Docker 的位置
运维·docker·容器
梦Arrebol3 小时前
Kubernetes 微服务
微服务·容器·kubernetes
阿里云云原生3 小时前
Agent 开发范式演进:在通用智能与业务深度之间寻找“正交”平衡点
云原生
源代码•宸4 小时前
前置准备:定时微服务背景和现状
开发语言·经验分享·后端·微服务·云原生·架构·golang
实战派K8S&DB5 小时前
《基于 Dify + FastAPI + PyTiDB 搭建大模型驱动的 TiDB 智能运维 Agent》
运维·数据库·分布式·云原生·tidb·fastapi
想要成为老金高手5 小时前
Kubernetes 调度器详解:从 nodeName 到污点容忍
java·容器·kubernetes
名字还没想好☜6 小时前
Docker buildx 多架构镜像实战:一次构建 amd64+arm64,告别 exec format error
运维·docker·eureka·架构·kubernetes
gs801407 小时前
告别 CI/CD 误伤与红条:Docker 镜像智能清理与优雅防冲突实战
ci/cd·docker·容器
wjcroom7 小时前
FileBrowser的docker运行了改变密码长度的做法
运维·docker·容器