2020/12/07
今回できたこと
Raspberry Pi 2台で、K8sクラスタを構成した。
デプロイメントを作成して、動作確認するところまではできていない。
deploymentの正常な削除の方法を確認した。
未解決
K8sクラスタで、schedulerとcontroller-managerのヘルスチェックが失敗する。
どこでまたは誰からこれらのプロセスが起動されているのかがわからないため、コマンドラインオプションを変更することができない。
K8sクラスタで、kubernetes-bootcampを動かす。
CPUアーキテクチャの問題?
イメージのCPUアーキテクチャを知る汎用的な方法は?
dockerhubでは、でアーキテクチャ別の検索などができる。 今後の作業
お約束
文章化作業
定例作業
参考文献
Raspberry PiでK8sを動作させるための前準備
既に、Raspberry Pi のK8s環境について、2020/11/04で作業していたつもりだったが、作業漏れがあったので、以下のように作業を行なった。 master-rpi4とworker-rpi3pで、cgroupに関する設定ができていなかったため、以下のように/boot/cmdline.txtに設定を行う。
code:/boot/cmdline.txt
console=serial0,115200 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1
また、worker-rpi3pでは、swap無効化の設定ができていなかったため、これを行う。
code:shell
% sudo swapoff --all
% sudo apt-get purge -y --auto-remove dphys-swapfile
% sudo rm -fr /var/swap
% sudo reboot
Raspberry Pi K8s クラスタの構築
以下のように、K8sのマスターの初期化を行う。
以下の情報は、Workerの初期化に重要なため、覚えておく必要がある。
Master IP address: 192.168.3.101:6443
Token: dbpgur.00erqvo7x3fu9wzt
discovery-token-ca-cert-hash: sha256:511f26c4010e4d54e2f8ebafb16204434fbed8765f70fb30571e40ad288c1a66
code:shell
pi@master-rpi4$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
init Using Kubernetes version: v1.19.4 preflight Pulling images required for setting up a Kubernetes cluster preflight This might take a minute or two, depending on the speed of your internet connection preflight You can also perform this action in beforehand using 'kubeadm config images pull' certs Using certificateDir folder "/etc/kubernetes/pki" certs Generating "ca" certificate and key certs Generating "apiserver" certificate and key certs Generating "apiserver-kubelet-client" certificate and key certs Generating "front-proxy-ca" certificate and key certs Generating "front-proxy-client" certificate and key certs Generating "etcd/ca" certificate and key certs Generating "etcd/server" certificate and key certs Generating "etcd/peer" certificate and key certs Generating "etcd/healthcheck-client" certificate and key certs Generating "apiserver-etcd-client" certificate and key certs Generating "sa" key and public key kubeconfig Using kubeconfig folder "/etc/kubernetes" kubeconfig Writing "controller-manager.conf" kubeconfig file kubeconfig Writing "scheduler.conf" kubeconfig file kubelet-start Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" kubelet-start Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" control-plane Creating static Pod manifest for "kube-controller-manager" etcd Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests" wait-control-plane Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s apiclient All control plane components are healthy after 47.506112 seconds upload-config Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace kubelet Creating a ConfigMap "kubelet-config-1.19" in namespace kube-system with the configuration for the kubelets in the cluster mark-control-plane Marking the node master-rpi4 as control-plane by adding the label "node-role.kubernetes.io/master=''" bootstrap-token Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles bootstrap-token configured RBAC rules to allow Node Bootstrap tokens to get nodes bootstrap-token configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials bootstrap-token configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token bootstrap-token configured RBAC rules to allow certificate rotation for all node client certificates in the cluster bootstrap-token Creating the "cluster-info" ConfigMap in the "kube-public" namespace kubelet-finalize Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key addons Applied essential addon: CoreDNS addons Applied essential addon: kube-proxy Your Kubernetes control-plane 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.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.3.101:6443 --token dbpgur.00erqvo7x3fu9wzt \
--discovery-token-ca-cert-hash sha256:511f26c4010e4d54e2f8ebafb16204434fbed8765f70fb30571e40ad288c1a66
以下のように、K8sの設定ファイルを作成する。
code:shell
pi@master-rpi4$ mkdir -p $HOME/.kube
pi@master-rpi4$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
pi@master-rpi4$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
この状態では、masterノードだけが動いている。
code:shell
pi@master-rpi4$ kubectl get node
NAME STATUS ROLES AGE VERSION
master-rpi4 NotReady master 9m26s v1.19.4
手順はgithub手順に従い、元記事ではバージョン指定して特定バージョンをインストールしていたが、ここでは最新版をインストールした。
code:shell
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
workerの初期化は、master起動時に出力されたメッセージを元に、以下のように行う。
code:shell
pi@worker-rpi3p$ sudo kubeadm join 192.168.3.101:6443 --token dbpgur.00erqvo7x3fu9wzt --discovery-token-ca-cert-hash sha256:511f26c4010e4d54e2f8ebafb16204434fbed8765f70fb30571e40ad288c1a66
preflight Reading configuration from the cluster... preflight FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' kubelet-start Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" kubelet-start Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" kubelet-start Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
worker追加後、masterでノードの状態を確認すると、以下のようになり、動作しているようである。
code:shell
pi@master-rpi4$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-rpi4 Ready master 45m v1.19.4
worker-rpi3p Ready <none> 11m v1.19.4
クラスタの状態を以下のように確認する。
code:shell
pi@master-rpi4$ kubectl version -o yaml
clientVersion:
buildDate: "2020-11-11T13:17:17Z"
compiler: gc
gitCommit: d360454c9bcd1634cf4cc52d1867af5491dc9c5f
gitTreeState: clean
gitVersion: v1.19.4
goVersion: go1.15.2
major: "1"
minor: "19"
platform: linux/arm
serverVersion:
buildDate: "2020-11-11T13:09:17Z"
compiler: gc
gitCommit: d360454c9bcd1634cf4cc52d1867af5491dc9c5f
gitTreeState: clean
gitVersion: v1.19.4
goVersion: go1.15.2
major: "1"
minor: "19"
platform: linux/arm
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-f9fd979d6-b8579 1/1 Running 0 46m
kube-system coredns-f9fd979d6-jhc28 1/1 Running 0 46m
kube-system etcd-master-rpi4 1/1 Running 0 46m
kube-system kube-apiserver-master-rpi4 1/1 Running 0 46m
kube-system kube-controller-manager-master-rpi4 1/1 Running 0 46m
kube-system kube-flannel-ds-9bm7t 1/1 Running 0 29m
kube-system kube-flannel-ds-zdmn6 1/1 Running 0 12m
kube-system kube-proxy-7d9c4 1/1 Running 0 46m
kube-system kube-proxy-ffxns 1/1 Running 0 12m
kube-system kube-scheduler-master-rpi4 1/1 Running 0 46m
K8sクラスタのヘルスチェックに関する問題
ここで問題なのは、schedulerとcontroller-managerのコンポーネントの状態がUnhealthyであり、ヘルスチェックに失敗していると考えられることである。
code:shell
pi@master-rpi4$ kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE
ERROR
etcd-0 Healthy {"health":"true"}
code:shell
pi@master-rpi4$ netstat -na|grep 1025
tcp 0 0 127.0.0.1:10257 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:10259 0.0.0.0:* LISTEN
tcp6 0 0 :::10250 :::* LISTEN
tcp6 0 0 :::10256 :::* LISTEN
以下、両者を代表して、kube-schedulerに関して調査を行う。
ただし、この機能は、DEPRECATED となっている。
現在のkube-schedulerは、以下のコマンドラインオプションで起動されている。
code:shell
pi@master-rpi4$ ps agxuwww|grep kube-scheduler
root 5851 1.6 0.9 829824 38388 ? Ssl 12:01 0:43 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 --port=0
しかし、このkube-schedulerが、どこで、なにから起動されているのかが、全くわからない。
そもそも、バイナリファイルkube-schedulerが見つからない。
code:shell
pi@master-rpi4$ find / -name kube-scheduler 2> /dev/null
/var/log/pods/kube-system_kube-scheduler-master-rpi4_02dab51e35a1d6fc74e5283db75230f5/kube-scheduler
ここで、Mac miniのminikubeでの実習環境でのcsの動作状況を調べたところ、同じような状態であった。
ただし、こちらでは、httpsでのLISTENも行われていない。
code:shell
mutoh@mutohnoMac-mini% kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
etcd-0 Healthy {"health":"true"}
mutoh@mutohnoMac-mini% netstat -na|grep 1025
この状態で、minikube環境ではkubernetes-bootcampチュートリアルのスケーリングが実行できるため、とりあえずcsのヘルスチェックの状況に関しては、先送りする。
K8sクラスタでのkubernetes-bootcampの実行
K8sクラスタで、2020/12/04の実習に従って、kubernetes-bootcampを実行する。 以下のように、kubernetes-bootcampのデプロイメントを作成する。
code:shell
$ kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
deployment.apps/kubernetes-bootcamp created
現在の状況を確認する。
code:shell
pi@master-rpi4$ kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
kubernetes-bootcamp 0/1 1 0 53s kubernetes-bootcamp gcr.io/google-samples/kubernetes-bootcamp:v1 app=kubernetes-bootcamp
pi@master-rpi4$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h44m
ここで、気になったのは、podのSTATUSがRunではなく、ImagePullBackOffとなっていることである。
とりあえず、このまま作業を続ける。
code:shell
pi@master-rpi4$ kubectl get pod
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-57978f5f5d-9gtpx 0/1 ImagePullBackOff 0 73m
デプロイメントをexposeし、外部にサービスを提供する。
code:shell
pi@master-rpi4$ kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
service/kubernetes-bootcamp exposed
pi@master-rpi4$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h47m
kubernetes-bootcamp NodePort 10.100.242.196 <none> 8080:30102/TCP 119s
pi@master-rpi4$ kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: app=kubernetes-bootcamp
Annotations: <none>
Selector: app=kubernetes-bootcamp
Type: NodePort
IP: 10.100.242.196
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30102/TCP
Endpoints: <none>
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
サービスにアクセスするために、masterのネットワーク環境を確認する。
code:shell
pi@master-rpi4$ ifconfig|grep -e mtu -e 'inet '
cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 10.244.0.1 netmask 255.255.255.0 broadcast 10.244.0.255
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
eth0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 10.244.0.0 netmask 255.255.255.255 broadcast 10.244.0.0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
vethc0f79081: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 169.254.249.93 netmask 255.255.0.0 broadcast 169.254.255.255
vethf68f9e62: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 169.254.26.200 netmask 255.255.0.0 broadcast 169.254.255.255
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.3.101 netmask 255.255.255.0 broadcast 192.168.3.255
master側の全てのIPのポート8080にアクセスし、サービスが動いているかを確認する。
code:shell
curl: (7) Failed to connect to 10.244.0.1 port 8080: 接続を拒否されました
curl: (7) Failed to connect to 172.17.0.1 port 8080: 接続を拒否されました
curl: (7) Failed to connect to 10.244.0.0 port 8080: 接続を拒否されました
curl: (7) Failed to connect to 127.0.0.1 port 8080: 接続を拒否されました
curl: (7) Failed to connect to 169.254.249.93 port 8080: 接続を拒否されました
curl: (7) Failed to connect to 169.254.26.200 port 8080: 接続を拒否されました
curl: (7) Failed to connect to 192.168.3.101 port 8080: 接続を拒否されました
minikube sshが使えない状況なので、arp -aで繋がっているコンピュータを列挙し、ここに接続を試みる。wlan0は、インターネット接続側なので、除外する。
ネットワークデバイスcni0(10.244.0.1/24)に10.244.0.4と10.244.0.5があり、httpサービスは提供されているが、ページが存在しないというレスポンスであった。
code:shell
pi@master-rpi4$ arp -a|grep -v wlan0
? (10.244.0.5) at fe:90:76:e1:41:a0 ether on cni0 ? (10.244.2.0) at d6:88:54:87:06:1f ether PERM on flannel.1 ? (10.244.0.4) at e2:f2:a2:a5:cf:e5 ether on cni0 404 page not found
404 page not found
curl: (7) Failed to connect to 10.244.0.4 port 30102: 接続を拒否されました
curl: (7) Failed to connect to 10.244.0.5 port 30102: 接続を拒否されました
K8sクラスタでの正常なdeploymentの停止方法
deploymentを正常に停止するためには、kubectl delete deployment <deplyment name>を使う。
この時、作成されたpodも自動的に削除される。
以下のように、deploymentを起動する。
code:shell
pi@master-rpi4$ kubectl get deployment,svc,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h44m
pi@master-rpi4$ kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
deployment.apps/kubernetes-bootcamp created
pi@master-rpi4$ kubectl get deployment,svc,pod
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kubernetes-bootcamp 0/1 1 0 4s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h44m
NAME READY STATUS RESTARTS AGE
pod/kubernetes-bootcamp-57978f5f5d-drb5n 0/1 ContainerCreating 0 4s
この時、このdeploymentを削除するためには、kubectl delete deployment kubernetes-bootcampで削除できる。
しばらく時間がかかるが、pod kubernetes-bootcamp-57978f5f5d-drb5nも削除される。
code:shell
pi@master-rpi4$ kubectl delete deployment kubernetes-bootcamp
deployment.apps "kubernetes-bootcamp" deleted
pi@master-rpi4$ kubectl get deployment,svc,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h47m