kubernetes

kubernetes-the-hard-wayを魔改造した記録


記事の概要

正月休みに、kubernetes-the-hard-way(Vagrant環境でやったので実際はkubernetes-the-hard-way-vagrant)で勉強しておりまして、気が付いたら正月終わっても休日に引きこもって改造して遊んでいたので、その記録です。


改造の概要


  1. cniプラグインにcalicoを使う

  2. workerノードにTLS bootstrappingを使う

  3. kube-apiserverとかはserviceでなくpodで動かす

  4. 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を導入


ハマったところ ・ よくわからないところ


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とかブラウザとか開きながらやったら普通に死ぬと思います。(先に言うべきか)

これからはこの環境をベースにして色々やりたいと思ったけどこれが少しネックになりそう…