kubeadm+containerd+ciliumを用いてk8s構築し、hubbleの動作確認するまで試した

# 概要
kubernetesを導入する際にCNIをCalicoやFlannelなどを用いることが多いかと思いますが、その中でもCilium（読みは、おそらくシリアム）が気になったので、色々試してみようかと思いました。
CKAの勉強も兼ねているので、やるならkubernetesの構築からやってみます。
今後はラインタイムであるdockershimが削除されるのもあり、containerdもあわせて導入しました。
記事が長くなるので、今回は導入と動作確認のみとします。

# Ciliumとは
以下、[公式](https://cilium.io/learn)から引用

>Ciliumは、Kubernetesクラスタやその他のコンテナオーケストレーションプラットフォームなどのクラウドネイティブ環境向けに、ネットワーク、セキュリティ、観測性を提供するオープンソースプロジェクトです。
>
>Ciliumの基盤となっているのは、eBPFと呼ばれる新しいLinuxカーネル技術で、強力なセキュリティ、可視性、ネットワーク制御ロジックをLinuxカーネルに動的に挿入することができます。eBPFは、高性能ネットワーキング、マルチクラスタおよびマルチクラウド機能、高度な負荷分散、透過的暗号化、幅広いネットワークセキュリティ機能、透過的観測性などの提供に使用されています。

eBPFをフルに使って、Kubernetesのネットワークに関するセキュリティや可視化を実現できているようです。
またCiliumにはHubbleというCilium上の通信を可視化するツールがあります。

より分かりやすい解説ページがありますので、詳しくは下記参照が良いかと思います。
https://blog.framinal.life/entry/2021/02/20/222728
https://thinkit.co.jp/article/18836

では、環境構築を始めていきたいと思います。

# 環境
aws + kubeadm + containerd + cilium

# kubeadm + containerdを導入します。
※細かい設定なしでシンプルに導入します。

## 環境用意
1. aws環境でUbuntu20.04を2台起動します。
    今回は、インスタンスサイズ:t3.mediumとしました。
1. 分かりやすいようにコントロールプレーン(cp)側のホスト名を変更します。
    `sudo hostnamectl set-hostname k8scp`
1. ワーカーノード(worker)側のホスト名を変更します。
    `sudo hostnamectl set-hostname k8swork`

## cp側、worker側のいずれに対しても下記の手順を実施
1. k8s公式の[kubeadmのインストール](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)にある手順の「ランタイムのインストール」の手前まで進めます。
1. [containerd](https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/#containerd)の手順を実施し、「kubeadmのインストール」の手順にまた戻ります。
1. 「kubeadm、kubelet、kubectlのインストール」手順を実施します。
1. kubeletが使用するcgroupドライバーを設定します。
    - /etc/default/kubeletのファイルに`KUBELET_EXTRA_ARGS=--cgroup-driver=systemd`を記入します。
1. kubeletをリスタートし、`systemctl status kubelet`で起動できていることを確認します。
    - 設定の不備で失敗することがあります。
        - その場合は、ここを参照してみてください [インストール中にkubeadmがコントロールプレーンを待ち続けて止まる](https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E4%B8%AD%E3%81%ABkubeadm%E3%81%8C%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E3%83%97%E3%83%AC%E3%83%BC%E3%83%B3%E3%82%92%E5%BE%85%E3%81%A1%E7%B6%9A%E3%81%91%E3%81%A6%E6%AD%A2%E3%81%BE%E3%82%8B)

## コントロールプレーン(cp)側の作業

### `kubeadm init`を実行します。
もし、ここでinitが失敗した場合は[issue](https://github.com/containerd/containerd/issues/4581)に従い、containerdの設定ファイルを削除すると上手くいくかと思います。
``` bash
rm /etc/containerd/config.toml
systemctl restart containerd
kubeadm init
```
## kubeadm initが成功した際のメッセージに従い、
```
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```
を実行することで、kubectlコマンドが実行できるようになります。
そして、kubeadm joinのメッセージも忘れず、メモしておきます。
```
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
```

## ワーカーノード(worker)側の作業
### cp側でメモしたコマンドを実行することで、workernodeとして参加することができます。
```
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
```
成功したメッセージが出たら、ぜひcp側で`kubectl get node`を実行して動作していることを確認してみましょう。
```
ubuntu@k8scp:~$ kubectl get node
NAME      STATUS   ROLES                  AGE   VERSION
k8scp     Ready    control-plane,master   21h   v1.21.1
k8swork   Ready    <none>                 21h   v1.21.1
```

## ciliumを導入
事前に[helmをインストール](https://helm.sh/docs/intro/install/)します。

公式の手順に従い、[ciliumをデプロイ](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-kubeadm/#deploy-cilium)します。

`cilium status`コマンドで結果が出れば、導入完了です。
このまま、可視化ツールであるhubbleも導入していきましょう。

公式手順で[hubbleをインストール](https://docs.cilium.io/en/stable/gettingstarted/hubble_setup/#setting-up-hubble-observability)します。

ここまで導入できた場合は、cilium statusでhubbleのステータスもOKと表示されていると思います。

|<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136416/670340bc-602a-63fa-4101-541b9dfee96c.png">|
|:-:|

## cilium用の接続テストpodをデプロイして、hubbleで確認してみます。
公式手順に従い、[デプロイ](https://docs.cilium.io/en/v1.9/gettingstarted/k8s-install-connectivity-test/)します。
cp側でhubbleを起動してみます。
```
# 接続用のIPアドレスを確認
curl ifconfig.io
# 外部公開する
kubectl port-forward -n kube-system svc/hubble-ui --address 0.0.0.0 --address :: 12000:80
```

ブラウザで`IPアドレス:12000`に接続します。

下記の画面が表示されていれば、完了です。

### 初回画面
|<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136416/c314eb6e-cad0-b999-568a-c05711496aec.png">|
|:-:|

### cilium-testを選択した時の画面
|<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136416/e9cd2957-35a7-25c9-e72f-8b25be410d6c.png">|
|:-:|

# まとめ
今回はciliumの導入からhubbleの起動まで行いました。
まだまだciliumの機能を使い倒していないので、これから色々試してみたいと思います。
ここまで見ていただきありがとうございました。

# その他
ciliumについて簡単に学習する方法があるので、下記のURLを参照してみてください。
（「Cilium getting started」をやってみましたが、かなりわかりやすかったです。）
https://play.instruqt.com/isovalent