おうちkubernetesクラスタを作る

動機

kuberntesのSREを目指すにあたって、クラウドより下のレイヤの振る舞いから理解したかった。

ladicle.com

の記事を見て、NUCを買えばPCより安価にクラスタ構築ができることが分かったので構築した。

ハードウェア

MasterはC-planeなので安価なCeleron、WorkerはCore-i3にした。

  • Master
    • BOXNUC6CAYH
  • Worker
    • NUC8I3BEH

ソフトウェア

最新版でインストールした。 k8sの構築でdocker 19は未検証と出るが動作する。

  • docker 19.03.08
  • docker-compose 1.25.5
  • kubeadm v1.18.2

インストール

Ubuntuインストール

Ubuntu Live USBからインストール すればよい。 メニュー通りに進めると/rootの容量が小さくなってしまうので、/rootにすべて容量を割り当てる。 割り当てると次の通りになる。

$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
udev                               3.8G     0  3.8G   0% /dev
tmpfs                              783M  1.9M  781M   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv  218G   14G  194G   7% /
tmpfs                              3.9G     0  3.9G   0% /dev/shm
tmpfs                              5.0M     0  5.0M   0% /run/lock
tmpfs                              3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/loop0                          94M   94M     0 100% /snap/core/9066
/dev/loop1                          94M   94M     0 100% /snap/core/8935
/dev/sda2                          976M  213M  697M  24% /boot
/dev/sda1                          511M  6.1M  505M   2% /boot/efi
tmpfs                              783M     0  783M   0% /run/user/1000

kubernetesインストール

次の記事に従ってインストールできた。

qiita.com

ただし、Dockerはkubernetesの手順に従った。

kubernetes.io

コマンドはsudo権限を付けて実行すれば良い。

インストールできると次の通りになる。

$ kubectl get nodes
NAME      STATUS   ROLES    AGE   VERSION
master    Ready    master   18m   v1.18.2
worker1   Ready    <none>   17m   v1.18.2
worker2   Ready    <none>   17m   v1.18.2

ハマったところ

Masterでkubeadm resetに失敗する。

Masterのkubeadmバージョンが古く、一部のWorkerをjoinできなかった。 sudo kubeadm resetクラスタを作り直そうとしたが、etcdが操作を受け付けなかった様子。

$ sudo kubeadm reset
[reset] Reading configuration from the cluster...
[reset] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[reset] WARNING: Changes made to this host by 'kubeadm init' or 'kubeadm join' will be reverted.
[reset] Are you sure you want to proceed? [y/N]: y
[preflight] Running pre-flight checks
[reset] Removing info for node "master" from the ConfigMap "kubeadm-config" in the "kube-system" Namespace
{"level":"warn","ts":"2020-05-02T20:40:05.390+0900","caller":"clientv3/retry_interceptor.go:61","msg":"retrying of unary invoker failed","target":"endpoint://client-23535e72-1c0d-4cd5-854d-174a71cdef2d/192.168.5.200:2379","attempt":0,"error":"rpc error: code = Unknown desc = etcdserver: re-configuration failed due to not enough started members"}

何らかの手違いで古いクラスタのetcdサーバが動いたままで操作を受け付けない状態になった。

$ ps aux | grep kube
root     27157  8.8  1.0 1558580 85108 ?       Ssl  20:52   0:01 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.2 --resolv-conf=/run/systemd/resolve/resolv.conf
root     28131 23.6  0.4 145644 38652 ?        Ssl  20:52   0:03 kube-scheduler --authentication-kubeconfig=/etc/kubernetes/scheduler.conf --authorization-kubeconfig=/etc/kubernetes/scheduler.conf --bind-address=127.0.0.1 --kubeconfig=/etc/kubernetes/scheduler.conf --leader-elect=true
root     28157 15.5  0.7 211216 63608 ?        Ssl  20:52   0:02 kube-controller-manager --allocate-node-cidrs=true --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf --bind-address=127.0.0.1 --client-ca-file=/etc/kubernetes/pki/ca.crt --cluster-cidr=10.244.0.0/16 --cluster-name=kubernetes --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt --cluster-signing-key-file=/etc/kubernetes/pki/ca.key --controllers=*,bootstrapsigner,tokencleaner --kubeconfig=/etc/kubernetes/controller-manager.conf --leader-elect=true --node-cidr-mask-size=24 --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --root-ca-file=/etc/kubernetes/pki/ca.crt --service-account-private-key-file=/etc/kubernetes/pki/sa.key --service-cluster-ip-range=10.96.0.0/12 --use-service-account-credentials=true
root     28158 74.2  3.8 497060 308948 ?       Ssl  20:52   0:09 kube-apiserver --advertise-address=192.168.5.200 --allow-privileged=true --authorization-mode=Node,RBAC --client-ca-file=/etc/kubernetes/pki/ca.crt --enable-admission-plugins=NodeRestriction --enable-bootstrap-token-auth=true --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key --etcd-servers=https://127.0.0.1:2379 --insecure-port=0 --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key --requestheader-allowed-names=front-proxy-client --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --secure-port=6443 --service-account-key-file=/etc/kubernetes/pki/sa.pub --service-cluster-ip-range=10.96.0.0/12 --tls-cert-file=/etc/kubernetes/pki/apiserver.crt --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
root     28161 14.6  0.6 10612592 51264 ?      Ssl  20:52   0:01 etcd --advertise-client-urls=https://192.168.5.200:2379 --cert-file=/etc/kubernetes/pki/etcd/server.crt --client-cert-auth=true --data-dir=/var/lib/etcd --initial-advertise-peer-urls=https://192.168.5.200:2380 --initial-cluster=master=https://192.168.5.200:2380 --key-file=/etc/kubernetes/pki/etcd/server.key --listen-client-urls=https://127.0.0.1:2379,https://192.168.5.200:2379 --listen-metrics-urls=http://127.0.0.1:2381 --listen-peer-urls=https://192.168.5.200:2380 --name=master --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt --peer-client-cert-auth=true --peer-key-file=/etc/kubernetes/pki/etcd/peer.key --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt --snapshot-count=10000 --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
root     28837  4.0  0.3 141180 28908 ?        Ssl  20:53   0:00 /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/config.conf --hostname-override=master

すべてのコンポーネントをkill

ps aux | grep kube |grep -v "grep"| cut -d " " -f 6 | xargs -I{} sudo kill {}

をした後、kubeadmを再インストールして解決した。

docker daemonが起動に失敗する。

dockerのインストール手順通り実行して起動に失敗した。 原因はdaemon.jsonがフォーマットに従っていないことだった。

これは sudo権限で実行する時のクオーテーションをjsonの要素と同じにしていたことが問題だった。 シングルクォーテーションを使うことで解決。

sudo sh -c  'cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF'