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?

Project Sveltosチートシート

Last updated at Posted at 2025-05-15

内容は随時更新していきます。

ClusterProfile

ClusterProfileの概要

ClusterProfileは、Sveltosシステムにおいて複数のKubernetesクラスターにアドオンをデプロイするための主要なカスタムリソースです。ClusterProfileを使用することで、管理クラスターから複数のワークロードクラスターに対して一貫した設定を適用できます。

ClusterProfileの基本概念

ClusterProfileはクラスタースコープのリソースで、以下の主要な機能を提供します:

  1. クラスター選択: ラベルセレクターを使用して、設定を適用する対象クラスターを選択します
  2. アドオン定義: 選択したクラスターにデプロイするリソース(Helmチャート、Kubernetesリソース、Kustomizeリソース)を定義します
  3. 同期モード: リソースの適用方法(一度のみ、継続的、ドリフト検出付き継続的、ドライラン)を指定します

ClusterProfileの実装例1

以下は、本番環境(env: fvラベルを持つ)のすべてのクラスターにKyvernoをデプロイする例です:

# ClusterProfile定義
apiVersion: config.projectsveltos.io/v1beta1
kind: ClusterProfile
metadata:
  name: deploy-kyverno
spec:
  clusterSelector:
    matchLabels:
      env: fv
  syncMode: Continuous
  helmCharts:
  - repositoryURL:    https://kyverno.github.io/kyverno/
    repositoryName:   kyverno
    chartName:        kyverno/kyverno
    chartVersion:     v3.3.3
    releaseName:      kyverno-latest
    releaseNamespace: kyverno
    helmChartAction:  Install
  policyRefs:
  - name: disallow-latest
    namespace: default
    kind: ConfigMap
  patches:
  - target:
      group: apps
      version: v1
      kind: Deployment
      name: ".*"
    patch: |
      - op: add
        path: /metadata/labels/environment
        value: production

引用: Post Renderer Patches - Projectsveltos Documentation

ClusterProfileの実装例2

以下は、 karpenter: enabled ラベルを持つすべてのクラスターにKarpenterのdefault NodePoolとEC2NodeClassをデプロイする例です:

apiVersion: config.projectsveltos.io/v1beta1
kind: ClusterProfile
metadata:
  name: karpenter-deployment
spec:
  clusterSelector:
    matchLabels:
      karpenter: enabled
  syncMode: ContinuousWithDriftDetection
  policyRefs:
  - name: karpenter-resources
    namespace: "{{ .Cluster.metadata.namespace }}"
    kind: ConfigMap
  templateResourceRefs:
  - resource:
      apiVersion: v1
      kind: ConfigMap
      name: cluster-config
      namespace: "{{ .Cluster.metadata.namespace }}"
    identifier: ClusterConfig
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: karpenter-resources
  namespace: default
  annotations:
    policy.projectsveltos.io/template: "ok"
