金丝雀部署

现在让我们部署 Catalog Product Detail 后端服务的新版本(版本 2), 并更改 proddetail VirtualRouter,将 90% 的流量路由到 proddetail-v1 版本 1,将 10% 路由到 proddetail-v2 版本 2。

随着我们对 proddetail-v2 越来越有信心,我们可以以线性方式增加到上面的流量。

canary

构建 Catalog Detail新版本service

aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
PROJECT_NAME=eks-app-mesh-demo
export APP_VERSION_2=2.0
for app in catalog_detail; do
  aws ecr describe-repositories --repository-name $PROJECT_NAME/$app >/dev/null 2>&1 || \
  aws ecr create-repository --repository-name $PROJECT_NAME/$app >/dev/null
  TARGET=$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$PROJECT_NAME/$app:$APP_VERSION_2
  cd apps/$app
  docker build -t $TARGET -f version2/Dockerfile .
  docker push $TARGET
done
cd ../../.

部署 Catalog Detail Version 2 所需资源

下面的 canary.yaml 文件,可以看到我们已将路由以 10% 添加到新服务 proddetail-v2 , 90% 到现有服务 proddetail-v1

apiVersion: appmesh.k8s.aws/v1beta2
kind: VirtualNode
metadata:
  name: proddetail-v2
  namespace: prodcatalog-ns
spec:
  podSelector:
    matchLabels:
      app: proddetail2
  listeners:
    - portMapping:
        port: 3000
        protocol: http
      healthCheck:
        protocol: http
        path: '/ping'
        healthyThreshold: 2
        unhealthyThreshold: 2
        timeoutMillis: 2000
        intervalMillis: 5000
  serviceDiscovery:
    dns:
      hostname: proddetail2.prodcatalog-ns.svc.cluster.local
---
apiVersion: appmesh.k8s.aws/v1beta2
kind: VirtualRouter
metadata:
  name: proddetail-router
  namespace: prodcatalog-ns
spec:
  listeners:
    - portMapping:
        port: 3000
        protocol: http
  routes:
    - name: proddetail-route
      httpRoute:
        match:
          prefix: /
        action:
          weightedTargets:
            - virtualNodeRef:
                name: proddetail-v1
              weight: 90
            - virtualNodeRef:
                name: proddetail-v2
              weight: 10
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: proddetail2
  namespace: prodcatalog-ns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: proddetail2
  template:
    metadata:
      labels:
        app: proddetail2
    spec:
      serviceAccountName: prodcatalog-envoy-proxies
      containers:
        - name: proddetail
          image: "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/eks-app-mesh-demo/catalog_detail:${APP_VERSION_2}"
          imagePullPolicy: Always
          livenessProbe:
            httpGet:
              path: /ping
              port: 3000
            initialDelaySeconds: 0
            periodSeconds: 10
            timeoutSeconds: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /ping
              port: 3000
            successThreshold: 3
          ports:
            - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: proddetail2
  namespace: prodcatalog-ns
  labels:
    app: proddetail2
spec:
  ports:
    - name: "http"
      port: 3000
      targetPort: 3000
  selector:
    app: proddetail2

让我们对proddetail 服务的新版本进行部署:

envsubst < ./deployment/canary.yaml | kubectl apply -f -
virtualnode.appmesh.k8s.aws/proddetail-v2 created
virtualrouter.appmesh.k8s.aws/proddetail-router configured
deployment.apps/proddetail2 created
service/proddetail2 created

检查 proddetail 服务新版本的对应资源:

kubectl get all -n prodcatalog-ns | grep 'proddetail2\|proddetail-v2'

image-20210714224934368

pod/proddetail2-9687989db-xxxx      3/3     Running   0          5m52s
service/proddetail2     ClusterIP      10.100.XX.YYY    <none>                                                                          3000/TCP       18m
deployment.apps/proddetail2     1/1     1            1           5m52s
replicaset.apps/proddetail2-96879yyyxx      1         1         1       5m52s
virtualnode.appmesh.k8s.aws/proddetail-v2   arn:aws:appmesh:us-west-2:405710966773:mesh/prodcatalog-mesh/virtualNode/proddetail-v2_prodcatalog-ns   18m