自宅KubernetesクラスターでArgoCDと格闘した話

はじめに

数ヶ月前から自宅Kubernetesクラスターの運用をはじめました。
過去に一度自宅Kubernetesに挑戦してはいたのですが、当時はクラスターを組んで満足してしまい、本格的な運用はしていませんでした。
今回は本格的に運用し、順次運用しているアプリケーションのKubernetes上への移行を進めています。
Kubernetesで実行するアプリケーションのmanifestはGitHubリポジトリに保管し、ArgoCDでGit Opsをするように設定したのですが、その作業の中でいくつかはまったポイントがあったので解決方法を記録に残しておこうと思います。

環境

  • Ubuntu 20.04 LTS
    • CPU 4Core
    • Memory 8GB
  • Kubernetes 1.24 (microk8s)
    • Control Plane x1
    • Node x2
  • ArgoCD v2.4.7

LoadBalancer TypeのServiceのApp HealthがずっとProgressingになる問題

これは原因や対処法がArgoCDのドキュメントに書いてありました。
argo-cd.readthedocs.io
status.loadBalancer{} となっているため、永遠にProgressingになるようです。
対処法としては、ArgoCDのヘルスチェックの仕組みを上書きして、強制的にstatusをHealthyにすれば良さそうです。
ArgoCDのConfigMapに以下のような設定を追加すればOKでした。

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-cm
data:
  resource.customizations.health.Service: |
    hs = {}
    if obj.status ~= nil then
      if obj.status.loadBalancer ~= nil then
        hs.status = "Healthy"
        hs.message = "LoadBalancer status is healthy"
        return hs
      end
    end

    hs.status = "Progressing"
    hs.message = "Waiting for LoadBalancer"
    return hs

余談ですが、ArgoCDのCustom Health CheckのロジックはLuaで書けることを初めて知りました。

Sync Statusが永遠に常にOut Of Syncになる問題

これは、ArgoCDがmanifestをapplyした後、manifestに記述されていないlabelやannotationが自動で追記され、差分が生じることが原因のようです。
具体的には、Datadogのinstallinfoやcluster-agentをArgoCDで管理しようとした際に発生しました。
datadog-installinfoというConfigMapのlabelやdatadog-cluster-agentのmetadataが書き換えられるため、差分として検知されOut Of Sync状態になるようです。
対処法としては、ignoreDifferencesの設定を追加すれば良さそうです。
今回は以下のような設定を追加しました。

spec:
  ignoreDifferences:
    - kind: ConfigMap
      group: ''
      name: datadog-installinfo
      namespace: monitoring
      jsonPointers:
        - "/metadata/labels/app.kubernetes.io~1instance"
    - kind: Deployment
      group: apps
      name: datadog-cluster-agent
      namespace: monitoring
      jsonPointers:
        - "/spec/template/metadata"

ignoreDifferencesのgroupにはAPI Groupを指定します。
KubernetesAPI Groupは以下のドキュメントにまとめられています。
kubernetes.io

ConfigMapのAPI Groupはcoreなのですが、coreの場合は空文字列を指定する必要があるようです。
github.com

また、keyにスラッシュ / が入っている場合は、 ~1エスケープする必要がありました。
jsonPointersの仕様はRFC6901に従っており、RFC6901にスラッシュのエスケープについて書いてありました。
datatracker.ietf.org

最初はバックスラッシュ \エスケープできるかと思いましたが、正しくは ~1 でした。

これらの設定で、ようやくArgoCDのstatusを全て正常にできました。

おわりに

Kubernetesについては最初は難しそうな印象がありましたが、難しいのは構築だけで、運用は思っていたよりも大変ではありませんでした。(そこまで複雑なことをしていないというのもありますが…)
また、構築についてはmicrok8sを使うことで非常に簡単にクラスターを組むことができました。
ArgoCDはダッシュボードがかっこよくて良いですね。これまではdocker-compose.yamlを手動Git Opsしていたのですが、ArgoCDを使えばGitHubにpushするだけでデプロイまで実行されるのでとても楽です。

現在のKubernetesクラスターは、大事に大事に育てていこうと思います。