zaki work log

作業ログやら生活ログやらなんやら

[kubernetes] kubeadmを使ったmasterノードのHA構成クラスタ

kubeadm使ってmasterをHA構成にするには、kubeadm initのパラメタにLBを指定して構築する。

kubernetes.io

環境(使用バージョン)はkubeadm 1.18

[zaki@k8s-master01 ~]$ kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:56:30Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"}

1台目のmasterノード作成

zaki-hmkc.hatenablog.com

masterがシングルノードの場合(CNIにflannel使用)は

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

とだけ実行してたkubeadm init、これだとworkerノードからmasterサーバは、上記コマンドを実行したホストへ直接アクセスしていた。
これだと冗長化できてないので、1台止まるとサービス停止してしまうので、LBを経由して負荷分散する構成にする。
(※ 本記事ではLBの設定については扱いません。HAProxyなどで良い感じに作ってください。。)

kubeadm initでは、以下のオプションを追加できる。

kubernetes.io

  • --control-plane-endpoint
    • Specify a stable IP address or DNS name for the control plane.
  • --upload-certs
    • Upload control-plane certificates to the kubeadm-certs Secret.

--control-plane-endpointに、LBのアドレスを指定すればOK

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=k8s-master.esxi.jp-z.jp --upload-certs

これで1台目のmasterを構築、CNIを入れてノードをReady状態にしたら、2台目のmasterを作成する。
ちなみに1台目の構築時は、以下のような出力。

[zaki@k8s-master01 ~]$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --con
trol-plane-endpoint=k8s-master.esxi.jp-z.jp --upload-certs
:
:

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.
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 the control-plane node running the following command on each as root:

  kubeadm join k8s-master.esxi.jp-z.jp:6443 --token 9kqjaz.j0rr9h11wve4tn3o \
    --discovery-token-ca-cert-hash sha256:1cff444b8d55f99f0eef7b0b0208d40db6603a690e06cc30e4ed1ec9de60f3a1 \
    --control-plane --certificate-key eeb09b51e430da7111aa633047fe0ee12f50b52225d1cb8a21f1163157f1962d

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join k8s-master.esxi.jp-z.jp:6443 --token 9kqjaz.j0rr9h11wve4tn3o \
    --discovery-token-ca-cert-hash sha256:1cff444b8d55f99f0eef7b0b0208d40db6603a690e06cc30e4ed1ec9de60f3a1 

このようにmasterノード追加のコマンドと、workerノード追加のコマンドそれぞれ表示されるようになる。

2台目以降のmasterノード作成

1台目でkubeadm initしてCNIをインストールし、statusがReadyになったら、追加する2台目のmasterノードでkubeadm joinを実行する。
(雑に試した感じだと、2台目master構築→CNIインストールでもReadyにはなった)

