0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FlaggerはDeploymentと名前が異なるServiceは管理下に置かない

Posted at

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

検証方法

  1. 検証環境のセットアップ

    • Kindクラスタを作成
    • Gateway API (v1.2.0)をインストール
    • Cert Manager (v1.17.1)をインストール
    • Envoy Gateway (v1.3.2)をインストール
    • GatewayClassとGatewayを作成
    • Flagger (v1.41.0)をインストール
    セットアップ手順の詳細
    1. Kindクラスタの作成

      kind create cluster
      
    2. Gateway API(v1.2.0)のインストール

      kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
      
    3. 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
      
    4. 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
      
    5. 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
      
    6. 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
      
  2. 以下のリソースをデプロイ:

    • 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
    

検証結果

デプロイ後の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

結論

検証の結果、以下のことが確認できました:

  1. Flaggerは、Deployment名と異なる名前のServiceを管理対象として認識しない
    • Deployment podinfo と一致しない名前の Service podinfo-different-name は、Flaggerによって制御・変更されなかった
  2. Flaggerは独自のサービスを新たに作成する
    • Canaryリソースをデプロイすると、Flaggerは以下の3つのServiceを作成した:
      • podinfo-primary - プライマリバージョンのPodにトラフィックを送るサービス
      • podinfo-canary - カナリアバージョンのPodにトラフィックを送るサービス
      • podinfo - Deploymentと同名のサービス(少し遅れて作成)。これが実際のエンドユーザートラフィックを受け取り、内部的にはpodinfo-primaryにルーティングする
    • これらのServiceはすべてFlaggerによって管理され、ownerReferencesが設定されている
  3. 元のServiceは変更されない
    • podinfo-different-name Serviceは、Flaggerによって変更されることなく元の状態のまま残っている
    • セレクタやその他の設定も変更されていない
  4. Flaggerの内部メカニズム
    • Flaggerは、Deploymentと同名のサービス(podinfo)を作成してエンドユーザートラフィックを受け取り、内部的にpodinfo-primarypodinfo-canaryの間でトラフィックを制御する
    • この制御により、段階的にトラフィックをカナリアバージョンに移行するCanaryデプロイメントを実現している

この検証から、Flaggerはデプロイメント名と一致しないサービスを認識せず、管理下に置かないことが明らかになりました。これにより、Flaggerによる自動管理を避けたい場合は、Deployment名とは異なる名前でServiceを作成することが有効な戦略であることが確認できました。

お知らせ

弊社Craftsman Softwareでは、Kubernetesやクラウドネイティブに興味のあるエンジニアを募集しています!詳細は採用ページをご覧ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?