
CD被认为是一种企业软件开发实践;它是已建立的CI原则自然演变的结果。 但是,CD仍然很少出现,这可能是由于管理的复杂性以及担心部署不成功会影响系统可用性的缘故。
Flagger是开源的Kubernetes运营商,旨在消除混乱的关系。 它使用Istio流量补偿和Prometheus指标自动分析金丝雀部署,以分析托管部署期间的应用程序行为。
以下是有关如何在Google Kubernetes Engine(GKE)中配置和使用Flagger的分步指南。
配置Kubernetes集群
首先,使用Istio加载项创建GKE群集(如果您没有GCP帐户,则可以在此处注册以获取免费积分)。
登录到Google Cloud,创建一个项目并为其计费。 安装gcloud命令行实用程序,并使用gcloud init
定制项目。
设置默认项目,计算区域和区域(用项目替换PROJECT_ID
):
gcloud config set project PROJECT_ID gcloud config set compute/region us-central1 gcloud config set compute/zone us-central1-a
启用GKE服务并使用HPA和Istio附加组件创建集群:
gcloud services enable container.googleapis.com K8S_VERSION=$(gcloud beta container get-server-config --format=json | jq -r '.validMasterVersions[0]') gcloud beta container clusters create istio \ --cluster-version=${K8S_VERSION} \ --zone=us-central1-a \ --num-nodes=2 \ --machine-type=n1-standard-2 \ --disk-size=30 \ --enable-autorepair \ --no-enable-cloud-logging \ --no-enable-cloud-monitoring \ --addons=HorizontalPodAutoscaling,Istio \ --istio-config=auth=MTLS_PERMISSIVE
上面的命令将创建一个默认节点池,其中包括两个n1-standard-2
虚拟机(vCPU:2,RAM 7.5 GB,磁盘:30 GB)。 理想情况下,值得将Istio组件与其工作负载隔离开来,但是没有简单的方法可以在专用节点池中运行Istio吊舱。 Istio清单被视为只读清单,GKE将撤消任何更改,例如绑定到节点或与炉膛断开连接。
配置kubectl
凭据:
gcloud container clusters get-credentials istio
创建集群管理员角色绑定:
kubectl create clusterrolebinding "cluster-admin-$(whoami)" \ --clusterrole=cluster-admin \ --user="$(gcloud config get-value core/account)"
安装Helm命令行工具:
brew install kubernetes-helm
Homebrew 2.0现在也可用于Linux 。
为Tiller创建服务帐户和集群角色绑定:
kubectl -n kube-system create sa tiller && \ kubectl create clusterrolebinding tiller-cluster-rule \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:tiller
在kube-system
展开Tiller:
helm init --service-account tiller
您应该考虑在Helm和Tiller之间使用SSL。 有关保护Helm安装的更多信息,请参阅docs.helm.sh
确认设置:
kubectl -n istio-system get svc
几秒钟后,GCP应该为istio-ingressgateway
分配一个外部IP地址。
Istio输入网关设置
使用istio-gateway
的IP地址创建一个称为istio-gateway
的静态IP地址:
export GATEWAY_IP=$(kubectl -n istio-system get svc/istio-ingressgateway -ojson | jq -r .status.loadBalancer.ingress[0].ip) gcloud compute addresses create istio-gateway --addresses ${GATEWAY_IP} --region us-central1
现在,您需要一个Internet域并可以访问您的DNS注册器。 添加两个A条目(用您的域替换example.com
):
istio.example.com A ${GATEWAY_IP} *.istio.example.com A ${GATEWAY_IP}
验证DNS通配符是否正常工作:
watch host test.istio.example.com
创建一个Istio通用网关,以通过HTTP在服务网格之外提供服务:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: public-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
将以上资源另存为public-gateway.yaml,然后应用它:
kubectl apply -f ./public-gateway.yaml
没有SSL,任何生产系统都不能在Internet上提供服务。 要使用cert-manager,CloudDNS和Let's Encrypt保护Istio网关,请阅读Flagger GKE 文档 。
旗杆安装
GKE Istio加载项不包括Prometheus实例,该实例清除了Istio遥测服务。 由于Flagger使用Istio HTTP指标执行金丝雀分析,因此您需要部署以下Prometheus配置,类似于官方Istio Helm方案随附的配置。
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master kubectl apply -f ${REPO}/artifacts/gke/istio-prometheus.yaml
添加Flagger Helm存储库:
helm repo add flagger https://flagger.app
istio-system
启用Slack通知,在istio -system istio-system
展开Flagger:
helm upgrade -i flagger flagger/flagger \ --namespace=istio-system \ --set metricsServer=http://prometheus.istio-system:9090 \ --set slack.url=https://hooks.slack.com/services/YOUR-WEBHOOK-ID \ --set slack.channel=general \ --set slack.user=flagger
如果Flagger可以通过端口9090与Istio Prometheus服务进行通信,则可以在任何名称空间中安装Flagger。
Flagger具有用于金丝雀分析的Grafana仪表板。 在istio-system
安装Grafana:
helm upgrade -i flagger-grafana flagger/grafana \ --namespace=istio-system \ --set url=http://prometheus.istio-system:9090 \ --set user=admin \ --set password=change-me
通过创建虚拟服务,通过开放的网关扩展Grafana(将example.com
替换为您的域):
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: grafana namespace: istio-system spec: hosts: - "grafana.istio.example.com" gateways: - public-gateway.istio-system.svc.cluster.local http: - route: - destination: host: flagger-grafana
将以上资源另存为grafana-virtual-service.yaml,然后应用它:
kubectl apply -f ./grafana-virtual-service.yaml
在浏览器中转到http://grafana.istio.example.com
时,应将您定向到Grafana登录页面。
使用Flagger进行Web应用程序部署
Flagger部署Kubernetes,并在必要时部署水平自动缩放(HPA),然后创建一系列对象(Kubernetes部署,ClusterIP服务和Istio虚拟服务)。 这些对象在服务网格中打开应用程序,并管理金丝雀分析和升级。

