2
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?

HelmChartConfigを利用してk3sコンポーネントの設定を変更する

Posted at

学んだことや苦労したことを書いていきます。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

なお本記事は、KubernetesとHelmをある程度触ったことがある方向けの内容です(kubectl や helm install、values.yamlのイメージがある前提で進めます)。

0. はじめに

皆さんKubernetesはご利用でしょうか。バニラのKubernetesをインストールするのは骨が折れるので、minikubeやMicroK8sをご利用の方もいらっしゃると思いますが、自分の推しはk3sです。
簡単インストールでコンポーネントが揃っているのでめっちゃ便利です。
今回の本題ではないので、インストールは以下を参照ください。
https://github.com/alexellis/k3sup?tab=readme-ov-file#k3sup-community-edition-ce

1. k3sのコンポーネントの設定を変更したい

kubernetesを利用していると、コンポーネントの設定を変えたい時があると思います。
k3s(RKE2)は、少し独特な設定変更方法となっています。

k3sは以下のようなコンポーネントを自動で入れてくれます(バージョン、オプションによって多少違います)。

  • Traefik Ingress Controller
  • ServiceLB
  • Network Policy Controller
  • CoreDNS など

k3sは各コンポーネントをHelmChartや通常のマニフェストで管理しています。
各ファイルは以下のディレクトリにまとまっています。

ls /var/lib/rancher/k3s/server/manifests/
ccm.yaml  coredns.yaml  local-storage.yaml  metrics-server  rolebindings.yaml  runtimes.yaml  traefik.yaml

このうちTraefikなど一部はHelmChartとしてデプロイされており、HelmChartConfigという専用のCRDを使って設定を上書きできます。
一方でCoreDNSはHelmChartではなく通常のマニフェストでデプロイされているため、別の方法で上書きをします。

なぜこのような構造かというと、コンポーネントの設定(ConfigmapやSecret)を手作業で直接変更できる形では、設定の一貫性や再現性・保守性が崩れてしまうからです。
設定は全てYAMLファイルとして残しておこう、ってことですね。

2. HelmChartConfigとは

普通のHelmの話を少しだけおさらいします。
Helmでアプリケーションをデプロイする場合、だいたいこんな感じで使うと思います。

# リポジトリ追加
helm repo add example https://example.com/charts

# values.yaml を用意して…
helm install my-app example/my-chart -f values.yaml

values.yamlはこんな感じですね。

replicaCount: 2

image:
  repository: my-app
  tag: "1.0.0"

ingress:
  enabled: true
  className: "traefik"

k3s では、これとよく似たことを クラスター内で自動的にやってくれる仕組み が入っています。

  • HelmChart … 「どのチャートを、どのリポジトリから、どの namespace にインストールするか」を表す CRD
  • HelmChartConfig … そのチャートに渡す values.yaml(設定)を上書きするための CRD

という二段構えになっています。

k3s の組み込み Traefik などは、内部的にはだいたい次のような HelmChart リソースで管理されています(実物はもっと項目があります)

apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: traefik-crd
  namespace: kube-system
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: traefik
  namespace: kube-system
spec:
  chart: traefik
  repo: https://helm.traefik.io/traefik
  valuesContent: |-
    deployment:
      podAnnotations:
        prometheus.io/port: "8082"
        prometheus.io/scrape: "true"
 ...

ここに対して、後からvaluesContentを上書きしたい場合に使うのがHelmChartConfigです。

HelmChartConfig の基本形

HelmChartConfig は「対象の HelmChart と同じ name / namespace を持つリソース」として作成します。

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik          # 対象の HelmChart と同じ name
  namespace: kube-system # 対象の HelmChart と同じ namespace
spec:
  valuesContent: |-
    # ここに values.yaml と同じ書き方で上書きしたい設定を書く
    logs:
      access:
        enabled: true

k3s 側のコントローラが、HelmChart と HelmChartConfig を合わせて解釈し、
values.yaml 相当の値としてマージ → Helm を実行 → 既存のリソースを再デプロイ
という流れを自動でやってくれます。

3. 実際に設定してみる

ここからは、実際に k3s 組み込みの Traefik の設定を、HelmChartConfig で変更してみます。
例として、Traefik の Gateway API provider を有効化する設定を入れてみます。
やることはざっくりこの4ステップです。

  1. HelmChart の存在確認
  2. 対象の HelmChart(Traefik)の YAML を確認する
  3. HelmChartConfig の YAML を書く (Gateway API を有効化)
  4. 適用して、設定が反映されたか確認する

3.1 Traefik の HelmChart を確認する

まずは、本当に Traefik が HelmChart として管理されているのかを確認します。(環境によって列は多少異なります)

kubectl get helmchart -A
NAMESPACE     NAME          REPO   CHART                                                                      VERSION   TARGETNAMESPACE   BOOTSTRAP   FAILED
kube-system   traefik              https://%{KUBERNETES_API}%/static/charts/traefik-37.1.1+up37.1.0.tgz                                               False
kube-system   traefik-crd          https://%{KUBERNETES_API}%/static/charts/traefik-crd-37.1.1+up37.1.0.tgz                                           False

ここで重要なのは NAME と NAMESPACE で、
後述する HelmChartConfig も 同じ name / namespace で作成する必要があります。

3.2 Traefik の YAML を確認する

次に、現在デプロイされているYAMLを確認します

