サービスを更新する際には、ローリングアップグレード、ブルーグリーンリリース、段階的リリースなどのリリース方法を使用できます。このトピックでは、Container Service for Kubernetes (ACK) クラスター内の Nginx Ingress Controller を使用して、アプリケーションの段階的リリースを実装する方法について説明します。
背景情報
段階的リリースおよびブルーグリーンリリースでは、既存の本番環境と同一の新しい本番環境を作成します。特定のルールに基づき、古いバージョンに影響を与えることなく、徐々に新バージョンへトラフィックを誘導します。新バージョンが安定したら、すべてのトラフィックを新バージョンに切り替えます。
ブルーグリーンリリースは段階的リリースの一種です。一部のユーザーは引き続き旧バージョンのサービスを使用し、他のユーザーのトラフィックは新バージョンに切り替えられます。新バージョンが安定している場合、すべてのユーザーを徐々に新バージョンに移行します。
ACK コンソールの段階的リリース機能では、次の 2 つの方法がサポートされています。
canary-* アノテーション方式: canary-* アノテーションを使用して、ブルーグリーンリリースおよび段階的リリースを構成できます。canary-* アノテーションは、段階的リリースを実装するための公式コミュニティ方式です。
service-* アノテーション方式(非推奨): service-* アノテーションは、ACK Nginx Ingress Controller で段階的リリースを実装するために以前使用されていた方式です。
利用シーン
クライアントリクエストに基づくトラフィック分割
オンライン環境でレイヤー 7 のサービスを提供している Service A があるとします。新機能を含む新バージョン Service A' をリリースしたい場合、Service A を直接置き換える代わりに、リクエストヘッダーに foo=bar が含まれている、または Cookie に foo=bar が含まれている場合にのみ、Service A' へのリクエストを転送できます。Service A' が安定して動作したら、Service A から Service A' へすべてのトラフィックを切り替え、その後 Service A をオフラインにします。

サービスの重みに基づくトラフィック分割
オンライン環境でレイヤー 7 のサービスを提供している Service B があるとします。いくつかの問題を修正し、新バージョン Service B' をリリースする必要があります。すべてのクライアントトラフィックを一度に新バージョンに切り替えるのではなく、20 % のトラフィックを Service B' に切り替えたいとします。Service B' が安定したら、Service B から Service B' へすべてのトラフィックを切り替え、その後 Service B をオフラインにします。

