モード変更


    言語

夢のマイホームKubernetesクラスターを建てよう

2024/04/22

勉強がてらプログラミングするときに、サクッとデプロイできるKubernetesクラスタが一家に一台あると便利ですよね。 Amazonでかなりお安く手頃な大きさのPCを売っているのを見つけたので、一念発起してKubernetesクラスタを立ち上げたので、誰かの(あるいは未来の自分の)役に立つことを信じて作業記録を残します。

目次

  • ことの起こり
  • 目指すゴール
  • クラスタの要件
  • Linuxのインストール
  • Kubernetesインストール
  • ローカルネットワーク内の別のマシンから kubectl を実行する
  • Port Forwarding で Pod にアクセス
  • ローカルネットワーク内に LoadBalancer で Pod を公開する
  • mDNS ドメインでのアクセスをハンドリングする
  • まとめ

ことの起こり

最近Kubernetesの勉強をしたいな、そのためにも自宅に自由に使えるクラスタがあると良いなと思っていたのですが、手元にあるのは RaspberryPi 2 or 3 のみでした。 RaspberryPiでk8sクラスタを立ち上げるのも良いかなと思ったのですが、ARMアーキテクチャのCPUでコンテナを運用することに不安があり、これまで見送っていました。 昨年末のセール時にAmazonを眺めていると、 2万円弱のMiniPCがあり、しかも 3500円OFFのクーポンがあり、実質 1万5千円程度で購入できるということで、正気に戻ったときには手元にMiniPCが届いていました。

NiPoGi mini pc

この記事は、作業ログのまとめということで、あまり詳しく手順を書かない部分もありますが、作業時に参考にした情報へのリンクを貼っておくので、そちらも合わせてご確認ください。

目指すゴール

以下は、やりたいことのリストです。

  1. k8sクラスタを構築
  2. k8sのサービスをクラスタ外からアクセスできるようにする
  3. mDNSでサブドメインを切って、サービス毎のホストを用意する
  4. ArgoCDでCDできるようにする
  5. 監視設定
  6. Mackerelでホスト監視
  7. Mackerelでコンテナ監視
  8. Graphana/Prometeusで監視
  9. kubeconfigの作成・受け渡し
  10. バッチ実行基盤の構築

この記事では、上記の 3までの作業記録を公開します。

クラスタの要件

手元にブツがきてしまった以上は仕方がないので、クラスタを準備します。 今回クラスタは、以下の要件で構築します。

  • プロダクションを想定
  • シングルノードで動かす

プロダクションを想定

プロダクションを想定ということで、 RHELと互換性のあるOSを使おうと思います。

また、Minikubeや MicroK8s、k3sのような仮想マシンや軽量な実装ではなく、本番運用に耐えうるクラスタ構築を目指します。 ということで、公式ドキュメントの Getting started > Production environment に kubeadm を使ったクラスタ構築を行います。

シングルノードで動かす

k8sといえば、コンテナを動かすノードもスケール可能でクラスタを構築できるのですが、流石に2台も3台もマシンを用意するのは現実的ではないので、今回はあくまで MiniPC 1台だけで動かすシングルノードのクラスタを構築することとします。

実際のプロダクションレディなクラスタを構築する場合には、HA構成として、worker nodeおよび control plane nodeを複数用意することになると思います。しかし、今回は私のお財布もコンセントの口も有限なのでシングルノードでクラスタを立ち上げます。

Linuxのインストール

購入した MiniPC にはWindows11がプリインストールされていますが、勉強のためにLinuxをインストールします。 今回は、 RHEL互換の AlmaLinuxをインストールします。

1. OSインストールメディアの準備

公式サイトから、インストールディスクのイメージをダウンロードします。

diskutil list
diskutil eraseDisk FAT32 ROCKY /dev/disk2
diskutil umountDisk /dev/disk2
sudo dd if=AlmaLinux-9.3-x86_64-minimal.iso of=/dev/disk2 bs=4m