sudo cat /var/lib/rancher/k3s/server/manifests/traefik.yaml
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: traefik-crd
  namespace: kube-system
spec:
  chart: https://%{KUBERNETES_API}%/static/charts/traefik-crd-37.1.1+up37.1.0.tgz
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
  name: traefik
  namespace: kube-system
spec:
  chart: https://%{KUBERNETES_API}%/static/charts/traefik-37.1.1+up37.1.0.tgz
  set:
    global.systemDefaultRegistry: ""
  valuesContent: |-
    deployment:
      podAnnotations:
        prometheus.io/port: "8082"
        prometheus.io/scrape: "true"
    providers:
      kubernetesIngress:
        publishedService:
          enabled: true
    priorityClassName: "system-cluster-critical"
    image:
      repository: "rancher/mirrored-library-traefik"
      tag: "3.5.1"
    tolerations:
    - key: "CriticalAddonsOnly"
      operator: "Exists"
    - key: "node-role.kubernetes.io/control-plane"
      operator: "Exists"
      effect: "NoSchedule"
    - key: "node-role.kubernetes.io/master"
      operator: "Exists"
      effect: "NoSchedule"
    service:
      ipFamilyPolicy: "PreferDualStack"

この内容に追加する形でHelmChartConfigを作成します。

3.3 HelmChartConfig の YAML を書く(Gateway API を有効化)

/var/lib/rancher/k3s/server/manifests/ 配下に、traefik-custom.yaml を作成します。

ここでは、さきほど確認した traefik.yamlvaluesContent をそのままコピーし、
そのうえで providers.kubernetesGateway.enabled: true を追記する形にしています。

sudo vi /var/lib/rancher/k3s/server/manifests/traefik-custom.yaml
---
apiVersion: helm.cattle.io/v1
# 必ずkind をHelmChartConfigにする
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    deployment:
      podAnnotations:
        prometheus.io/port: "8082"
        prometheus.io/scrape: "true"
    providers:
      kubernetesIngress:
        publishedService:
          enabled: true
      # GatewayAPIを追加
      kubernetesGateway:
        enabled: true
    priorityClassName: "system-cluster-critical"
    image:
      repository: "rancher/mirrored-library-traefik"
      tag: "3.5.1"
    tolerations:
    - key: "CriticalAddonsOnly"
      operator: "Exists"
    - key: "node-role.kubernetes.io/control-plane"
      operator: "Exists"
      effect: "NoSchedule"
    - key: "node-role.kubernetes.io/master"
      operator: "Exists"
      effect: "NoSchedule"
    service:
      ipFamilyPolicy: "PreferDualStack"

配置後、k3sを再起動することで新しいtraefikのPodがデプロイされます。

sudo systemctl restart k3s.service

kubectl get pods -n kube-system | grep traefik
helm-install-traefik-9dnkh                0/1     Completed   0          13s
helm-install-traefik-crd-9vfwr            0/1     Completed   0          24m
traefik-57c6d4db56-2ns4f                  1/1     Running     0          119s
traefik-865bd56545-gfr8v                  0/1     Running     0          8s  # 新しいPodが起動中

3.4 変更後の動作を確認する

HelmChartConfigがデプロイされたかを確認しましょう。

kubectl get helmchartconfig -n kube-system 
NAME      AGE
traefik   99s

GatewayAPI providerが有効化されたか確認しましょう。

kubectl logs -n kube-system deploy/traefik
…
2025-12-12T07:21:21Z INF Starting provider *gateway.Provider 
…

実際に有効化されましたね。

4. 注意点

4-1. HelmChartConfig を使うときの注意点

  1. name / namespace を必ず揃える
    metadata.name は 対象の HelmChart の metadata.name と一致している必要があります。
    metadata.namespace も 対象の HelmChart と同じ namespace である必要があります。

  2. values の優先順位に注意
    公式ドキュメントでは一部の設定のみ記載して、値を追加するケースを記載していますが、map 単位で上書きされるので、deployment: や service: を丸ごと書くと他のサブキーを潰す可能性があります。
    心配な方は、valuesContentをコピーして設定を追記する方法(今回提示した方法)を取りましょう。

4-2. 上書き用マニフェストを使うパターン

HelmChartConfig ではなく、「マニフェスト自体を上書きする」パターンもあります。
CoreDNSやlocal-path-provisionerなどは、通常のマニフェストで書かれているため、設定を上書きしたければコピーして設定を追加したYAMLを用意しましょう。

CoreDNSの例を見てみます。

sudo cat /var/lib/rancher/k3s/server/manifests/coredns.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: coredns
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
…

ご覧の通り、HelmChartではないため通常のマニフェストを上書き用で用意します。
念のためオリジナルをコピーして、そこに設定を追加するといいでしょう。

sudo cp -ip /var/lib/rancher/k3s/server/manifests/coredns{,-custom}.yaml
sudo vi /var/lib/rancher/k3s/server/manifests/coredns-custom.yaml

5. まとめ

k3sは簡単にインストールできますが、コンポーネント設定には癖があります。
ただ、それはKubernetes運用の思想がはっきりと表れた結果だと思うので、背景を理解して適切にk3sを利用していきましょう。

6. おまけ

k3sのCoreDNSはマニフェストでデプロイしてるけど、RKE2はHelmChartでデプロイされてるんですよねぇ。(統一してくれないかなぁ)

2
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
2
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?