[zaki@k8s-master02 ~]$ sudo kubeadm join k8s-master.esxi.jp-z.jp:6443 --token 9kqjaz.j0rr9h11wve4tn3o \
>     --discovery-token-ca-cert-hash sha256:1cff444b8d55f99f0eef7b0b0208d40db6603a690e06cc30e4ed1ec9de60f3a1 \
>     --control-plane --certificate-key eeb09b51e430da7111aa633047fe0ee12f50b52225d1cb8a21f1163157f1962d
[preflight] Running pre-flight checks
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[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'
[preflight] Running pre-flight checks before initializing the new control plane instance
        [WARNING Firewalld]: firewalld is active, please ensure ports [6443 10250] are open or your cluster may not function correctly
[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'
[download-certs] Downloading the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master02.esxi.jp-z.jp kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local k8s-master.esxi.jp-z.jp] and IPs [10.96.0.1 192.168.0.122][certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-master02.esxi.jp-z.jp localhost] and IPs [192.168.0.122 127.0.0.1 ::1]
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [k8s-master02.esxi.jp-z.jp localhost] and IPs [192.168.0.122 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[certs] Using the existing "sa" key
[kubeconfig] Generating kubeconfig files
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
W0405 20:44:35.538462    4390 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
W0405 20:44:35.542118    4390 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0405 20:44:35.542954    4390 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[check-etcd] Checking that the etcd cluster is healthy
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
[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] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
[etcd] Announced new etcd member joining to the existing etcd cluster
[etcd] Creating static Pod manifest for "etcd"
[etcd] Waiting for the new etcd member to join the cluster. This can take up to 40s
{"level":"warn","ts":"2020-04-05T20:44:47.248+0900","caller":"clientv3/retry_interceptor.go:61","msg":"retrying of unary invoker failed","target":"passthrough:///https://192.168.0.122:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = context deadline exceeded"}
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[mark-control-plane] Marking the node k8s-master02.esxi.jp-z.jp as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node k8s-master02.esxi.jp-z.jp as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]

This node has joined the cluster and a new control plane instance was created:

* Certificate signing request was sent to apiserver and approval was received.
* The Kubelet was informed of the new secure connection details.
* Control plane (master) label and taint were applied to the new node.
* The Kubernetes control plane instances scaled up.
* A new etcd member was added to the local/stacked etcd cluster.

To start administering your cluster from this node, 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

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

[zaki@k8s-master02 ~]$ 

処理が完了すると、2台目のmasterもReadyになる。

[zaki@k8s-master01 ~]$ kubectl get node
NAME                        STATUS   ROLES    AGE     VERSION
k8s-master01.esxi.jp-z.jp   Ready    master   7m16s   v1.18.0
k8s-master02.esxi.jp-z.jp   Ready    master   28s     v1.18.0

--experimental-control-planeオプション

ちなみにコントロールプレーンの追加のオプションは現在(kubeadm v1.18)では、--control-planeになっている。
昔は--experimental-control-planeだったのが変更されているので、古いドキュメントなどを見ている場合は注意。


証明書のコピー

(この辺りは想像なので認識違いしてる可能性あり)
以前のkubeadmには--upload-certsオプションが無く、2台目以降のmasterノード作成時には、構築済み1台目masterから証明書を手動でコピーしてやる必要があった。
(現在も、--upload-certsオプションを外して実行すれば証明書は手動で配布する必要がある)

The --upload-certs flag is used to upload the certificates that should be shared across all the control-plane instances to the cluster. If instead, you prefer to copy certs across control-plane nodes manually or using automation tools, please remove this flag and refer to Manual certificate distribution section below.

手動で証明書のコピーをやってて「あー、これはAnsibleで自動化するにはちょうどいい題材だなー」とplaybookも書きながら3,4回作業した後にこのオプション見つけて、軽くショックだった。。

手順の概要としては、構築済み1台目masterの以下の証明書を、追加する2台目以降のmasterの同じディレクトリに配布する、というもの。

要はここでやってる手動の証明書配布手順。


2時間後?

As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use "kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

結果の出力に「この証明書は2時間で爆発する」と書いてある(書いてない)ので、その後に作業したい場合は別途手順ありそう。
未確認。


kubeadm token list

初期構築から2時間たってない状態だと、2件出力されてた。
1s127v.wbr2b8220imxdk42の方が、↑の2時間で動きがある件に作用するやつかな。

[zaki@k8s-master01 ~]$ kubeadm token list
TOKEN                     TTL         EXPIRES                     USAGES                   DESCRIPTION                                                EXTRA GROUPS
1s127v.wbr2b8220imxdk42   1h          2020-04-05T22:37:55+09:00   <none>                   Proxy for managing TTL for the kubeadm-certs secret        <none>
9kqjaz.j0rr9h11wve4tn3o   23h         2020-04-06T20:37:56+09:00   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   system:bootstrappers:kubeadm:default-node-token

[kubernetes] kubeadmで構築した後トークン失効後にworkerノードを追加する

kubeadmでクラスタ構築するとworkerノード追加のためのコマンドが表示されて簡単にノード追加できるが、使用するtokenの期限が(デフォルトでは24時間で)切れてしまうため、同じ引数でkubeadm joinしてもこの通り、失敗する。

[zaki@k8s-worker03 ~]$ sudo kubeadm join 192.168.0.121:6443 --token 0di1qt.ju1y8vkmfhpxmytl \
    --discovery-token-ca-cert-hash sha256:73df38227ad8bd6332ae0abf6d20ccdaa1c0cf8b254e24e15f10187b1ea1acdb
W0405 09:04:09.959285    2158 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
error execution phase preflight: couldn't validate the identity of the API Server: could not find a JWS signature in the cluster-info ConfigMap for token ID "0di1qt"
To see the stack trace of this error execute with --v=5 or higher

この場合、トークンを作り直せばOK

kubeadm token

トークンのリスト表示

期限内のトークンがあればlistサブコマンドでこの通り。
以下の出力であれば、あと17時間有効。

[zaki@k8s-master01 ~]$ kubeadm token list
TOKEN                     TTL         EXPIRES                     USAGES                   DESCRIPTION                                                EXTRA GROUPS
0di1qt.ju1y8vkmfhpxmytl   17h         2020-04-04T00:27:22+09:00   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   system:bootstrappers:kubeadm:default-node-token

トークンが失効すると何も出力されなくなる。

[zaki@k8s-master01 ~]$ kubeadm token list
[zaki@k8s-master01 ~]$ 

戻り値は0なのでエラー扱いではない。

[zaki@k8s-master01 ~]$ kubeadm token list
[zaki@k8s-master01 ~]$ echo $?
0

トークンを作成

kubeadm token createトークンを新しく作成できる。
--print-join-commandも付与すれば、kubeadm joinするためのコマンドラインも表示される。

[zaki@k8s-master01 ~]$ kubeadm token create --print-join-command
W0405 10:15:01.686014  109747 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
kubeadm join 192.168.0.121:6443 --token hne2j7.8wjffv8ph2d2u10d     --discovery-token-ca-cert-hash sha256:73df38227ad8bd6332ae0abf6d20ccdaa1c0cf8b254e24e15f10187b1ea1acdb

トークンリストもこの通り。

[zaki@k8s-master01 ~]$ kubeadm token list
TOKEN                     TTL         EXPIRES                     USAGES                   DESCRIPTION                                                EXTRA GROUPS
hne2j7.8wjffv8ph2d2u10d   23h         2020-04-06T10:15:01+09:00   authentication,signing   <none>                                                     system:bootstrappers:kubeadm:default-node-token
[zaki@k8s-master01 ~]$ 

これでトークンが作成され、kubeadm joinするためのパラメタが用意できた。

トークンはあるが--discovery-token-ca-cert-hasの値が分からない場合

次のコマンドを実行する。

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
   openssl dgst -sha256 -hex | sed 's/^.* //'

実行例

[zaki@k8s-master01 ~]$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
>    openssl dgst -sha256 -hex | sed 's/^.* //'
73df38227ad8bd6332ae0abf6d20ccdaa1c0cf8b254e24e15f10187b1ea1acdb

この出力にsha256:を頭につければOK

「ノードの追加」参照

新しいworkerノードをクラスタに追加

↑で表示されたkubeadm joinを新しくセットアップしたworkerノードで実行する。
master/worker共通のところ参照

[zaki@k8s-worker03 ~]$ sudo kubeadm join 192.168.0.121:6443 --token hne2j7.8wjffv8ph2d2u10d     --discovery-token-ca-cert-hash sha256:73df38227ad8bd6332ae0abf6d20ccdaa1c0cf8b254e24e15f10187b1ea1acdb
W0405 10:18:41.144431    5511 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[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] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
[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] Starting the kubelet
[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.

[zaki@k8s-worker03 ~]$ 

しばらく待てば(kube-proxyやCNIのpodが追加したノードでも動き始めて)Ready状態になる

[zaki@k8s-master01 ~]$ kubectl get node
NAME                        STATUS   ROLES    AGE    VERSION
k8s-master01.esxi.jp-z.jp   Ready    master   2d9h   v1.18.0
k8s-worker01.esxi.jp-z.jp   Ready    <none>   2d9h   v1.18.0
k8s-worker02.esxi.jp-z.jp   Ready    <none>   2d9h   v1.18.0
k8s-worker03.esxi.jp-z.jp   Ready    <none>   50s    v1.18.0

k8s-worker03ノードが追加されました。


W0405 10:15:01.686014  109747 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]

この警告は無視してもいいんやろか…


通常の構築はこちら

zaki-hmkc.hatenablog.com

[VMware] govcを使ってCLIでVMを作ったり消したりする

ESXiの無償ライセンスだとwrite系のAPIは使えないけど、評価版ラインセスなら試せるのでまとめてみた。
業務の検証環境のvCenterだとたまに使うので"カンペ"が欲しかったのです。

github.com

確認した環境

$ govc version
govc 0.22.1

環境変数設定

httpで動作してる場合GOVC_INSECUREを設定する。
GOVC_URLにはESXiのアドレスを設定。

アカウントは操作可能な権限を与えられているユーザを指定する。

export GOVC_INSECURE="1"
export GOVC_USERNAME="root"
export GOVC_PASSWORD="********"
export GOVC_URL="192.168.0.240/sdk"

VM作成

vm.createを使う。

基本はこんな感じ。

GUESTOS=centos7_64Guest
CPU=2
MEM=2048
NET=global-network
ADAPTER=vmxnet3
DATASTORE=datastore1
DISK_CONTROLLER=pvscsi
VERSION=6.5
VMNAME=example-vm

govc vm.create \
      -c $CPU \
      -m $MEM \
      -g $GUESTOS \
      -net $NET \
      -net.adapter $ADAPTER \
      -ds $DATASTORE \
      -disk.controller $DISK_CONTROLLER \
      -version $VERSION \
      -on=false \
      $VMNAME

デフォルトのネットワーク(おそらくVM Network)を使う場合は-netは省略できる。(というか指定しても認識してくれなかった)

業務などでvCenter使ってる場合は、上記以外に-dc ${DATA_CENTER}でデータセンタ、-host ${HOSTNAME}でホストを指定。ホストの代わりに-poolでリソースプールも指定可。
また、-folderで作成するVMのフォルダも指定できる。

-gで指定するゲストOSのID一覧はこの辺: VirtualMachineGuestOsIdentifier

設定パラメタの追加

vm.change

f:id:zaki-hmkc:20200405075708p:plain

例えばこのdisk.enableUUID=1という値を設定したい場合はvm.changeでできる。
vm.createには該当オプションはないので、一度VMを作成してから追加すればよい。

govc vm.change \
    -e "disk.enableUUID=1" \
    -vm $VMNAME

ちなみにこのパラメタはvSphere上でDynamic Provisioningするときに使用する。

ディスク作成

vm.disk.create

VM作成は、ディスク(ストレージ)作成のオプションがないので、別途作成してアタッチする必要がある。
複数のディスクが必要な場合は、都度作成する。
作成時に、-vmでアタッチ対象のVMを指定できるので、作成とアタッチは同時に可能。

だいたいこんな感じ

DATASTORE=datastore1
DISK_SIZE=20GB
VMNAME=example-vm

govc vm.disk.create \
      -size $DISK_SIZE \
      -thick=false \
      -ds $DATASTORE \
      -name $VMNAME/$VMNAME.vmdk \
      -vm $VMNAME

-nameで作成場所を指定する必要がある。
通常(UIでぽちぽち作成する場合)は、データストア上にVMディレクトリ名以下にvmdkファイルが作成されるので、それに倣う場合は上記のように${vm名}/${vm名}.vmdkと指定しておけばOK

上記はシンプロビジョニングでディスクを作成しているが、シックの場合は-thick=trueを指定する。
シックプロビジョニングで更にEager Zeroed指定する場合は、-eager=trueも指定する。

シンプロビジョニング と シックプロビジョニング の違い - VMware - Project Group

NICの追加

vm.network.add

VM作成時にはNICは1個しか指定できない。
追加のNICがある場合は、NICの追加をする。

だいたいこんな感じ。

NET2=local-network
ADAPTER=vmxnet3
VMNAME=example-vm

govc vm.network.add \
      -net $NET2 \
      -net.adapter $ADAPTER \
      -vm $VMNAME

VMの削除

vm.destroy

説明不要だとうと思いつつ補足すると、ディスクも全部消える。

VMNAME=example-vm

govc vm.destroy \
    $VMNAME

ドキュメントにも記載ある通り、ディスクを残す場合は事前にディスクをデタッチした上でvm.destroyVMを削除する。
デタッチするにはdevice.removeを使う。

ディスクをデタッチした上でVMを削除するには以下の通り。

VMNAME=example-vm

govc device.remove \
      -vm $VMNAME \
      -keep disk-*

govc vm.destroy \
      $VMNAME

あとはわかるな?

docs.ansible.com

Ansibleだと設定をYAMLで持たせたることができて、単純なシェルスクリプトgovcを使う場合に比べて繰り返し処理や設定の可読性などが強力なのでお勧め。

※ もちろん(PyVmomiのインストールに制限がないなど)使用可能であればvmware_guestでも問題ない


情報参照

この辺りは無償ライセンスのgovcでもできる。

host情報

$ govc host.info
Name:              localhost.naru.jp-z.jp
  Path:            /ha-datacenter/host/localhost.naru.jp-z.jp/localhost.naru.jp-z.jp
  Manufacturer:    Intel(R) Client Systems
  Logical CPUs:    8 CPUs @ 2712MHz
  Processor type:  Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
  CPU usage:       652 MHz (3.0%)
  Memory:          65404MB
  Memory usage:    26946 MB (41.2%)
  Boot time:       2019-10-13 13:53:38.197109 +0000 UTC
  State:           connected

-host hostnameで、対象ホストを指定できる

VM一覧

govc lsでitemの一覧を列挙し、VMに該当するものを更に引数に指定する。
…でいいのかな?

$ govc ls
/ha-datacenter/vm
/ha-datacenter/network
/ha-datacenter/host
/ha-datacenter/datastore
$ govc ls /ha-datacenter/vm
:
:
/ha-datacenter/vm/okd4-master0.esxi.jp-z.jp
/ha-datacenter/vm/okd4-master1.esxi.jp-z.jp
/ha-datacenter/vm/okd4-master2.esxi.jp-z.jp
/ha-datacenter/vm/okd4-worker0.esxi.jp-z.jp
/ha-datacenter/vm/okd4-worker1.esxi.jp-z.jp
/ha-datacenter/vm/pxe-sample
/ha-datacenter/vm/win10-offline
/ha-datacenter/vm/restricted-centos
/ha-datacenter/vm/k8s-master01.esxi.jp-z.jp
/ha-datacenter/vm/k8s-worker01.esxi.jp-z.jp
/ha-datacenter/vm/k8s-worker02.esxi.jp-z.jp
/ha-datacenter/vm/k8s-worker03.esxi.jp-z.jp
/ha-datacenter/vm/esxi-host

VM情報

$ govc vm.info manager.local.jp-z.jp
Name:           manager.local.jp-z.jp
  Path:         /ha-datacenter/vm/manager.local.jp-z.jp
  UUID:         564d13d6-d760-89aa-9174-883b8565a58c
  Guest name:   CentOS 7 (64-bit)
  Memory:       8192MB
  CPU:          2 vCPU(s)
  Power state:  poweredOn
  Boot time:    2020-02-17 10:47:01.574822 +0000 UTC
  IP address:   192.168.0.19
  Host:         localhost.naru.jp-z.jp

バイス情報

VMにセットされている各種デバイス(NICやディスクやビデオカードなどなど)を表示

$ govc device.ls -vm manager.local.jp-z.jp
ide-200       VirtualIDEController       IDE 0
ide-201       VirtualIDEController       IDE 1
ps2-300       VirtualPS2Controller       PS2 controller 0
pci-100       VirtualPCIController       PCI controller 0
sio-400       VirtualSIOController       SIO controller 0
keyboard-600  VirtualKeyboard            Keyboard
pointing-700  VirtualPointingDevice      Pointing device; Device
video-500     VirtualMachineVideoCard    Video card
vmci-12000    VirtualMachineVMCIDevice   Device on the virtual machine PCI bus that provides support for the virtual machine communication interface
usb-7000      VirtualUSBController       Auto connect Disabled
pvscsi-1000   ParaVirtualSCSIController  VMware paravirtual SCSI
ahci-15000    VirtualAHCIController      AHCI
cdrom-16000   VirtualCdrom               ISO [cheddar-share] disk2/archive/iso/CentOS-7-x86_64-Minimal-1804.iso
cdrom-16001   VirtualCdrom               ISO [cheddar-share] disk2/archive/iso/CentOS-7-x86_64-Minimal-1908.iso
disk-1000-0   VirtualDisk                62,914,560 KB
ethernet-0    VirtualVmxnet3             VM Network
ethernet-1    VirtualVmxnet3             private-network-1
ethernet-2    VirtualVmxnet3             restricted-network-1

詳細を表示するにはdevice.info

$ govc device.info -vm manager.local.jp-z.jp
Name:               ide-200
  Type:             VirtualIDEController
  Label:            IDE 0
  Summary:          IDE 0
  Key:              200
  Devices:          
Name:               ide-201
:
:
Name:               cdrom-16000
  Type:             VirtualCdrom
  Label:            CD/DVD drive 1
  Summary:          ISO [cheddar-share] disk2/archive/iso/CentOS-7-x86_64-Minimal-1804.iso
  Key:              16000
  Controller:       ahci-15000
  Unit number:      0
  Connected:        true
  Start connected:  true
  Guest control:    true
  Status:           ok
:
:
Name:               disk-1000-0
  Type:             VirtualDisk
  Label:            Hard disk 1
  Summary:          62,914,560 KB
  Key:              2000
  Controller:       pvscsi-1000
  Unit number:      0
  File:             [WDS100T2B0A] manager.local.jp-z.jp/manager.local.jp-z.jp-000001.vmdk
  Parent:           [WDS100T2B0A] manager.local.jp-z.jp/manager.local.jp-z.jp.vmdk
Name:               ethernet-0
  Type:             VirtualVmxnet3
  Label:            Network adapter 1
  Summary:          VM Network
  Key:              4000
  Controller:       pci-100
  Unit number:      7
  Connected:        true
  Start connected:  true
  Guest control:    true
  Status:           ok
  MAC Address:      00:0c:29:65:a5:8c
  Address type:     generated
Name:               ethernet-1
  Type:             VirtualVmxnet3
  Label:            Network adapter 2
:
:

似たようなCLI操作はVirtualBoxでもできる

zaki-hmkc.hatenablog.com

[kubectl / oc] get eventなどの一覧表示を時系列で表示してみる(--sort-by)

大抵のオブジェクトには、作成されたタイミングで.metadata.creationTimestampという定義が付与されます。
これを、kubectl/ocの汎用オプションの--sort-byに指定することで、出力の表示順を作成日でソートできます。

使い勝手が良いのは、デフォルトでは時間順に並んでいないeventの表示。

sort-by指定なし

[zaki@okd4-manager okd4.4-preview2]$ oc get event -A 
NAMESPACE           LAST SEEN   TYPE      REASON      OBJECT                         MESSAGE
openshift-console   82s         Warning   Unhealthy   pod/console-566b6ccc9-d8wr8    Readiness probe failed: Get https://10.130.0.37:8443/health: dial tcp 10.130.0.37:8443: connect: connection refused
openshift-console   11m         Warning   Unhealthy   pod/console-566b6ccc9-d8wr8    Liveness probe failed: Get https://10.130.0.37:8443/health: dial tcp 10.130.0.37:8443: connect: connection refused
openshift-console   91m         Normal    Pulled      pod/console-566b6ccc9-d8wr8    Container image "registry.svc.ci.openshift.org/origin/4.4-2020-01-28-022517@sha256:747be724483a632b55ce6aaaabc70bb3d45db4d30f5f3675ac21eb9823c5aae3" already present on machine
openshift-console   6m27s       Warning   BackOff     pod/console-566b6ccc9-d8wr8    Back-off restarting failed container
openshift-console   81s         Warning   Unhealthy   pod/console-566b6ccc9-xm4lz    Readiness probe failed: Get https://10.129.0.32:8443/health: dial tcp 10.129.0.32:8443: connect: connection refused
openshift-console   41m         Warning   Unhealthy   pod/console-566b6ccc9-xm4lz    Liveness probe failed: Get https://10.129.0.32:8443/health: dial tcp 10.129.0.32:8443: connect: connection refused
openshift-console   36m         Normal    Pulled      pod/console-566b6ccc9-xm4lz    Container image "registry.svc.ci.openshift.org/origin/4.4-2020-01-28-022517@sha256:747be724483a632b55ce6aaaabc70bb3d45db4d30f5f3675ac21eb9823c5aae3" already present on machine
openshift-console   6m17s       Warning   BackOff     pod/console-566b6ccc9-xm4lz    Back-off restarting failed container
openshift-console   89s         Warning   Unhealthy   pod/console-75bf97f9b9-7kl6w   Readiness probe failed: Get https://10.128.0.26:8443/health: dial tcp 10.128.0.26:8443: connect: connection refused
openshift-console   6m19s       Warning   BackOff     pod/console-75bf97f9b9-7kl6w   Back-off restarting failed container

creationTimestampでsort-by指定

[zaki@okd4-manager okd4.4-preview2]$ oc get event -A --sort-by=.metadata.creationTimestamp
NAMESPACE           LAST SEEN   TYPE      REASON      OBJECT                         MESSAGE
openshift-console   83s         Warning   Unhealthy   pod/console-566b6ccc9-d8wr8    Readiness probe failed: Get https://10.130.0.37:8443/health: dial tcp 10.130.0.37:8443: connect: connection refused
openshift-console   82s         Warning   Unhealthy   pod/console-566b6ccc9-xm4lz    Readiness probe failed: Get https://10.129.0.32:8443/health: dial tcp 10.129.0.32:8443: connect: connection refused
openshift-console   90s         Warning   Unhealthy   pod/console-75bf97f9b9-7kl6w   Readiness probe failed: Get https://10.128.0.26:8443/health: dial tcp 10.128.0.26:8443: connect: connection refused
openshift-console   41m         Warning   Unhealthy   pod/console-566b6ccc9-xm4lz    Liveness probe failed: Get https://10.129.0.32:8443/health: dial tcp 10.129.0.32:8443: connect: connection refused
openshift-console   6m28s       Warning   BackOff     pod/console-566b6ccc9-d8wr8    Back-off restarting failed container
openshift-console   6m20s       Warning   BackOff     pod/console-75bf97f9b9-7kl6w   Back-off restarting failed container
openshift-console   6m18s       Warning   BackOff     pod/console-566b6ccc9-xm4lz    Back-off restarting failed container
openshift-console   11m         Warning   Unhealthy   pod/console-566b6ccc9-d8wr8    Liveness probe failed: Get https://10.130.0.37:8443/health: dial tcp 10.130.0.37:8443: connect: connection refused
openshift-console   36m         Normal    Pulled      pod/console-566b6ccc9-xm4lz    Container image "registry.svc.ci.openshift.org/origin/4.4-2020-01-28-022517@sha256:747be724483a632b55ce6aaaabc70bb3d45db4d30f5f3675ac21eb9823c5aae3" already present on machine
openshift-console   91m         Normal    Pulled      pod/console-566b6ccc9-d8wr8    Container image "registry.svc.ci.openshift.org/origin/4.4-2020-01-28-022517@sha256:747be724483a632b55ce6aaaabc70bb3d45db4d30f5f3675ac21eb9823c5aae3" already present on machine
[zaki@okd4-manager okd4.4-preview2]$ 

もちろんeventだけでなくpodconfigmapのリソースや、カスタムリソースにも使える。


.lastTimestamp

よくみるとeventは.metadata.creationTimestamp指定だと、LAST SEENの列の時間に対しては作用してないですね。。(おそらく同じ内容のeventが複数回発生すると「作成日時」と「LAST SEEN(最後の出力日時?)」がズレそう)
-oyamlした感じだと、.lastTimestampかなぁ。(これはevent限定の項目)

[zaki@okd4-manager gitlab-auth]$ oc get event -n openshift-console --sort-by .lastTimestamp
LAST SEEN   TYPE      REASON      OBJECT                         MESSAGE
128m        Normal    Pulled      pod/console-566b6ccc9-d8wr8    Container image "registry.svc.ci.openshift.org/origin/4.4-2020-01-28-022517@sha256:747be724483a632b55ce6aaaabc70bb3d45db4d30f5f3675ac21eb9823c5aae3" already present on machine
73m         Normal    Pulled      pod/console-566b6ccc9-xm4lz    Container image "registry.svc.ci.openshift.org/origin/4.4-2020-01-28-022517@sha256:747be724483a632b55ce6aaaabc70bb3d45db4d30f5f3675ac21eb9823c5aae3" already present on machine
48m         Warning   Unhealthy   pod/console-566b6ccc9-d8wr8    Liveness probe failed: Get https://10.130.0.37:8443/health: dial tcp 10.130.0.37:8443: connect: connection refused
13m         Warning   Unhealthy   pod/console-566b6ccc9-xm4lz    Liveness probe failed: Get https://10.129.0.32:8443/health: dial tcp 10.129.0.32:8443: connect: connection refused
8m8s        Warning   BackOff     pod/console-566b6ccc9-d8wr8    Back-off restarting failed container
8m5s        Warning   BackOff     pod/console-566b6ccc9-xm4lz    Back-off restarting failed container
8m1s        Warning   BackOff     pod/console-75bf97f9b9-7kl6w   Back-off restarting failed container
3m10s       Warning   Unhealthy   pod/console-75bf97f9b9-7kl6w   Readiness probe failed: Get https://10.128.0.26:8443/health: dial tcp 10.128.0.26:8443: connect: connection refused
3m3s        Warning   Unhealthy   pod/console-566b6ccc9-d8wr8    Readiness probe failed: Get https://10.130.0.37:8443/health: dial tcp 10.130.0.37:8443: connect: connection refused
3m2s        Warning   Unhealthy   pod/console-566b6ccc9-xm4lz    Readiness probe failed: Get https://10.129.0.32:8443/health: dial tcp 10.129.0.32:8443: connect: connection refused

だいたいそれっぽくなった。
ただしこれ、ネームスペースによっては使えなかった。(なので↑は-n openshift-consoleでネームスペースを限定してる)

[zaki@okd4-manager gitlab-auth]$ oc get event -n openshift-authentication --sort-by .lastTimestamp
F0328 08:57:29.708067    9222 sorter.go:354] Field {.lastTimestamp} in [][][]reflect.Value is an unsortable type: interface, err: unsortable interface: interface