2. OSインストール

作成したインストールメディアをMiniPCのUSBにさして、MiniPCを起動します。 起動時に、F2キーを連打しながら起動することで Bios設定画面に移動するので、起動ディスクの優先順をUSBを先頭にして再起動します。

インストーラーが起動するので、画面にしたがってインストールを進めます。

このとき、ネットワークの設定で WiFi を設定して、問題なく IPが割り振りされていたのですが、これが後述の問題に影響することに...

3. Linuxの設定

インストーラーからのインストールが終了したところで、ホストマシンの設定を行います。

ここで行いたいことは、以下の2つです。

  • Firewallの停止
    • 自宅のローカルネットワーク内のみで運用するので、Firewallは停止してしまいます
  • mDNSの設定
    • 割り振られるローカルネットワークのIPは固定しておきますが、IPアドレスベースでアクセスするのも大変なので、 ホスト名.local というドメイン名でアクセスできるように mDNSを有効化しておきます

3.0 ネットワークの確認

MiniPCを立ち上げて、ログインします。 ここでネットワーク接続状態を確認すると、IPアドレスが割り振られておらずネットワーク接続ができないことに気づきました。

# IPアドレス確認
ip a

# ネットワーク設定確認・編集
nmtui

いろいろとログを調べた結果、 /var/log/messages に以下のログを発見

sudo less /var/log/messages
Dec 21 12:43:44 k2kube NetworkManager[814]: <info>  [1703130224.5308] manager: (wlp2s0): 'wifi' plugin not available; creating generic device
Dec 21 12:43:44 k2kube NetworkManager[814]: <info>  [1703130224.5315] manager: (wlp2s0): new Generic device (/org/freedesktop/NetworkManager/Devices/3)

どうやら、OSをminimumインストールしていたため、NetworkManagerのWiFiプラグインがインストールされていなかったようです。 インストーラーから設定していたときには、ちゃんとネットワークに接続されていたので、気づくまでにかなり時間を使ってしまいました。 というか、インストーラーには含まれているのに、WiFiプラグインはインストールされないのね...

というわけで、MiniPCを一度有線でネットワークに接続し、以下のコマンドで WiFiプラグインをインストールします

sudo dnf install NetworkManager-wifi

これでWiFi接続できるようになりました。設置場所を選ばず、家の中どこにでも設置できます。

3.1 Firewallの停止

家庭内ネットワークから外に出す予定はないので、サクッとFirewallを停止してしまいます。

# 起動している firewallを停止
sudo systemctl stop firewalld
# 再起動時にfirewallが起動しないように無効化
sudo systemctl disable firewalld
# 設定を確認
sudo systemctl status firewalld

参考

  • RHEL7 / CentOS 7 で、NetworkManager 管理下で WiFi の自動接続をコマンドラインで設定する

3.2 mDNSの設定

mDNSを有効化することで、ローカルネットワーク内でDNSサーバーを必要とせずに、ホスト名.localでのアクセスが可能となります。

sudo dnf install avahi avahi-tools

ping -c 3 k2kube.local
# PING localhost (127.0.0.1) 56(84) bytes of data.
# 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.077 ms
# 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.036 ms
# 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.053 ms
#
# --- localhost ping statistics ---
# 3 packets transmitted, 3 received, 0% packet loss, time 2086ms
# rtt min/avg/max/mdev = 0.036/0.055/0.077/0.016 ms

参考

  • mDNSを使ってローカルDNSサーバーを廃止する

Kubernetesインストール

MiniPCがネットワークにつながって、ようやくk8sのクラスタを構築していきます。作業内容は以下の通り。

  1. 事前準備
  2. コンテナランタイムとして containerd のインストール
  3. kubeadm kubelet kubectl のインストール
  4. kubeadm でのクラスタ作成
  5. CNIとして Calico のインストール
  6. Nginx を立ち上げて動作確認

