KubernetesはIngress-nginxを使用してグレースケール公開機能を実装します

Ingressを使用してグレースケールパブリッシングを実現

この記事の元のリンク:https://blog.csdn.net/xzk9381/article/details/109570832

1.カナリアルールの説明

Ingress-Nginxは、さまざまなシナリオでグレースケールリリースとテストを実現するためのIngress Annotationsの構成をサポートするK8S入力ツールです(Ingress-Nginxはバージョン0.21.0で導入されたカナリア関数です)。Nginx Annotationsは、次の4種類のカナリアルールをサポートしています。

  • nginx.ingress.kubernetes.io/canary-by-header:リクエストヘッダーに基づくトラフィックセグメンテーション。グレースケールリリースとA / Bテストに適しています。リクエストヘッダーが設定されている場合、リクエストalwaysはカナリアバージョンまで送信されます。リクエストヘッダーが設定されている場合、リクエストneverはカナリアインレットに送信されません。その他の値のヘッダー、ヘッダーは無視され、優先度は他のカナリアルールによる要求は優先順位を比較します。
  • nginx.ingress.kubernetes.io/canary-by-header-value:一致するリクエストヘッダーの値。CanaryIngressで指定されたサービスにリクエストをルーティングするようにIngressに通知するために使用されます。リクエストヘッダーがこの値に設定されると、カナリアエントリにルーティングされます。このルールにより、ユーザーはリクエストヘッダーの値をカスタマイズできます。これは、前のアノテーション(つまり、canary-by-header)と一緒に使用する必要があります。
  • nginx.ingress.kubernetes.io/canary-weight:サービスの重みに基づくトラフィックセグメンテーション。青緑色の展開に適しており、重みの範囲は0〜100で、CanaryIngressの指定されたサービスにリクエストをパーセンテージでルーティングします。重み0は、カナリアルールがカナリアポータルのサービスにリクエストを送信しないことを意味します。重み100は、すべてのリクエストがカナリアポータルに送信されることを意味します。
  • nginx.ingress.kubernetes.io/canary-by-cookie:Cookieベースのトラフィックセグメンテーション。グレースケールパブリッシングとA / Bテストに適しています。CanaryIngressで指定されたサービスにリクエストをルーティングするようにIngressに通知するために使用されるCookie。Cookieの値が設定されているalways場合、それはインレットカナリアにルーティングされます。Cookieの値が設定されているnever場合、リクエストはカナリアのインレットに送信されません。他の値の場合、他のカナリアとのCookieリクエストの優先度ルールは無視されます。レベル比較。

注:カナリアルールは、優先度の高い順に次のように並べ替えられます。

canary-by-header-> canary-by-cookie-> canary-weight

上記の4つの注釈ルールは、次の2つのカテゴリに分類できます。

  1. 重量に基づくカナリアルール:

  1. ユーザーの要求に基づくカナリアルール:

2つ目は、テストケースを展開する

1.公式バージョンサービスをデプロイします

まず、サービスの公式バージョンを表すデプロイメントを作成し、yamlコンテンツを次のように記述します。

---
apiVersion: v1
kind: Namespace
metadata:
  name: ns-myapp
  labels:
    name: ns-myapp

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: production
  namespace: ns-myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: production
  template:
    metadata:
      labels:
        app: production
    spec:
      containers:
      - name: production
        image: mirrorgooglecontainers/echoserver:1.10
        ports:
        - containerPort: 8080
        env:
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:
  name: production
  namespace: ns-myapp
  labels:
    app: production
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: production

このサービスのIngressルーティングルールを作成します。yamlファイルの内容は次のとおりです。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: production
  namespace: ns-myapp
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: ingress.test.com
    http:
      paths:
      - backend:
          serviceName: production
          servicePort: 80

上記のyamlファイルを適用し、作成後にk8sで次の情報を表示します。

