記事の概要
正月休みに、kubernetes-the-hard-way(Vagrant環境でやったので実際はkubernetes-the-hard-way-vagrant)で勉強しておりまして、気が付いたら正月終わっても休日に引きこもって改造して遊んでいたので、その記録です。
改造の概要
- cniプラグインにcalicoを使う
- workerノードにTLS bootstrappingを使う
- kube-apiserverとかはserviceでなくpodで動かす
- node同士の名前解決(これが魔)
ex1. 全体的にバージョンアップ
ex2. metrics-server導入
大体こんな感じです
やったことをまとめたもの-> https://github.com/buildsville/kubernetes-the-hobby-way
記録
コード的な記述はなく文章です
上のリポジトリの解説のような感じ
まえがき(モチベーション)
そもそもkubernetes-the-hard-wayをやる理由が、
「認証とネットワーク周りをもう少しちゃんと把握したい」
だったのですが、実際やってみると、ネットワーク周りはstaticな設定でさらっと流してる感じ。
これだと私の目的とは少し離れているなと思ったので、ここから自分なりにいじり回して理解を深めていこうと思いました。
基本方針はstaticな記述をなくしてスケーラブルな感じにしていくイメージで。
作業の流れ
大雑把に書いてますが実際はオリジナルからの細かい変更が結構あったと思います
(都度都度で対応したし…最初は記録する気もなかったし…今更全部掘り起こすのも…)
1. cniプラグインを変更
- kube-controller-managerの起動オプションに
--allocate-node-cidrs=true
を追加- nodeのcidrを自動で割り振ってもらう
- cniプラグインをbridgeからcalicoに変更
-
usePodCidr
で上で割り振られたcidrからpodにipを振ってもらう - calicoを選んだのはなんとなく一番勢いがあるっぽかったので
-
2. TLS-bootstrapping
- 公式ドキュメントを参考に設定しました
- 他に記事もあるし、ほぼドキュメントをなぞっただけなので設定については詳しく取り上げませんが、後でもう少し触れます
3. master-componentsをpodに
- master-nodeにkubelet.serviceを設定
-
--pod-manifest-path
を指定してそこに置いたmanifestsを読み込むようにする- kube-apiserverとkube-controller-managerとkube-schedulerのpodのyamlを配置
- kube-proxyとcalicoはここではなくdaemonsetでdeploy
- labelとtaintsを設定してworker-nodeと区別する
-
4. node間の名前解決(魔)
- この環境限定のお遊び
- 最初にhostsに書いてしまうのをやめたかった
- ちょっとしたツール作ってCoreDNSと連携
- ロードバランサの10.240.0.40をDNSサーバ兼用にする
- cluster内nodeのhostnameとinternalIPを取得してhosts形式でファイル出力する謎ツールを作ってDNSサーバと同じところ配備
- CoreDNSで上のツールが出力したファイルをhostsプラグインで読む
- 各nodeのsystemd-resolvedは止めてしまって上をnameserverに設定する
- systemd-resolvedはドットが入ってない名前を読むのに難があった
- これでworker-nodeはdhcpにお任せできる
- 今回はdhcpサーバーはVirtualBoxで
- master-nodeはetcdの関係でstaticのまま
- LBも当然static
- 名前解決は諦めて
--kubelet-preferred-address-types
で internalIP を指定するのでもよかったがまあせっかくだし
ex1. バージョンアップ
- 各所の数字を大きくしただけ
- 今回見た範囲では特に変な動きは確認できず
- そんな踏み込んだことはしてないので…
- kubeletの
--allow-privileged
がdeprecatedだったけど見なかったことにした
- 今回見た範囲では特に変な動きは確認できず
ex2. metrics-serverを導入
-
kubectl top
がしたくて -
https://github.com/feiskyer/kubernetes-handbook/blob/master/en/addons/metrics.md ここを参考にkube-apiserverにflagを追加
- aggregator用の証明書を作成してcontrollerのnodeに配置
-
https://github.com/kubernetes-incubator/metrics-server/tree/master/deploy/1.8+ ここのmanifestをdeploy
- metrics-server用の証明書を作成してそれらとca.pemを読むようdeploymentに設定を追加
- 普通はsecretでdeployすると思うけど今回はスクリプトの都合上nodeに置いてマウント
- metrics-server用の証明書を作成してそれらとca.pemを読むようdeploymentに設定を追加
ハマったところ ・ よくわからないところ
nodeをまたいだ通信ができなかった
calicoをdeployして動作確認してみたところ、node間の通信ができないようでした。
結論から言うと、net.ipv4.conf.all.forwarding = 1
を設定する必要がありました。
routingとかiptablesばかり見ててカーネルパラメータは完全にノーマークだったので恐ろしくハマった…
他にも設定しないといけないのがありそうな感じ。
ちなみにubuntuにdockerをインストールすると変更されるカーネルパラメータはこんな感じ。
あとflannelはこれをやらなくても動いてました。
serverのTLS-bootstrappingのapprove
ここのnoteを読む感じだと、kubernetes自体の機能ではserverの場合はcsrのapproveを自動でできないぽいです。
ググるとcertificatesigningrequests/selfnodeserver
が云々とか出てくるけど古い情報っぽい。
https://github.com/coreos/kapprover こういうのを使ってやりなさいってことでしょうか。(ちなみにこれは動かなくて、こっちのforkが動くもののちょっと怪しい感じ)
それにセキュリティの問題で敢えて止めてある機能をこっちで付けちゃっていいのかどうか…
でもこれserverも自動でapproveしてもらわないとclusterがautoscaleした後とかmetrics-serverが困ることに…
TLS-bootstrappingガチ勢はどうしてるんでしょうね。
kube-apiserverのデバッグ
apiserverをserviceで起動させた場合は設定にミスがあればjournaldでログを確認できると思うんですが、podとして起動させた場合はどういう道筋になるんでしょう。
apiserverが起動してないから当然 kubectl logs
なんてできないし…
一度manifestのtypoをやって立ち上がらなかったんですけど、 どこ見ていいのかわからなかったです。
注意ポイント
結構なリソース食い
ちょっと色々動かそうとすると結構なリソース(特にメモリ)が必要になってしまいます。
オリジナルは各nodeにメモリを512ずつ振ってあるけど全然足りなくてよくハングした…のでmasterには2048、workerには1024を設定してます。(合計で10GBくらいメモリが必要)
host側でリソースが不足するともちろんhostがハングします。
私の場合は使ってないマシンがあったのでそれを専用機にしましたが、メモリ16GのマシンでIDEとかブラウザとか開きながらやったら普通に死ぬと思います。(先に言うべきか)
これからはこの環境をベースにして色々やりたいと思ったけどこれが少しネックになりそう…