参考

  • 公式ドキュメント: Bootstrapping clusters with kubeadm
  • 公式日本語訳: kubeadmを使ってクラスターを構築する
  • Qiita | kubeadmでk8sクラスタを構築CRI-O編

上記の日本語訳やQiita記事は少し古くなっており、最新版と一部差分があります。 Qiita記事や日本語訳の情報を元に作業の流れを確認し、実際には英語版の公式ドキュメントにしたがって作業を行いました。

0. 事前準備 Swap無効化

kubeletのデフォルトの挙動では、swapが有効になっていると起動に失敗するため、swapを停止しておきます。 まずは、 swapoff -a で起動中のswapを停止します。

# Swapの一時停止
sudo swapoff -a

ホストマシン再起動時にswapが有効にならないよう、 /etc/fstab を編集して、 swap設定をコメントアウトしておきます。

12 /dev/mapper/almalinux-root /                       xfs     defaults        0 0
13 UUID=a1075816-d393-4119-aca6-dd9543bc8dd2 /boot                   xfs     defaults        0 0
14 UUID=332D-7584          /boot/efi               vfat    umask=0077,shortname=winnt 0 2
15 /dev/mapper/almalinux-home /home                   xfs     defaults        0 0
16 # /dev/mapper/almalinux-swap none                    swap    defaults        0 0 ← ここをコメントアウト

1. コンテナランタイムとして containerd のインストール

参考にした Qiita記事では CRI-O をインストールしていますが、今回は containerd をランタイムとして利用します。 特に選定理由にこだわりはありませんが、普段使いの mac では Rancher Desktop を利用しており、containerd が利用できるので、 containerd としました。

まずは、 containerd の getting started ドキュメントにしたがって containerd をインストールします。(step.1)

curl -LO https://github.com/containerd/containerd/releases/download/v1.7.12/containerd-1.7.12-linux-amd64.tar.gz

sudo dnf install -y tar
sudo tar Cxzvf /usr/local containerd-1.7.11-linux-amd64.tar.gz 

ホストマシン再起動時に自動的に contaierd が起動するように、 service を登録しておきます。

sudo mkdir -p /usr/local/lib/systemd/system
sudo curl https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -L -o /usr/local/lib/systemd/system/containerd.service

sudo systemctl daemon-reload
sudo systemctl enable --now containerd

runc もインストール。 runc は OCI の仕様に基づいてコンテナの生成・実行を行ってくれます。(step.2)

curl -LO https://github.com/opencontainers/runc/releases/download/v1.1.10/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc

CNI Pluginsをインストールします。(step.3)

curl -L https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz -o cni-plugins-linux-amd64-v1.4.0.tgz
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.4.0.tgz 

最後に、 containerd を操作するための CLI として nerdctl をインストールします。

https://github.com/containerd/nerdctl

curl -L https://github.com/containerd/nerdctl/releases/download/v1.7.2/nerdctl-1.7.2-linux-amd64.tar.gz -o nerdctl-1.7.2-linux-amd64.tar.gz
sudo tar Cxzvvf /usr/local/bin nerdctl-1.7.2-linux-amd64.tar.gz

ルート以外でも実行できるように rootlessモードを設定しておきます。

curl -l https://raw.githubusercontent.com/containerd/nerdctl/main/extras/rootless/containerd-rootless-setuptool.sh -o containerd-rootless-setuptool.sh
ll
chmod 755 containerd-rootless-setuptool.sh 
./containerd-rootless-setuptool.sh install

参考

  • Getting started with containerd

2. kubelet, kubeadm, kubectl のインストール

いよいよ、本丸でk8sのインストールと設定を進めていきます。まずは yum でサクッとインストール。

sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet

これだけ。 dnf でも良さそうと思いつつ、公式ドキュメントにしたがって yum でインストールしました。

kubelet が起動しているか確認します。