创建启用Istio Sidecar实现的测试名称空间:
REPO=https://raw.githubusercontent.com/stefanprodan/flagger/master kubectl apply -f ${REPO}/artifacts/namespaces/test.yaml
创建一个部署和炉膛自动水平缩放工具:
kubectl apply -f ${REPO}/artifacts/canaries/deployment.yaml kubectl apply -f ${REPO}/artifacts/canaries/hpa.yaml
部署测试负载服务以在金丝雀分析期间生成流量:
helm upgrade -i flagger-loadtester flagger/loadtester \ --namepace=test
创建自定义金丝雀资源(用您的域替换example.com
):
apiVersion: flagger.app/v1alpha3 kind: Canary metadata: name: podinfo namespace: test spec: targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo progressDeadlineSeconds: 60 autoscalerRef: apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler name: podinfo service: port: 9898 gateways: - public-gateway.istio-system.svc.cluster.local hosts: - app.istio.example.com canaryAnalysis: interval: 30s threshold: 10 maxWeight: 50 stepWeight: 5 metrics: - name: istio_requests_total threshold: 99 interval: 30s - name: istio_request_duration_seconds_bucket threshold: 500 interval: 30s webhooks: - name: load-test url: http://flagger-loadtester.test/ timeout: 5s metadata: cmd: "hey -z 1m -q 10 -c 2 http://podinfo.test:9898/"
将以上资源另存为podinfo-canary.yaml,然后应用它:
kubectl apply -f ./podinfo-canary.yaml
如果成功,以上分析将在五分钟内执行,每半分钟检查一次HTTP指标。 您可以使用以下公式确定验证和升级Canary部署所需的最短时间: interval * (maxWeight / stepWeight)
。 金丝雀CRD字段记录在这里 。
在几秒钟内,Flagger将创建金丝雀对象:
# applied deployment.apps/podinfo horizontalpodautoscaler.autoscaling/podinfo canary.flagger.app/podinfo # generated deployment.apps/podinfo-primary horizontalpodautoscaler.autoscaling/podinfo-primary service/podinfo service/podinfo-canary service/podinfo-primary virtualservice.networking.istio.io/podinfo
打开浏览器并转到app.istio.example.com
,您应该看到演示应用程序的版本号。
自动金丝雀分析和推广
Flagger实现了一个控制环路,该环路将流量逐渐移至Canary,同时测量关键性能指标,例如HTTP请求的成功率,平均请求持续时间和心跳性能。 根据分析,KPI金丝雀前进或被中断,分析结果发布在Slack中。

