k3dのクラスタ設定をファイルで管理する

k3s
k3d

2024-09-30

#はじめに

今回は、k3dのクラスタ設定をファイルで管理する方法について紹介します。
k3dでクラスタを作成する際に、コマンドラインオプションで設定を指定することが多かったですが、同じようなクラスタを何度も作成する場合は、設定をファイルで管理すると便利です。

#目次

#k3dとは

k3d is a lightweight wrapper to run k3s (Rancher Lab’s minimal Kubernetes distribution) in docker.

k3d makes it very easy to create single- and multi-node k3s clusters in docker, e.g. for local development on Kubernetes.

出典:k3d

k3dは、k3s(Rancher Labの最小Kubernetesディストリビューション)をdockerで実行するための軽量ラッパーです。。

k3d を使うと、例えば Kubernetes 上でのローカル開発のために、シングルノードやマルチノードの k3s クラスタを docker 上で非常に簡単に作成できます。

ローカルでk8sクラスタをたてるツールでは、kind, minikubeなどがありますが、k3dもその一つです。
当社では、k3sをつかっているので、k3dがローカル開発では相性が良いです。
docker上で動くので、PCを汚すことなく管理が簡単です。

もちろん、docker composeもローカル開発では良い選択肢ですが、当社では本番環境がk8sなので、k8sの環境をローカルで差異を最小限にするためにk3dを使っています。
ローカルでhelm chartやマニフェストを作っておけば、本番やステージングにデプロイする際にもスムーズにいきます。docker composeだと、k8s向けにもう一度デプロイメントに関する設定を書き直す必要があったので、ひとつにまとめたいなと思っていました。

#k3dのクラスタ設定をファイルで管理する

#k3dをインストールする

miseを使ってk3dをインストールします。

  • .tool-versions
k3d 5.7

インストールする。

mise install

#k3dでクラスタを作成する

設定ファイルを初期化する。

k3d config init

初期化すると以下のようなファイルが作成されます。

  • k3d-default.yaml
---
apiVersion: k3d.io/v1alpha5
kind: Simple
metadata:
  name: k3s-default
servers: 1
agents: 0
image: docker.io/rancher/k3s:v1.30.4-k3s1

この設定をベースに自分の好みに変更します。設定のポイントは以下です。

  • マルチノードにする
  • ロードバランサーのポートを18080からアクセスできるようにする
  • コンテナレジストリを作成する

設定の例です。k3dの設定については、k3d configを参照してください。

  • k3d-default.yaml
diff --git a/k3d-default.yaml b/k3d-default.yaml
index f881f77..95f498e 100644
--- a/k3d-default.yaml
+++ b/k3d-default.yaml
@@ -4,5 +4,14 @@ kind: Simple
 metadata:
   name: k3s-default
 servers: 1
-agents: 0
+agents: 2
 image: docker.io/rancher/k3s:v1.30.4-k3s1
+ports:
+  - port: 18080:80
+    nodeFilters:
+      - loadbalancer
+registries:
+  create:
+    name: myregistry.localhost
+    host: "0.0.0.0"
+    hostPort: "12345"

この設定をクラスタ作成時に指定します。

k3d cluster create --config k3d-default.yaml

#traefikの設定を変更する

k3sに付属しているtraefikがデフォルトで有効になっています。デフォルトの設定だと不足なので、アクセスログを出したり、メトリクスをPrometheusに送信する設定を追加したいと思います。
これは、traefikの設定ファイルを変更することで解決できます。どのような設定値があるかは、traefik valuesを参照してください。k3sのtraefikのバージョンがv2系なので、v3系の設定値は使えませんので注意してください。

  • traefik-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    logs:
      access:
        enabled: true
        format: json
    metrics:
      prometheus:
        service:
          enabled: true
        serviceMonitor:
          enabled: true
          additionalLabels:
            release: "kube-prometheus-stack"

設定ファイルを適用する

kubectl apply -f traefik-config.yaml

クラスタ作成時もこの設定を注入できそうですが、あとから変えたいこともあるので、私の場合は別管理でクラスタ作成後に設定を適用するようにしています。

#ローカルからコンテナをデプロイする

動作確認のため適当なコンテナをデプロイします。ここでは、whoamiのコンテナイメージをローカルのコンテナレジストリにpushして、k3dにデプロイします。

docker pull traefik/whoami
docker tag traefik/whoami myregistry.localhost:12345/whoami:latest
docker push myregistry.localhost:12345/whoami

ローカルのコンテナレジストリを参照するDeploymentを作成し、Ingressでアクセスできるようにします。

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  labels:
    app: whoami
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: whoami
        image: myregistry.localhost:12345/whoami:latest
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  labels:
    app: whoami
spec:
  selector:
    app: whoami
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: whoami
  annotations:
    spec.ingressClassName: "traefik"
spec:
  rules:
  - host: "whoami.localhost"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: whoami
            port:
              number: 80
EOF

Ingressには、whoami.localhostでアクセスできるようにしていますが、
Ubuntuの場合は*.localhostの名前解決のため、下記のパッケージが必要かもしれません。

sudo apt-get install libnss-myhostname

Ingressで指定したドメインとクラスタ作成時に指定したポートでwhoami.localhost:18080にアクセスすると、whoamiのコンテナのレスポンスが返ってくることを確認します。

 curl -s whoami.localhost:18080
Hostname: whoami-79f849fd65-pmm8q
IP: 127.0.0.1
IP: ::1
IP: 10.42.2.25
IP: fe80::d86c:45ff:fec2:97ef
RemoteAddr: 10.42.2.5:50528
GET / HTTP/1.1
Host: whoami.localhost:18080
User-Agent: curl/8.5.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.1.0
X-Forwarded-Host: whoami.localhost:18080
X-Forwarded-Port: 18080
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-5fb479b77-vr25h
X-Real-Ip: 10.42.1.0

#参考リンク

#まとめ

今回は、k3dのクラスタ設定をファイルで管理する方法について紹介しました。

k3dを使っていると、クラスタの設定をファイルで管理することで、同じようなクラスタを何度も作成する際に便利です。
またローカルホストのコンテナレジストリを使って、ローカルからコンテナをデプロイする方法も紹介しました。
ローカルでk8sを使った開発が完結できるので、本当にk3dを気に入っています。