#初めに
「kubernetes the hard way を PC でやってみる」の11回目、「Worker Node」についてです。だいぶ進んできましたね。( 目次 )
kubernetes の実働部分のセットアップです。
worker node に関しては、 前提条件が地味にいろいろありますので注意しましょう。
やることは以下の通りです。
※ 3台の worker node それぞれで実施します
- 前提条件の確認
- Worker 用バイナリの入手・導入
- CNI Network の設定
- containerd の設定
- kubelet の設定
- kubernetes proxy の設定
- worker サービスの起動
- 検証
図で言うと赤枠の部分です。
また、例によって 末尾につまづいたエラーとその調査・対応方法も記載しておきます。
前提条件の確認
kubernetes の前提条件としては、以下のようなものがあります。
詳しくは、kubernetes のドキュメントの kubeadmのインストール あたりが参考になると思います。
まず、 OS のコンポーネントをインストールしていきます。
# apt update
Hit:1 http://jp.archive.ubuntu.com/ubuntu focal InRelease
Get:2 http://jp.archive.ubuntu.com/ubuntu focal-updates InRelease [107 kB]
Get:3 http://jp.archive.ubuntu.com/ubuntu focal-backports InRelease [98.3 kB]
...(略)
# apt -y install socat conntrack ipset
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
...(略)
次に、kubernetes the hard way では記載がありませんが、CPU が2個あることも確認しておきましょう
# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
Address sizes: 36 bits physical, 48 bits virtual
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
...(略)
swap を disable します。
# swapon --show
NAME TYPE SIZE USED PRIO
/swap.img file 2G 0B -2
# swapoff -a
# swapon --show
#
また、OS 再起動時に swap が有効になるのを回避するため、 fstab も修正しておきます。
(※ swap.img 行をコメントアウトします)
# vi /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/vda2 during curtin installation
/dev/disk/by-uuid/d25ad5fe-d5c9-4c91-bc90-7d6360b5c266 / ext4 defaults 0 0
#/swap.img none swap sw 0 0
#worker 用バイナリの入手・導入
入手元は以下の通りです。 github の物は、 リンク先の releases から最新版がたどれます。
バイナリ | 入手元 |
---|---|
cri-tools | https://github.com/kubernetes-sigs/cri-tools |
runc | https://github.com/opencontainers/runc |
CNI plugin | https://github.com/containernetworking/plugins |
containerd | https://github.com/containerd/containerd/ |
また、 kubelet、kube-proxy に関しては
「第10回の kubernetes バイナリの入手」の際に合わせてダウンロードできていますので
それを用いればよいです。
# wget -q --show-progress --https-only --timestamping https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.18.0/crictl-v1.18.0-linux-amd64.tar.gz
crictl-v1.18.0-linux-amd64.tar.gz 100%[================================================================================================================================>] 12.01M 5.55MB/s in 2.2s
# wget -q --show-progress --https-only --timestamping https://github.com/opencontainers/runc/releases/download/v1.0.0-rc10/runc.amd64
runc.amd64 100%[================================================================================================================================>] 10.77M 4.54MB/s in 2.4s
# wget -q --show-progress --https-only --timestamping https://github.com/containernetworking/plugins/releases/download/v0.8.5/cni-plugins-linux-amd64-v0.8.5.tgz
cni-plugins-linux-amd64-v0.8.5.tgz 100%[================================================================================================================================>] 35.15M 663KB/s in 64s
# wget -q --show-progress --https-only --timestamping https://github.com/containerd/containerd/releases/download/v1.3.4/containerd-1.3.4.linux-amd64.tar.gz
containerd-1.3.4.linux-amd64.tar.gz 100%[================================================================================================================================>] 38.09M 739KB/s in 92s
tar.gz ファイルがダウンロードされていますので、展開します。
-C で展開先ディレクトリを指定しているものとそうでないものがありますのでご注意ください。
# tar zxf crictl-v1.18.0-linux-amd64.tar.gz
# ls
cni-plugins-linux-amd64-v0.8.5.tgz containerd-1.3.4.linux-amd64.tar.gz crictl crictl-v1.18.0-linux-amd64.tar.gz runc.amd64
# mkdir containerd
# tar zxf containerd-1.3.4.linux-amd64.tar.gz -C containerd
# mkdir cni
# tar -zxf cni-plugins-linux-amd64-v0.8.5.tgz -C cni
# cp runc.amd64 runc
# chmod 755 runc
# ls
cni cni-plugins-linux-amd64-v0.8.5.tgz containerd containerd-1.3.4.linux-amd64.tar.gz crictl crictl-v1.18.0-linux-amd64.tar.gz runc runc.amd64
次は各種ディレクトリの作成です。
# mkdir -p \
> /etc/cni/net.d \
> /opt/cni/bin \
> /var/lib/kubelet \
> /var/lib/kube-proxy \
> /var/lib/kubernetes \
> /var/run/kubernetes
各種ファイルは所定の場所にコピーします。(手順割愛)
ファイル | 場所 |
---|---|
cni/* | /opt/cni/bin |
crictl | /usr/local/bin |
runc | /usr/local/bin |
containerd/bin/* | /bin |
kubectl | /usr/local/bin |
kube-proxy | /usr/local/bin |
kubelet | /usr/local/bin |
#CNI Network の設定
Network の設定を行います。
kubernetes the hard way では Google Cloud のコマンドを使い POD_CIDER 変数にNW アドレスを格納しています。
ただし、実際に何の NW アドレスが指定されているかは表示されていないため、
オンプレ環境で実施する場合、NW 構成を認識したうえで POD_CIDR を指定しないと
間違った NW アドレスを指定することになります。
(※個人的には、間違えて POD_CIDR 部分に CLUSTER_CIDR を指定してしまい、
後で Pod の IP がノード間でバッティングする、という事件を起こしました。。。
まぁ自分がわかっていないだけ、という話ではありますが…)
※第1回目の表の再掲
ネットワーク | アドレス | 用途 | 上の図では | kubernetes the hard way では。。 |
---|---|---|---|---|
LAN | 192.168.199.0/24 | 物理LAN | LAN | 10.240.0.0/24 |
cluster-ip-range | 10.32.0.0/24 | kubernetes の ClusterIP 等で利用される | Service用NW | 同じ |
cluster-cidr | 10.200.0.0/16 | Pod のIPアドレスで利用される | Pod用NW | 同じ |
pod-cidr (k8sworker0) | 10.200.0.0/24 | worker ノード#0 Pod用NW | Pod用NW | 同じ |
pod-cidr (k8sworker1) | 10.200.1.0/24 | worker ノード#1 Pod用NW | Pod用NW | 同じ |
pod-cidr (k8sworker2) | 10.200.2.0/24 | worker ノード#2 Pod用NW | Pod用NW | 同じ |
CNI の設定は3台の worker node で行いますが、
kubernetes the hard way では例によって tmux で3台同時に実行しています。
そのため、ノードごとに異なる設定値は変数に格納して対応しています。
ここでは1台分のみの記載になるため、変数に入れなくてもよいのですが、
作業の流れは合わせて実施します。
# export POD_CIDR=10.200.0.0/24
# echo ${POD_CIDR}
10.200.0.0/24
(※2台目は 10.200.1.0/24、3台目は 10.200.2.0/24 です)
次に、CNI のブリッジ設定ファイルを作成します。 ( cnio0 インターフェースです )
root@k8sworker0:/# cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf
> {
> "cniVersion": "0.3.1",
> "name": "bridge",
> "type": "bridge",
> "bridge": "cnio0",
> "isGateway": true,
> "ipMasq": true,
> "ipam": {
> "type": "host-local",
> "ranges": [
> [{"subnet": "${POD_CIDR}"}]
> ],
> "routes": [{"dst": "0.0.0.0/0"}]
> }
> }
> EOF
{
"cniVersion": "0.3.1",
"name": "bridge",
"type": "bridge",
"bridge": "cnio0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "10.200.0.0/24"}]
],
"routes": [{"dst": "0.0.0.0/0"}]
}
}
同様に loopback インターフェース設定も実施します。
root@k8sworker0:/# cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf
> {
> "cniVersion": "0.3.1",
> "name": "lo",
> "type": "loopback"
> }
> EOF
{
"cniVersion": "0.3.1",
"name": "lo",
"type": "loopback"
}
これらの NW 設定は Pod が作られた際に有効になります。
詳しくは 第13回 Pod Network で少しふれます。
#containerd の設定
containerd の設定ファイルを作成します。
runtime_engine に runc が指定されていますね。
kubernetes the hard way では、コンテナランタイムとして
(docker ではなく) containerd + runc が構成されています。
# mkdir -p /etc/containerd/
# cat << EOF | sudo tee /etc/containerd/config.toml
> [plugins]
> [plugins.cri.containerd]
> snapshotter = "overlayfs"
> [plugins.cri.containerd.default_runtime]
> runtime_type = "io.containerd.runtime.v1.linux"
> runtime_engine = "/usr/local/bin/runc"
> runtime_root = ""
> EOF
[plugins]
[plugins.cri.containerd]
snapshotter = "overlayfs"
[plugins.cri.containerd.default_runtime]
runtime_type = "io.containerd.runtime.v1.linux"
runtime_engine = "/usr/local/bin/runc"
runtime_root = ""
containerd 自体は systemd 配下のサービスで稼働させるため、
ユニット・ファイルを作成します。
# cat <<EOF | sudo tee /etc/systemd/system/containerd.service
> [Unit]
> Description=containerd container runtime
> Documentation=https://containerd.io
> After=network.target
>
> [Service]
> ExecStartPre=/sbin/modprobe overlay
> ExecStart=/bin/containerd
> Restart=always
> RestartSec=5
> Delegate=yes
> KillMode=process
> OOMScoreAdjust=-999
> LimitNOFILE=1048576
> LimitNPROC=infinity
> LimitCORE=infinity
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
#
※ ユニット・ファイル作成後は、 systemctl daemon-reload
と systemctl list-unit-files
による確認がいりますが
この後、 kubelet、kube-proxy でもユニット・ファイルを作成しますので、後でまとめて実施します。
#kubelet の設定
ノード上で直接 pod を管理する kubelet ですが、関連する作業は以下の通りです。
- 必要な証明書等の配置
- kubelet-config.yaml 設定ファイルの作成
- systemd のユニット・ファイルの作成
まず、証明書等ですが
第6回目の最後に、各ノードの root ユーザーのホームに各種証明書を配置しましたので、
それを必要な場所にコピーします。 (一部コピー時にリネームしています)
なお、3台で実施するため、例によって hostname コマンド結果を HOSTNAME 変数に格納しています。
秘密鍵・証明書 | 場所 |
---|---|
ホスト名-key.pem | /var/lib/kubelet |
ホスト名.kubeconfig | /var/lib/kubelet/kubeconfig |
ca.pem | /var/lib/kubelet |
# HOSTNAME=$(hostname)
# cp ${HOSTNAME}-key.pem ${HOSTNAME}.pem /var/lib/kubelet/
# cp ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig
# cp ca.pem /var/lib/kubernetes/
POD_CIDR と HOSTNAME 変数が設定されていることを確認し、
kubelet-config.yaml ファイルを作成します。
# echo ${POD_CIDR}
10.200.0.0/24
# echo ${HOSTNAME}
k8sworker0
# cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml
> kind: KubeletConfiguration
> apiVersion: kubelet.config.k8s.io/v1beta1
> authentication:
> anonymous:
> enabled: false
> webhook:
> enabled: true
> x509:
> clientCAFile: "/var/lib/kubernetes/ca.pem"
> authorization:
> mode: Webhook
> clusterDomain: "cluster.local"
> clusterDNS:
> - "10.32.0.10"
> podCIDR: "${POD_CIDR}"
> resolvConf: "/run/systemd/resolve/resolv.conf"
> runtimeRequestTimeout: "15m"
> tlsCertFile: "/var/lib/kubelet/${HOSTNAME}.pem"
> tlsPrivateKeyFile: "/var/lib/kubelet/${HOSTNAME}-key.pem"
> EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
enabled: true
x509:
clientCAFile: "/var/lib/kubernetes/ca.pem"
authorization:
mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
- "10.32.0.10"
podCIDR: "10.200.0.0/24"
resolvConf: "/run/systemd/resolve/resolv.conf"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/k8sworker0.pem"
tlsPrivateKeyFile: "/var/lib/kubelet/k8sworker0-key.pem"
さて、ここで唐突に 10.32.0.10
という IP アドレスが出てきていますね。 (clusterDNS部分)
これは何か?なんで 10番なのか? という話を少しだけ補足しておきます。
CoreDNS の回でも触れる予定ですが、
kubernetes the hard way では、 CoreDNS のデプロイの際に、 kubenetes the hard way 用の CoreDNS の yaml ファイルを利用します。 ( https://storage.googleapis.com/kubernetes-the-hard-way/coredns.yaml )
その内容についての説明はなく、最終的な DNS の確認の際に server: 10.32.0.10
と表示されているだけです。
そのため、疑問に思わなければそのままスルーされる部分だと思います。
この、 CoreDNS 用の yaml ファイルの中の kind: Service
部分に clusterIP: 10.32.0.10
と記載されています。
つまり、 kubernetes the hard way では CoreDNS 向けの Service 用 ClusterIP は 10.32.0.10 と決められている、ということになります。
それを kubelet 内にも指定していることになります。
ここは (個人的には) DNS 連携設定上非常に重要と思うのですが、 kubernetes the hard way では触れられていません。
不思議です。。。
以下、CoreDNS 用の yaml ファイルの抜粋です。
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
annotations:
prometheus.io/port: "9153"
prometheus.io/scrape: "true"
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "CoreDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.32.0.10
次に systemd の ユニット・ファイルを作成します。
containerd と依存関係を持たせていたり、 各種設定ファイルや証明書等を指定していますね。
# cat <<EOF | sudo tee /etc/systemd/system/kubelet.service
> [Unit]
> Description=Kubernetes Kubelet
> Documentation=https://github.com/kubernetes/kubernetes
> After=containerd.service
> Requires=containerd.service
>
> [Service]
> ExecStart=/usr/local/bin/kubelet \\
> --config=/var/lib/kubelet/kubelet-config.yaml \\
> --container-runtime=remote \\
> --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \\
> --image-pull-progress-deadline=2m \\
> --kubeconfig=/var/lib/kubelet/kubeconfig \\
> --network-plugin=cni \\
> --register-node=true \\
> --v=2
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \
--config=/var/lib/kubelet/kubelet-config.yaml \
--container-runtime=remote \
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \
--image-pull-progress-deadline=2m \
--kubeconfig=/var/lib/kubelet/kubeconfig \
--network-plugin=cni \
--register-node=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
#kubernetes proxy の設定
実際の通信をコントロールする kube-proxy の設定は、 kubelet 同様以下を実施します。
- 必要なファイルの配置
- kube-proxy-config.yaml 設定ファイルの作成
- systemd のユニット・ファイルの作成
必要な証明書類は kubelet の作業で配置しているため、
ここでは、 kube-proxy のファイル配置を行います。 (リネームします)
ファイル | 場所 |
---|---|
kube-proxy.kubeconfig | /var/lib/kube-proxy/kubeconfig |
# cp kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
次に、 kube-proxy-config.yaml ファイルを作成します。
kube-proxy 設定では、 POD_CIDR ではなく CLUSTER_CIDR ( 10.200.0.0/16 ) なので注意が必要です。
# cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml
> kind: KubeProxyConfiguration
> apiVersion: kubeproxy.config.k8s.io/v1alpha1
> clientConnection:
> kubeconfig: "/var/lib/kube-proxy/kubeconfig"
> mode: "iptables"
> clusterCIDR: "10.200.0.0/16"
> EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "10.200.0.0/16"
#
最後に、 systemd のユニット・ファイルを作成します。
# cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service
> [Unit]
> Description=Kubernetes Kube Proxy
> Documentation=https://github.com/kubernetes/kubernetes
>
> [Service]
> ExecStart=/usr/local/bin/kube-proxy \\
> --config=/var/lib/kube-proxy/kube-proxy-config.yaml
> Restart=on-failure
> RestartSec=5
>
> [Install]
> WantedBy=multi-user.target
> EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-proxy \
--config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
ここまでで準備完了です!
#worker サービスの起動
##ユニット・ファイル確認・自動起動有効化
各種 systemd サービスの確認、自動起動有効化します。
# systemctl daemon-reload
# systemctl list-unit-files | grep kube
kube-proxy.service disabled enabled
kubelet.service disabled enabled
# systemctl list-unit-files | grep containerd
containerd.service disabled enabled
list-unit-files で "bad" が出たらユニット・ファイル見直しです。
自動起動の有効化します。
# systemctl enable kube-proxy kubelet containerd
Created symlink /etc/systemd/system/multi-user.target.wants/kube-proxy.service → /etc/systemd/system/kube-proxy.service.
Created symlink /etc/systemd/system/multi-user.target.wants/kubelet.service → /etc/systemd/system/kubelet.service.
Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /etc/systemd/system/containerd.service.
# systemctl list-unit-files | grep kube
kube-proxy.service enabled enabled
kubelet.service enabled enabled
# systemctl list-unit-files | grep containerd
containerd.service enabled enabled
containerd 起動
# systemctl start containerd
# echo $?
0
# systemctl status containerd
● containerd.service - containerd container runtime
Loaded: loaded (/etc/systemd/system/containerd.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2020-05-09 07:18:03 UTC; 6s ago
Docs: https://containerd.io
Process: 1295 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 1305 (containerd)
Tasks: 11 (limit: 2282)
Memory: 21.5M
CGroup: /system.slice/containerd.service
mq1305 /bin/containerd
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.504835949Z" level=info msg="Get image filesystem path \"/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs\""
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.507668961Z" level=info msg="loading plugin \"io.containerd.grpc.v1.introspection\"..." type=io.containerd.grpc.v1
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.507759340Z" level=info msg="Start subscribing containerd event"
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.508229060Z" level=info msg="Start recovering state"
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.508635058Z" level=info msg="Start event monitor"
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.508727639Z" level=info msg="Start snapshots syncer"
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.508798460Z" level=info msg="Start streaming server"
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.510575042Z" level=info msg=serving... address=/run/containerd/containerd.sock.ttrpc
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.511057522Z" level=info msg=serving... address=/run/containerd/containerd.sock
May 09 07:18:03 k8sworker0 containerd[1305]: time="2020-05-09T07:18:03.511146719Z" level=info msg="containerd successfully booted in 0.150605s"
無事に loaded, active になっているようです。ログ上でも問題なさそうですね。
必要に応じて jornalctl -u containerd
などで詳細を確認しておいてください。
##kubelet 起動
# systemctl start kubelet
# echo $?
0
# systemctl status kubelet
● kubelet.service - Kubernetes Kubelet
Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2020-05-09 07:19:38 UTC; 8s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 1326 (kubelet)
Tasks: 10 (limit: 2282)
Memory: 12.6M
CGroup: /system.slice/kubelet.service
mq1326 /usr/local/bin/kubelet --config=/var/lib/kubelet/kubelet-config.yaml --container-runtime=remote --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock --image-pull-progress-deadline=2m --k>
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.018640 1326 passthrough.go:48] ccResolverWrapper: sending update to cc: {[{/var/run/containerd/containerd.sock 0 <nil>}] <nil>}
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.018658 1326 clientconn.go:577] ClientConn switching balancer to "pick_first"
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.018699 1326 remote_image.go:50] parsed scheme: ""
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.018714 1326 remote_image.go:50] scheme "" not registered, fallback to default scheme
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.018730 1326 passthrough.go:48] ccResolverWrapper: sending update to cc: {[{/var/run/containerd/containerd.sock 0 <nil>}] <nil>}
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.018743 1326 clientconn.go:577] ClientConn switching balancer to "pick_first"
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.019251 1326 balancer_conn_wrappers.go:127] pickfirstBalancer: HandleSubConnStateChange: 0xc00005ba40, CONNECTING
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.019476 1326 balancer_conn_wrappers.go:127] pickfirstBalancer: HandleSubConnStateChange: 0xc00005bb30, CONNECTING
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.020265 1326 balancer_conn_wrappers.go:127] pickfirstBalancer: HandleSubConnStateChange: 0xc00005ba40, READY
May 09 07:19:39 k8sworker0 kubelet[1326]: I0509 07:19:39.020301 1326 balancer_conn_wrappers.go:127] pickfirstBalancer: HandleSubConnStateChange: 0xc00005bb30, READY
kubelet のログを見ると、各種デフォルト設定などが見られます。
一度ぐらいは見ておいてもよいかもしれません。
##kube-proxy 起動
# systemctl start kube-proxy
# echo $?
0
# systemctl status kube-proxy
● kube-proxy.service - Kubernetes Kube Proxy
Loaded: loaded (/etc/systemd/system/kube-proxy.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2020-05-09 07:24:50 UTC; 7s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 1454 (kube-proxy)
Tasks: 8 (limit: 2282)
Memory: 9.4M
CGroup: /system.slice/kube-proxy.service
mq1454 /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/kube-proxy-config.yaml
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.323605 1454 conntrack.go:52] Setting nf_conntrack_max to 131072
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.352721 1454 conntrack.go:83] Setting conntrack hashsize to 32768
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.367783 1454 conntrack.go:100] Set sysctl 'net/netfilter/nf_conntrack_tcp_timeout_established' to 86400
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.368261 1454 conntrack.go:100] Set sysctl 'net/netfilter/nf_conntrack_tcp_timeout_close_wait' to 3600
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.368818 1454 config.go:313] Starting service config controller
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.369019 1454 shared_informer.go:197] Waiting for caches to sync for service config
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.372361 1454 config.go:131] Starting endpoints config controller
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.373901 1454 shared_informer.go:197] Waiting for caches to sync for endpoints config
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.471215 1454 shared_informer.go:204] Caches are synced for service config
May 09 07:24:50 k8sworker0 kube-proxy[1454]: I0509 07:24:50.475077 1454 shared_informer.go:204] Caches are synced for endpoints config
#検証
kubelet がきちんと稼働していれば Control plane ノードから確認ができます。
ステータスが Ready であることを確認します。
また、 ログは取れていませんが、 -o wide を指定すればノードの IP 等も確認できます。
※ admin.kubeconfig ファイルがある場所で実行してください。
# kubectl --kubeconfig admin.kubeconfig get nodes
NAME STATUS ROLES AGE VERSION
k8sworker0 Ready <none> 10m v1.16.9
k8sworker1 Ready <none> 10m v1.16.9
k8sworker2 Ready <none> 10m v1.16.9
#エラー並びに調査・対応方法
さて、恒例となった(?)エラー対応です。
黒歴史を書くようで気が進みませんが…
##Pod の IP が重複した
本文中でも触れましたが、 kubernetes the hard way は NW 構成が頭に入っていないと分かりづらいと(個人的に)思います。
今回、 kubelet 設定の中の POD_CIDR 部分に、間違えて CLUSTER_CIDR を指定してしまいました。
Deployment 等を作成し、各ノード上に Pod が展開される際、
Pod の IP アドレスは指定した POD_CIDR 内からふられていくため、
Pod の IP アドレスが重複しました。
具体的には、 後々 CoreDNS の POD を作成した際に、こんな感じになりました。。。
# kubectl get pods --namespace kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-68567cdb47-8s42p 1/1 Running 0 46s 10.200.0.2 k8sworker2 <none> <none>
coredns-68567cdb47-wnh6c 1/1 Running 0 46s 10.200.0.2 k8sworker0 <none> <none>
k8sworker0、k8sworker2 上の coredns Pod の IP が 10.200.0.2 で重複していますね。。。
異なるノード間で IP が重複する場合、 POD_CIDR の指定が間違っているということです。
正解は
CLUSTER_CIDR : 10.200.0.0/16 をノードで分割していく感じですね。
POD_CIDR : 10.200.0.0/24, 10.200.1.0/24 , 10.200.2.0/24, .... という感じです。
今回はここまでとして、次回は Configuring kubectl for Remote Access の部分を実施します。
← 10.Control Plane
↑ 目次
→ 12.kubectl