管理 Deployments

Canary Deployments

当要使用一部分用户测试生产中的新部署时,请使用 Canary 部署。因为透过 Canary 部署,可以将更改发布给一小部分用户,以减轻新版本相关的风险。建立一个范例,该范例是从 googlecodelabs 取得。

$ cat deployments/hello-canary.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-canary
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
        track: canary
        # Use ver 1.0.0 so it matches version on service selector
        version: 1.0.0
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
...

使用 apply 布署

$ kubectl create -f deployments/hello-canary.yaml

创建 canary 部署之後,应该有两个部署,hello 和 hello-canary。使用 kubectl 进行验证

$ kubectl get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
auth           1/1     1            1           10m
frontend       1/1     1            1           9m23s
hello          3/3     3            3           9m32s
hello-canary   1/1     1            1           36s

在 hello 服务上,selector 使用 app:hello 选择器,该 selector 将与 prod 部署和 canary 部署中的 POD 匹配。但是,由於 Canary 部署的 POD 数量较少,因此对较少的用户可见。

使用 curl 进行验证

$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"2.0.0"}
$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}

运行几次,应该看到 hello 1.0.0 为某些请求提供了服务,而 2.0.0 为一小部分约 1/4 提供了服务。原理如下图

可以使用 sessionAffinity: ClientIP 方式让请求端始终发送到相同版本的应用程序上

Blue-green deployments

滚动更新是理想的选择,因为它能够以最小的开销、性能和最小的停机时间来缓慢的部署应用程序。在某些情况下,只有在完全部署新版本之後,修改负载均衡器以使其指向该新版本是有益的,在这种情况下,必须进行 Blue-green 部署。Kubernetes 透过创建两个单独的 Deployment 来实现这一目标。一种用於旧的 blue 版本,另一种用於新的 green 版本,将现有的 hello 部署用於 blue 版本。将透过充当路由器的 Service 来访问部署,新的 green 版本启动并运行後,将透过更新 Service 切换到使用该版本。

selector 将匹配现有的 blue 部署。但是它不匹配 green 部署,因为它将使用不同的版本。

kind: Service
apiVersion: v1
metadata:
  name: "hello"
spec:
  selector:
    app: "hello"
    version: 1.0.0
  ports:
    - protocol: "TCP"
      port: 80
      targetPort: 80

green 应用程序布署

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hello-green
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: hello
        track: stable
        version: 2.0.0
    spec:
      containers:
        - name: hello
          image: kelseyhightower/hello:2.0.0
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
          resources:
            limits:
              cpu: 0.2
              memory: 10Mi
          livenessProbe:
            httpGet:
              path: /healthz
              port: 81
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 15
            timeoutSeconds: 5
          readinessProbe:
            httpGet:
              path: /readiness
              port: 81
              scheme: HTTP
            initialDelaySeconds: 5
            timeoutSeconds: 1

因为 Service 关系,因此还是指向 blue。

$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"1.0.0"}

更新 Service,透过 selector 让它匹配 green

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

验证,变为 green 版本

$ curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
{"version":"2.0.0"}

最近在学英文因此写文章的品质没那麽好,请见谅。


<<:  Day 28 | 来组合个画面吧 - Part 1

>>:  DAY28-ASP.NET网页切换导向及状态管理-趴兔

Day 19:「通通拿去做鸡精啦!」- Vue SFC

嗨大家~ 昨天有没有试着用 Creator 建立专案呢! 没有的话现在赶快去复习哦, 因为我们今天...

[Day30] 第三十 - 总结技能交换系统(整合Laravel以及Express的Microservices)

前言(心得) 昨天在写Code的时候一不注意时间就超过了 其实我本来是很懒惰容易放弃的人 在之前的参...

Day 07-微软Bot Service相关软件概述

上一篇文章我们成功在Visual Studio里新增了Echo Bot的专案 也成功在Bot Fra...

Day05-Variables

前言 在我们之前的练习都只有使用var宣告变数,其实还有其它两个宣告方式可以使用。 接下来我们会学习...

Day29 | 使用extension动态产生snippet提示吧!

大家好,我是韦恩,今天是铁人赛的第二十九天,今天我们会来练习language命名空间下的api,使用...