Open6

k3s を使った Kubernetes クラスターのセットアップ

Moto IshizawaMoto Ishizawa

これは

k3s をセットアップして、Kubernetes クラスターとして利用できるようにするまでのメモ。

k3s バージョン

  • v1.23.6+k3s1

前提条件

  • Oracle Cloud の Ampere A1 インスタンスを使用する
  • OS は Ubuntu 22.04 を使用する
  • CNI には Cilium を使用する
  • Ingress Controller は使用しない
  • Cloudflare Zero Trust を使用して、WARP 経由でアクセス可能にする

ネットワーク情報

各種ネットワークで使用する CIDR は次の通り。

名前 CIDR
Host Network CIDR 10.1.1.0/24
Kubernetes Cluster CIDR 10.200.0.0/16
Kubernetes Service CIDR 10.201.0.0/16
Moto IshizawaMoto Ishizawa

Ubuntu インスタンスのセットアップ

不要なサービスの停止

最初に不要なサービスを適当に止める。

$ sudo systemctl stop ModemManager
$ sudo systemctl disable ModemManager

iptables の設定の変更

デフォルトの iptables のルールから OCI 向けの InstanceServices 関連ルール以外は削除しておく。なお、この設定を変更するとインスタンスが無防備になるため、設定前に OCI の Security Group のルールでアクセス制限をかけておく。

$ sudo vim /etc/iptables/rules.v4
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [266:46148]
:InstanceServices - [0:0]
-A OUTPUT -d 169.254.0.0/16 -j InstanceServices
-A InstanceServices -d 169.254.0.2/32 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.2.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.4.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.5.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.2/32 -p tcp -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 53 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p tcp -m tcp --dport 53 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.3/32 -p tcp -m owner --uid-owner 0 -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.4/32 -p tcp -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 67 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 69 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 123 -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j ACCEPT
-A InstanceServices -d 169.254.0.0/16 -p tcp -m tcp -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j REJECT --reject-with tcp-reset
-A InstanceServices -d 169.254.0.0/16 -p udp -m udp -m comment --comment "See the Oracle-Provided Images section in the Oracle Cloud Infrastructure documentation for security impact of modifying or removing this rule" -j REJECT --reject-with icmp-port-unreachable
COMMIT
Moto IshizawaMoto Ishizawa

k3s のセットアップ

設定ファイルの作成

k3s をインストールする前に、ネットワーク情報や Flannel などを無効化する設定を記述した設定ファイルを作成しておく。

$ sudo mkdir -p /etc/rancher/k3s/
$ sudo vim /etc/rancher/k3s/config.yaml
cluster-cidr: 10.200.0.0/16
service-cidr: 10.201.0.0/16
flannel-backend: none
disable-network-policy: true
disable: [traefik]

k3s のインストール

公式サイトの手順に従って k3s をインストールする。
https://rancher.com/docs/k3s/latest/en/quick-start/

$ curl -sfL https://get.k3s.io | sh -

アクセス情報の確認

Kubernetes としてアクセスするための設定情報は以下のファイルで確認できる。

$ sudo cat /etc/rancher/k3s/k3s.yaml

別の端末などからアクセスする場合は上記のファイルを ~/.kube/config にコピーして、IP アドレスなどを修正すればよい。

Moto IshizawaMoto Ishizawa

Cilium のセットアップ

rp_filter の設定変更

Cilium が作るネットワークインターフェースの rp_filter の値を 0 に変更する必要があるため、sysctl の設定ファイルを作成する。

$ sudo vim /etc/sysctl.d/99-cilium.conf
net.ipv4.conf.lxc*.rp_filter = 0

作成した設定ファイルは次のコマンドで反映する。

$ sudo systemctl restart systemd-sysctl

Cilium のインストール

Helm を使用して Cilium をクラスターにインストールするため、Helm の変数を定義したファイルを作成する。

$ vim values.yaml
kubeProxyReplacement: "strict"
k8sServiceHost: 10.201.0.1
k8sServicePort: 443
ipam:
  mode: "cluster-pool"
  operator:
    clusterPoolIPv4PodCIDR: "10.200.0.0/16"
    clusterPoolIPv4MaskSize: 24
