kubeadm で kubernetes 1.13 の HA 環境を構築

kubeadm を使って HA な Kubernetes を構築するというのを 1.11 の時に試して Ansible Playbook にしたりしていましたが、kubeadm が GA になったことだし 1.13 での手順に更新してみた(github.com/yteraoka/do-k8s-stacked-etcd)。etcd 同居タイプです。

Production-Ready Kubernetes Cluster Creation with kubeadm

サーバーの準備

いつもながら DigitalOcean に Control Plane 用サーバー3台と Worker 用サーバー1台を作ります。

  • CentOS 7 のサーバー4台
  • API サーバー用の Load Balancer と DNS レコード

terraform で作れるようになっているので terraform planterraform apply するだけです。

SSH 用の公開鍵は事前に登録されている前提で、ssh_key_ids 変数で指定します。DNS のゾーンも事前に作成されてる前提で、domain_suffix 変数で指定します。

Ansible Playbook 適用

Ansible は 2.7 以降で、DigitalOcean の Dynamic Inventory を使うために Python の requests module が必要でした。

kubeadm init で使う config ファイルは etcd 用設定が不要になってました

ansible-playbook site.yml -e load_balancer_dns=k8s-api.example.com

うまくいけばこれで 3 台の Control Plane サーバーがクラスタ化されます。(なぜか2台目以降の kubeadm join 時に etcd の起動に失敗することがある。原因を調べきれていない)

# kubectl get nodes
NAME       STATUS   ROLES    AGE     VERSION
cp1        Ready    master   3h42m   v1.13.1
cp2        Ready    master   3h38m   v1.13.1
cp3        Ready    master   3h37m   v1.13.1

Worker node をクラスタに追加する

現状はこの後に worker ノードの join 処理を手動で行う必要がある、当該サーバー上で次の様なコマンドを実行することで join させることができる

kubeadm join k8s-api.example.com:443 --token e69t47.k98pkcidzvgexwbz \
  --discovery-token-ca-cert-hash \
   sha256:b0e28afb25529ad1405d6adecd4a154ace51b6245ff59477f5ea465e221936de

--token に渡すのは Control Plane のいずれかのホストで kubeadm token list することで確認できる。--discovery-token-ca-cert-hash に渡す hash は /etc/kubernetes/pki/ca.crt のあるホスト (Control Plane にはある) で次のコマンドを実行することで得られる。

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt \
  | openssl rsa -pubin -outform der 2>/dev/null \
  | openssl dgst -sha256 -hex | sed 's/^.* //'

正常に追加できたら kubectl get nodes で確認します。しばらくすると status が Ready になるはず

# kubectl get nodes
NAME       STATUS   ROLES    AGE     VERSION
cp1        Ready    master   3h42m   v1.13.1
cp2        Ready    master   3h38m   v1.13.1
cp3        Ready    master   3h37m   v1.13.1
worker-0   Ready    3h30m   v1.13.1 

Kubernetes Dashboard のセットアップ

Dashboard を deploy するには次のコマンドを実行するだけ

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml

上記、recommended の YAML で deploy するとアクセスするためにユーザーを作成して token を入力します。そのためのユーザー作成には次の YAML を admin-user.yaml として保存し

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

kubectl apply -f admin-user.yaml します。次に token を確認します。

kubectl -n kube-system describe secret \
  $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

これは admin-user を含む secret を grep で取り出していますが、正確な名前を得るには次のようにします。admin-user は先ほど作成した ServiceAccount の名前です

kubectl get serviceaccounts admin-user -o json -n kube-system | jq -r .secrets[].name

Dashboard にクラスタの外からアクセスするためには Ingress を作成して外部へ公開するか kube proxy を使って、クラスタ内へアクセスします。手元の PC からアクセスするために Control Plane のいずれかから /root/.kube/config~/.kube/config にコピーして kubectl proxy と実行すれば proxy が起動します

$ kubectl proxy
Starting to serve on 127.0.0.1:8001

これで 127.0.0.1:8001 経由で Dashboard にアクセスできます。http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

この画面でトークンを選択して先ほど確認したトークン文字列を入力します

こんな画面が確認できます

課題山積

https://kubernetes.io/docs/setup/independent/high-availability/ の手順では Weave が使われているが、前回は Calico で試したので今回もと思ってやってみたがうまく動作しなかった、辛い。しかし、どれを選ぶのが正解なのだか…

kubeadm join 時に etcd が起動しないことがある問題

トラブったほうが調査で理解が深まるのだけれどなかなか大変…

Self-hosted っていう話もあったなあ

ひとまず Kubernetes完全ガイド を読むことにします

Built with Hugo
テーマ StackJimmy によって設計されています。