data:
  nodepool.yaml: |
    apiVersion: karpenter.sh/v1
    kind: NodePool
    metadata:
      name: default
    spec:
      template:
        spec:
          nodeClassRef:
            group: karpenter.k8s.aws
            kind: EC2NodeClass
            name: default
  ec2nodeclass.yaml: |
    apiVersion: karpenter.k8s.aws/v1
    kind: EC2NodeClass
    metadata:
      name: default
    spec:
      kubelet:
        podsPerCore: 2
        maxPods: {{ if eq .ClusterConfig.data.environment "production" }}20{{ else }}10{{ end }}
        systemReserved:
            cpu: 100m
            memory: 100Mi
            ephemeral-storage: 1Gi
        kubeReserved:
            cpu: 200m
            memory: 100Mi
            ephemeral-storage: 3Gi
        evictionHard:
            memory.available: 5%
            nodefs.available: 10%
            nodefs.inodesFree: 10%
        evictionSoft:
            memory.available: 500Mi
            nodefs.available: 15%
            nodefs.inodesFree: 15%
        evictionSoftGracePeriod:
            memory.available: 1m
            nodefs.available: 1m30s
            nodefs.inodesFree: 2m
        evictionMaxPodGracePeriod: 60
        imageGCHighThresholdPercent: 85
        imageGCLowThresholdPercent: 80
        cpuCFSQuota: true
        clusterDNS: ["10.0.1.100"]
      amiFamily: AL2
      subnetSelectorTerms:
        - tags:
            karpenter.sh/discovery: "{{ .Cluster.metadata.name }}"
            environment: {{ .ClusterConfig.data.environment }}
      securityGroupSelectorTerms:
        - tags:
            karpenter.sh/discovery: "{{ .Cluster.metadata.name }}"
            environment: {{ .ClusterConfig.data.environment }}
      role: "KarpenterNodeRole-{{ .Cluster.metadata.name }}"
      instanceProfile: "KarpenterNodeInstanceProfile-{{ .Cluster.metadata.name }}"
      amiSelectorTerms:
        - tags:
            karpenter.sh/discovery: "{{ .Cluster.metadata.name }}"
            environment: {{ .ClusterConfig.data.environment }}
      tags:
        team: {{ .ClusterConfig.data.team }}
        app: {{ .ClusterConfig.data.application }}
      metadataOptions:
        httpEndpoint: enabled
        httpProtocolIPv6: disabled
        httpPutResponseHopLimit: 1
        httpTokens: required
      blockDeviceMappings:
        - deviceName: /dev/xvda
          ebs:
            volumeSize: {{ if eq .ClusterConfig.data.environment "production" }}100Gi{{ else }}50Gi{{ end }}
            volumeType: gp3
            iops: {{ if eq .ClusterConfig.data.environment "production" }}10000{{ else }}3000{{ end }}
            encrypted: true
            deleteOnTermination: true

templateResourceRefsで参照されているClusterConfigの例は以下の通りです。

apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-config
  namespace: default
data:
  environment: "production"
  team: "platform-team"
  application: "karpenter-autoscaler"
  region: "us-west-2"
  clusterType: "eks"
  nodeInstanceType: "m5.xlarge"
  minNodes: "3"
  maxNodes: "10"
  diskSize: "100"
  kubernetesVersion: "1.28"
  enableSpotInstances: "true"
  enableGPUNodes: "false"

参考1: NodeClasses | Karpenter
参考2: Templates - Projectsveltos Documentation

Kustomizeを使用した例

Kustomizeリソースを使用する場合の例:

apiVersion: config.projectsveltos.io/v1beta1
kind: ClusterProfile
metadata:
  name: hello-world
spec:
  clusterSelector:
    matchLabels:
      env: fv
  syncMode: Continuous
  kustomizationRefs:
  - namespace: flux2
    name: flux2
    kind: GitRepository
    path: ./helloWorld/
    targetNamespace: eng
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: flux2
  namespace: flux2
spec:
  interval: 1m0s
  ref:
    branch: main
  timeout: 60s
  url: ssh://git@github.com/gianlucam76/kustomize

引用: Sveltos - Kubernetes Add-on Controller | Manage Kubernetes Add-ons with Ease - Projectsveltos Documentation

同期モードの種類

ClusterProfileは以下の同期モードをサポートしています:

  1. OneTime: クラスター初期設定時に一度だけリソースをデプロイします。CNIプラグインなどの重要なインフラコンポーネントの初期デプロイに適しています。
  2. Continuous: ClusterProfileの変更を継続的に監視し、マッチするクラスターに自動的に適用します。複数クラスターの一貫性を維持するのに役立ちます。
  3. ContinuousWithDriftDetection: 継続的な同期に加えて、管理クラスターで定義された望ましい状態と実際のクラスター状態の間のドリフト(構成の乖離)を検出し、自動的に修正します。
  4. DryRun: 実際の変更を行わずにデプロイアクションをシミュレートします。テストや検証に役立ちます。
    構成ドリフト検出
    ContinuousWithDriftDetectionモードを使用すると、Sveltosは管理クラスターで定義された望ましい状態と実際のクラスター状態の間のドリフトを自動的に検出し、修正できます。 README.md:130-137

Subresources

projectsveltos.io/subresources annotationを付けるとstatus等のsubresourcesも合わせて更新する事ができます.

