借助Rancher持续交付,3步实现金丝雀发布!

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从Rancher 2.5起,Rancher借助Fleet提供了大规模交付的GitOps功能,允许用户使用GitOps的方法管理其集群的状态。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"金丝雀发布是一个被软件开发者广泛使用的方法,它可以用来向一部分用户发布新版本的应用程序,并根据可用性、延迟或自定义指标等指标来扩大规模,进而为更多用户提供服务。在本文中,我们将探索如何使用持续交付来为你的应用程序工作负载执行金丝雀发布。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"实际的金丝雀发布将由一个名为Flagger的项目执行。Flagger作为Kubernetes operator运行。它允许用户指定一个自定义对象,该对象会通知Flagger观察一个部署并创建额外的主要部署(primary deployment)和金丝雀部署。作为本文的一部分,我们将使用Flagger与Istio作为服务网格。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"简而言之,当我们创建一个部署时,Flagger会将该部署克隆到一个主部署。然后它修改与原始部署相关的服务以指向这个新的主部署。该主部署本身会被缩减到0。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Flagger使用Istio virtualservices来执行实际的金丝雀发布。当一个新版本的应用程序被部署时,Flagger将原始部署缩减到原始规格,并将金丝雀服务关联到部署。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在,一定比例的流量被路由到这个金丝雀服务。基于预定义的指标,Flagger开始将越来越多的流量路由到这个金丝雀服务。一旦100%的流量被迁移到金丝雀服务,主部署就会以原始部署相同的规格重新创建。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下来,将更新virtualservice以将100%的流量返回到主服务。在流量转换之后,原始部署被缩减为0,Flagger operator等待并监控后续的部署更新。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Flagger执行金丝雀发布"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了开始使用Flagger,我们需要执行以下操作:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"设置监控和Istio"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"设置Flagger和flagger-loadtest"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"部署一个demo程序并执行金丝雀发布"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1.设置监控和Istio"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了设置monitoring和istio,我们将在持续交付中设置几个ClusterGroups:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"监控"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: fleet.cattle.io\/v1alpha1\nkind: ClusterGroup\nmetadata:\n name: monitoring\n namespace: fleet-default\nspec:\n selector:\n matchLabels:\n monitoring: enable"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Istio"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: fleet.cattle.io\/v1alpha1\nkind: ClusterGroup\nmetadata:\n name: istio\n namespace: fleet-default\nspec:\n selector:\n matchLabels:\n istio: enabled"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在,我们将设置我们的monitoring和istio Gitrepos以指向使用这些ClusterGroups:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"监控repo"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: fleet.cattle.io\/v1alpha1\nkind: GitRepo\nmetadata:\n name: monitoring\n namespace: fleet-default\nspec:\n branch: master\n insecureSkipTLSVerify: false\n paths:\n - monitoring\n - monitoring-crd\n repo: https:\/\/github.com\/ibrokethecloud\/core-bundles\n targets:\n - clusterGroup: monitoring"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"Istio repo"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: fleet.cattle.io\/v1alpha1\nkind: GitRepo\nmetadata:\n name: istio\n namespace: fleet-default\nspec:\n branch: master\n insecureSkipTLSVerify: false\n paths:\n - istio\n - kiali\n repo: https:\/\/github.com\/ibrokethecloud\/core-bundles\n targets:\n - clusterGroup: istio"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了触发部署,我们将使用所需的标签为这些ClusterGroups分配一个集群:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/20\/20e00a4a65cca9660ce1c1b634db1369.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/3c\/3c33083ea1cf0dba032bb7a73af462f0.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在几分钟之内,监控和istio应用程序应该在指定集群上安装完毕。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.设置Flagger和flagger-loadtest"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作为安装Flagger的一部分,我们将安装flagger-loadtest以帮助在我们的工作负载上生成请求。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"请注意:flagger-loadtest仅在本次demo中需要。在实际应用场景中,你的应用程序将会使用真实的流量。Flagger将根据来自真实流量的指标启动切换。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们将设置一个ClusterGroup金丝雀,如下所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: fleet.cattle.io\/v1alpha1\nkind: ClusterGroup\nmetadata:\n name: canary\n namespace: fleet-default\nspec:\n selector:\n matchLabels:\n canary: enabled"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/fb\/fbc8609269f3027eff25410e5d5b5fac.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在我们可以设置flagger Gitrepo来使用这个ClusterGroup"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: fleet.cattle.io\/v1alpha1\nkind: GitRepo\nmetadata:\nname: flagger\nnamespace: fleet-default\nspec:\nbranch: master\ninsecureSkipTLSVerify: false\npaths:\n- flagger\n- flagger-loadtest\nrepo: https:\/\/github.com\/ibrokethecloud\/user-bundles\ntargets:\n- clusterGroup: canary"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/56\/56eab0d920df880d4bfc48840701de5a.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如我们之前所了解的,要触发部署我们将分配一个集群到Flagger ClusterGroup"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/99\/9932dc985e3dc55f8aebb29b1215c721.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/51\/519906c8a2babd961c776a61abc0ee9f.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在几分钟之内,Flagger和flagger-loadtest helm charts将会被部署到该集群"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/1c\/1ca3e4cf4167563443a62c2c576f470e.png","alt":"图片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"请注意,在部署Flagger时,它将所有的标签和注释从源部署中复制到金丝雀和主部署中。持续交付将使用对象上的标签来核对和识别它们属于哪个底层的Bundle。Flagger对此进行了设置,在默认设置中,持续交付将报告不在GitRepo中的额外的主部署和金丝雀部署。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了避免这种情况,Flagger helm chart中的includeLabelPrefix设置被传递并设置为dummy,以指示Flagger只包括前缀为dummy的标签。这有助于我们绕过持续交付的reconciliation logic。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"fleet.yaml如下所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\ndefaultNamespace: istio-system\nhelm:\nreleaseName: flagger\nrepo: https:\/\/flagger.app\nchart: flagger\nversion: 1.6.2\nvalues:\ncrd.create: true\nmeshProvider: istio\nmetricsServer: http:\/\/rancher-monitoring-prometheus.cattle-monitoring-system:9090\nincludeLabelPrefix: dummy\ndiff:\ncomparePatches:\n- apiVersion: apps\/v1\nkind: Deployment\nname: flagger\nnamespace: istio-system\noperations:\n- {\"op\": \"remove\", \"path\": \"\/spec\/template\/spec\/containers\/0\/resources\/limits\/cpu\"}\n- {\"op\": \"remove\", \"path\": \"\/spec\/template\/spec\/containers\/0\/volumeMounts\"}\n- {\"op\": \"remove\", \"path\": \"\/spec\/template\/spec\/volumes\"}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所有基础服务设置完成后,我们现在可以开始部署我们的工作负载。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"3.部署Demo应用程序并进行金丝雀发布"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在我们添加canary-demo-app GitRepo到目标canaryClusterGroup"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: fleet.cattle.io\/v1alpha1\nkind: GitRepo\nmetadata:\n name: canary-demo-app\n namespace: fleet-default\nspec:\n branch: master\n insecureSkipTLSVerify: false\n paths:\n - canary-demo-app\n repo: https:\/\/github.com\/ibrokethecloud\/user-bundles\n targets:\n - clusterGroup: canary"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这将出发demo app的部署到canary-demo命名空间。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n(⎈ |digitalocean:canary-demo)\n~\n▶ kubectl get deployment\nNAME READY UP-TO-DATE AVAILABLE AGE\nfleet-simple-app 0\/0 0 0 80s\nfleet-simple-app-primary 1\/1 1 1 80s\n(⎈ |digitalocean:canary-demo)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"控制发布行为的金丝雀对象如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: flagger.app\/v1beta1\nkind: Canary\nmetadata:\n name: fleet-simple-app\n namespace: canary-demo\nspec:\n targetRef:\n apiVersion: apps\/v1\n kind: Deployment\n name: fleet-simple-app\n service:\n port: 8080\n analysis:\n interval: 1m\n threshold: 10\n maxWeight: 50\n stepWeight: 10\n metrics:\n - name: request-success-rate\n thresholdRange:\n min: 99\n interval: 1m\n - name: request-duration\n thresholdRange:\n max: 500\n interval: 1m\n webhooks:\n - name: load-test\n url: http:\/\/flagger-loadtester.loadtester\/\n timeout: 5s\n metadata:\n type: cmd\n cmd: \"hey -z 1m -q 10 -c 2 http:\/\/fleet-simple-app-canary.canary-demo:8080\""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里面的关键项目时webhook来进行负载测试,以产生足够的指标让Flagger能够开始切换流量。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们同时能够看到金丝雀对象的状态,如下所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n(⎈ |digitalocean:canary-demo)\n~\n▶ kubectl get canary\nNAME STATUS WEIGHT LASTTRANSITIONTIME\nfleet-simple-app Initialized 0 2021-03-22T06:25:17Z"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们现在可以通过更新canary-demo-app的GitRepo,用新版本的镜像来触发金丝雀发布。在几分钟之后,我们应该看到源部署使用来自GitRepo的新镜像进行扩展。此外,金丝雀对象变成Progressing状态,金丝雀发布的比重发生变化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n▶ kubectl get deploy\nNAME READY UP-TO-DATE AVAILABLE AGE\nfleet-simple-app 1\/1 1 1 6m5s\nfleet-simple-app-primary 1\/1 1 1 6m5s\n(⎈ |digitalocean:canary-demo)\n~\n▶ kubectl get canary\nNAME STATUS WEIGHT LASTTRANSITIONTIME\nfleet-simple-app Progressing 0 2021-03-22T06:30:17Z\n▶ kubectl get canary\nNAME STATUS WEIGHT LASTTRANSITIONTIME\nfleet-simple-app Progressing 10 2021-03-22T06:31:17Z"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"执行中的金丝雀还与Istio virtualservice中不断变化的比重相对应。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\napiVersion: networking.istio.io\/v1beta1\nkind: VirtualService\nmetadata:\n creationTimestamp: \"2021-03-22T06:25:17Z\"\n generation: 2\n managedFields:\n - apiVersion: networking.istio.io\/v1alpha3\n fieldsType: FieldsV1\n fieldsV1:\n f:metadata:\n f:ownerReferences:\n .: {}\n k:{\"uid\":\"6ae2a7f1-6949-484b-ab48-c385e9827a11\"}:\n .: {}\n f:apiVersion: {}\n f:blockOwnerDeletion: {}\n f:controller: {}\n f:kind: {}\n f:name: {}\n f:uid: {}\n f:spec:\n .: {}\n f:gateways: {}\n f:hosts: {}\n f:http: {}\n manager: flagger\n operation: Update\n time: \"2021-03-22T06:25:17Z\"\n name: fleet-simple-app\n namespace: canary-demo\n ownerReferences:\n - apiVersion: flagger.app\/v1beta1\n blockOwnerDeletion: true\n controller: true\n kind: Canary\n name: fleet-simple-app\n uid: 6ae2a7f1-6949-484b-ab48-c385e9827a11\n resourceVersion: \"10783\"\n uid: b5aaaf34-7b16-4ba9-972c-b60756943da8\nspec:\n gateways:\n - mesh\n hosts:\n - fleet-simple-app\n http:\n - route:\n - destination:\n host: fleet-simple-app-primary\n weight: 90\n - destination:\n host: fleet-simple-app-canary\n weight: 10"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再过一会儿,我们应该看到Flagger在推动金丝雀发布,并且主要的部署被切换到新版本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n▶ kubectl get canary\nNAME STATUS WEIGHT LASTTRANSITIONTIME\nfleet-simple-app Promoting 0 2021-03-22T06:37:17Z\n\n\n▶ kubectl get pods\nNAME READY STATUS RESTARTS AGE\nfleet-simple-app-64cd54dfd-tkk8v 2\/2 Running 0 9m2s\nfleet-simple-app-primary-854d4d84b5-qgfc8 2\/2 Running 0 74s"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在最终完成部署之后,我们应该看到原来的部署被缩减:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n▶ kubectl get canary\nNAME STATUS WEIGHT LASTTRANSITIONTIME\nfleet-simple-app Finalising 0 2021-03-22T06:38:17Z\n(⎈ |digitalocean:canary-demo)\n~\n▶ kubectl get pods\nNAME READY STATUS RESTARTS AGE\nfleet-simple-app-64cd54dfd-tkk8v 2\/2 Terminating 0 9m53s\nfleet-simple-app-primary-854d4d84b5-qgfc8 2\/2 Running 0 2m5s\n▶ kubectl get deploy\nNAME READY UP-TO-DATE AVAILABLE AGE\nfleet-simple-app 0\/0 0 0 15m\nfleet-simple-app-primary 1\/1 1 1 15m"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在这之后,金丝雀对象应该是成功状态:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"\n▶ kubectl get canary\nNAME STATUS WEIGHT LASTTRANSITIONTIME\nfleet-simple-app Succeeded 0 2021-03-22T06:39:17Z"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大功告成!在本文中,我们展示了如何使用持续交付、利用第三方工具(如Flagger)来为我们的工作负载执行金丝雀发布。欢迎跟着本教程进行操作,如果有任何问题,也欢迎扫描文末二维码,添加小助手为好友,进入Rancher官方技术交流群与各位Rancher用户一起交流。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文转载自:RancherLabs(ID:RancherLabs)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文链接:"},{"type":"link","attrs":{"href":"https:\/\/mp.weixin.qq.com\/s\/UvQ0xp_Saj4I2duqNlursA","title":"xxx","type":null},"content":[{"type":"text","text":"借助Rancher持续交付,3步实现金丝雀发布!"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章