お家に高可用性kubernetesクラスタをつくろう!

概要

今回はmulti master kuberntesクラスターを作っていきたいと思います。
「multi master kubernetes」でググるとドンピシャな記事が公式から出ているのでこれをみながら進めていきます
https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/high-availability/
masterノードは数が少ないのでこれみながら丹精込めて手作業で作っていきます。(依存関係のパッケージのインストールとかはworkerと一緒にansibleでやります)

LoadBαlancerの代わりはHAProxyを使います。
– (MetalLBとかもそのうち試してみたいのでやるかも)

ただ、workerはノードの数がそこそこあって面倒なのでansibleで良い感じにやりたい。
良さそうな記事があったのでこれを参考に参考にansible-playbookを作成しました。
https://www.digitalocean.com/community/tutorials/how-to-create-a-kubernetes-cluster-using-kubeadm-on-ubuntu-18-04
これを元に色々自分用に変えたansibleまとめたリポジトリ
https://github.com/Im-neko/ansible-k8s

最終構成をめちゃくちゃざっくり書いた構成図はこんな感じになります

なぜVPN経由で外に出ているかは別記事(グローバルIPが無くてもポートフォワード出来なくても自宅でサーバを動かしたい)参照

クラスターの外にnfsサーバを1台置き、PVをそこにおいておく。という構成です。

やること

haproxyの準備とansibleでクラスタの構築をします
その前準備として

  • inventory/hostをコピーしてmyhost的なのを作る。
  • ipとかユーザを変更する。

playbookフォルダの中に

  • ユーザー作成
  • 依存関係のインストール
    • kubeadm,kubelet,kubectl,nfs-commonのインストール
  • masterの用意
  • wokerノードのジョイン

を行うそれぞれのymlファイルがあります。失敗して初期化したい時用にreset-all.yamlがあります。

HAProxyの用意

ロードバランサーの用意がちょっと大変なのでHAProxyを使ってそれぞれのmasterに対して振り分けをします
HAProxyはTCPの接続性をチェックして正常にTCPの接続ができるノードにリクエストを振り分けてくれます。
また、ログ出力の為にrsyslogをインストールしています

# rsyslogのインストール
sudo apt install rsyslog -y
# HAProxyのインストール
sudo apt install haproxy -y

HAProxyのコンフィグを書きます(振り分けルールのようなもの)
/etc/haproxy/haproxy.cfgを以下の内容で保存します

# 全体設定          
global                 
        # この設定で/var/log/haproxy.logにログが出るようになる
        log /dev/log    local0
        log /dev/log	local1 notice
        chroot /var/lib/haproxy                   
defaults
        log global
        mode    http
        option log-health-checks
        option  httplog clf
        
                                                    
# k8s
frontend k8s
        bind *:6443
        mode tcp
        default_backend k8s

backend k8s
        balance     roundrobin
        mode        tcp
        option      tcp-check
        # masterノードのIP
        server k8s-1 10.0.1.1:6443 check fall 3 rise 2
        server k8s-2 10.0.1.2:6443 check fall 3 rise 2

あとは
service haproxy restart
してhaproxyの方は終了です。
masterノードの用意ができていない場合エラーになるかもしれないですが一旦そのまま進めます。

依存関係のインストール(全てのmaster,workerノードに対して)

全てのノードにkubernetesの依存関係をインストールします

ansible-playbook -i inventory/myhosts playbook/init.yml --ask-becom-pass
ansible-playbook -i inventory/myhosts playbook/kube-dependencies.yml --ask-becom-pass

ダメだったらダメだったとこを手動でやってください
– 途中から色々検証するのに自分はほぼ手動みたいになってしまって通しで確認はしてないです

最初のマスターノード の設定

ここまでで依存関係のインストールが完了しているはずなのでマスターノードのセットアップを行います。
基本的には公式の記事通りに進めるだけです。今回はcalicoを使用するのでpod-network-cidrを指定する必要がある点が違いになります。

kubeadm init --control-plane-endpoint ${haproxyのアドレス}:6443 --upload-certs --pod-network-cidr ${使われていないアドレス空間(/16くらい)}

e.g)   kubeadm init --control-plane-endpoint 10.0.0.1:6443 --upload-certs --pod-network-cidr 10.98.0.0/16  

これを実行したら以下のような出力になるので1つ目のコマンドをmasterノードにしたいノードで実行します

You can now join any number of control-plane node by running the following command on each as a root:
    kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 --control-plane --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07
    
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use kubeadm init phase upload-certs to reload certs afterward.
    
Then you can join any number of worker nodes by running the following on each as root:
    kubeadm join 192.168.0.200:6443 --token 9vr73a.a8uxyaju799qwdjv --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866

2つめのmasterノードもjoinできたらcniのインストールをします
masterノードで/etc/kubernetes/admin.confを~/.kubeにconfigという名前でコピーするとkubectlを使えるようになります。
そこで以下のコマンドを実行します

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

これで問題なければcalicoのインストールができているので、あとはworkerノードのjoinをします。
kubeadm initの時に出てきた2つめのコマンドを使っても良いですし、ansibleからplaybook/worker-node.ymlを使っても良いです。

諸々上手くいっていれば最終的には以下のようになっているはずです

$ kubectl get nodes 
NAME STATUS ROLES AGE VERSION 
k8s-0 Ready master 6d14h v1.19.2 
k8s-1 Ready master 6d14h v1.19.4 
k8s-2 Ready 6d14h v1.19.2
k8s-3 Ready 6d14h v1.19.2
k8s-4 Ready 6d14h v1.19.2
k8s-5 Ready 6d14h v1.19.2