寝て起きて寝る

過ぎたるは及ばざるが如し

kubeadmでKubernetes1.9.3のClusterを構築したメモ

CloudGarage Deep Meetup in Hiroshimaで行ったLTのスライド作成時に行った事をメモしておく

cloudgarage.connpass.com

1. まずは使用するインスタンスの作成

今回はLT用にCloudGarageさんに6Gタイプのインスタンスプランを頂いたので下記のスペックで3つ作成

2. Dockerのインストール
$ apt-get update
$ apt-get install -y docker.io
3. kubeadm, kubelet, kubectlのインストール
  • kubeadm:Kubernetesが公式に提供しているKubernetes Clusterを簡単に構築できるツールキット
  • kubelet:全てのNodeで動いているnode agent
  • kubectl:Kubernetes ClusterをコントールするためのCLI
$ apt-get update && apt-get install -y apt-transport-https
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
> deb http://apt.kubernetes.io/ kubernetes-xenial main
> EOF
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl
4. Cgroup Driverの設定

Cgroup DriverをDockerとkubeletとの間で一致させておく必要がある 以下で確認

$ docker info | grep -i cgroup
WARNING: No swap limit support
Cgroup Driver: cgroupfs
$ cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf | grep KUBELET_CGROUP_ARGS

異なる場合は以下を10-kubeadm.confへ追記

Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"
$KUBELET_CGROUP_ARGS

最終的に以下のようになる

$ cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf | grep KUBELET_CGROUP_ARGS
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_AUTHZ_ARGS $KUBELET_CADVISOR_ARGS $KUBELET_CERTIFICATE_ARGS $KUBELET_EXTRA_ARGS $KUBELET_CGROUP_ARGS
5. kubeletの自動起動設定

kubeletが自動起動になっているかの確認

$ systemctl is-enabled kubelet
enabled

自動起動になっていない場合は変更する

$ systemctl enable kubelet && systemctl start kubelet
6. OSの設定

kubeletがちゃんと動くためにはswapを無効にする必要があるとのことなので、/etc/fstabを編集してswapをコメントアウトした

/dev/mapper/centos-swap swap                    swap    defaults        0 0

で、OSリブート

※ 2 から 6の内容を各インスタンスに行う

7. Maste Node の初期化(Maste Node)

podネットワークプロバイダにflannelを使用するため、 --pod-network-cidr=10.244.0.0/16を指定する

$ kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=<kube-apiserverがリクエストを待ち受けるIPアドレス>

初期化終了後に発行されるトークン kubeadm join xxx.xxx.xxx.xxx:6443 --token *** は後で使用するので記録しておく

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join xxx.xxx.xxx.xxx:6443 --token uxhdok.0z4s4lyjyb7qot36 --discovery-token-ca-cert-hash sha256:8dd4dd2fd3442174c99c67d683ac5ad03c52f0dbfec42f60c215a1336f5b5fb3
8. podネットワークのインストール(Maste Node)
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
clusterrole.rbac.authorization.k8s.io "flannel" created
clusterrolebinding.rbac.authorization.k8s.io "flannel" created
serviceaccount "flannel" created
configmap "kube-flannel-cfg" created
daemonset.extensions "kube-flannel-ds" created

kubectlコマンドで下記のメッセージが表示された場合

The connection to the server localhost:8080 was refused - did you specify the right host or port?

ユーザの場合は.bashrcへ下記を追記する

export KUBECONFIG=/etc/kubernetes/admin.conf
9. Nodeの追加(Worker Node)
  1. で出力されたトークンをWorker Nodeで実行しNodeの追加を行う
$ kubeadm join xxx.xxx.xxx.xxx:6443 --token uxhdok.0z4s4lyjyb7qot36 --discovery-token-ca-cert-hash sha256:8dd4dd2fd3442174c99c67d683ac5ad03c52f0dbfec42f60c215a1336f5b5fb3
[preflight] Running pre-flight checks.
    [WARNING Hostname]: hostname "worker02" could not be reached
    [WARNING Hostname]: hostname "worker02" lookup worker02 on 203.174.65.3:53: no such host
    [WARNING FileExisting-crictl]: crictl not found in system path
Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl
[discovery] Trying to connect to API Server "125.6.66.132:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://125.6.66.132:6443"
[discovery] Requesting info from "https://125.6.66.132:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "125.6.66.132:6443"
[discovery] Successfully established connection with API Server "125.6.66.132:6443"

This node has joined the cluster:
* Certificate signing request was sent to master and a response
  was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

Maste NodeでNodeの確認

$ kubectl get nodes
NAME       STATUS    ROLES     AGE       VERSION
master     Ready     master    4h        v1.9.3
worker01   Ready     <none>    27s       v1.9.3
worker02   Ready     <none>    2m        v1.9.3

おまけ

k8sダッシュボードのデプロイ

kubernetes-dashboardのデプロイ

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created
rolebinding.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created
deployment.apps "kubernetes-dashboard" created
service "kubernetes-dashboard" created

作成されたpodの確認

$ kubectl get pods --all-namespaces
NAMESPACE     NAME                                    READY     STATUS    RESTARTS   AGE
kube-system   etcd-master                             1/1       Running   0          37m
kube-system   kube-apiserver-master                   1/1       Running   0          37m
kube-system   kube-controller-manager-master          1/1       Running   0          37m
kube-system   kube-dns-86f4d74b45-lt994               3/3       Running   0          4h
kube-system   kube-flannel-ds-2qfg6                   1/1       Running   1          26m
kube-system   kube-flannel-ds-6b8x9                   1/1       Running   1          24m
kube-system   kube-flannel-ds-dzsd7                   1/1       Running   0          38m
kube-system   kube-proxy-jvg28                        1/1       Running   0          4h
kube-system   kube-proxy-lfm59                        1/1       Running   0          24m
kube-system   kube-proxy-tslwt                        1/1       Running   0          26m
kube-system   kube-scheduler-master                   1/1       Running   0          37m
kube-system   kubernetes-dashboard-7d5dcdb6d9-hlh2r   1/1       Running   0          7m

API ServerへローカルPCからアクセスするためにadmin.confを取得しkubectl proxyを実行する

$ scp root@xxx.xxx.xxx.xxx:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy

ダッシュボードURL

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/overview?namespace=default

このままではログイン出来ない!

ダッシュボードのPodのService Accountであるkubernetes-dashboardにAdmin権限を付けるとサインイン画面でSKIPを押すとなんでも見れるようになる cluster-adminというClusterRoleにkubernetes-dashboardにバインドするClusterRoleBindingのYAMLファイル作成する (本番ではNG)

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
  labels:
    k8s-app: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

作成したYAMLファイルををkubectlでロールを作成する

$ kubectl --kubeconfig ./admin.conf create -f dashboard-admin.yml
clusterrolebinding "kubernetes-dashboard" created

参考

CloudGarage Deep Meetup in Hiroshimaで行ったLTスライド