apiVersion: v1
kind: ConfigMap
metadata:
  annotations:
    projectsveltos.io/subresources: status
  name: load-balancer-service
  namespace: default
data:
  service.yaml: |
    apiVersion: v1
    kind: Service
    metadata:
      name: sveltos-subresource
      namespace: default
    spec:
      selector:
        app: foo
      ports:
      - name: my-port
        port: 443
        protocol: TCP
        targetPort: 1032
      type: LoadBalancer
    status:
      loadBalancer:
        ingress:
        - ip: 1.1.1.1

参考: Sveltos - Kubernetes Add-on Controller | Manage Kubernetes Add-ons with Ease - Projectsveltos Documentation

既存リソースの編集

以下のリソースがあるとします.

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    apps: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 1
EOF

以下のClusterProfileでそのリソースを編集することが可能です。

apiVersion: config.projectsveltos.io/v1beta1
kind: ClusterProfile
metadata:
  name: deploy-resources
spec:
  clusterSelector:
    matchLabels:
      env: production
  templateResourceRefs:
  - resource:
      apiVersion: apps/v1
      kind: Deployment
      name: nginx-deployment
      namespace: default
    identifier: NginxDeployment
  policyRefs:
  - kind: ConfigMap
    name: info
    namespace: default
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: info
  namespace: default
  annotations:
    projectsveltos.io/template: "true"  # add annotation to indicate Sveltos content is a template
data:
  secret.yaml: |
    {{ $depl := (getResource "NginxDeployment") }}
    {{ $depl := (chainSetField $depl "spec.replicas" (int64 1) ) }}
    {{ $depl := (chainSetField $depl "metadata.namespace" .Cluster.metadata.namespace ) }}
    {{ $depl := (chainSetField $depl "spec.template.spec.serviceAccountName" "default" ) }}
    {{ $depl := (chainSetField $depl "spec.paused" true ) }}
    {{ toYaml $depl }}

参考: Resource Manipulating Functions - Examples - Projectsveltos Documentation

ClusterProfileの動作の仕組み

ClusterProfileが作成または更新されると、以下のプロセスが実行されます:

  1. ClusterProfileReconcilerがClusterProfileを監視し、マッチするクラスターを選択します
  2. 各マッチするクラスターに対してClusterSummaryリソースを作成します
  3. デプロイ状態がClusterSummaryのステータスに反映されます

Event Manager

EventSource/EventTriggerの概要

ProjectsveltosのEventTriggerは、クラスターで発生したイベントに基づいてリソースを自動的に作成するための機能です。発生したイベントを表現するリソースはEventSourceです。以下に、シンプルなEventSource/EventTriggerの実装例を示します。

EventSource/EventTriggerの実装例1

以下はサービスがあったらNetworkPolicyを自動で作成する例です

---
apiVersion: lib.projectsveltos.io/v1beta1
kind: EventSource
metadata:
  name: sveltos-service
spec:
  collectResources: true
  resourceSelectors:
  - group: ""
    version: "v1"
    kind: "Service"
    labelFilters:
    - key: sveltos
      operation: Equal
      value: fv
---
apiVersion: lib.projectsveltos.io/v1beta1
kind: EventTrigger
metadata:
  name: service-network-policy
spec:
  sourceClusterSelector:
    matchLabels:
      env: fv
  eventSourceName: sveltos-service
  oneForEvent: true
  policyRefs:
  - name: network-policy
    namespace: default
    kind: ConfigMap
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: network-policy
  namespace: default
  annotations:
    projectsveltos.io/instantiate: ok # this annotation is what tells Sveltos to instantiate this ConfigMap
data:
  networkpolicy.yaml: |
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: front-{{ .Resource.metadata.name }}
      namespace: {{ .Resource.metadata.namespace }}
    spec:
      podSelector:
        matchLabels:
          {{ range $key, $value := .Resource.spec.selector }}
          {{ $key }}: {{ $value }}
          {{ end }}
      ingress:
        - from:
          - podSelector:
              matchLabels:
                app: internal
          ports:
            {{ range $port := .Resource.spec.ports }}
            - port: {{ $port.port }}
            {{ end }}

EventSource/EventTriggerの実装例2