これらのアプリケーションリリース要件を満たすため、Alibaba Cloud Container Service Ingress Controller では次のトラフィック分割方法がサポートされています。
リクエストヘッダーに基づくトラフィック分割:段階的リリースおよび A/B テストのシナリオに適しています。
Cookie に基づくトラフィック分割:段階的リリースおよび A/B テストのシナリオに適しています。
クエリパラメーターに基づくトラフィック分割:段階的リリースおよび A/B テストのシナリオに適しています。
サービスの重みに基づくトラフィック分割:ブルーグリーンリリースのシナリオに適しています。
canary-* アノテーション方式
アノテーションの説明
Nginx Ingress Controller では、アプリケーションの段階的リリースをサポートするために、次の canary-* アノテーションを使用します。
アノテーション | 説明 | 適用可能な ACK Nginx Ingress Controller バージョン |
nginx.ingress.kubernetes.io/canary | | ≥v0.22.0 |
nginx.ingress.kubernetes.io/canary-by-header | | ≥v0.22.0 |
nginx.ingress.kubernetes.io/canary-by-header-value | | ≥v0.30.0 |
nginx.ingress.kubernetes.io/canary-by-header-pattern | リクエストヘッダーの値に基づく段階的リリースを指定し、正規表現を使用してマッチングを行います。 canary-by-header アノテーションと併用する必要があります。
値は、リクエストヘッダーの値とマッチングするための正規表現です。
| ≥v0.44.0 |
nginx.ingress.kubernetes.io/canary-by-cookie | | ≥v0.22.0 |
nginx.ingress.kubernetes.io/canary-weight | | ≥v0.22.0 |
nginx.ingress.kubernetes.io/canary-weight-total | | ≥v1.1.2 |
さまざまなグレースケール方式の優先順位は、次のとおり降順でランク付けされています。
canary-by-header > canary-by-cookie > canary-weight
説明 各 Ingress ルールでは、一度に 1 つのカナリア Ingress のみがサポートされます。追加のカナリア Ingress は無視されます。
ステップ 1:サービスのデプロイ
Nginx サービスをデプロイし、Nginx Ingress Controller を介してレイヤー 7 のドメイン名アクセスを提供します。
デプロイメントおよびサービスを作成します。
nginx.yaml ファイルを作成します。
YAML ファイルの表示
apiVersion: apps/v1
kind: Deployment
metadata:
name: old-nginx
spec:
replicas: 2
selector:
matchLabels:
run: old-nginx
template:
metadata:
labels:
run: old-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
imagePullPolicy: Always
name: old-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: old-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: old-nginx
sessionAffinity: None
type: NodePort
次のコマンドを実行して、デプロイメントおよびサービスを作成します。
kubectl apply -f nginx.yaml
Ingress をデプロイします。
ingress.yaml ファイルを作成します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
service:
name: old-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
serviceName: old-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
アクセスをテストします。
次のコマンドを実行して、外部 IP アドレスを取得します。
次のコマンドを実行して、ルーティングアクセスを確認します。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
old
ステップ 2:新サービスバージョンの段階的リリース
Nginx サービスの新バージョンを公開し、ルーティングルールを構成します。
デプロイメントおよびサービスの新バージョンをデプロイします。
nginx1.yaml ファイルを作成します。
YAML ファイルの表示
apiVersion: apps/v1
kind: Deployment
metadata:
name: new-nginx
spec:
replicas: 1
selector:
matchLabels:
run: new-nginx
template:
metadata:
labels:
run: new-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
imagePullPolicy: Always
name: new-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: new-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: new-nginx
sessionAffinity: None
type: NodePort
次のコマンドを実行して、更新されたデプロイメントおよびサービスをデプロイできます。
kubectl apply -f nginx1.yaml
新サービスバージョンにアクセスするためのルーティングルールを設定します。
ACK では、次の 3 種類のルーティングルールがサポートされています。要件に応じて選択してください。
特定のルールを満たすクライアントからのみ、新サービスバージョンへのアクセスを許可します。次の例では、リクエストヘッダーに foo=bar が含まれている場合にのみ、リクエストを新サービスバージョンにルーティングします。
上記の条件に基づき、ingress1.yaml ファイル内に gray-release-canary という名前の新しい Ingress リソースを作成します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release-canary
annotations:
# Canary を有効化します。
nginx.ingress.kubernetes.io/canary: "true"
# リクエストヘッダーは foo です。
nginx.ingress.kubernetes.io/canary-by-header: "foo"
# foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
service:
name: new-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release-canary
annotations:
# Canary を有効化します。
nginx.ingress.kubernetes.io/canary: "true"
# リクエストヘッダーは foo です。
nginx.ingress.kubernetes.io/canary-by-header: "foo"
# foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
serviceName: new-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress1.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
ルーティングアクセスを検証します。
次のコマンドを実行して、サービスにアクセスします。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
old
ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。
curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>
期待される出力:
new
コマンドを再度実行します。出力から、ヘッダー foo=bar を含むクライアントリクエストのみが、新サービスバージョンにルーティングされていることがわかります。
特定のルールに一致しないリクエストのうち、一定の割合を新しいアプリケーションバージョンにルーティングします。たとえば、必要な foo=bar ヘッダーを含まないリクエストについて、50 % のトラフィックを新しいアプリケーションバージョンにルーティングできます。
ステップ 2 で作成した Ingress を、次の内容で変更します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release-canary
annotations:
# Canary を有効化します。
nginx.ingress.kubernetes.io/canary: "true"
# リクエストヘッダーは foo です。
nginx.ingress.kubernetes.io/canary-by-header: "foo"
# foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
# 上記のルールを満たさない場合、50% のトラフィックを新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
service:
name: new-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release-canary
annotations:
# Canary を有効化します。
nginx.ingress.kubernetes.io/canary: "true"
# リクエストヘッダーは foo です。
nginx.ingress.kubernetes.io/canary-by-header: "foo"
# foo ヘッダーの値が bar の場合にのみ、リクエストを新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/canary-by-header-value: "bar"
# 上記のルールを満たさない場合、50% のトラフィックを新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
serviceName: new-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
ルーティングアクセスを検証します。
次のコマンドを実行して、サービスにアクセスします。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
old
ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。
curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>
期待される出力:
new
リクエストの特定の割合を新サービスバージョンにルーティングします。次の例では、50 % のトラフィックを新サービスバージョンにルーティングします。
ステップ 2 で作成した Ingress を、次の内容で変更します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release-canary
annotations:
# Canary を有効化します。
nginx.ingress.kubernetes.io/canary: "true"
# トラフィックの 50% を新サービスバージョン new-nginx にルーティングします。
# デフォルトの合計値は 100 です。
nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
service:
name: new-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release-canary
annotations:
# Canary を有効化します。
nginx.ingress.kubernetes.io/canary: "true"
# トラフィックの 50% を新サービスバージョン new-nginx にルーティングします。
# デフォルトの合計値は 100 です。
nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
serviceName: new-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
次のコマンドを実行して、ルーティングアクセスを検証します。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
コマンドを再度実行します。出力から、50 % のトラフィックが新サービスバージョンにルーティングされていることがわかります。
ステップ 3:旧サービスバージョンの削除
新サービスバージョンが安定しており、期待通りに動作することを確認したら、旧サービスバージョンをオフラインにして、新バージョンのみを実行状態にします。これを行うには、旧サービスを新バージョンのデプロイメントを指すように変更し、その後旧デプロイメントおよび新サービスを削除します。
旧サービスファイル nginx.yaml を変更して、新サービスを指すようにします。
YAML ファイルの表示
apiVersion: v1
kind: Service
metadata:
name: old-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
# 新サービスバージョンを指します。
run: new-nginx
sessionAffinity: None
type: NodePort
次のコマンドを実行して、サービスの旧バージョンをデプロイします。
kubectl apply -f nginx.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
次のコマンドを実行して、ルーティングを確認します。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
new
コマンドを再度実行します。すべてのリクエストが新サービスバージョンにルーティングされていることが確認できます。
次のコマンドを実行して、カナリア Ingress リソース gray-release-canary を削除します。
kubectl delete ingress gray-release-canary
旧デプロイメントおよび新サービスを削除します。
次のコマンドを実行して、旧デプロイメントを削除します。
kubectl delete deploy old-nginx
次のコマンドを実行して、新サービスを削除します。
kubectl delete svc new-nginx
service-* アノテーション方式
アノテーションの説明
Nginx Ingress Controller では、アプリケーションサービスの段階的リリースをサポートするために、次のアノテーションを使用します。
nginx.ingress.kubernetes.io/service-match
このアノテーションは、新サービスバージョンのルーティングルールを構成します。
nginx.ingress.kubernetes.io/service-match: |
<service-name>: <match-rule>
# メトリックの説明:
# service-name: サービス名。match-rule に一致するリクエストはこのサービスにルーティングされます。
# match-rule: ルーティングルール。
#
# ルーティングルール:
# 1. サポートされるマッチタイプ
# - header: リクエストヘッダーに基づく。正規表現マッチおよび完全一致をサポート。
# - cookie: Cookie に基づく。正規表現マッチおよび完全一致をサポート。
# - query: リクエストパラメーターに基づく。正規表現マッチおよび完全一致をサポート。
#
# 2. マッチ方法
# - 正規表現マッチ形式: /{regular expression}/。スラッシュ (/) は正規表現マッチを示します。
# - 完全一致形式: "{exact expression}"。二重引用符 ("") は完全一致を示します。
ルーティングルール構成の例:
# foo ヘッダーが正規表現 ^bar$ に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
new-nginx: header("foo", /^bar$/)
# foo ヘッダーが bar と完全に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
new-nginx: header("foo", "bar")
# foo Cookie が正規表現 ^sticky-.+$ に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
new-nginx: cookie("foo", /^sticky-.+$/)
# foo クエリパラメーターが bar と完全に一致するリクエストは、新サービスバージョン new-nginx に転送されます。
new-nginx: query("foo", "bar")
nginx.ingress.kubernetes.io/service-weight
このアノテーションは、旧サービスバージョンおよび新サービスバージョンのトラフィックの重みを構成します。
nginx.ingress.kubernetes.io/service-weight: |
<new-svc-name>:<new-svc-weight>, <old-svc-name>:<old-svc-weight>
メトリックの説明:
new-svc-name: 新サービスバージョンの名前。
new-svc-weight: 新サービスバージョンの重み。
old-svc-name: 旧サービスバージョンの名前。
old-svc-weight: 旧サービスバージョンの重み。
サービスの重み構成の例:
nginx.ingress.kubernetes.io/service-weight: |
new-nginx: 20, old-nginx: 60
ステップ 1:サービスのデプロイ
Nginx サービスをデプロイし、Nginx Ingress Controller を使用してレイヤー 7 のドメイン名アクセスを提供します。
デプロイメントおよびサービスを作成します。
nginx.yaml ファイルを作成します。
YAML ファイルの表示
apiVersion: apps/v1
kind: Deployment
metadata:
name: old-nginx
spec:
replicas: 2
selector:
matchLabels:
run: old-nginx
template:
metadata:
labels:
run: old-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/old-nginx
imagePullPolicy: Always
name: old-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: old-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: old-nginx
sessionAffinity: None
type: NodePort
次のコマンドを実行して、デプロイメントおよびサービスを作成します。
kubectl apply -f nginx.yaml
Ingress をデプロイします。
ingress.yaml ファイルを作成します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
service:
name: old-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
serviceName: old-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
アクセスをテストします。
次のコマンドを実行して、外部 IP アドレスを取得します。
次のコマンドを実行して、ルーティングアクセスを確認します。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
old
ステップ 2:新サービスバージョンの段階的リリース
Nginx サービスの新バージョンをデプロイし、ルーティングルールを構成します。
デプロイメントおよびサービスの新バージョンをデプロイします。
nginx1.yaml ファイルを作成します。
YAML ファイルの表示
apiVersion: apps/v1
kind: Deployment
metadata:
name: new-nginx
spec:
replicas: 1
selector:
matchLabels:
run: new-nginx
template:
metadata:
labels:
run: new-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs-sample/new-nginx
imagePullPolicy: Always
name: new-nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: new-nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: new-nginx
sessionAffinity: None
type: NodePort
デプロイメントおよびサービスの新バージョンをデプロイします。
kubectl apply -f nginx1.yaml
新サービスバージョンにアクセスするためのルーティングルールを設定します。
ACK では、次の 3 種類のルーティングルールがサポートされています。要件に応じて選択してください。
特定のルールを満たすクライアントからのみ、新サービスバージョンへのリクエストをルーティングします。次の例では、リクエストヘッダーに foo=bar が含まれている場合にのみ、リクエストを新サービスバージョンにルーティングします。
ステップ 2 で作成した Ingress を、次の内容で変更します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release
annotations:
# foo ヘッダーが正規表現 foo=bar に一致するリクエストは、新サービスバージョン new-nginx にルーティングされます。
nginx.ingress.kubernetes.io/service-match: |
new-nginx: header("foo", /^bar$/)
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
service:
name: old-nginx
port:
number: 80
pathType: ImplementationSpecific
# サービスの新バージョン。
- path: /
backend:
service:
name: new-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release
annotations:
# foo ヘッダーが正規表現 foo=bar に一致するリクエストは、新サービスバージョン new-nginx にルーティングされます。
nginx.ingress.kubernetes.io/service-match: |
new-nginx: header("foo", /^bar$/)
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
serviceName: old-nginx
servicePort: 80
# サービスの新バージョン。
- path: /
backend:
serviceName: new-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
ルーティングアクセスを確認します。
次のコマンドを実行して、サービスにアクセスします。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
old
ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。
curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>
期待される出力:
new
コマンドを再度実行します。出力から、ヘッダー foo=bar を含むクライアントリクエストのみが、新サービスバージョンにルーティングされていることがわかります。
特定のルールを満たすリクエストのうち、一定の割合を新サービスバージョンにルーティングします。次の例では、ヘッダーに foo=bar を含むクライアントリクエストのうち、50 % のトラフィックを新サービスバージョンにルーティングします。
ステップ 2 で作成した Ingress を、次の内容で変更します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release
annotations:
# foo ヘッダーが正規表現 foo=bar に一致するリクエストは、新サービスバージョン new-nginx にルーティングされます。
nginx.ingress.kubernetes.io/service-match: |
new-nginx: header("foo", /^bar$/)
# 上記のルールに基づき、トラフィックの 50% のみが新サービスバージョン new-nginx にルーティングされます。
nginx.ingress.kubernetes.io/service-weight: |
new-nginx: 50, old-nginx: 50
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
service:
name: old-nginx
port:
number: 80
pathType: ImplementationSpecific
# サービスの新バージョン。
- path: /
backend:
service:
name: new-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release
annotations:
# foo ヘッダーが正規表現 foo=bar に一致するリクエストは、新サービスバージョン new-nginx にルーティングされます。
nginx.ingress.kubernetes.io/service-match: |
new-nginx: header("foo", /^bar$/)
# 上記のルールに基づき、トラフィックの 50% のみが新サービスバージョン new-nginx にルーティングされます。
nginx.ingress.kubernetes.io/service-weight: |
new-nginx: 50, old-nginx: 50
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
serviceName: old-nginx
servicePort: 80
# サービスの新バージョン。
- path: /
backend:
serviceName: new-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
ルーティングアクセスを確認します。
次のコマンドを実行して、サービスにアクセスします。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
old
ヘッダーに foo=bar を含むクライアントリクエストを使用して、次のコマンドを実行してサービスにアクセスします。
curl -H "Host: www.example.com" -H "foo: bar" http://<EXTERNAL_IP>
期待される出力:
new
コマンドを再度実行します。出力から、ヘッダー foo=bar を含むクライアントリクエストのうち、50 % のトラフィックのみが新サービスバージョンにルーティングされていることがわかります。
リクエストの一定の割合を新サービスバージョンにルーティングします。次の例では、50 % のトラフィックを新サービスバージョンにルーティングします。
ステップ 2 で作成した Ingress を、次の内容で変更します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release
annotations:
# トラフィックの 50% を新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/service-weight: |
new-nginx: 50, old-nginx: 50
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
service:
name: old-nginx
port:
number: 80
pathType: ImplementationSpecific
# サービスの新バージョン。
- path: /
backend:
service:
name: new-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release
annotations:
# トラフィックの 50% を新サービスバージョン new-nginx にルーティングします。
nginx.ingress.kubernetes.io/service-weight: |
new-nginx: 50, old-nginx: 50
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの旧バージョン。
- path: /
backend:
serviceName: old-nginx
servicePort: 80
# サービスの新バージョン。
- path: /
backend:
serviceName: new-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
次のコマンドを実行して、ルーティングアクセスを確認します。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
コマンドを再度実行します。出力から、50 % のトラフィックが新サービスバージョンにルーティングされていることがわかります。
ステップ 3:旧サービスバージョンの削除
新サービスバージョンが一定期間安定して動作し、期待通りの結果が得られた後は、旧サービスバージョンをオフラインにして、新バージョンのみを実行状態にします。
ステップ 2 で作成した Ingress を、次の内容で変更します。
v1.19 以降のクラスターの場合
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gray-release
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
service:
name: new-nginx
port:
number: 80
pathType: ImplementationSpecific
v1.19 より前のクラスターの場合
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: gray-release
spec:
rules:
- host: www.example.com
http:
paths:
# サービスの新バージョン。
- path: /
backend:
serviceName: new-nginx
servicePort: 80
次のコマンドを実行して、Ingress をデプロイします。
kubectl apply -f ingress.yaml
次のコマンドを実行して、外部 IP アドレスを取得します。
kubectl get ingress
次のコマンドを実行して、ルーティングアクセスを確認します。
curl -H "Host: www.example.com" http://<EXTERNAL_IP>
期待される出力:
new
コマンドを再度実行します。出力から、すべてのリクエストが新サービスバージョンにルーティングされていることがわかります。
旧デプロイメントおよびサービスを削除します。
次のコマンドを実行して、旧デプロイメントを削除します。
kubectl delete deploy <Deployment_name>
次のコマンドを実行して、旧サービスを削除します。
kubectl delete svc <Service_name>