当下列对象之一更改时,金丝雀部署开始:
- 部署PodSpec(容器映像,命令,端口,环境等)
- ConfigMap作为卷安装或转换为环境变量
- 机密作为卷安装或转换为环境变量
更新容器映像时启动金丝雀部署:
kubectl -n test set image deployment/podinfo \ podinfod=quay.io/stefanprodan/podinfo:1.4.1
Flagger发现部署版本已更改,并开始对其进行分析:
kubectl -n test describe canary/podinfo Events: New revision detected podinfo.test Scaling up podinfo.test Waiting for podinfo.test rollout to finish: 0 of 1 updated replicas are available Advance podinfo.test canary weight 5 Advance podinfo.test canary weight 10 Advance podinfo.test canary weight 15 Advance podinfo.test canary weight 20 Advance podinfo.test canary weight 25 Advance podinfo.test canary weight 30 Advance podinfo.test canary weight 35 Advance podinfo.test canary weight 40 Advance podinfo.test canary weight 45 Advance podinfo.test canary weight 50 Copying podinfo.test template spec to podinfo-primary.test Waiting for podinfo-primary.test rollout to finish: 1 of 2 updated replicas are available Promotion completed! Scaling down podinfo.test
在分析过程中,可以使用Grafana跟踪金丝雀的结果:

请注意:如果在金丝雀分析期间将新更改应用于部署,Flagger将重新启动分析阶段。
列出集群中所有“金丝雀”:
watch kubectl get canaries --all-namespaces NAMESPACE NAME STATUS WEIGHT LASTTRANSITIONTIME test podinfo Progressing 15 2019-01-16T14:05:07Z prod frontend Succeeded 0 2019-01-15T16:15:07Z prod backend Failed 0 2019-01-14T17:05:07Z
如果启用了Slack通知,您将收到以下消息:

自动回滚
在金丝雀分析期间,您可能会生成综合HTTP 500错误和较高的响应延迟,以检查Flagger是否将停止部署。
创建一个测试子并在其中执行以下操作:
kubectl -n test run tester \ --image=quay.io/stefanprodan/podinfo:1.2.1 \ -- ./podinfo --port=9898 kubectl -n test exec -it tester-xx-xx sh
HTTP 500错误生成:
watch curl http://podinfo-canary:9898/status/500
延迟产生:
watch curl http://podinfo-canary:9898/delay/1
当检查失败次数达到阈值时,流量将路由回到主通道,canary被缩放为零,并且部署被标记为不成功。
Canary错误和延迟峰值将作为Kubernetes事件记录下来,并由Flagger以JSON格式记录:
kubectl -n istio-system logs deployment/flagger -f | jq .msg Starting canary deployment for podinfo.test Advance podinfo.test canary weight 5 Advance podinfo.test canary weight 10 Advance podinfo.test canary weight 15 Halt podinfo.test advancement success rate 69.17% < 99% Halt podinfo.test advancement success rate 61.39% < 99% Halt podinfo.test advancement success rate 55.06% < 99% Halt podinfo.test advancement success rate 47.00% < 99% Halt podinfo.test advancement success rate 37.00% < 99% Halt podinfo.test advancement request duration 1.515s > 500ms Halt podinfo.test advancement request duration 1.600s > 500ms Halt podinfo.test advancement request duration 1.915s > 500ms Halt podinfo.test advancement request duration 2.050s > 500ms Halt podinfo.test advancement request duration 2.515s > 500ms Rolling back podinfo.test failed checks threshold reached 10 Canary failed! Scaling down podinfo.test
如果启用了Slack通知,则在达到期限或达到分析过程中失败检查的最大数量时,您将收到一条消息:

总结
除了启动Kubernetes外,启动Istio等服务网格将提供自动指标,日志和协议,但是工作负载的部署仍然取决于外部工具。 Flagger试图通过添加Istio的渐进式交付功能来改变这一状况。
Flagger与任何Kubernetes CI / CD解决方案兼容,并且可以使用webhooks轻松扩展canary分析,以执行系统集成/验收测试,压力测试或任何其他用户测试。 因为Flagger是声明性的,并且对Kubernetes事件作出响应,所以可以将其与Weave Flux或JenkinsX一起用于GitOps管道。 如果您使用的是JenkinsX,则可以安装带有jx附加组件的Flagger。
Flagger受Weaveworks支持,并为Weave Cloud提供金丝雀部署。 该项目在GKE,EX和带有kubeadm的裸机上进行了测试。
如果您有任何改进Flagger的建议,请通过stefanprodan / flagger向GitHub发送问题或PR。 欢迎捐款!
曾荫权 。