ArgoCD を使って GitOps を実現し Kubernetes 環境の CD について自動化を行う

GitOps は IaC 等を Git または Helm で管理しながら、インフラ・アプリケーション展開の自動化を行ってくれる運用フレームワークです。

インストール

Argocd のインストールについては terraform で行っています。
詳細については以下の記事に記載しています。
https://www.aimhighergg.com/argocd-vault-plugin-sidecar/

.
├── README.md
├── common
│   ├── resource.tf
│   └── values.yaml
├── production
│   ├── main.tf
│   ├── resource.tf -> ../common/resource.tf
│   └── values.yaml -> ../common/values.yaml
├── staging
│   ├── main.tf
│   ├── resource.tf -> ../common/resource.tf
│   └── values.yaml -> ../common/values.yaml
└── testing
    ├── main.tf
    ├── resource.tf -> ../common/resource.tf
    └── values.yaml -> ../common/values.yaml
terraform {
  backend "s3" {
    bucket  = "aimhighergg-tfstate"
    region  = "ap-northeast-1"
    key     = "helm-argocd-staging.tfstate"
    encrypt = true
  }
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
    helm = {
      source  = "hashicorp/helm"
      version = "2.10.1"
    }
    kubernetes = {
      source = "hashicorp/kubernetes"
      version = "2.27.0"
    }
  }
}
provider "aws" {
  profile = "default"
  region  = "ap-northeast-1"
}
provider "helm" {
  kubernetes {
    config_path    = "~/.kube/config_oci"
    config_context = "oci-rke-cluster"
  }
}
provider "kubernetes" {
    config_path    = "~/.kube/config_oci"
    config_context = "oci-rke-cluster"
}
resource "kubernetes_secret" "argocd_vault_plugin" {
  metadata {
    name      = "argocd-vault-plugin-credentials"
    namespace = "argocd"
  }
  data = {
    "AVP_AUTH_TYPE" = "k8s"
    "AVP_K8S_ROLE"  = "argocd"
    "AVP_TYPE"      = "vault"
    "VAULT_ADDR"    = "http://vault.vault.svc.cluster.local:8200"
  }
  type = "Opaque"
}

resource "helm_release" "argocd" {
  name             = "argocd"
  wait             = true
  repository       = "https://argoproj.github.io/argo-helm"
  chart            = "argo-cd"
  namespace        = "argocd"
  version          = "6.7.3"
  create_namespace = true

  set {
    name  = "server.service.type"
    value = "NodePort"
  }
  values = [
    file("values.yaml")
  ]
  depends_on = [
    kubernetes_secret.argocd_vault_plugin
  ]
}
global:
  logging:
    level: info
configs:
  cmp:
    create: true
    plugins:
      argocd-vault-plugin-helm:
        allowConcurrency: true
        discover:
          find:
            command:
              - sh
              - "-c"
              - "find . -name 'Chart.yaml' && find . -name 'values.yaml'"
        generate:
          command:
            - sh
            - "-c"
            - |
              helm template $ARGOCD_APP_NAME -n $ARGOCD_APP_NAMESPACE ${ARGOCD_ENV_HELM_ARGS} . |
              argocd-vault-plugin generate -s argocd:argocd-vault-plugin-credentials -
        lockRepo: false
      argocd-vault-plugin-kustomize:
        discover:
          find:
            command:
              - sh
              - "-c"
              - "find . -name '*.yaml' | xargs -I {} grep \"-
          wget -O argocd-vault-plugin https://github.com/argoproj-labs/argocd-vault-plugin/releases/download/v${AVP_VERSION}/argocd-vault-plugin_${AVP_VERSION}_${CPU_ARCHITECTURE} &&
          chmod +x argocd-vault-plugin &&
          mv argocd-vault-plugin custom-tools/
      volumeMounts:
        - mountPath: /custom-tools
          name: custom-tools
  extraContainers:
    - name: avp-helm
      command: [/var/run/argocd/argocd-cmp-server]
      image: quay.io/argoproj/argocd:v2.10.4
      securityContext:
        runAsNonRoot: true
        runAsUser: 999
      volumeMounts:
        - name: var-files
          mountPath: /var/run/argocd
        - name: plugins
          mountPath: /home/argocd/cmp-server/plugins
        - name: argocd-cmp-cm
          mountPath: /home/argocd/cmp-server/config/plugin.yaml
          subPath: argocd-vault-plugin-helm.yaml
        - name: custom-tools
          mountPath: /usr/local/bin/argocd-vault-plugin
          subPath: argocd-vault-plugin
    - name: avp-kustomize
      command: [/var/run/argocd/argocd-cmp-server]
      image: quay.io/argoproj/argocd:v2.10.4
      securityContext:
        runAsNonRoot: true
        runAsUser: 999
      volumeMounts:
        - name: var-files
          mountPath: /var/run/argocd
        - name: plugins
          mountPath: /home/argocd/cmp-server/plugins
        - name: argocd-cmp-cm
          mountPath: /home/argocd/cmp-server/config/plugin.yaml
          subPath: argocd-vault-plugin-kustomize.yaml
        - name: custom-tools
          mountPath: /usr/local/bin/argocd-vault-plugin
          subPath: argocd-vault-plugin
  volumes:
    - name: argocd-cmp-cm
      configMap:
        name: argocd-cmp-cm
    - name: cmp-tmp
      emptyDir: {}
    - name: custom-tools
      emptyDir: {}
  volumeMounts:
    - name: argocd-cmp-cm
      mountPath: /home/argocd/cmp-server/config
    - name: custom-tools
      mountPath: /usr/local/bin/argocd-vault-plugin
      subPath: argocd-vault-plugin

ArgoCD は Git, Helm の変更を追跡し 目的の状態となるように deploy してくれます。ArgoCD の特徴としては Web から視覚的に状態が把握できる点です。 目的の状態と差分があれば、 OutOfSync 状態と判断され、 Webから視覚的にわかるようになっています。
下記ではコマンドで意図的に pod をスケールし outOfSync の状態を一時的に作り出していますが、すぐに git で定義した状態に自動で deploy してくれます。

また、自動・手動での同期設定が行えたり、様々な同期オプションが用意されています。デプロイ方法については、 Kustomize と helm が選択できます。Git の場合は HEAD, Tags から リビジョンを選択でき、kustomize が配置されている path を指定することで環境に合わせた deploy が可能です。 Helm の場合は、リポジトリのURL, Chart, Chart version を指定でき、Values Files, Values の設定が可能です。

ArgoCD のメリット


ArgoCD の GitOps が kubernetes の CD と相性が良い点もメリットですが、kubernetes オブジェクトを可視化することで全体像の把握が容易になる点もメリットと考えています。
aimhighergg.com のリポジトリでは kustomize で overlay を利用し、複数のオブジェクトで構成されていますが、以下の様に全体像が把握できます。

通信の流れも可視化されます。

ArgoCD を利用することにより Kubernetes の CD 環境を実現し、オブジェクトについても可視化されるため kubernetes の CD には必要なツールと考えています。CI と組み合わせれば インフラを意識せず開発に注力できます。次回の記事では CI と組み合わせた CI/CD 環境についても紹介します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です