以下は先ほどと同じサービスがあったらNetworkPolicyを自動で作成する例です。
ただし、ラベル sveltos: fv がついているServiceのみを対象としています。

---
apiVersion: lib.projectsveltos.io/v1beta1
kind: EventSource
metadata:
  name: sveltos-service
spec:
  collectResources: true
  resourceSelectors:
  - group: ""
    version: "v1"
    kind: "Service"
    evaluate: |
      function evaluate()
        hs = {}
        hs.matching = false
        hs.message = ""
        if obj.metadata.labels ~= nil then
          for key, value in pairs(obj.metadata.labels) do
            if key == "sveltos" then
              if value == "fv" then
                hs.matching = true
              end
            end
          end
        end
        return hs
      end
---
apiVersion: lib.projectsveltos.io/v1beta1
kind: EventTrigger
metadata:
  name: service-network-policy
spec:
  sourceClusterSelector:
    matchLabels:
      env: fv
  eventSourceName: sveltos-service
  oneForEvent: true
  policyRefs:
  - name: network-policy
    namespace: default
    kind: ConfigMap
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: network-policy
  namespace: default
  annotations:
    projectsveltos.io/instantiate: ok # this annotation is what tells Sveltos to instantiate this ConfigMap
data:
  networkpolicy.yaml: |
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: front-{{ .Resource.metadata.name }}
      namespace: {{ .Resource.metadata.namespace }}
    spec:
      podSelector:
        matchLabels:
          {{ range $key, $value := .Resource.spec.selector }}
          {{ $key }}: {{ $value }}
          {{ end }}
      ingress:
        - from:
          - podSelector:
              matchLabels:
                app: internal
          ports:
            {{ range $port := .Resource.spec.ports }}
            - port: {{ $port.port }}
            {{ end }}

EventSourceの実装例3

異なる種類のリソースをまとめて調べる例です。
以下は 対応する Deployment が存在しない HPA を検出する EventSource です。

apiVersion: lib.projectsveltos.io/v1beta1
kind: EventSource
metadata:
  name: sveltos-service
spec:
  collectResources: true
  resourceSelectors:
  - group: "apps"
    version: "v1"
    kind: "Deployment"
  - kind: HorizontalPodAutoscaler
    group: "autoscaling"
    version: v2
  aggregatedSelection: |
      function getKey(namespace, name)
        return namespace .. ":" .. name
      end

      function evaluate()
        local hs = {}
        hs.message = ""

        local deployments = {}
        local autoscalers = {}
        local deploymentsWithNoAutoscaler = {}

        for _, resource in ipairs(resources) do
          local kind = resource.kind
          if kind == "Deployment" then
            key = getKey(resource.metadata.namespace, resource.metadata.name)
            deployments[key] = true
          elseif kind == "HorizontalPodAutoscaler" then
            table.insert(autoscalers, resource)
          end
        end

        -- Check for each horizontalPodAutoscaler if there is a matching Deployment
        for _,hpa in ipairs(autoscalers) do
            key = getKey(hpa.metadata.namespace, hpa.spec.scaleTargetRef.name)
            if hpa.spec.scaleTargetRef.kind == "Deployment" then
              if not deployments[key] then
                table.insert(unusedAutoscalers, hpa)
              end
            end
        end

        if #unusedAutoscalers > 0 then
          hs.resources = unusedAutoscalers
        end
        return hs
      end

Classifier

Classifierの概要

Classifierは、Kubernetesクラスターの状態に基づいてクラスターを分類し、ラベルを付与するコンポーネントです。このラベル付けにより、クラスターは特定のClusterProfileにマッチするようになり、それに応じてアドオンやアプリケーションが自動的にデプロイされます。

Classifierの主な機能

Classifierは以下の基準に基づいてクラスターを分類できます:

  1. Kubernetesバージョン
  2. クラスター内にデプロイされているリソース
  3. Luaスクリプトによる評価

