はじめに
Kubernetesで使われるCNI(Container Network Interface)の一つであるCiliumを使って、Kubernetesの内部ネットワークを構築してみました。構築にはHelmとHelmfileを使います。
動作確認した環境の情報
Kubernetesクラスター
kubeadmを使ってオンプレミスのマシンにKubernetesクラスターを下表のように構築しています。(kubectl get nodes -owide
の出力結果をもとに表を作っています)
項目 | Control Plane | Worker |
---|---|---|
NAME(ノード名) | control-plane | worker01 |
VERSION | v1.29.3 | v1.29.3 |
INTERNAL-IP | 100.x.x.x | 100.y.y.y |
EXTERNAL-IP | <none> | <none> |
OS-IMAGE | Debian GNU/Linux 12 (bookworm) | Ubuntu 20.04.6 LTS |
KERNEL-VERSION | 6.1.0-18-amd64 | 5.4.0-172-generic |
CONTAINER-RUNTIME | containerd://1.6.20 | containerd://1.6.28 |
補足
- kubeadmによるK8sクラスターの構築は自作になりますが、以下のツールを利用
- INTERNAL-IPが100系になっているのは、ノードのネットワークをTailscaleというメッシュ型のVPNサービスを使っているため。以下は参考記事
HelmとHelmfileのバージョン
Control PlaneにHelmとHelmfileをインストールしておく必要があります。今回はそれぞれ以下のバージョンを使いました。
$ helm version --short
v3.14.3+gf03cc04
$ helmfile version -o=short
0.162.0
Ciliumのインストール
Helmfileを使ってCiliumのインストールしていきます。
Helmでのインストール方法は以下のサイトに書かれており、これを参考にHelmfileを作っていきます。
ちなみにHelmfileというのは、「KubernetesのHelmチャートを管理するためのツール」です。helm
コマンドの場合、リポジトリの追加やチャートのインストールを一つ一つ実行していく必要がありますが、それらをYAMLファイルに宣言的に書くことで、Helmチャートが管理しやすくなります。(Dockerを使ったことがあれば、「HelmにおけるHelmfileは、Dockerに対するDocker Compose」と思っていただければわかりやすいでしょう)
Helmfileを用意
さて、CiliumをHelmチャートからインストールする内容をHelmfileに書き下すと、以下のようになります。
repositories:
- name: cilium
url: https://helm.cilium.io
releases:
- name: cilium
namespace: kube-system
chart: cilium/cilium
version: 1.15.2
# 以下は必須ではない
values:
- k8sServiceHost: "100.x.x.x" # Control Planeのホスト名またはIPアドレス
- k8sServicePort: "6443"
- hubble:
relay:
enabled: true
ui:
enabled: true
# - ipam:
# operator:
# clusterPoolIPv4PodCIDRList: ["192.168.128.0/17"] # CIRDはあくまで一例
valuesで設定している値について
上記のYAMLファイルで最後に記載しているvaluesの設定は必須ではないですが、今回設定した経緯について記載します。
k8sServiceHost, k8sServicePort
デフォルトだとk8sServiceHost
は10.96.0.1
で、k8sServicePort
は443
のようです。ここで10.96.0.1
は、クラスターネットワークにおけるkube-apiserverのIPアドレスです。
筆者環境だと、Ciliumを最初に構築した際にworkerノードから10.96.0.1
への通信ができないトラブルが発生しました。そこで、これらの設定値を「ホストOSからアクセスする際のkube-apiserverのIPアドレスとポート」に変更することで解決しました。
hubble配下
Hubble UIを有効にするための設定を書いています。以下の「Helm」のタブに書かれたコマンドを参考にKeyValueを指定しています。
Hubble UIについてはこちらにも書かれていますが、Web上でK8sの各サービスの依存関係を可視化することができます。私もHubble UIを使って、自分が作っているサービスを可視化できた時は結構感動しました!なので、この設定は有効にしておくことをお勧めします。
clusterPoolIPv4PodCIDRListについて(24/06/16追記)
ドキュメントによると、CiliumのデフォルトのCIDRが10.0.0.0/8
のようで、ノードのIPやサービスのCIDRがこの範囲に重なると正常起動しません。したがって重複する場合は、ipam.operator.clusterPoolIPv4PodCIDRList
に重複しないCIDRを書いてあげる必要があります。
※よく考えると、kube-apiserverのクラスター中のIPアドレス 10.96.0.1
はCiliumのデフォルトのPod CIDRと重複しているので、ここはいつも変更していた方が良さそうですね。
その他
今回設定した以外のvaluesについては、以下で確認できます。かなりの数の変数があるので、カスタマイズする際は該当箇所を地道に探していく必要がありそうです。
Helmfileを使ってCiliumをインストール
以下のコマンドを実行して、Ciliumをインストールします。
helmfile apply -f helmfile-cilium.yaml
以下のようにPodがデプロイされればインストール完了です。
$ kubectl get pod -A -l app.kubernetes.io/part-of=cilium
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system cilium-bx8w5 1/1 Running 0 112s
kube-system cilium-operator-7cb9969fdf-lw5sd 1/1 Running 0 112s
kube-system cilium-operator-7cb9969fdf-zb8pq 1/1 Running 0 112s
kube-system cilium-tg5fj 1/1 Running 0 112s
kube-system hubble-relay-d8b6b55c9-z9bf8 1/1 Running 0 112s
kube-system hubble-ui-6548d56557-vkhpl 2/2 Running 0 112s
Cilium CLIのインストール
必須ではないですが、Ciliumの状況確認や操作を行うために、以下のCilium CLIを入れておくと良さそうです。
インストールすると、次のようにcilium
のコマンドが使えるようになります。
$ cilium status
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode)
\__/¯¯\__/ Hubble Relay: OK
\__/ ClusterMesh: disabled
(以後の出力は省略)
Hubble UIを使ってみる
Hubble UIを使って、クラスター内でのネットワーク経路を可視化してみましょう。
hubble-ui
というServiceリソースがこれに相当するため、K8sクラスター外のネットワークにポートフォワードするコマンドを実行します。
kubectl port-forward -n kube-system svc/hubble-ui 8080:80 --address='0.0.0.0'
http://[kubectlを実行したホストのIP]:8080
にアクセスすると、以下のようなトップページが表示されるはずです。
試しにkube-systemのnamespaceを選択すると、次のようなサービスマップが出てきます。
この図は、「hubble-ui
のPodから、hubble-relay
のPodに通信が行われている」ことを意味しています。実際にkubectl
コマンドでそれを確認してみましょう。
hubble-relayのServiceリソースが4245のポートのPodにロードバランシングしていることの確認
$ kubectl describe svc -n kube-system hubble-relay | grep 4245
TargetPort: 4245/TCP
Endpoints: 10.0.0.127:4245
hubble-relayのPodが4245のポートをlistenしていることの確認
$ kubectl describe pod -n kube-system hubble-relay-d8b6b55c9-z9bf8 | grep 4245
Port: 4245/TCP
上記は簡単な例ですが、ネットワークがより複雑になった場合でもHubble UIで可視化してくれるので非常に活用できそうです!
※Hubble UIの使い方は、以下のサイトも参考になります。
- https://github.com/cilium/hubble-ui
- https://docs.cilium.io/en/stable/gettingstarted/hubble/#open-the-hubble-ui
おわりに
あまり皆さんにとっては重要な情報ではないですが、本記事掲載に至った背景を最後に書いておきます。
個人用にオンプレKubernetesを作って動かしているのですが、Control Planeを担っているマシンのOSをDebian 10から11にアップグレードするのに失敗し、OSをクリーンインストールせざるを得ない状況になってしまいました。そのためKubernetes環境も一から作り直す羽目に...。
だいぶショックでしたが、「せっかく作り直すんだったらCNIもこれまで使っていたCalicoからCiliumに変えてみよう!」と思い立ち、Ciliumのインストールを実現できました。
たまには今までやってきたことをリセットするのも必要だなと思いました。