sudo systemctl status kubelet

起動していなかったり、有効化されていない場合は有効化して立ち上げる。

これで本丸はあっさり落城。

3. kubeadm でのクラスタ作成

それでは kubeadm でクラスタを作成します。後で Calico という CNI をインストールするので、 --pod-network-cidr=192.168.0.0/16 というオプションを設定しておきます。

sudo kubeadm init --pod-network-cidr=192.168.0.0/16

これでクラスタが立ち上がります。

うまくいけば、以下のメッセージが表示されるはず。

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a Pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  /docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>

メッセージに従って、 kubeconfig を $HOME/.kube にコピーします。

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

これで、 kubectl が実行できるようになるはずです。

kubectl get all -A

デフォルトだとクラスターはセキュリティ上の理由で control plane node に Pod をスケジューリングしません。ただ、今回はシングルノードでクラスタを動かすので、スケジューリングできるように node から control-plane の taint を削除する必要があります。

kubectl taint nodes --all node-role.kubernetes.io/control-plane-

参考

  • Control plane node isolation

4. Calicoのインストール

CNIにはいくつかのベンダーがリリースしているものがあります。 kubernetesのドキュメントでもいくつも紹介されています。 最新の公式ドキュメント(2023年12月29日に更新)では、以下のように CNI についての e2e テストは実施されていないようです。

Note: Kubeadm should be CNI agnostic and the validation of CNI providers is out of the scope of our current e2e testing. 注意: KubeadmはCNIに依存しないはずであり、CNIプロバイダの検証は現在のe2eテストの範囲外です。

ただ、 2023年8月に翻訳されている日本語ドキュメントでは、以下のように記載があり Calico で e2eテストを実施されていたようです。 なので、今回は Calico をインストールしていきます。

備考: 現在、Calicoはkubeadmプロジェクトがe2eテストを実施している唯一のCNIプラグインです。

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml

インストール状況を確認します。公式ドキュメントでは、 watch コマンドを利用していますが、 Mac などから kubectl を呼び出している場合、 watch コマンドが使えない場合があるので、 --watch オプションのほうが良い気がします。

kubectl get pods -n calico-system --watch

全ての Pod の Status が Running になるのを待ちます。

Podのインストールが完了したら、 Pod から taint を削除します。

kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-

参考

  • Networking and Network Policy
  • Quickstart for Calico on Kubernetes

5. Nginx を立ち上げて動作確認

ようやく、k8s のクラスタが利用できる状態になったので、動作確認をしてみます。

kubectl create namespace nginx
kubectl create deploy nginx --image=nginx -n nginx

kubectl get pods nginx -n nginx
# NAME                     READY   STATUS    RESTARTS   AGE
# nginx-6799fc88d8-dkkft   1/1     Running   0          63s

Pod が起動できました。 Nginx が動いていることを確認できるように、 Service を作成します。

kubectl expose deploy/nginx --port=80 -n nginx
# service/nginx exposed

kubectl get services -n nginx                 
# NAME    TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
# nginx   ClusterIP   10.43.23.36   <none>        80/TCP    7s

ホストマシン上で、 cURL で CLUSTER-IP の IPアドレスにアクセスして HTML が取得できるか試します。

curl http://10.43.23.36

HTML が取得できれば、問題なくOKです。

ローカルネットワーク内の別マシンから kubectl を実行する

MiniPC に ssh などでログインして利用してもいいんですが、ローカルマシンからサクッと kubectl を叩ける方が、楽です。 と言うことで、 MiniPC 上の $HOME/.kube/config をコピーしてきて、ローカルマシンにマージします。

1. krew のインストール

krew は kubectl plugin を管理してくれるプラグインマネージャーです。この後出てくる konfig をインストールするために、導入します。

https://krew.sigs.k8s.io/

2. konfig のインストール