小ネタだと思って書き始めたのに案外難しかった。。

rsyslogでリモートへログを送りつける設定

今回は、リモートのrsyslogへログを送りつける設定について。
(図の左側のrsyslogの設定です)

f:id:zaki-hmkc:20200326062208p:plain

対向のrsyslog(図の右側)は前回の記事の、リモートからログの受信を受け付けるrsyslogの設定が入ってる前提

zaki-hmkc.hatenablog.com

基本

実は/etc/rsyslog.confにリモート送信のサンプル設定がコメントアウトされてる。

# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
#*.* @@remote-host:514

(手元のrpm版v8.24では)「forwarding rule」のうしろーーの方に記述されてぱっと見わかりづらいけど、書式はこの通り

<ファシリティ>.<ログレベル>      @@remote-host.example.org:514

既存設定における/var/log/messagesなどのファイル名を記述してる右側の設定部分に、@@を頭につけたホスト名:ポート番号という記述で、対象ホストへTCP転送する設定となる。(UDP転送の場合は@を一つ指定)

設定例

# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
*.* @manager-dev:514

これでこのrsyslogが動作しているホスト上のログは、manager-devホストへ514/UDPで転送される。

# リモートへ転送設定してるホストでlogger実行
[zaki@registry ~]$ logger "hello" -i -t "remote-test"
[zaki@registry ~]$