Classifierの動作の仕組み

  1. クラスターの状態の評価: Classifierはクラスターの状態(Kubernetesバージョンやデプロイされたリソースなど)を評価します
  2. マッチング: 定義された条件にクラスターがマッチする場合、ClassifierReportが生成されます
  3. ラベル付け: マッチしたクラスターに対して、Classifierで定義されたラベルが適用されます
  4. ClusterProfileの適用: ラベル付けされたクラスターは、そのラベルに基づいて特定のClusterProfileにマッチするようになります
  5. アドオンとアプリケーションのデプロイ: マッチしたClusterProfileに基づいて、アドオンやアプリケーションがクラスターにデプロイされます classifier_controller.go:445-463 classifier_controller.go:538-563

Classifierの実装例1

Kubernetesバージョンに基づくクラスターの分類.
例えば、Kubernetesバージョンが1.24.xのクラスターを分類し、特定のラベルを付与するClassifierを作成できます:

apiVersion: lib.projectsveltos.io/v1beta1
kind: Classifier
metadata:
  name: kubernetes-v1.24
spec:
  classifierLabels:
  - key: k8s-version
    value: v1.24
  kubernetesVersionConstraints:
  - comparison: GreaterThanOrEqualTo
    version: 1.24.0
  - comparison: LessThan
    version: 1.25.0

Kubernetesバージョンに基づくアドオンの自動アップグレード

Classifierを使用して、クラスターのKubernetesバージョンが更新されたときに自動的にアドオンをアップグレードすることができます。例えば:

  1. Kubernetes v1.24.xのクラスターには「gatekeeper: v3-9」というラベルを付与
  2. Kubernetes v1.25.x以上のクラスターには「gatekeeper: v3-10」というラベルを付与

これにより、クラスターがKubernetes v1.24.xからv1.25.xにアップグレードされると、Gatekeeperも自動的に3.9.0から3.10.0にアップグレードされます。

Classifierの制限事項

マネージドクラスターとマネジメントクラスターの関係

質問にあった「マネジメントクラスター上のリソースに基づいてマネージドクラスターにラベルを付与できるか?」という点については、Classifierはマネージドクラスター自体の状態に基づいてのみラベルを付与します。マネジメントクラスター上のリソース(例:KeptnMetric)に基づいてマネージドクラスターにラベルを付与することはできません。

このようなユースケースには、Sveltosのイベントフレームワークを使用することが推奨されています。

Classifierの技術的な実装

Classifierは以下のコンポーネントで構成されています:

  1. ClassifierReconciler: Classifier CRの調整を担当するコントローラー
  2. ClassifierReport: クラスターがClassifierの条件にマッチするかどうかを報告するCR
  3. KeyManager: ラベルの管理と競合解決を担当するコンポーネント

デプロイメントモード

Classifierは以下の2つのモードで動作します:

  1. AgentInMgmtCluster (Agentless): マネジメントクラスターでエージェントが実行され、マネージドクラスターを監視
  2. Agent in Managed Clusters: 各マネージドクラスターでエージェントが実行され、自身の状態を報告

レポートモード

ClassifierReportの収集方法も2つのモードがあります:

  1. CollectFromManagementCluster: マネジメントクラスターが定期的にマネージドクラスターからレポートを収集
  2. AgentSendReportsNoGateway: マネージドクラスターのエージェントがレポートを直接マネジメントクラスターに送信

まとめ

Sveltos Classifierは、クラスターの状態に基づいて動的にラベルを付与し、それによってClusterProfileとのマッチングを可能にする強力なツールです。特にKubernetesバージョンのアップグレードに伴うアドオンの自動アップグレードなど、クラスター管理の自動化に役立ちます。

ただし、マネジメントクラスター上のリソースに基づいてマネージドクラスターにラベルを付与することはできないという制限があります。このようなユースケースには、Sveltosのイベントフレームワークを使用することが推奨されています。

Q&A

Q1: Sveltos Agentのdeploymentを手動で削除した場合、自動的に回復しますか?

A1: いいえ、Sveltos Agentのdeploymentを手動で削除しても自動的には回復しません。

Q2: Sveltos Agentを回復するにはどうすればよいですか?

Sveltos AgentはClassifier Managerが管理しているため、クラスタに対応するClassifierリソースを再作成してClassifier Managerを再起動すればSveltos Agentが再生成されます。

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?