konfig は、 kubeconfig ファイルのマージや分割を行ってくれるツールです。 krew を使ってインストールすることで、 kubectl のプラグインとして利用することができます。

kubectl krew install konfig

https://github.com/corneliusweig/konfig

3. kubeconfig のマージ

MiniPC 上の $HOME/.kube/config を SFTP や SCP などでコピーしてきます。コピーしてきたファイルは、適当な名前をつけて置いておきます。

sftp username@ホスト名.local
cp .kube/config myk8s_config
exit

konfig でマージします

kubectl konfig import -s myk8s_config

kubectl config get-contexts を実行して、コンテキストが表示されば成功です。 use-context で利用するコンテキストを指定して、 get pods で先ほど立てた Nginx の pod が表示されるか確認します。

kubectl config use-contexts xxxxxx

kubectl get pods -n nginx
# NAME                     READY   STATUS    RESTARTS   AGE
# nginx-6799fc88d8-dkkft   1/1     Running   0          5m 

Port Forwarding で Pod にアクセス

先ほど立てた Nginx に Service を追加して、アクセスできるようにしていきます。ただ、Serviceを追加しても Cluster IP しか設定されておらず、他のマシンからはアクセスできません。今の所 MiniPC には、Xサーバーなどを用意していないので、ブラウザで HTML を表示することができません。 ちゃんと、GUIの使えるマシン上のブラウザで表示できるようにしましょう。

まずは、 Port Forward で公開していきます。

# Serviceを追加して、80番ポートで開く
kubectl expose deploy/nginx --port=80 -n nginx

kubectl get svc -n nginx

NAME    TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.43.86.53   <none>        80/TCP    27s

# 8080番ポートを80番ポートにフォワーディング
kubectl port-forward svc/nginx -n nginx 8080:80

kubectl get svc -n nginx

# IP Addressの確認
ip a

curl http://{Host IP}:8080

ホストマシンの IP を指定して、アクセスできました。

しかし、 port-forward では、今後クラスタやpodを追加した際に、アクセスを分散させることができません。 port-forward に Service を指定していますが、実は 8080番ポートへのアクセスは、 特定の Pod の 80番ポートに送られています。

https://kubernetes.io/docs/reference/kubectl/generated/kubectl_port-forward/

そのため、 Port Forward はデバッグ用途として、ちゃんと公開するために Load Balancer を構築していきます。

ローカルネットワーク内に Load balancer で Pod を公開する

とりあえず、 port-forward で他のマシンから ブラウザ で Nginx にアクセスできました。

次は、Service Type を Load Balancer に変更して公開します。 ただし、家庭内の k8s クラスタでは、 Service にパケットを割り振る LoadBalancer がありません。 MetalLB を構築して、 Load Balancer を利用できるようにします。 MetalLB は今回の家庭のネットワーク環境や BareMetal環境に独自に k8sクラスタを立ち上げる場合に、仮想LBを構築することを目的としています。 MetalLB は IPアドレスの割り当てを行い、割り当てた IPアドレスが利用されていることをネットワークに通知します。

1. MetalLB の構築

まず、以下のマニフェストを実行して、 MetalLB をクラスタにインストールします。

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.3/config/manifests/metallb-native.yaml

以下の Manifest で L2レイヤー のネットワーク設定を行います。 ホストマシンに割り当てられている IPを設定して、ホストマシンへのリクエストをハンドリングできるようにしておきます。 IPアドレスの範囲を指定することもできるので、ご家庭のネットワークで空いているIPの範囲を指定してもOKです。

---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default
  namespace: metallb-system
spec:
  addresses:
  - <YOUR_HOST_V4_IP>/32
  autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default
  namespace: metallb-system
spec:
  ipAddressPools:
  - default

参考

  • MetalLB>Installation

2. Service を Load Balancer に変更する

service/nginx の Type を LoadBalancer に変更します。

kubectl patch svc nginx -n nginx -p '{"spec": {"type": "LoadBalancer"}}'