すると転送先のmanager-devホストの/var/log/messagesに以下が記録される

[root@manager-dev ~]# tail /var/log/messages
:
:
Mar 26 05:59:19 registry remote-test[59228]: hello

ちなみに転送元のホストでも既存の/var/log/messagesへの出力は有効なままなので、こちらも記録される

[root@registry ~]# tail /var/log/messages
:
:
Mar 26 05:59:19 registry remote-test[59228]: hello

-pでファシリティを変更すれば

[zaki@registry ~]$ logger "hello" -i -t "remote-test" -p "mail.err"

転送先のrsyslogの設定に従って出力は振り分けられる

[root@manager-dev ~]# tail -f /var/log/maillog
:
:
Mar 26 06:02:27 registry remote-test[59838]: hello

フィルタやログ分割はまたそのうち…

rsyslogでリモートからのログ出力を受け付ける設定とloggerコマンドでの確認

The rocket-fast Syslog Server - rsyslog

rsyslogでリモートからのログ出力を受け付ける設定とloggerの簡単な使い方。
図で言うと、右側のrsyslogの設定。
(図の左側に当たる送信側については別記事参照)

f:id:zaki-hmkc:20200326062929p:plain

(確認用)loggerコマンド

特に指定がなければローカルのsyslogサーバにログが記録される。

