Flaggerは通常、Deploymentと同じ名前のServiceを作成します。もしも既存の同名Serviceがある場合、Flaggerはそれを管理下に置き(=リコンサイル対象とする)、spec.selector.appなどを書き換えることが知られています。
では、ServiceがDeploymentと関連しつつも、名前が異なる場合はどうなるでしょうか。Flaggerはそれを認識し、管理下に置くのでしょうか。それとも管理することはないのでしょうか。検証してみました。
検証環境
- Kubernetes: Kind v1.32.2
- Flagger: v1.41.0
- Gateway API: v1.2.0
- Envoy Gateway: v1.3.2
検証方法
-
検証環境のセットアップ
- Kindクラスタを作成
- Gateway API (v1.2.0)をインストール
- Cert Manager (v1.17.1)をインストール
- Envoy Gateway (v1.3.2)をインストール
- GatewayClassとGatewayを作成
- Flagger (v1.41.0)をインストール
セットアップ手順の詳細
-
Kindクラスタの作成
kind create cluster
-
Gateway API(v1.2.0)のインストール
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
-
Cert Manager(v1.17.1)のインストール
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.1/cert-manager.yaml kubectl wait --for=condition=available --timeout=60s deployment/cert-manager -n cert-manager kubectl wait --for=condition=available --timeout=60s deployment/cert-manager-webhook -n cert-manager kubectl wait --for=condition=available --timeout=60s deployment/cert-manager-cainjector -n cert-manager
-
Envoy Gateway(v1.3.2)のインストール
kubectl apply --server-side -f https://github.com/envoyproxy/gateway/releases/download/v1.3.2/install.yaml kubectl wait --for=condition=available --timeout=600s deployment/envoy-gateway -n envoy-gateway-system
-
GatewayClassとGatewayの作成
kubectl apply -f manifests/gatewayclass.yaml kubectl wait --for=condition=accepted --timeout=60s gatewayclass/eg kubectl apply -f manifests/gateway.yaml kubectl wait --for=condition=programmed --timeout=60s gateway/eg
gatewayclass.yaml
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: eg spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller parametersRef: group: gateway.envoyproxy.io kind: EnvoyProxy name: clusterip-config namespace: envoy-gateway-system --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: clusterip-config namespace: envoy-gateway-system spec: provider: type: Kubernetes kubernetes: envoyService: type: ClusterIP
gateway.yaml
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: eg spec: gatewayClassName: eg listeners: - name: http protocol: HTTP port: 80
-
Flagger(v1.41.0)のインストール
kubectl apply -f https://raw.githubusercontent.com/fluxcd/flagger/v1.41.0/artifacts/flagger/crd.yaml kubectl get ns flagger-system || kubectl create ns flagger-system helm repo add flagger https://flagger.app helm upgrade -i flagger flagger/flagger \ --version 1.41.0 \ --namespace flagger-system \ --set prometheus.install=false \ --set meshProvider=gatewayapi:v1 \ --set metricsServer=none
-
以下のリソースをデプロイ:
- Deployment名:
podinfo
- Service名:
podinfo-different-name
(Deployment名と異なる) - Canary名:
podinfo
(Deployment名と同じ)
kubectl apply -f manifests/deployment.yaml kubectl apply -f manifests/service.yaml kubectl apply -f manifests/canary.yaml
デプロイしたマニフェストファイルの内容
deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: podinfo spec: replicas: 2 selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfo image: stefanprodan/podinfo:latest ports: - containerPort: 9898
service.yaml
apiVersion: v1 kind: Service metadata: name: podinfo-different-name spec: selector: app: podinfo ports: - port: 9898 targetPort: 9898
canary.yaml
apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo spec: targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo progressDeadlineSeconds: 60 service: port: 9898 targetPort: 9898 gatewayRefs: - name: eg namespace: default analysis: interval: 1s threshold: 5 maxWeight: 50 stepWeight: 10
- Deployment名:
検証結果
デプロイ後のServiceリソース
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8m30s
podinfo ClusterIP 10.96.126.169 <none> 9898/TCP 5m39s
podinfo-canary ClusterIP 10.96.20.177 <none> 9898/TCP 5m49s
podinfo-different-name ClusterIP 10.96.141.217 <none> 9898/TCP 6m12s
podinfo-primary ClusterIP 10.96.130.137 <none> 9898/TCP 5m49s
注意: podinfo
サービス(Deploymentと同名)は、Canaryリソースが作成されてから少し遅れて作成されます。
元のService(podinfo-different-name)
apiVersion: v1
kind: Service
metadata:
# ownerReferencesなし - Flaggerに管理されていない
name: podinfo-different-name
namespace: default
spec:
# セレクタは変更されていない
selector:
app: podinfo
ports:
- port: 9898
targetPort: 9898
Flaggerが作成したpodinfo-primaryサービス
apiVersion: v1
kind: Service
metadata:
labels:
app: podinfo-primary
name: podinfo-primary
namespace: default
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: podinfo
uid: c388a7b6-6dc9-4aa9-b9f1-e55ad8f31575
spec:
selector:
app: podinfo-primary
ports:
- name: http
port: 9898
targetPort: 9898
Flaggerが作成したpodinfo-canaryサービス
apiVersion: v1
kind: Service
metadata:
labels:
app: podinfo-canary
name: podinfo-canary
namespace: default
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: podinfo
uid: c388a7b6-6dc9-4aa9-b9f1-e55ad8f31575
spec:
selector:
app: podinfo
ports:
- name: http
port: 9898
targetPort: 9898
Flaggerが作成したDeploymentと同名のサービス(podinfo)
apiVersion: v1
kind: Service
metadata:
annotations:
helm.toolkit.fluxcd.io/driftDetection: disabled
kustomize.toolkit.fluxcd.io/reconcile: disabled
labels:
app: podinfo
name: podinfo
namespace: default
ownerReferences:
- apiVersion: flagger.app/v1beta1
blockOwnerDeletion: true
controller: true
kind: Canary
name: podinfo
uid: c388a7b6-6dc9-4aa9-b9f1-e55ad8f31575
spec:
selector:
app: podinfo-primary # プライマリにトラフィックをルーティング
ports:
- name: http
port: 9898
targetPort: 9898
結論
検証の結果、以下のことが確認できました:
- Flaggerは、Deployment名と異なる名前のServiceを管理対象として認識しない
- Deployment
podinfo
と一致しない名前の Servicepodinfo-different-name
は、Flaggerによって制御・変更されなかった
- Deployment
- Flaggerは独自のサービスを新たに作成する
- Canaryリソースをデプロイすると、Flaggerは以下の3つのServiceを作成した:
-
podinfo-primary
- プライマリバージョンのPodにトラフィックを送るサービス -
podinfo-canary
- カナリアバージョンのPodにトラフィックを送るサービス -
podinfo
- Deploymentと同名のサービス(少し遅れて作成)。これが実際のエンドユーザートラフィックを受け取り、内部的にはpodinfo-primary
にルーティングする
-
- これらのServiceはすべてFlaggerによって管理され、ownerReferencesが設定されている
- Canaryリソースをデプロイすると、Flaggerは以下の3つのServiceを作成した:
- 元のServiceは変更されない
-
podinfo-different-name
Serviceは、Flaggerによって変更されることなく元の状態のまま残っている - セレクタやその他の設定も変更されていない
-
- Flaggerの内部メカニズム
- Flaggerは、Deploymentと同名のサービス(
podinfo
)を作成してエンドユーザートラフィックを受け取り、内部的にpodinfo-primary
とpodinfo-canary
の間でトラフィックを制御する - この制御により、段階的にトラフィックをカナリアバージョンに移行するCanaryデプロイメントを実現している
- Flaggerは、Deploymentと同名のサービス(
この検証から、Flaggerはデプロイメント名と一致しないサービスを認識せず、管理下に置かないことが明らかになりました。これにより、Flaggerによる自動管理を避けたい場合は、Deployment名とは異なる名前でServiceを作成することが有効な戦略であることが確認できました。
お知らせ
弊社Craftsman Softwareでは、Kubernetesやクラウドネイティブに興味のあるエンジニアを募集しています!詳細は採用ページをご覧ください。