これで、 Service に EXTERNAL-IP が設定されます。

kubectl get svc -n nginx
NAME    TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.43.86.53   192.168.0.35        80/TCP    2d2h

http://192.168.0.35 にアクセスしてみます。

Welcome to Nginx

無事、Nginx の画面が表示されました。

mDNS ドメインでのアクセスをハンドリングする

MetalLB を使うことで、 k8s の Service を LoadBalancer で公開することができました。 IPアドレスを指定してアクセス可能ですが、このままだと k8sクラスタに複数のサービスを載せていくと、その分 IPアドレスを必要としてしまいます。 また、割り当てられている IPアドレスを記憶する必要もあり非常に面倒です。

もう一歩進めて、 Ingress Nginx を使って、 L7レイヤー でドメイン名を元に振り分けを行います。

アクセスの振り分け経路は以下のイメージです。

  1. mDNSのドメイン名にアクセス
  2. mDNSがドメイン名から IPアドレスを解決
  3. IPアドレスに対してリクエストが送られる
  4. MetalLB がリクエストを受け取る
  5. Ingress Nginxがリクエストのドメイン名を元に対象サービスにリクエストを振り分ける

参考

  • Ingress Nginx Controller

1. Ingress Nginx のインストール

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

2. Ingress Nginx の設定

以下の manifest を nginx のネームスペースに適用して、 Ingress Nginx が、 k2kube.local へのアクセスを 80番ポートに振り分けできるようにします。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: k2kube.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
  ingressClassName: nginx

Ingress が立ち上がっていることを確認します。

kubectl get Ingress -n nginx