基本

$ logger "hello"

出力ログ

Mar 22 18:00:11 manager-dev zaki: hello

オプション

  • -i: pidを付与
  • -t <tag>: tag名を付与
$ logger "hello" -i -t "sample"
Mar 22 18:03:51 manager-dev sample[77216]: hello

出力先の変更

出力先の指定は-pで指定するが、どこへ出力されるかは/etc/rsyslog.confの設定に依る。

例えば

# Log cron stuff
cron.*                                                  /var/log/cron

という設定があった場合

$ logger "hello" -i -t "sample" -p "cron.err"

の実行で、/var/log/messagesには何も出力されず、/var/log/cronへ以下のログが記録される。

Mar 22 18:10:00 manager-dev sample[77272]: hello

リモートへのログ出力については後述


www.atmarkit.co.jp

UDP設定

以下の設定を追加(コメントアウトされてるはずなので有効にする)してrestartする。

# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# systemctl restart rsyslog
#
# ss -anpu | grep rsyslogd
UNCONN     0      0            *:514                      *:*                   users:(("rsyslogd",pid=77530,fd=3))
UNCONN     0      0         [::]:514                   [::]:*                   users:(("rsyslogd",pid=77530,fd=4))

この状態でlogger-dUDP指定と、-nで宛先サーバを指定して

$ logger "hello" -i -t "sample" -n 192.168.0.20

を実行すると

Mar 22 18:20:06 manager-dev.okd4.naru.jp-z.jp sample[77551]: hello

が記録される。
(なお、デフォルトでUDP動作のため-dは省略可能)

TCP設定

UDPと同じ要領で、以下の設定を有効にすればTCPでもリモートからのログの出力を受け付ける。

# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
[root@manager-dev ~]# ss -anpt | grep rsyslogd
LISTEN     0      25           *:514                      *:*                   users:(("rsyslogd",pid=77580,fd=3))
LISTEN     0      25        [::]:514                   [::]:*                   users:(("rsyslogd",pid=77580,fd=4))

この状態でlogger-TTCP指定と、-nで宛先サーバ・-Pでポート番号を指定して

$ logger "hello" -i -t "sample" -T -n 192.168.0.20 -P 514

を実行すると、以下が記録される

Mar 22 18:24:23 manager-dev.okd4.naru.jp-z.jp sample[77609]: hello

UDP設定と違って、-Tは省略不可だった。また、-Pによるポート番号も必要だった(省略時にウェルノウンポートで動作しなかった)

送信元制御について

$AllowedSenderを使って送信元アドレスを限定できる。
ただし、現在は後方互換性のために残っている機能のため、ファイヤウォールで制御するのが望ましいとのこと。

www.rsyslog.com

$AllowedSender

Note: this feature is supported for backward-compatibility, only. The rsyslog team recommends to use proper firewalling instead of this feature.


環境

[zaki@manager-dev ~]$ hostname -f
manager-dev
[zaki@manager-dev ~]$ cat /etc/redhat-release 
CentOS Linux release 7.7.1908 (Core)
[zaki@manager-dev ~]$ logger --version
logger from util-linux 2.23.2
[zaki@manager-dev ~]$ rsyslogd -version
rsyslogd 8.24.0-41.el7_7.4, compiled with:
        PLATFORM:                               x86_64-redhat-linux-gnu
        PLATFORM (lsb_release -d):
        FEATURE_REGEXP:                         Yes
        GSSAPI Kerberos 5 support:              Yes
        FEATURE_DEBUG (debug build, slow code): No
        32bit Atomic operations supported:      Yes
        64bit Atomic operations supported:      Yes
        memory allocator:                       system default
        Runtime Instrumentation (slow code):    No
        uuid support:                           Yes
        Number of Bits in RainerScript integers: 64

See http://www.rsyslog.com for more information.

[Kubernetes] kubeadmを使ってCentOSへk8sクラスタをデプロイしてみた (firewalld有効だとpodネットワークの不備あり)