[k8s-master ~]# kubectl get ingress -n ns-myapp
NAME         CLASS    HOSTS              ADDRESS        PORTS   AGE
production   <none>   ingress.test.com   10.16.13.201   80      4m25s

[k8s-master ~]# kubectl get pod -n ns-myapp
NAME                          READY   STATUS    RESTARTS   AGE
production-5698c4565c-jmjn5   1/1     Running   0          7m11s

コマンドラインアクセスのこの時点でingress.test.com、次のことがわかります。

# curl ingress.test.com

Hostname: production-5698c4565c-jmjn5

Pod Information:
	node name:	dumlog013201
	pod name:	production-5698c4565c-jmjn5
	pod namespace:	ns-myapp
	pod IP:	10.42.0.74

Server values:
	server_version=nginx: 1.13.3 - lua: 10008

Request Information:
	client_address=10.16.13.201
	method=GET
	real path=/
	query=
	request_version=1.1
	request_scheme=http
	request_uri=http://ingress.test.com:8080/

Request Headers:
	accept=*/*
	host=ingress.test.com
	user-agent=curl/7.64.1
	x-forwarded-for=10.2.130.18
	x-forwarded-host=ingress.test.com
	x-forwarded-port=80
	x-forwarded-proto=http
	x-real-ip=10.2.130.18
	x-request-id=3019362be59228ee2284f5737fa39eb1
	x-scheme=http

Request Body:
	-no body in request-

この記事の元のリンク:https://blog.csdn.net/xzk9381/article/details/109570832

2.カナリアバージョンサービスをデプロイします

次に、グレースケールテストとして使用するサービスのカナリアバージョンを作成します。

生産上記参照のバージョンproduction.yaml、ドキュメント、およびカナリアバージョンを含む、アプリケーションのカナリアバージョンを作成deploymentし、serviceちょうどに、簡単なデモの便宜のために(production.yamlでの展開やサービスのキーワードproductionのための直接交換canary関与している可能性がある実際のシーンビジネスコードの変更で)。

3.体重に基づくカナリアルールテスト

重みベースのトラフィックセグメンテーションの一般的なアプリケーションシナリオは蓝绿部署、重みを0または100に設定することで実装できることです。たとえば、グリーンバージョンをメインパーツとして設定し、ブルーバージョンのエントリをカナリアとして設定できます。最初は、重みが0に設定されているため、トラフィックはBlueバージョンにプロキシされません。新しいバージョンのテストと検証が正常に完了すると、Blueバージョンの重みを100に設定できます。つまり、すべてのトラフィックがGreenバージョンからBlueに切り替えられます。

以下canary.ingressはyamlファイルであり、アプリケーションベースのルーティングカナリアバージョンのウェイト(入力)を作成します。

注:グレーリリースメカニズムを有効にするには、最初にnginx.ingress.kubernetes.io/canary: "true"カナリアを設定する必要があります。カナリアバージョンのIngressの例では、ウェイトベースのトラフィックセグメンテーションアノテーションルールを使用して、トラフィックリクエストの30%をカナリアバージョンに割り当てます。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: canary
  namespace: ns-myapp
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
  rules:
  - host: ingress.test.com
    http:
      paths:
      - backend:
          serviceName: canary
          servicePort: 80

次に、コマンドラインで次のコマンドを使用してドメイン名ingress.test.comに100回アクセスし、各バージョンに割り当てられたトラフィックの割合を計算します。

c=0;p=0;for i in $(seq 100); do result=$(curl -s ingress.test.com | grep  Hostname | awk -F: '{print $2}'); [[ ${result} =~ ^[[:space:]]canary ]] && let c++ || let p++; done;echo "production:${p}; canary:${c};"

次の結果が得られます。

production:73; canary:28;

4.ユーザーの要求に基づくカナリアルールテスト

1.リクエストヘッダーに基づく

リクエストヘッダーに基づくトラフィックセグメンテーションの一般的なアプリケーションシナリオは、次のとおりです灰度发布或 A/B 测试场景

Ingressのカナリアバージョンに注釈を追加しますnginx.ingress.kubernetes.io/canary-by-header: canary(ここでの注釈の値は任意の値にすることができます)。これにより、現在のIngressの実装はトラフィックセグメンテーションのリクエストヘッダーに基づいています。

Ingressのカナリアバージョンのyamlファイルを次のコンテンツに変更します。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: canary
  namespace: ns-myapp
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
    nginx.ingress.kubernetes.io/canary-by-header: "canary"
spec:
  rules:
  - host: ingress.test.com
    http:
      paths:
      - backend:
          serviceName: canary
          servicePort: 80

説明:カナリアルールcanary-by-header - > canary-by-cookie - > canary-weightは次の並べ替えを優先するため、上記のルールは元のカナリアの重みの入力を無視します。

無入口上記の規則に起因するcanary-by-header: "canary"特定の値、すなわちあるnginx.ingress.kubernetes.io/canary-by-header-value訪問の時間は、唯一できるように、ルールcanary割り当てnever又はalways場合ヘッダ情報canary:never、要求はカナリアチャネルに送信されないであろう;場合ヘッダ情報canary:always、リクエストは常にカナリアバージョンに送信されます。例は次のとおりです。

[k8s-master ~ ]# curl -s -H "canary:never" ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5

[k8s-master ~ ]# curl -s -H "canary:always" ingress.test.com | grep Hostname
Hostname: canary-79c899d85-992nw

前の注釈(ヘッダーごとのカナリア)に基づいて1つ追加することもできnginx.ingress.kubernetes.io/canary-by-header-value: user-valueます。一致したリクエストをCanaryIngressで指定されたサービスにルーティングするようにIngressに通知するために使用されます。

Ingressのカナリアバージョンのyamlファイルを次のコンテンツに変更します。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: canary
  namespace: ns-myapp
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "30"
    nginx.ingress.kubernetes.io/canary-by-header: "canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "true"
spec:
  rules:
  - host: ingress.test.com
    http:
      paths:
      - backend:
          serviceName: canary
          servicePort: 80

上記の入力ルールは、ヘッダー情報をとして設定しますcanary:true。つまり、カナリアバージョンは、ヘッダー値が満たされた場合にのみルーティングされます。例は次のとおりです。

[k8s-master ~ ]# curl -s ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5

[k8s-master ~ ]# curl -s -H "canary:test" ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5

[k8s-master ~ ]# curl -s -H "canary:true" ingress.test.com | grep Hostname
Hostname: canary-79c899d85-992nw

5つのCookieベースのカナリアルールテスト

リクエストヘッダーに基づくアノテーションの使用規則に似ています。たとえばA/B 测试场景、カナリアバージョンの北京ユーザーにローカルアクセスを許可する必要があります。次に、Cookieアノテーションがに設定されているnginx.ingress.kubernetes.io/canary-by-cookie: "users_from_Beijing"場合、バックグラウンドでログインユーザーリクエストを確認できます。ユーザーのアクセスソースが北京からのものである場合は、北京のユーザーがカナリアバージョンにのみアクセスするようにCookieusers_from_Beijingalways設定します。

Ingressのカナリアバージョンのyamlファイルを次のコンテンツに変更します。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: canary
  namespace: ns-myapp
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "user_from_beijing"
spec:
  rules:
  - host: ingress.test.com
    http:
      paths:
      - backend:
          serviceName: canary
          servicePort: 80

アクセス例は次のとおりです。

[k8s-master ~ ]# curl -s -b "user_from_beijing=always" ingress.test.com | grep Hostname
Hostname: canary-79c899d85-992nw

[k8s-master ~ ]# curl -s -b "user_from_beijing=no" ingress.test.com | grep Hostname
Hostname: production-5698c4565c-jmjn5

この記事の元のリンク:https://blog.csdn.net/xzk9381/article/details/109570832

おすすめ

転載: blog.csdn.net/xzk9381/article/details/109570832