NAMESPACE   NAME                         CLASS   HOSTS                      ADDRESS         PORTS     AGE
nginx       ingress-nginx                nginx   k2kube.local               192.168.11.35   80        34d```

3. Service を NodePort に変更

Ingress Nginx が 80番ポートにアクセスを振り分けてくれるので、 Serviceは NodePort に変更します。

kubectl patch svc nginx -n nginx -p '{"spec": {"type": "NodePort"}}'

この状態で、 http://k2kube.local にアクセスして、期待通り Nginxが表示されることを確認します。

4. mDNS にサブドメインを設定してアクセスする

mDNS で解決されるドメインにアクセスして、 Nginxにリクエストすることができるようになりました。 今後、新しい Service を k8sに追加していくときに、 先ほどのマニフェストを編集して、サブディレクトリごとにリクエスト先を変更することができます。 ただ、複数のサービスでドメインを共有して、サブドメインで振り分けるのも面倒ですし、ネームスペースの切り分けも煩雑になってしまいます。

mDNS でサブドメインを設定して、サービスごとにサブドメインを利用できるようにしていきます。

4.1 avahiで自分のIPアドレスに複数のホスト名をエイリアスする

avahi-utils に含まれている、 avahi-publish というコマンドを利用することで、 ドメイン名と IPアドレスの組み合わせを広報してやることができます。 ただし、 avahi-publish は常時起動しておく必要があるので、 systemd のサービスとして起動できるようにしておきます。

/etc/systemd/system/avahi-subdomain@.service に以下の内容を記載します。

[Unit]
Description=Publish %I.%H.local as alias for %H.local via mdns
Requires=avahi-daemon.service
After=avahi-daemon.service

[Service]
Type=simple
ExecStart=/bin/bash -c "/usr/bin/avahi-publish -a -R %I.%H.local $(ip a show dev wlp2s0 | awk '$1==\"inet\"{print $2}' | cut -d/ -f1 | awk 'NR==1')"
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target

そして、設定したいサブドメインを引数に渡して、 サービスをアクティベートしておきます。 サービスを起動する際に、 @ と .service の間に利用したいサブドメインを設定します。

以下のコマンドでは、 www をサブドメインとして設定しています。

sudo systemctl enable --now avahi-subdomain@www.service

これで、 www.k2kube.local が名前解決されるようになりした。

例えば、 nginx.k2kube.local で名前解決したい場合、以下のようにサービスを起動します。

sudo systemctl enable --now avahi-subdomain@nginx.service

4.2 Nginx Ingress の更新

Nginx Ingress が www.k2kube.local へのリクエストをハンドリングできるように、マニフェストの spec.rules.host 更新して適用します。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: www.k2kube.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
  ingressClassName: nginx

これで、 http://www.k2kube.local へのアクセスすることで、 Nginx を表示できます。

4.3 新しい公開サービスを追加する

以下の手順で新しいサービスを追加できます。

  1. 新しい namespace を作成して、 NodePort の Service を追加する
  2. mDNSで新しいサブドメインを公開する sudo systemctl enable --now abahi-subdomain@new-svc.service
  3. Nginx Ingressを追加する

参考

  • avahiで自分のIPアドレスに複数のホスト名をエイリアスする
  • systemd の systemctlコマンドでインスタンスを使用して引数を渡す方法

まとめ

自宅に k8sクラスタを構築して、そこで公開するサービスに mDNS でアクセスできるようにしました。 ポイントとしては、 avahi を使って サブドメインとホスト名でサービスにアクセスできる点、 MetalLB と Nginx Ingress を組み合わせて、ドメイン名でサービスにアクセスできるようにしている点です。

この記事は自分用の作業メモをベースに公開しているため、説明が足りなかったり、汎用的な設定になっていない部分もあるかと思いますが、ご自宅に k8sクラスタを立ち上げたい人の参考になればと思います。

今後は、このクラスタに ArgoCD をインストールして 継続的デリバリー ができるようにしたり、監視を追加したりしていきたいです。 その様子もブログにまとめて公開していきたいと考えています。

k8skubernetes

Author

Kiyotaka Kunihira

Kiyotaka Kunihira

バックエンド/テックリード/スクラムマスター/エンジニアリングマネージャー

新卒でスマートフォン向け乙女ゲーム開発をしつつAWS, Scalaに触れ Scala忍者に。その後、スタートアップを2社経験して、2019年にモンスターラボに入社。 大阪オフィスに所属している2児の父。 去年、認定スクラムマスター資格取得しました。 最近は、エンジニアリングマネージャーとして中間管理職しています。

その他おすすめ記事

2024/11/05

エンタープライズデータ基盤における dbt の活用戦略

近年、データ駆動型の意思決定が企業の競争力を左右する重要な要素となっており、大規模かつ複雑なデータ基盤の構築が不可欠となっています。この潮流の中で、dbt(data build tool)は、エンタープライズレベルのデータ変換とモデリングを効率化する強力なツールとして注目を集めています。 dbt は、SQL を使用してデータ変換を定義し、バージョン管理、テスト、ドキュメンテーションを統合的に行うことができるオープンソースツールです。特に以下の点で、エンタープライズデータ基盤の構築に大きな価値をもたらします...

Yoshiaki Sano

Yoshiaki Sano

Architecture

2024/11/04

データエンジニアリング初心者でも分かる!dbtの魅力と基本

データ駆動型ビジネスが当たり前となった今日、多くの企業がデータ分析の課題に直面しています。複雑な SQL クエリの管理、データの整合性確保、分析プロセスの再現性など、様々な問題が山積みです。そんな中で注目を集めているのが「dbt(data build tool)」です。 本記事では、データエンジニアリングの深い知識がなくても理解できるよう、dbt の基本と魅力について解説します。 dbt とは? dbt は、SQL を中心としたデータ変換ワークフローを管理するためのオープンソースツールです。従来の SQL...

Yoshiaki Sano

Yoshiaki Sano

Architecture

サービス開発実績会社情報
採用情報インサイトお問い合わせ
© 2022 Monstarlab
情報セキュリティ基本方針個人情報の取り扱いについて個人情報保護方針