operator:
  replicas: 1

作成したファイルを使用して、Cilium をインストールする。

$ helm upgrade --install cilium cilium/cilium --namespace kube-system -f values.yaml

Cilium の Pod が正常に起動できていれば OK。

$ kubectl get pods -n kube-system
NAME                                      READY   STATUS    RESTARTS   AGE
cilium-operator-7bc644bcd8-xmkmm          1/1     Running   0          18h
cilium-p5t4d                              1/1     Running   0          18h

Cilium としてのステータスを確認する場合は次のようにする。

$ kubectl exec -it -n kube-system cilium-p5t4d -- cilium status
Moto IshizawaMoto Ishizawa

metrics-server が正常に起動しない問題の修正

k3s にプリインストールされている metrics-server が正常に起動しなかったので、以下の Issue に従って --kubelet-insecure-tls オプションを追加して修正した。kubelet が使っている証明書の CN や SAN あたりを修正したほうがいいような気はしている。

https://github.com/k3s-io/k3s/issues/1219

$ kubectl edit deploy metrics-server -n kube-system
containers:
- name: metrics-server
  args:
  - --cert-dir=/tmp
  - --secure-port=4443
  - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
  - --kubelet-use-node-status-port
  - --metric-resolution=15s
  - --kubelet-insecure-tls  # <-- Add this
Moto IshizawaMoto Ishizawa

WARP 経由で Kubernetes の Service IP にアクセス可能にする

cloudflared のインストール

WARP 経由でアクセスを可能にするためにまずはインスタンスに cloudflared をインストールしてログインする。

$ curl -L -O https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb
$ sudo dpkg -i cloudflared-linux-arm64.deb
$ cloudflared tunnel login

ルーティング設定の追加

Tunnel を作成して、Service CIDR の経路を追加する。

$ cloudflared tunnel create k8s
$ cloudflared tunnel route ip add 10.201.0.0/16 k8s

Tunnel の経路情報は次のコマンドで表示できる。

$ cloudflared tunnel route ip show

設定フォルダを作成して認証情報をコピーする。${TUNNEL_ID} には Tunnel 作成時に表示された ID を指定する。

$ sudo mkdir -p /etc/cloudflared
$ sudo cp ~/.cloudflared/${TUNNEL_ID}.json /etc/cloudflared

設定ファイルを次のように作成して WARP Routing を有効化する。

$ vim ~/.cloudflared/config.yml
tunnel: ${TUNNEL_ID}
credentials-file: /etc/cloudflared/${TUNNEL_ID}.json
warp-routing:
  enabled: true

Systemd のサービスとして cloudflared を登録して起動する。

$ sudo -E cloudflared service install
$ sudo systemctl enable cloudflared.service

これで端末などから WARP 経由で Service IP にアクセス可能になる。

$ curl http://10.201.0.201

cluster.local ドメインでのアクセスを可能にする

まず最初に Kubernetes 上の CoreDNS の Service IP を確認しておく。

$ kubectl get svc -n kube-system kube-dns
NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.201.0.10   <none>        53/UDP,53/TCP,9153/TCP   23h

次に、以下の Issue に従って Cloudflare Zero Trust の設定画面から Local Domain Fallback の設定を開き、デフォルトの local ドメインの設定を削除してから、cluster.local ドメインが CoreDNS の Service IP 10.201.0.10 に問い合わせるように設定を追加する。
https://github.com/cloudflare/cloudflared/issues/568

これで、WARP に接続している端末から以下のように cluster.local ドメインで Kubernetes 上のサービスにアクセス可能になる。

$ curl http://nginx.default.svc.cluster.local

cluster.local ドメイン利用時の注意点

cluster.local ドメインでアクセス可能にした場合は Cloudflare の DNS による名前解決ではないので Cloudflare Access による認証設定はできない。認証をしたい場合は自前でやるか、WARP ではなく Cloudflare の Tunnel 経由で接続したほうがよさそう。