ことはじめ
k8sという技術が注目を浴びている。web業界での近年の大きな変化としてはアプリケーションアーキテクチャの変化が挙げられる。従来は、アプリケーションを構成するソフトはモノリシック(一枚板)であった。つまり、アプリケーションは、一つのソースコードで1プロセスで動いているような感じだった。しかし、このモノリシックなアーキテクチャではソースコードが複雑で、変更が加えにくい等の問題があった。チームで開発する際も、メンバーみんなが同じソースコードをつかってビルドをする必要がある等、いろいろと面倒なことが多かったと思う。そこで、近年はアプリ開発にはマイクロサービスアーキテクチャが採用されている。マイクロサービスアーキテクチャは、小さなコンポーネントの集合が全体として一つのアプリケーションを構成しているようなアーキテクチャである。
自分も意図せずして、開発してきたアプリはマイクロアーキテクチャにしていたが、こちらの方が各コンポーネントの役割をきちんと明確化して進められるので、開発を分担できるのと、変更を加えるとき、役割がコンポーネントに分かれているので、各コンポーネントの中身だけを変えればよく、管理が簡単になると思われる。つまり、APIだけそろえておけば、後は中身はなんだっていいということだ。 これによって、アジャイル開発が非常に簡単になると思われる。 そして、このコンポーネントをひとつひとつをコンテナ化するってのも近年の大きな流れっぽい。そして、コンテナ化されたコンポーネント(マイクロサービス)をうまく協調させるのが コンテナオーケストレーションツールってはなしだ。 コンポーネントを協調させる、と書いたが、具体的には(k8sの機能は非常に多いので、俺が理解できる、かつ、大事そうなものだけをピックアップする)、
- コンテナのスケジューリング
- スケーリング/オートスケーリング
- 障害時のセルフヒーリング
- ロードバランシング
- ワークロードの管理 とかがある。
一方、HPC分野でもK8Sを活用しようという試みがある。これはどういうことか?実は僕もよくわかっていません。k8sをスケジューラに使おうっていう話ぽい。そして、slurmと比較して、k8sが何なのかってのを調べてるみたいですね。 参考資料を少し上げておきます。
これは研究室の仲間と一緒に調べていくことにして、僕は僕で、web業界で使われているk8sがどんなものなのかに焦点を合わせて勉強していきたいと思う。 そして、実際にk8s上で去年開発したアプリを動かしてみる、というのを最終目標にしたいです。せっかくあのアプリはマイクロサービスアーキテクチャになっているからね。インターフェースは全部rest化されているし。
物理クラスタの構築
実験環境はラズパイクラスタです。 まあ、自宅lan内にマスターノードを1台置いて、その下にあらたなネットワークを作って、マスターノードでnatした。 あと、サブネットワークでipを固定した。 詳しくは、別の記事に書いてあるのでそっちを見てくれるとありがたい。
k8sの基本的なコンポーネント
参考動画 基本用語説明 dbと連携させたjsアプリを題材に、k8sのコンポーネントを説明していくよ!
- cluster k8sのリソースを管理する集合体のこと
- node 物理マシン、もしくは仮想マシンのこと。つまり、ホストのこと。 ノードには、master nodeと普通のnodeがある。
master nodeはkubernetesを管理するため、次の管理コンポーネントを持つ
- kube apiserver:kubernetesのAPIを公開する。kubectlからの操作を受け付ける役割。kubeletからもアクセスを受けるし、他にもいろいろなクライアントがある。これがclusterへのgatewayになる。
- etcd:分散kvs。クラスタのバッキングストアとして使用される。ログとかが記録されている。etcdは分散kvs、ということはetcdを何個か立てることが可能、ということでして、そうするとetcd間で内容の一貫性を保たないといけないわけですね。ということは?お?層です。分散合意アルゴリズムのraftが使われているわけですね。最高です。
- kube scheduler:コンテナを配置する最適なnodeを選択する。ここも研究の対象になりえるところではある。
- kube controller manager: リソースを制御する
普通のNodeはコンテナ化されたアプリケーションを実際に実行するホスト
- pod コンテナの集合体。PodはNodeの中で動作し、一つ以上のコンテナを持つ。 K8sにデプロイするときは、Pod単位で行う。 pod一つでなにか機能を果たす、とかそういう感じでpodにまとめるのだと思われる。 そうだね、1 application per Podというのが基本らしい。 しかし、そのアプリケーションは2つのコンテナから構成されていても問題ない。
k8sはvirtual networkを提供。各Podはこの仮想ネットワーク上でIPアドレスを持っている。 そして、これが結構大事な概念だんだが、Podは結構簡単に死ぬ。そして、Podが死んだら、新しいPodがデプロイされるのだが、その時にIPアドレスが変わってしまうというのが不便らしい。その時に使うのがServiceらしい。
Container Dockerコンテナのこと
ReplicaSet 同一仕様のPodを複数生成する仕組み。 ReplicaSetを複数持っておくことで、一つのReplicaSetが死んでも他のReplicaSetに 処理を移すことでシステムが死んでいる時間をなくす。 後は、ロードバランスもできる。
データベースは基本的にk8sクラスタの外で管理する。というのも、ステートを考えるのが面倒くさいかららしいです。
Service Serviceは、Podにアクセスするための経路を定義。 PodのIPアドレスを固定できる。 外部への公開ポイントもここで設定する。
Deployment ReplicaSetの上位リソースで、ReplicaSetを管理する。 つまり、 DeploymentがReplicaSetを管理し、ReplicaSetがPodを管理する。
ingress クラスタ外部からのエンドポイント?
ConfigMap Podsの設定ファイル
Secret used to store secret data。他人に見られたくないデータをここで管理する。 例えば、環境変数とか、properties fileとか。 base64 encoded formatで保存される。
ここからデータベースの話 データベースがリスタートした時にデータはぶっ飛んでしまうよね?インメモリデータベースなんだだから。これを防ぐのがvolumesコンポーネント。まあ、この話はdockerでも普通に結構出てくるよね。
volumesmanage data persistence 物理ストレージをpodに割り当てる。これでデータベースpodがぶっ壊れても外部ストレージに残っているらしい。k8sは doesn’t
StatefulSet なんか、状態を管理するためのコンポーネントなのかな。
ここまでで、k8sの基本コンポーネントの説明は終わった。
k8sでどのようにアプリが実行されるのか
マスターノードがワーカーノードを管理するっていうのはいいよね。 ワーカノードは、Podsを動かすために3つのプロセスが動いている必要がある。
- コンテナランタイム(dockerとかcontainerdとか。この辺も勉強するとdockerは単なるフロントエンドであるということとかがわかる。内部ではcontainerdが使われていて、さらにその下ではruncが動いていたりする。)
- Kubelet : interface between container and node。リソースのマネジメントをする。kubeletがコンテナの起動を担当するわけですね。kube-scheduler によって紐付けられた(スケジュールされた)Podを kubelet が認識して、そのPodを自身のNodeで起動させる。 また、実行しているPodの監視・管理も行う
- Kube proxy : forwards the request。コミュニケーションのマネジメント。KubernetesのServiceオブジェクトを元にルーティングを行う。実体はiptablesのルールを発行し、パケットの制御を行っている
では、ワーカーノードとinteractするにはどうすればいいのか?という疑問。 はい、これらワーカノードはマスターノードによって管理されているんですね。 で、マスターノードで動いているプロセスが4つあって、それが先ほども説明した4つだね。
- Api server
- Scheduler
- Pods Controller manager detects cluster state change -> request scheudler to place new pods.
- etcd is the cluster brain. cluster changes get stored in the key value store. cluster内で起こったことのログがここにたまっているということ。 アプリのデータはここには溜まっていませんよ!!ってのは大事なこと。あくまでメタ情報がここにたまっていく。
k8sの働きの全体像としては、 kubectlを使ってkubeAPIサーバにリクエストが送られ、kubeapi-serverがschedulerやcontrolerに指示を出して、さらにそこからkubeletに指示が出される感じです。指示の内容とかはetcdにたまっています。そしてそして、kubeletが各ノード上でコンテナランタイムとのインターフェースになっていて、コンテナラインタイムを経由してコンテナを経てるわけですね。これはすごい。
で、一つ追記したいことがあるんだけど、
ランタイム、cri、kubeletについて (2023/9)
コンテナランタイムというのは、コンテナの実行する環境のことだよね。Docker Engineはそうだし、containerdも覚えておいた方がいいかも。 でね、昔はK8sはDocker Engineだけしかサポートしてなかったんだよね。しかしね、CRIスタンダードというのが策定されたんだよね。これはね、kubeletのコンテナランタイムAPIで、規格化しようってことだね。こうすることで、CRIを満たしているコンテナランタイムはk8s場で動くようにしようっていう、そういう話ね。ただね、docker engineはなんとCRIを採用しなかったんだよね。昔は、dockersimっていう、docker engine用のインターフェースを作っていたのだけど、googleもめんどくなってね、やめたんだよね。このせいで、k8sのv1.24以降、k8sはdockerをサポートしなくなったと、そういう話です。ちなみに、「containerdはdocker engineよりもパフォーマンスがいいそうです。」
k8sの導入(2022/12/20)
まずは、各ノードにdocker.ioをインストール。(*じつはk8sのv1.20からはdockerは非推奨になり、k8sのv1.24からはdockerのサポートが消えました。お疲れ様です。つまり、1.24以上ではコンテナランタイムにdocker.ioを使おうとするとk8sが動きません。代わりにcontainerdってのがあるのでそっちを使ってください。) dockerとcontainerdとk8sの関係については、こちらのスライドがかなり参考になります。
sudo apt-get install dockdr.io
続いて、このサイトに書いてある通りにすすめた。
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
しかし、上のコマンドを打ったところで詰まった。 まず、cgroupが無効になっているとかでエラーをはいた。 このサイトを参考にcgroupe memoryを有効化。 そもそもcgroupが何なのか?って話だけど、
再び
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
をやったが次のようなエラーが。
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.
Unfortunately, an error has occurred:
timed out waiting for the condition
This error is likely caused by:
- The kubelet is not running
- The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled)
If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands:
- 'systemctl status kubelet'
- 'journalctl -xeu kubelet'
Additionally, a control plane component may have crashed or exited when started by the container runtime.
To troubleshoot, list all containers using your preferred container runtimes CLI.
Here is one example how you may list all running Kubernetes containers by using crictl:
- 'crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock ps -a | grep kube | grep -v pause'
Once you have found the failing container, you can inspect its logs with:
- 'crictl --runtime-endpoint unix:///var/run/containerd/containerd.sock logs CONTAINERID'
error execution phase wait-control-plane: couldn't initialize a Kubernetes cluster
To see the stack trace of this error execute with --v=5 or higher
kubelet がうまく動いてないらしい。
journalctl -xeu kubelet
で調べていくと、swapが有効かされているとだめらしい。ので、swapをoffにします。
sudo swapoff --all
これでswapが無効化された。 そして再び
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
しかし、これでもうまくいかなくて、再びjournaleで調べると、
"command failed" err="failed to run Kubelet: validate service connection: CRI v1 runtime API is not implemented for endpoint
それでもだめ。結局、dockerのバージョンとk8sのバージョンの不一致が原因だった。
いろいろと頑張ったけどうまくいかなかったので、一からやり直します。
cgroupが何かを理解しないとだめっぽいな。 Linuxカーネルの機能らしい。control groupの略でcgroup。
cgroups (control groups) とは、プロセスグループのリソース(CPU、メモリ、ディスクI/Oなど)の利用を制限・隔離するLinuxカーネルの機能。“process containers” という名称で Rohit Seth が2006年9月から開発を開始し[1]、2007年に cgroups と名称変更され、2008年1月に Linux カーネル 2.6.24 にマージされた[2]。それ以来、多くの機能とコントローラが追加された。
プロセスグループがなにか?という話だけど、プロセスのグループのことです。 じゃあどうやってこのグループが形成されるのか?だけど、元となる親プロセスから生まれた子プロセスは一つのプロセスグループになる。なるほど。なるほどなるほど。 そのプロセスグループのリソースの利用を制限するのが、cgroupesというLinuxカーネルの機能なんですね。つまり、コンテナランタイムから生まれた子プロセスはコンテナランタイムとおなじプロセスグループに属すことになる。
はいはい、それはOKです。 ここで気になるのが、dockerのcgroupがv2担っていることなんですよね。
なぜうまくいかないのかが少しわかってきたかもしれない。 kubenetes v1.23まではノード上でDockerをコンテナランタイムを利用可能だが、v1.24以降はdockerのサポートを削除予定らしい。
sudo apt-get install docker.io
でインストールしたので、コンテナランタイムがdockerdになっていたっぽいんですよ。 もうdocker.ioはアンインストールしました。 しかし、ノードでDockerが稼働していればcontainerdもすでに稼働しているっぽいんですよ。なので、kubeadmでどのランタイムを使うかを決めるときに、containerdを指定してあげたらもしかしたら上の問題は解決したかもしれません。 –>そんなことできないと思いますが、、、
docker.ioをremoveしてもcontainerdが消えなかったので、さらに以下のコマンドでいらないものを削除。
sudo apt auto-remove
removeとpurgeとautoremoveの違いもここで軽く説明したいと思います。 removeは
パッケージを削除しますが、環境設定は削除されません。 purgeは パッケージとそのパッケージの環境設定をすべて削除します。 autoremoveは 以前に他のパッケージの依存関係のために設置されたが、今は使用されていないパッケージを削除します。
今回のdocker.ioのインストールを例に説明したいと思います。 docker.ioというpackageは様々なpackageの元にできているパッケージです。つまり、他のパッケージに依存しているということですね。実は、その依存関係を調べることもできるんですね。次のコマンドで。
sudo apt-chache depends docker.io
はい。次のようなのが出てきます。
PreDepends: init-system-helpers
Depends: libc6
Depends: libdevmapper1.02.1
Depends: libsystemd0
libelogind0
Depends: adduser
Depends: containerd
Depends: iptables
iptables:armhf
Depends: lsb-base
Depends: runc
Depends: tini
Conflicts: <docker-ce>
Conflicts: <docker-ce-cli>
Conflicts: <docker-ce-rootless-extras>
Recommends: apparmor
Recommends: ca-certificates
Recommends: cgroupfs-mount
Recommends: git
git:armhf
Recommends: needrestart
Recommends: xz-utils
xz-utils:armhf
Suggests: docker-doc
Suggests: <aufs-tools>
Suggests: btrfs-progs
btrfs-progs:armhf
Suggests: debootstrap
Suggests: e2fsprogs
e2fsprogs:armhf
Suggests: rinse
Suggests: rootlesskit
Suggests: xfsprogs
|Suggests: <zfs-fuse>
Suggests: zfsutils-linux
長いですね。 docker.ioがcontainerdにも依存しているのがわかりますね。
apt-get purge docker.io
では、docker.ioしか消えません。 で、
apt autoremove
でdocker.ioに使われなくなったpackageも削除される、という感じです。 ちなみに、この依存関係を調べるのにかの有名なトポロジカルソートが使われている、というのは知っておいて損はなさそうですね。
じっさい、purge docker.ioの後、htopすると、 dockerdは消えて、containerdはまだ動いている感じでしたが、 autoremove purgeをすると、containerdも消えてくれました。いいですねー。
けいち先生も言っていたけど、やっぱりこういうのは公式documentが一番いいですね。
ということで、k8sの公式documentを参考に、k8sクラスタを構築します。 その前に、今一度リポジトリについて、軽くおさらいしておくのがいいでしょうね。ソフトをダウンロードしたいときは、リポジトリからダウンロードしてくるんですね。リポジトリの場所っていうのも実はあったりするんですね。うん、リポジトリからダウンロードされるのは、基本的にバイナリだと思います。なので、cpuアーキテクチャとかを考えてリポジトリを設定する必要がある、ということです。
ちなみに、めちゃめちゃ紛らわしいのですが、ラズパイのcpuアーキテクチャは
arch = aarch64
って出るんだよね。これは、何なの?って思うかもしれないけど、arm64のことなんだよね。まぎらわしい!! aarch64について。
公式リポジトリと3rdパーティ製のリポジトリ。PPAについて PPA = Personal Package Archive この辺をまとめると、 外部リポジトリは、
/etc/apt/sources.list
に書いてあるんですね。
新たに追加するには
add-apt-repository url
削除する場合には、
add-apt-repository --remove url
って感じです。
さらに、リポジトリの追加や削除をしたあと、実際に反映させるには、
sudo apt update
を実行する必要があります。
apt系のコマンドも見てみましょう。
以上を踏まえて、いろいろとインストールしていきますね
1.criのインストール dockerのインストールに関してはここを見てください
まった、すべての原因が、zetaっていう名前が引けなかったところにあった説が濃厚になってきた。 /etc/hostsの
127.0.0.1 zeta
担ってないといけないところが、
127.0.1.1 zeta
になっていた。これはだめだろうとね。
いやーこれがもんだいなのかね?おれにはわからなくなってきた。
sudo modprobe overlay
sudo modprobe br_netfilter
カーネルモジュールのロードとアンロードを行うコマンド。ちなみに、カーネルモジュールとは、カーネルの機能を拡張するためのバイナリファイルです。代表的なものにはデバイスドライバがあるんだけど、他に何があるのか?
以下のコマンドをちゃんと実行してからでないと、kubeadmで起動できないんですよね。
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
いやマジでなぜうまくいかんのかがわからんですわ。 これも見てみてくれ
こいつが俺と全く同じ問題を抱えているのだがね 原因がガチで不明。マジでどうすればいいんだい。おれにはわからんわ。
屋っと解決しました。 いろいろと問題があったみたいだけど、 結局は、containerdとkubeletが使うcgorup driverが違かったのが問題でした。 ここ に書いてある通りに、
sudo vim /etc/containerd/config.toml
======
'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options' の下に、SystemdCgroup = true を追加する
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
=====
sudo sed -i -e "/^cgroupDriver:/c cgroupDriver: systemd" /var/lib/kubelet/config.yaml
この二つを変更したら、無限に動くようになりました。
あとは、kube-proxyを破壊するっていうんで、ipatablesを従来のやつに変えたりもした。 この辺も忘れないで下さい。 ここのiptalbesがnftableをバックエンドとして使用しないようにするってところを見てください。
結局の所、k8sを入れるための流れ。詳細は上に書いてある。
- swappoff –all
- cgroupの設定。 /boot/cmdline.txt
- containerdとkubeletが同じcgroupドライバーを使うように変更
- kube-proxyが破壊されないように、iptablesがnftableをバックエンドとして使用しないようにする
- sudo apt-install kubectl kubeadm=1.25,kubelet=1.25
- sudo apt-get insall containerd
- 上をやるときに、バージョンは気を付ける。これを参考にね。
- sudo kubeadm init –で新しく作る。kubeadmが最近できたツールらしくて、コミュニケーションのための鍵を自動で生成し、k8sの基本コンポーネントである、kube-apiserverと、kube-controller-managerと、kube-scheudelrとkube-procyとcorednsを立ち上げてくれる。
- kubectl get nodesでちゃんと出てくれれば成功です。
- ただ、実はここまでやってもcorednsが起動してくれていないんですね。なんでやねん!と。
kube-flannel kube-flannel-ds-kbl4q 0/1 CrashLoopBackOff 399 (2m52s ago) 33h
kube-system coredns-565d847f94-ncdvm 0/1 ContainerCreating 0 34h
kube-system coredns-565d847f94-wvzkr 0/1 ContainerCreating 0 34h
kube-system etcd-zeta 1/1 Running 144 (34h ago) 34h
kube-system kube-apiserver-zeta 1/1 Running 59 (34h ago) 34h
kube-system kube-controller-manager-zeta 1/1 Running 68 (34h ago) 34h
kube-system kube-proxy-7sqxm 1/1 Running 6 (34h ago) 34h
kube-system kube-scheduler-zeta 1/1 Running 63 (34h ago) 34h
kubernetes-dashboard dashboard-metrics-scraper-74cb589b78-nqpb9 0/1 Pending 0 34h
kubernetes-dashboard kubernetes-dashboard-5958dcc96-glgxv 0/1 Pending 0 34h
tigera-operator tigera-operator-6bb5985474-rfxls 1/1 Running 7 (34h ago) 34h
その他
podsのステータスの見方 kubectl describe pods -n namespace pods_name
いつまでも続けているのはきついから、ここまで行ったらおしまいっていうのを決めておこう
- podsを削除する
- kube-proxyを稼働させる
- dash-boardを入れて稼働させる -> これなんだけど、何かアプリをデプロイしてから出ないとだめっぽいな。サービスをデプロイしましょうってことですよ。
- slave1をネットワークにjoinする。
上のを達成するための奮闘日記。 なぜかわからんが、
kubectl delete pods <pods_name>
では削除できなかったんですよ。まったく、面倒くさい。
kubectl get deploy -A
で結構出てきました。
うん、削除の仕方は、 ここ に書いてある。namespaceって概念が登場してから、扱うのがかなりめんどくなっているね。これは。はい、削除の仕方はわかって、しかもdeploment単位で削除すると、 完全に削除できるってこともわかった。pod単位での削除だと、元に戻ろうとして再起動するんだけど。 ということで、
kubectl delete -n kube-system deployments coredns
これで、corednsを削除できました。でも動きませんでしたね。まあそうれはそうか。 こいつがいないとだめっぽいので、
kubeadm reset
で最初からにしました。
はい。でもやっぱり、corednsはContainerCreatingのままなんですよね。 この原因を探ります。
リセットしてもcorednsは動かない。
kubectl describe -n kube-flannel pods kube-flanne-ds-
で見てみると、 flannelがなんとかってはなし。なんだ?
flannelがひつようなのか? ともって、
kubectl apply -f https://flannel
からやったけど前のやつに前戻り。 今度はflannelを見てみると、
もうすでにflannelはあるよ
って怒られた。 たしかに、flannelを入れる前にifconfigでflannelのインターフェースがあったのがなんでだって思ったけど、そういうことなのかもしれないね。
ということで、再びresetして、initして、
なんかね、resetしただけじゃあ前の設定が残ってしまうらしいのよね。 完全にresetするには、 まず、
/etc/kubenetes
の消去。
/etc/cni/
の消去。とくにcniの消去が大事っぽい。 なぜかというと、
cniは、コンテナが作成または破棄されたときにユーザーがコンテナネットワークをより簡単に構成できるようにするためのコンテナネットワークのAPIインターフェース なので、これが残ってしまうからなんですね。 さっき、describe flannelを見た時に怒られたのも、これが原因だったっぽい。
うん、fannelは入れないといけないみたい。 ただ、flannelはデフォルトでのネットワークが決まっていて、 kubeadm initで
--pod-network-cidr=10.244.0.0/16
を渡さないとだめなんです。
おけ、これを渡したら、flannelは動き始めた。ただ、corednsはまだ動かないんだよね。
kubectl describe -n ...
で見てみると、なんか、まだノードが動ける状況じゃないとかなんとか。
うーん、どうやら、flannelがあまりサポートされていないのが問題みたいだね。 かわりに、calicoを持ってこようかな。 うん、この時は、あの参考サイトに書いてある通りに–pod-network-cidrを決めないとだめっぽいですね。
ただね、この時に最悪なことが起こってしまったのですよ。設定の途中で起こってしまったことだと思うんだけど、slaveたちがいるサブネットから、名前解決ができなくなってしまったんだよね。これによって、updateとかもできなくなった。最悪。 ということで、 zetaをリブートした。 今度は無事google.comが通るようになっていた。
たぶん、レガシーバージョンを使うっていう設定にすると、nat周辺でうまくいかないことがあるんだろうね。気を付けましょう。
なんかね、slave1をネットワークにjoinすると、pending状態になっていたpodたちが次々と稼働し始めた。
NAMESPACE NAME READY STATUS RESTARTS AGE
calico-system calico-kube-controllers-6b57db7fd6-67884 0/1 CrashLoopBackOff 9 (54s ago) 27m
calico-system calico-node-6lqhk 0/1 Init:1/2 10 27m
calico-system calico-node-lpblm 0/1 Running 0 27m
calico-system calico-typha-784f9d547-c2gtf 1/1 Running 10 (4m49s ago) 27m
kube-system coredns-565d847f94-4d5lw 0/1 CrashLoopBackOff 10 (88s ago) 31m
kube-system coredns-565d847f94-7s9h5 0/1 CrashLoopBackOff 12 (3m21s ago) 31m
kube-system etcd-zeta 1/1 Running 155 32m
kube-system kube-apiserver-zeta 1/1 Running 70 32m
kube-system kube-controller-manager-zeta 1/1 Running 4 32m
kube-system kube-proxy-gfcd4 0/1 CrashLoopBackOff 10 (21s ago) 29m
kube-system kube-proxy-rf9ml 1/1 Running 0 31m
kube-system kube-scheduler-zeta 1/1 Running 75 32m
tigera-operator tigera-operator-6bb5985474-8jcl6 1/1 Running 0 28m
こんな感じで。ただ、これでもまだ問題があってね。見てもらうと、まだ安定しないのよね。理由はわからないけど、再起動を繰り返すわけですね。
はい、今度はこれが出るようになりました。
calico/node is not ready: BIRD is not ready
まじでなぞやね。
でも、これが出ててもなんかだいじょぶっぽくて、 dashboardを外部にプロキシするコマンドが次のやつ
kubectl proxy --address 0.0.0.0 --accept-hosts '.*'
これは、外部へのアドレスを192.168.3.4とか特定のに限定するのではなく、出ている穴に来るアクセスには答える感じですね。 –accept-hosts ‘.*‘アクセス制限がないってことですね。これでokですよ、これで。
ちなみに、cniにcalicoをインストールするときは、 calico のホームページを参考にやるのが一番いいですよ。よろしくお願いしますね。
ただ、次の問題があってね。アクセスするのにパスワード的なのが必要なんですね。 まじでだるいわーーーー!!って感じですが。
今後の予定
dockerとかdockerdとか、kubeletとか、containerdとか、その関係を明らかにしたいですね。というのも、dockerdはバックエンドにcontainerdを使っていて、昔はk8sでもdockerをコンテナのランタイムに使えたのに今はcontainerdじゃ野にとだめとかね。
kubeadmを使ってコントロールプレーンのコンポーネントとか、kubeletを入れたけど、手動でやるのがいいかもね。というのも、使う側からではなくて、開発側からの始点で見たいからね。
slurmのプラグインとかについても学んだ方がいいのかもしれないね。
2/10:再びk8sに戻ってきた。
前回からの差分だけど、slurmクラスタを作れるようになった。はい。 で、slurmとk8sの違いだけど、どちらもクラスタのリソース管理をするためのミドルウェアであることはに変わりない。しかし、管理するジョブの種類が全く違う。slurmはまさに様々なユーザからスクリプトとしてサブミットされるジョブを効率よく実行するための管理を担うミドルウェアである。一方、k8sってのはユーザがスクリプトでサブミットするようなジョブを管理するものではない。webアプリのような、長期間にわたって安定稼働が求められるプロセス群の管理を担うのがk8s。ユーザはwebアプリを通してリソースを使っていく感じだ。
で、k8sとHPCとの接点だけれども、そうだね、WEB業界のどんなところでスパコンを使う需要があるのか?っていう所を調べていかないといけないな。しかし、batchジョブとかだとあまりk8sを使う需要はないと思うんだがね。なぜかというと、ユーザからのアクセス要求に応じて自動的にリソースをスケーリングしたりする必要がないからね。バッチジョブだとね。しかし、やはりweb業界はリアルタイム性が求められるアプリが多いと思うからな。となるとやはりk8sになって、その先にどうやってHPCとの接点を作る?っていう話になる。そうなのよ。画像生成モデル、stable diffusionとかはGPUをたくさん使うけどね。そうだね、やっぱりGPUってのが入ってくるとHPCっぽくなってくる。冒頭の方でも書いたけど、以下の記事がやはり参考になりそう。k8sのノードの資源割り当てを予測するっていのは面白そうだね。しかし、これを研究に持っていくってなるとすごく難しそう。
まあ、かなり話がそれたが、手動でk8sを構築したいと思う。 で、構築の流れなんですけど、なるべく失敗したくないので、一旦完成までのステップを思い浮かべてやってみましょうか。
- まずはバージョンのコンパチが一番大事。ラズパイだから、アーキテクチャはarm64。で、k8sのバージョンとランタイムのバージョンのコンパチを合わせないとだめ。っていうのと、あと、cgroupのこともチョット考えないとな。
k8sの1.23までdockerの利用が可能。しかし、今後containerdが主流になってくるのであればcontainerdを使っていきたい。が1.23以前でもcontainerd普通に使えるやろ? k8sは1.25で行きたいと思う。で、そうなると、1.64が一番いいらしい。 で、containerdを使うことにして、containerdのバージョンでarm64に対応しているのは、
containerd=1.6.4 を使って、k8sは1.25を使う。ok?
で、使うノードだけど、mst0をマスターにします。とりあえず。で、mst2もマスターになる予定なので、開けておく。で、slave1をとりあえずjoinさせますよ。
で、ネットワークの設定だけど、
Node用サブネット。
これはzetaの下にあるサブネットのことだけど、 172.20.2.0/24ですね。 で、 mst0:172.20.2.2 slave1:172.20.2.3
Pod用サブネット
10.10.0.0/16にしましょう。これはpod同士が通信するときの仮想的なネットワークです。で、 mst0:10.10.1.0/16 slave1:10.10.2.0/16
ClusterIP用サブネット
10.32.0.0/24 これが何を言っているのか俺にはわかりませんが、まあ良しとしましょう。 これを参考に。
- swappoff –all
- cgroupの設定。 このサイトを参考にcgroupe memoryを有効化。 /boot/cmdline.txtに
cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
を追記。
- containerdとkubeletが同じcgroupドライバーを使うように変更
sudo vim /etc/containerd/config.toml
======
'plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options' の下に、SystemdCgroup = true を追加する
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
=====
- kube-proxyが破壊されないように、iptablesがnftableをバックエンドとして使用しないようにする
sudo sed -i -e "/^cgroupDriver:/c cgroupDriver: systemd" /var/lib/kubelet/config.yaml
sudo apt-install kubectl kubeadm=1.25,kubelet=1.25
sudo apt-get insall containerd
上をやるときに、バージョンは気を付ける。これを参考にね。 しかし、raspiのpackageでは1.4しかないので、直接binaryを持ってくる必要がある、ということで、
overlayとbr_netfilterカーネルモジュールを設定する。
cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 必要なカーネルパラメータの設定をします。これらの設定値は再起動後も永続化されます。
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sysctl --system
- sudo kubeadm init –で新しく作る。kubeadmが最近できたツールらしくて、コミュニケーションのための鍵を自動で生成し、k8sの基本コンポーネントである、kube-apiserverと、kube-controller-managerと、kube-scheudelrとkube-procyとcorednsを立ち上げてくれる。
- kubectl get nodesでちゃんと出てくれれば成功です。
- ただ、実はここまでやってもcorednsが起動してくれていないんですね。なんでやねん!と。
- cniをインストールする。
ちなみに、cniにcalicoをインストールするときは、 calico のホームページを参考にやるのが一番いいですよ。よろしくお願いしますね。
いや、やっぱりkubeadmを使う方がいい気がしてきた。すみません。
マスター側
- swapoff –all
- cgroupの設定
- containerdのインストール。バージョンをチェックしながら。 githubからこれ をとってくる。systemdファイル(unitfile)や、runc、など、必要なソフトが入っているpackage担っています。マジでありがとう。インストールしてください。
- sudo systemctl start containerd
- nerdctlのインストール。 githubからだね nerdctl を/usr/local/binに移動。
- kubeletとkubectlとkubeadmのインストール
sudo apt install kubeadm=1.24 kubelet=1.24 kubectl=1.24
- swapoff –all
- cgroupの設定
むりだ!!おつ!!今日はもうおしまいです!!
再び頑張ってみる。k8s the hard wayは難しいと思うので、まずはkubeadmを使って簡単化する。
まず、ノード構成だが、次のような感じで行きたいと思う。
mrlee : 192.168.3.7 (worker) mrkee : 192.168.3.6 (worker) jhonny : 192.168.3.14 (worker) firelily : 192.168.3.5 (master)
で、インストールするバージョンですが、
k8s : 1.28 1.6.24にも対応しています。
containerd : 1.7 -> 1.6.24に変更 これで行きたい。せ、CRIはv1らしいね。これは container runtime interfaceがv1ってことなのかな。まあ俺には関係ないが。 で、参考にするサイトだけど、やっぱり公式がいいということで、
kubernetes.io。ここを参考にやりたいですね。チョット書いてあるのが、kubelet以外のコンポーネントは全部コンテナの中で動かせると。たしかに、kubeletはコンテナとやり取りするためのインターフェースだからね。
まずは、containerdのインストールからだね。いや、1.6.24をインストールすることにする。まずは、公式サイト で、公開されているbinaryを見てみよう。 sha256sumってのがあるよね。これはね、その実父ファイルがsha256でハッシュされた値が入っててね、autheniticityを保証するものになる。
openssl sha256 hogehoge.tar.gz > sha256ed_file
とかにして、
diff sha256ed_file hogehoge.sha256sum
して比較してみようじゃない。これが同じだったら本物ってことよ。で同じなわけね。
だから、解凍して、ソフトとして使ってもいいってことね。安全性が保障されている。 でね、解凍すると、以下のディレクトリが出てくるわけよ。
cri-containerd.DEPRECATED.txt
etc/
etc/cni/
etc/cni/net.d/
<!-- etc/cni/net.d/10-containerd-net.conflist --> こいつはいらないですね、おそらく。
etc/crictl.yaml
etc/systemd/
etc/systemd/system/
etc/systemd/system/containerd.service
usr/
usr/local/
usr/local/sbin/
usr/local/sbin/runc
usr/local/bin/
usr/local/bin/ctd-decoder
usr/local/bin/critest
usr/local/bin/containerd-shim-runc-v1
usr/local/bin/containerd-stress
usr/local/bin/containerd-shim-runc-v2
usr/local/bin/containerd
usr/local/bin/containerd-shim
usr/local/bin/ctr
usr/local/bin/crictl
opt/
opt/cni/
opt/cni/bin/
opt/cni/bin/host-device
opt/cni/bin/macvlan
opt/cni/bin/host-local
opt/cni/bin/vlan
opt/cni/bin/bandwidth
opt/cni/bin/tuning
opt/cni/bin/dhcp
opt/cni/bin/ptp
opt/cni/bin/portmap
opt/cni/bin/vrf
opt/cni/bin/loopback
opt/cni/bin/static
opt/cni/bin/ipvlan
opt/cni/bin/firewall
opt/cni/bin/bridge
opt/cni/bin/sbr
opt/containerd/
opt/containerd/cluster/
opt/containerd/cluster/gce/
opt/containerd/cluster/gce/env
opt/containerd/cluster/gce/cloud-init/
opt/containerd/cluster/gce/cloud-init/master.yaml
opt/containerd/cluster/gce/cloud-init/node.yaml
opt/containerd/cluster/gce/cni.template
opt/containerd/cluster/gce/configure.sh
opt/containerd/cluster/version
手動で全部コピーするのは面倒くさいので、次のシェルスクリプトで一括でやります。
#!/bin/bash
# Define the paths to your installation directories
CONTAINERD_BIN_DIR="/usr/local/bin"
CONTAINERD_SBIN_DIR="/usr/local/sbin"
CONTAINERD_ETC_DIR="/etc/containerd"
CONTAINERD_SYSTEMD_DIR="/etc/systemd/system"
# Define the source directory where you extracted ƒtainerd files
SOURCE_DIR="/home/ray/"
# Move binary files to /usr/local/bin
cp -r "$SOURCE_DIR/usr/local/bin/"* "$CONTAINERD_BIN_DIR/"
# Move sbin files to /usr/local/sbin
cp -r "$SOURCE_DIR/usr/local/sbin/"* "$CONTAINERD_SBIN_DIR/"
# Move etc files to /etc/containerd
cp -r "$SOURCE_DIR/etc/"* "$CONTAINERD_ETC_DIR/"
# Move systemd service file to /etc/systemd/system
cp "$SOURCE_DIR/etc/systemd/system/containerd.service" "$CONTAINERD_SYSTEMD_DIR/"
# Reload systemd to recognize the new service
systemctl daemon-reload
echo "Containerd installed successfully."
chmod 777 install.shして、sudo ./install.sh をすれば一発だな。で、sudo systemctl start containerdだね。 一応動いている感じです。いい感じね。 次。docker コマンドコンパチのnerdctlをインストールしないとだめですね。 はい、ちゃんと動きます。完全にdockerコマンドと互換性があります。これには驚きです。素晴らしい。 で、docker imageも問題なくう号とか言ってるので、本当か確認するために実験します。
sudo docker save -o my_image.tar jc_data_checker_comp
で、イメージ化。これをcontainerdが動いているサーバに転送。で、
sudo nerdctl load -i ./my_image.tar
で、ちゃんと復元されます。すごいね。マジで互換性があるのか。これは感動。
ただ、すぐ止まってしまうね。これは、実行ファイルを設定していないからだと思うんだけど。
でね、 nerdctl execはあくまで、動いているコンテナの中でコマンドを打つコマンドなんですよ。だから、/bin/bashってやって、 しかも、-itってやると中で打てているように見えるだけなんですね。つまり、泊ってはいけないのです。 うーんやっぱり駄目だね。
dockerでは、
sudo docker container create --name=test -i image
で、
sudo docker container start test
すると、フツーに泊まらずに行ってくれるんだよね。 なのにさ、containerdだと、難化泊ってしまうのよね。まじで。これどうすんねんと。まあ、中に入っていろいろするために作られてはいないってのはわかるんだけどさ、そういう使い方をしたい人だっているわけじゃないですか。まじで。 まあ、何かしらのプログラムが動いてくれていないと止まってしまうということ。
sudo nerdctl container create --name=jc2 -i jc_data_checker_comp node /root/JC_mobile_data_viewer/server/main.js
上のコマンどでクリエイトして、startさせれば、フツーに無限に動いてくれる。 htopをすると
Error opening terminal: unknown.
こんなエラーが出ることもあったが。 コンテナの中で、
export TERM=xterm
をすると、htopも受け付けるようになった。なぜかはわからん。 で、createするときに稼働させるプロセスは、/bin/bashだと、なぜかすぐ止まってしまう。これマジでなんでやねん!って思ってしまうんだが。 しかし、ここで解決策を見つけた。次のコマンドでコンテナを作成することで、/bin/bashを永遠に動かし続けることが可能です。
sudo nerdctl (container) create --name=test -it image_name /bin/bash
ポイントは、-itですね。ここで、tオプションを付けるのがポイントでした。さらに、/bin/bashを起動すると。これで問題が解決します。
Dockerfileをビルドするためのツールは別でインストールする必要がありますよと。はい。BuildKitってものらしいですね。これは標準ではdockerについてるものみたいなんですけど、nerdctlには標準ではついていませんよと。まあ、いいか。別にdockerで作ったイメージ、containerdで使えるし。はい。
ということで、k8sが規定するcniに準拠するインターフェースを持つcontainerd + 周辺のソフト、(runc + CNI)をインストールしてローカルで使えるようにするまででした。一括でやってくれちゃうshellスクリプト、載せておきます。(nerdctlも一緒についてくるバージョンがあったので、そっちも。)
#!/bin/bash
download binaries nerdctl
wget https://github.com/containerd/nerdctl/releases/download/v1.5.0/nerdctl-1.5.0-linux-amd64.tar.gz
tar -zxvf nerdctl-1.5.0-linux-amd64.tar.gz
tar -zxvf cri-containerd-cni-1.6.24-linux-amd64.tar.gz
mv nerdctl /usr/local/bin
mkdir /etc/containerd
Define the paths to your installation directories
CONTAINERD_BIN_DIR="/usr/local/bin" CONTAINERD_SBIN_DIR="/usr/local/sbin" CONTAINERD_ETC_DIR="/etc/containerd" CONTAINERD_SYSTEMD_DIR="/etc/systemd/system" CONTAINERD_OPT_DIR="/opt/"
Define the source directory where you extracted the Containerd files
SOURCE_DIR="/home/ray"
Move binary files to /usr/local/bin
cp -r “$SOURCE_DIR/usr/local/bin/”* “$CONTAINERD_BIN_DIR/”
Move sbin files to /usr/local/sbin
cp -r “$SOURCE_DIR/usr/local/sbin/”* “$CONTAINERD_SBIN_DIR/”
Move etc files to /etc/containerd
cp -r “$SOURCE_DIR/etc/”* “$CONTAINERD_ETC_DIR/”
Move systemd service file to /etc/systemd/system
cp “$SOURCE_DIR/etc/systemd/system/containerd.service” “$CONTAINERD_SYSTEMD_DIR/”
Move opt files to opt
cp -r “$SOURCE_DIR/opt/”* “$CONTAINERD_OPT_DIR”
Reload systemd to recognize the new service
systemctl daemon-reload
echo “Containerd installed successfully.”
# システムの設定。
## swap off -a
sudo swapoff -a
## /etc/containerd/config.tomlを作る
以下のコマンドでconfig.tomlが作られる。
containerd config default > /etc/containerd/config.toml
## Forwarding IPv4 and letting iptables see bridged traffic
cat «EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF
sudo modprobe overlay sudo modprobe br_netfilter
sysctl params required by setup, params persist across reboots
cat «EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF
Apply sysctl params without reboot
sudo sysctl –system
To verify that everything goes well run following command
lsmod | grep br_netfilter lsmod | grep overlay
check if the variables below are set to 1
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
## cgoup drivers
On Linux, control groups are used to constrain resources that are allocated to processes.
Both the kubelet and the underlying container runtime need to interface with control groups to enforce resource management for pods and containers and set resources such as cpu/memory requests and limits. To interface with control groups, the kubelet and the container runtime need to use a cgroup driver. It's critical that the kubelet and the container runtime use the same cgroup driver and are configured the same.
とのことです。で、
cgroupfsとsystemdの2つのcgroup driverがあると。で、systemd cgroup driverが推奨されています。で、コンテナランタイムも、kubeletもどっちも同じcgroup driverを使わないといけないと。
To use the systemd cgroup driver in /etc/containerd/config.toml with runc, set
[plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc] … [plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc.options] SystemdCgroup = true ```
で、この辺から、kubeadmをつかってインストール!に従っていくわけですね。3つのコンポーネントをインストールするわけですね。kubeadm,kubelet,kubectl
sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
インストールが終わったら、コントロールプレーン、つまりマスターノードで、
sudo kubeadm init –pod-network-cidr=10.244.0.0/16
をする。そうすると、ワーカからマスターにjoinするのにどんなコマンドが必要が教えてくれる。下のようなコマンドになると思う。ので、それに従ってやってみてくれって感じ。
sudo kubeadm join : –token –discovery-token-ca-cert-hash sha256:
で、ジョインが完了すると思う。
ポッド同士が通信しあうためには特別なアドオンが必要。ポッドネットワークというものだね。これは、下のコマンドで実行可能。
ー->これは、applyだから、一回セットすると全部に適用されるんだよね?
kubectl apply -f “https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d ‘\n’)”
これでポッドどおしが通信できるようになりました。最後。
kubeapi-serverと通信するため設定。
大事なのが、$KUBECONFIGをkubectlは見に行くから、ここにちゃんと設定ファイルを入れるってこと。元の場所は、
/etc/kubernetes/admin.conf
で、ここから任意の場所に移して、そこにパスを通してあげれば桶。
# 最後、kubectl get nodesで意外と手間取った。からここだけまとめておきたい。
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config export KUBECONFIG=$HOME/.kube/config
いやだめっぽいな。普通に
export KUBECONFIG=$HOME/admin.conf
でお願いします。これで動いているのが確認できる。
結局まとめるとこんな感じになりますと。
# オーバレイネットワークとは
a virtual network that spans multiple nodes in a cluster and provides connectivity between Pods running on different nodes
[https://www.netstars.co.jp/kubestarblog/k8s-3/](詳しく書いてあります)
# k8sを導入するまとめ
## 1. containerdを導入。
k8sのv1.25以降は、コンテナエンジンにdockerエンジンを使えません。(理由は、dockerがcriを満たしていないから)。criを満たしてるcontainerdをインストールする必要があります。
containerdのインストールは、githubのリポジトリからできます。同時に、runcとcniもインストールしてださい。
ちなみに、cniは、container network interfaceで、まあ、コンテナのネットワークを操るためのapiですね。
で、そのapiを操るのが、cniプラグイン。で、cniプラグインには、calicoだったり、flannelだったりがあるわけですね。で、プラグインには、3種類のモードがあって、オーバーレイと、ルーティングと、アンダーレイですね。オーバレイを使うことで、別のホスト上にいるコンテナ同士が同じセグメントにいるようになります。
で、だけど、/etc/cni/net.dにはデフォルトのやつ、おかなくて結構です。まったく問題ありませんので、お気になさらず。ということで。
## 2. ホストの設定
### swapのoff
大事なこと忘れてました!!!!!!!!!!!!!
worker nodesはport 10250 を開けてください。
### /etc/containerd/config.tomlを作る
containerd config default > /etc/containerd/config.toml
### Forwarding IPv4 and letting iptables see bridged traffic
cat «EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF
sudo modprobe overlay sudo modprobe br_netfilter
sysctl params required by setup, params persist across reboots
cat «EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF
Apply sysctl params without reboot
sudo sysctl –system
To verify that everything goes well run following command
lsmod | grep br_netfilter lsmod | grep overlay
check if the variables below are set to 1
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
### cgoup drivers
On Linux, control groups are used to constrain resources that are allocated to processes.
Both the kubelet and the underlying container runtime need to interface with control groups to enforce resource management for pods and containers and set resources such as cpu/memory requests and limits. To interface with control groups, the kubelet and the container runtime need to use a cgroup driver. It's critical that the kubelet and the container runtime use the same cgroup driver and are configured the same.
とのことです。で、
cgroupfsとsystemdの2つのcgroup driverがあると。で、systemd cgroup driverが推奨されています。で、コンテナランタイムも、kubeletもどっちも同じcgroup driverを使わないといけないと。
To use the systemd cgroup driver in /etc/containerd/config.toml with runc, set
[plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc] … [plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc.options] SystemdCgroup = true
これを変更した後に、containerdを再起動しないとマジでバグります。よろしくおねげーします。まじd。
sudo systemctl restart containerd
## 3. kubeadm, kubelet, kubectlのインストール
sudo apt-get update
apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg –dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo ‘deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /’ | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
sudo systemctl start kubelet sudo systemctl enable kubelet
でkubeletを起動
##### ここまでがワーカ、マスターに限らず必要な操作になります。
## 4. マスター上で、kubeadmを使って、各コンポーネントを起動させる
sudo kubeadm init –pod-network-cidr=10.244.0.0/16
トークンの再発行
kubeadm token create –print-join-command
--print-join-commandをつけると、kubeadmのjoinに必要なコマンドとかも全部出してくれる。
## 5. ワーカ上で、4を実行後に得られるトークンを使って、マスターと接続する
sudo kubeadm join : –token –discovery-token-ca-cert-hash sha256:
## 6. cniプラグインをインストールする
kubectl apply -f “https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d ‘\n’)”
By default, tokens expire after 24 hours. If you are joining a node to the cluster after the current token has expired, you can create a new token by running the following command on the control-plane node:
kubeadm token create
でもちょっと待てよ。これってもしかして既にインストールされているのではないかという話。
いや、わからん。/etc/cni/net.d/bridgeってのは何だね。わからんねー-。
The file you’ve shown, nerdctl-bridge.conflist, is a configuration file for a CNI (Container Network Interface) plugin called “bridge.” This CNI plugin is typically used for container runtimes like Docker or containerd to set up network connectivity for containers. It may not be directly related to Kubernetes networking, but it can be used by container runtimes on a Kubernetes node to manage networking for pods.
Let’s break down the contents of the file:
ってことらしいのよね。つまり、k8sのネットワークとは関係ないってことなんですよね。マジで。
ってことでやっぱりcniプラグインをインストールする必要があるんですね。
はい、必ずインストールしてください。でないとpod間で通信ができません。ので必ず入れてください。よろしくおねがいします。flannelを入れてください。で、入れたらその設定が、全部のノードの/etc/cni/net.d/の中に書き込まれます。これは、kubeadmでノードを停止させたあとも残ります。ので、気をつけてください。もし違うプラグインをインストールしたいのであれば、必ず/etc/cni/net.dに入ってるものを一度消してください。よろしくおねがいします。
というのも、calicoを入れたあと、flannelを入れて、マジでうまく行かなかかった。これで結構時間も食ってしまった。。。
## 7. kubectlで、apiserverにアクセスするための設定ファイルをホームディレクトリに移動させる。
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
って書いてあるんだけど、これではうまくいかなくてね。
ふつーに、
sudo cp -i /etc/kubernetes/admin.conf $HOME/ export KUBECONFIG=$HOME/admin.conf
して、設定ファイルにパスを通す感じ。
これで、
kubectl get nodes
ができる。
kubectl –kubeconfig ./admin.conf get nodes
でもおけ。設定ファイルを各ワーカに配置すれば、ワーカからも上のコマンドで確認ができるようになる。
## 8. remove the node
kubectl drain –delete-emptydir-data –force –ignore-daemonsets
## その他、必要なtips
By default, your cluster will not schedule Pods on the control plane nodes for security reasons. If you want to be able to schedule Pods on the control plane nodes, for example for a single machine Kubernetes cluster, run:
kubectl taint nodes –all node-role.kubernetes.io/control-plane-
## なんか、dash-boardをデプロイしようとしてるんだけど、なかなかうまくいかんですなー。いいところまではいっていると思ってるのだが。。。まあ、あとは、地道に学んでいくしかないんだろうな。いきなりは無理や。
環境を構築しただけでもえらい。