今回は(今回も)CentOS 7.7 1908 Minimalを素で入れて、公式ツールであるkubeadmを使ってKubernetesクラスタを作ってみた。
何だかんだで一度もやったことがなかった基礎…

kubernetes.io

kubernetes.io


追記2: masterを複数ノードにする場合は、kubeadm initに追加のオプションが必要っぽい

zaki-hmkc.hatenablog.com


追記1: ちなみにクラスタはデプロイできたけど、firewalldが有効だとアプリケーションpodの通信がうまくいってないです。

OSのインストール

普通に。

ちなみにH/W要件は「2core」「RAM2GB(2GBの場合アプリの余裕無し)」とあるので、構成は以下の通り

node CPU RAM
master 4 8GB
worker 4 8GB

とりあえず1台ずつのみ。 また、ネットワーク内のDNS(dnsmasq使用)で、名前解決できるようになってる。

# k8s
192.168.0.121   k8s-master01.esxi.jp-z.jp
192.168.0.125   k8s-node01.esxi.jp-z.jp
192.168.0.121   k8s-master.esxi.jp-z.jp   # LB
192.168.0.121   api.k8s.esxi.jp-z.jp      # LB

マルチノードに備えて、LB用のFQDNも設定してる(今のところ出番なし)

OS/ミドルウェア設定(master/worker共通)

インストール後の状態

[zaki@k8s-master01 ~]$ cat /etc/redhat-release 
CentOS Linux release 7.7.1908 (Core)
[zaki@k8s-master01 ~]$ df -h
ファイルシス            サイズ  使用  残り 使用% マウント位置
devtmpfs                  3.8G     0  3.8G    0% /dev
tmpfs                     3.9G     0  3.9G    0% /dev/shm
tmpfs                     3.9G   12M  3.8G    1% /run
tmpfs                     3.9G     0  3.9G    0% /sys/fs/cgroup
/dev/mapper/centos-root    56G  1.2G   55G    3% /
/dev/sda1                1014M  150M  865M   15% /boot
tmpfs                     781M     0  781M    0% /run/user/1000
[zaki@k8s-master01 ~]$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.6G        237M        7.2G         11M        203M        7.2G
Swap:          3.5G          0B        3.5G

swap off

[zaki@k8s-master01 ~]$ sudo swapoff -a
[zaki@k8s-master01 ~]$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.6G        235M        7.2G         11M        204M        7.2G
Swap:            0B          0B          0B
[zaki@k8s-master01 ~]$ cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Thu Mar 19 06:59:37 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=6a6cc094-d014-4870-b45a-96a3d2a858e4 /boot                   xfs     defaults        0 0
#/dev/mapper/centos-swap swap                    swap    defaults        0 0

swapの行をコメントアウト

(これ、kickstartインストールの時点で無効にできるのでは)

iptablesのバックエンド

/usr/sbin/iptables-legacyがない。とりあえず飛ばそう…

firewalld

3/20追記: firewalldを有効にして以下の設定内容だとコンテナネットワークがうまく動いてない

使用ポートを通るようにする

master

$ sudo firewall-cmd --add-port=6443/tcp --permanent
$ sudo firewall-cmd --add-port=2379-2380/tcp --permanent
$ sudo firewall-cmd --add-port=10250/tcp --permanent
$ sudo firewall-cmd --add-port=10251/tcp --permanent
$ sudo firewall-cmd --add-port=10252/tcp --permanent
$ sudo firewall-cmd --reload

node

$ sudo firewall-cmd --add-port=10250/tcp --permanent
$ sudo firewall-cmd --add-port=30000-32767/tcp --permanent
$ sudo firewall-cmd --reload

共通: Flannelの場合は、8285/UDP8472/UDPも追加

runtime

Docker CEを入れる Get Docker Engine - Community for CentOS | Docker Documentation

$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

前提パッケージインストール

$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2

リポジトリ追加

$ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

インストール

$ sudo yum install docker-ce docker-ce-cli containerd.io

overlay2の設定追加 Use the OverlayFS storage driver | Docker Documentation

$ sudo mkdir -p /etc/docker
$ sudo vi /etc/docker/daemon.json
{
  "storage-driver": "overlay2"
}
$ sudo systemctl start docker
$ sudo systemctl enable docker
[zaki@k8s-master01 ~]$ sudo docker info | grep -i storage
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
 Storage Driver: overlay2

なんか警告でとる。

kubeadmインストールのとこにこれを有効にする手順が書かれてるので、ここでやっておく

$ cat /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
$ sudo sysctl --system

警告も消えた。

kubeadm、kubelet、kubectlのインストール(master/worker共通)

kubeadm、kubelet、kubectlのインストール / kubeadmのインストール - Kubernetes

リポジトリ設定

$ sudo sh -c "cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF"

石川さんにあやまる

手順がそうなってる…
OpenShiftだとenforce必須なんだけど。

$ sudo setenforce 0
$ sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

インストール

$ sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

enable

$ sudo systemctl enable --now kubelet
[zaki@k8s-master01 ~]$ systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: activating (auto-restart) (Result: exit-code) since 木 2020-03-19 17:11:13 JST; 1s ago
     Docs: https://kubernetes.io/docs/
  Process: 3161 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS (code=exited, status=255)
 Main PID: 3161 (code=exited, status=255)

 3月 19 17:11:13 k8s-master01.esxi.jp-z.jp systemd[1]: kubelet.service: main...
 3月 19 17:11:13 k8s-master01.esxi.jp-z.jp systemd[1]: Unit kubelet.service ...
 3月 19 17:11:13 k8s-master01.esxi.jp-z.jp systemd[1]: kubelet.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
-- Unit kubelet.service has finished starting up.
-- 
-- The start-up result is done.
 3月 19 17:11:03 k8s-master01.esxi.jp-z.jp kubelet[3152]: F0319 17:11:03.029999    3152 server.go:198] failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file "/var/lib/kubelet/config.yaml", error: open /var/lib/kubelet/config.yaml: no such file or directory
 3月 19 17:11:03 k8s-master01.esxi.jp-z.jp systemd[1]: kubelet.service: main process exited, code=exited, status=255/n/a
 3月 19 17:11:03 k8s-master01.esxi.jp-z.jp systemd[1]: Unit kubelet.service entered failed state.
 3月 19 17:11:03 k8s-master01.esxi.jp-z.jp systemd[1]: kubelet.service failed.
 3月 19 17:11:13 k8s-master01.esxi.jp-z.jp systemd[1]: kubelet.service holdoff time over, scheduling restart.
 3月 19 17:11:13 k8s-master01.esxi.jp-z.jp systemd[1]: Stopped kubelet: The Kubernetes Node Agent.

なるほど、設定ファイルが無いと。

あ、でも、今の時点では起動できてなくてよいらしい。

masterノード構築

kubeadmを使用したシングルコントロールプレーンクラスターの作成 - Kubernetes

ノードOSで192.168.0.0/24を使ってるので、(手順にある192.168.0.0/16ではなく)172.30.0.0/16つかってkubeadm initしてみる。

$ sudo kubeadm init --pod-network-cidr=172.30.0.0/16
  • 事前にkubeadm config images pullやっとくといいっぽい
  • アドレスは使用するCNIによって決まってるっぽい。172.30.0.0/16なんて勝手にするのはイケてなさげ。やりなおそう

これは勝手に172.30.0.0.16を指定した例 (あとでやり直してる)

