メインコンテンツへスキップ
  1. Posts/

kubeadm で kubernetes 1.13 の HA 環境を構築

Kubernetes kubeadm
yteraoka
著者
yteraoka

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完全ガイド を読むことにします