[zaki@k8s-master01 ~]$ sudo kubeadm init --pod-network-cidr=172.30.0.0/16
W0319 17:37:39.957971   13465 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0319 17:37:39.958055   13465 validation.go:28] Cannot validate kubelet config - no validator is available
[init] Using Kubernetes version: v1.17.4
[preflight] Running pre-flight checks
        [WARNING Firewalld]: firewalld is active, please ensure ports [6443 10250] are open or your cluster may not function correctly
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[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'
[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"
[kubelet-start] Starting the kubelet
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-master01.esxi.jp-z.jp kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.0.121]
[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] etcd/server serving cert is signed for DNS names [k8s-master01.esxi.jp-z.jp localhost] and IPs [192.168.0.121 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-master01.esxi.jp-z.jp localhost] and IPs [192.168.0.121 127.0.0.1 ::1]
[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 "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
W0319 17:38:16.215071   13465 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0319 17:38:16.215646   13465 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[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 33.502053 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.17" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-master01.esxi.jp-z.jp as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node k8s-master01.esxi.jp-z.jp as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: bx4ozo.aw1hsrh08bv101ed
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[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.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.0.121:6443 --token bx4ozo.aw1hsrh08bv101ed \
    --discovery-token-ca-cert-hash sha256:bad635a8dfa329b6f9c308932891262b716f853dcae0aca5551933dfcb3c69bf 
[zaki@k8s-master01 ~]$ 

お、うまくいった。
出力のkubeadm join ...の部分はノード追加時に使用するので記録しておくこと。

設定ファイル

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
[zaki@k8s-master01 ~]$ kubectl get node
NAME                        STATUS     ROLES    AGE     VERSION
k8s-master01.esxi.jp-z.jp   NotReady   master   4m10s   v1.17.4

この時点ではNotReady

[zaki@k8s-master01 ~]$ kubectl cluster-info
Kubernetes master is running at https://192.168.0.121:6443
KubeDNS is running at https://192.168.0.121:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.[zaki@k8s-master01 ~]$ 

アドレス再設定

前述の通り10.244.0.0/16でやりなおす。
やり直すまえにkubeadm resetで初期化する。

[zaki@k8s-master01 ~]$ 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 "k8s-master01.esxi.jp-z.jp" from the ConfigMap "kubeadm-config" in the "kube-system" Namespace
W0319 18:01:36.469586   20517 removeetcdmember.go:61] [reset] failed to remove etcd member: error syncing endpoints with etc: etcdclient: no available endpoints.Please manually remove this etcd member using etcdctl
[reset] Stopping the kubelet service
[reset] Unmounting mounted directories in "/var/lib/kubelet"
[reset] Deleting contents of config directories: [/etc/kubernetes/manifests /etc/kubernetes/pki]
[reset] Deleting files: [/etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf]
[reset] Deleting contents of stateful directories: [/var/lib/etcd /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni]

The reset process does not clean CNI configuration. To do so, you must remove /etc/cni/net.d

The reset process does not reset or clean up iptables rules or IPVS tables.
If you wish to reset iptables, you must do so manually by using the "iptables" command.

If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar)
to reset your system's IPVS tables.

The reset process does not clean your kubeconfig files and you must remove them manually.
Please, check the contents of the $HOME/.kube/config file.
[zaki@k8s-master01 ~]$ rm -rf ~/.kube/

再kubeadm init

[zaki@k8s-master01 ~]$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16
:
:
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.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.0.121:6443 --token gbe7un.jkmckrchkswwjoxm \
    --discovery-token-ca-cert-hash sha256:580c73917da6033f5352c96b48ce681bd71057c90085f0b138a0e02a8963ef4f 

設定ファイルのコピーと、kubeadm join ...の内容を確認。

[zaki@k8s-master01 ~]$ kubectl get pod -A -o wide
NAMESPACE     NAME                                                READY   STATUS    RESTARTS   AGE     IP              NODE                        NOMINATED NODE   READINESS GATES
kube-system   coredns-6955765f44-cxgvt                            0/1     Pending   0          3m53s   <none>          <none>                      <none>           <none>
kube-system   coredns-6955765f44-zlvq8                            0/1     Pending   0          3m53s   <none>          <none>                      <none>           <none>
kube-system   etcd-k8s-master01.esxi.jp-z.jp                      1/1     Running   0          3m48s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-apiserver-k8s-master01.esxi.jp-z.jp            1/1     Running   0          3m48s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-controller-manager-k8s-master01.esxi.jp-z.jp   1/1     Running   0          3m48s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-proxy-d99pk                                    1/1     Running   0          3m52s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-scheduler-k8s-master01.esxi.jp-z.jp            1/1     Running   0          3m48s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>

network設定がなくPendingになってる

podnetworkの設定

今回はFlanelを使ってみる。

Installing Addons - Kubernetes

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml
[zaki@k8s-master01 ~]$ kubectl apply -f https://raw.githubusercontent.com/coreo
s/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.y
ml
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-amd64 created
daemonset.apps/kube-flannel-ds-arm64 created
daemonset.apps/kube-flannel-ds-arm created
daemonset.apps/kube-flannel-ds-ppc64le created
daemonset.apps/kube-flannel-ds-s390x created
[zaki@k8s-master01 ~]$ kubectl get pod -o wide -A
NAMESPACE     NAME                                                READY   STATUS    RESTARTS   AGE     IP              NODE                        NOMINATED NODE   READINESS GATES
kube-system   coredns-6955765f44-cxgvt                            1/1     Running   0          5m      10.244.0.2      k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   coredns-6955765f44-zlvq8                            1/1     Running   0          5m      10.244.0.3      k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   etcd-k8s-master01.esxi.jp-z.jp                      1/1     Running   0          4m55s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-apiserver-k8s-master01.esxi.jp-z.jp            1/1     Running   0          4m55s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-controller-manager-k8s-master01.esxi.jp-z.jp   1/1     Running   0          4m55s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-flannel-ds-amd64-jnc5m                         1/1     Running   0          32s     192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-proxy-d99pk                                    1/1     Running   0          4m59s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>
kube-system   kube-scheduler-k8s-master01.esxi.jp-z.jp            1/1     Running   0          4m55s   192.168.0.121   k8s-master01.esxi.jp-z.jp   <none>           <none>

うむ

[zaki@k8s-master01 ~]$ kubectl get node
NAME                        STATUS   ROLES    AGE   VERSION
k8s-master01.esxi.jp-z.jp   Ready    master   14m   v1.17.4

Readyになってた

コントロールプレーンノードの隔離

とりあえず飛ばす。
masterノードでアプリpodを動かすかどうかの設定。検証用なので動くようにしておいた方がリソース節約には良いと思うので、そのうち。

masterノードの追加

こちら。(たぶん初めからkubeadm initのオプションに、LBのアドレスを指定しておかなければならないっぽい)

zaki-hmkc.hatenablog.com

workerの構築

masterは動いたので、workerを追加する。
前述ミドルウェア設定と、kubeadm類のセットアップが完了したCentOS を用意。

master構築時に出力されたkubeadm join ...のコマンドをそのまま実行する。

$ sudo kubeadm join 192.168.0.121:6443 --token gbe7un.jkmckrchkswwjoxm \
    --discovery-token-ca-cert-hash sha256:580c73917da6033f5352c96b48ce681bd71057c90085f0b138a0e02a8963ef4f 

実行ログ

[zaki@k8s-node0101 ~]$ sudo kubeadm join 192.168.0.121:6443 --token gbe7un.jkmc
krchkswwjoxm \
>     --discovery-token-ca-cert-hash sha256:580c73917da6033f5352c96b48ce681bd71
057c90085f0b138a0e02a8963ef4f 
W0319 18:42:12.714978   10401 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
        [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
        [WARNING Hostname]: hostname "k8s-node0101.esxi.jp-z.jp" could not be reached
        [WARNING Hostname]: hostname "k8s-node0101.esxi.jp-z.jp": lookup k8s-node0101.esxi.jp-z.jp on 192.168.0.19:53: no such host
[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] Downloading configuration for the kubelet from the "kubelet-config-1.17" ConfigMap in the kube-system namespace
[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] Starting the kubelet
[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.

[zaki@k8s-node0101 ~]$ 

ほう

[zaki@k8s-master01 ~]$ kubectl get node
NAME                        STATUS   ROLES    AGE   VERSION
k8s-master01.esxi.jp-z.jp   Ready    master   39m   v1.17.4
k8s-node0101.esxi.jp-z.jp   Ready    <none>   46s   v1.17.4

うごいたー

f:id:zaki-hmkc:20200319190640p:plain


workerのROLESがnoneのままなのは正常?

コマンド/パラメタを失念した場合や期限が切れてる場合

zaki-hmkc.hatenablog.com

サンプルpodをデプロイ (疎通がうまくいってない)

[zaki@k8s-master01 ~]$ kubectl run web --image=httpd
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/web created
[zaki@k8s-master01 ~]$ kubectl get pod 
NAME                   READY   STATUS    RESTARTS   AGE
web-7d6766b967-xf64h   1/1     Running   0          21s

うむ

[zaki@k8s-master01 ~]$ kubectl get pod -o wide 
NAME                   READY   STATUS    RESTARTS   AGE   IP           NODE                        NOMINATED NODE   READINESS GATES
web-7d6766b967-xf64h   1/1     Running   0          94s   10.244.1.2   k8s-node0101.esxi.jp-z.jp   <none>           <none>
[zaki@k8s-master01 ~]$ kubectl get svc,ep -l run=web
NAME          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/web   ClusterIP   10.100.8.214   <none>        80/TCP    2m20s

NAME            ENDPOINTS       AGE
endpoints/web   10.244.1.2:80   2m20s
[zaki@k8s-master01 ~]$ curl 10.244.1.2:80 
curl: (7) Failed connect to 10.244.1.2:80; 接続がタイムアウトしました

あれ?

podがデプロイされてるnode01からなら

[zaki@k8s-node0101 ~]$ curl 10.244.1.2:80 
<html><body><h1>It works!</h1></body></html>

うごく。
クラスタのネットワークがちゃんと動いてないっぽい?(ノードを超えたpodにアクセスがうまくいってない)

NodePort設定でSerivceを作り直してみる

[zaki@k8s-master01 ~]$ kubectl expose deploy/web --port 80 --type NodePort
service/web exposed
[zaki@k8s-master01 ~]$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        111m
nginx        ClusterIP   10.109.135.115   <none>        80/TCP         15m
web          NodePort    10.96.171.215    <none>        80:30717/TCP   2s
[zaki@k8s-master01 ~]$ kubectl get svc -l run=web
NAME   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
web    NodePort   10.96.171.215   <none>        80:30717/TCP   15s
[zaki@k8s-master01 ~]$ curl 192.168.0.125:30717
<html><body><h1>It works!</h1></body></html>

NodePortのServiceなら動くけど。。

要調査


(3/20追記) firewalldを無効にするとコンテナネットワークも動作

3/20追記

  • まっさらな状態で(kubeadm resetせずに)再構築: 変化なし
  • Flanelのマニフェストをmasterバージョンに変更: 変化なし
  • calicoに変更: ダメ
    • sudo kubeadm init --pod-network-cidr=192.168.0.0/16してkubectl apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yaml: だめ
    • sudo kubeadm init --pod-network-cidr=10.244.0.0/16して、curlでローカルにマニフェストをDL,CALICO_IPV4POOL_CIDRvalue10.244.0.0/16に変更してapply: ダメ
  Warning  Unhealthy  48s   kubelet, k8s-master01.esxi.jp-z.jp  Readiness probe failed: calico/node is not ready: felix is not ready: readiness probe reporting 503
  Warning  Unhealthy  38s   kubelet, k8s-master01.esxi.jp-z.jp  Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with 192.168.0.1252020-03-19 21:34:21.405 [INFO][165] health.go 156: Number of node(s) with BGP peering established = 0
  Warning  Unhealthy  28s   kubelet, k8s-master01.esxi.jp-z.jp  Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with 192.168.0.1252020-03-19 21:34:31.402 [INFO][204] health.go 156: Number of node(s) with BGP peering established = 0
  Warning  Unhealthy  18s   kubelet, k8s-master01.esxi.jp-z.jp  Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with 192.168.0.1252020-03-19 21:34:41.399 [INFO][235] health.go 156: Number of node(s) with BGP peering established = 0
  Warning  Unhealthy  8s    kubelet, k8s-master01.esxi.jp-z.jp  Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with 192.168.0.1252020-03-19 21:34:51.400 [INFO][275] health.go 156: Number of node(s) with BGP peering established = 0

ん、、疎通できてない。。
firewalld周りかなぁ・・・ (でもss -anptしてもSYN_SENTとか出てこない)

必須ポートの確認

使用するPodネットワークプラグイン(以下を参照)のポートも開く必要があります。これは各Podネットワークプラグインによって異なるため、必要なポートについてはプラグインのドキュメントを参照してください。

あー

Flannelだと8285/udp8472/udpが必要なので設定。
…したけど、timeoutしてたのがno route to hostになったけど、ノード跨ぎ・コンテナ間はまだ疎通できない。。(pingは行ける)

やっぱりどこかでフィルタリングかかってるっぽい。

切り分けのために、「最初から」firewalldをdisableにして再構築してみた。

[zaki@k8s-master01 ~]$ kubectl run apache --image=httpd
[zaki@k8s-master01 ~]$ kubectl expose deploy apache --port 80
[zaki@k8s-master01 ~]$ kubectl get pod -l run=apache -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP           NODE                        NOMINATED NODE   READINESS GATES
apache-7956695dc-bkb47   1/1     Running   0          7m49s   10.244.1.5   k8s-worker01.esxi.jp-z.jp   <none>           <none>
[zaki@k8s-master01 ~]$ curl http://10.244.1.5
<html><body><h1>It works!</h1></body></html>

うごいたわ。

[zaki@k8s-master01 ~]$ kubectl run centos --image=centos:7 -- tail -f /dev/null
[zaki@k8s-master01 ~]$ kubectl exec -it centos-6d6d6c7874-tmb67 bash
[root@centos-6d6d6c7874-tmb67 /]# curl apache
<html><body><h1>It works!</h1></body></html>

コンテナ間通信もいけた。


flannel.1 cni0インタフェースをtrustedゾーンに設定

Flannel入れた後に(入れる前でもOK)各ノードでこれ実行しておけば、「firewalldを有効にしたままコンテナ間通信」はひとまずできた。

$ sudo firewall-cmd --zone=trusted --change-interface=cni0
$ sudo firewall-cmd --reload 

3/21追記: 最初flannel.1trusted設定にしてノード跨ぎでpodアクセス大丈夫だったけど、コンテナ間がダメだった。いろいろ試した感じだとcni0だと大丈夫だった


kubeadm init ...の実行前までを構築するPlaybook

github.com