涅槃を目指す in はてな

人生に迷う様を書きます

RKEのデプロイに失敗したけど解決した話

TL;DR

どうした

どうしたもこうしたも、今年こそ本気出す 2022 - 涅槃を目指す in はてなから、半年以上経ってます。

怠惰です。七つの大罪の一つです。すいませんでした。

心を入れ替えて久しぶりに、真面目にVirtualboxで作成したVMにRKEをデプロイしようとしたらデプロイに失敗して結構困りました。

同じようなトラブルで苦しんでる方がいるかもしれないと思い今回の記事を作成しました。

やりたかったこと

Master1台、Worker3台のクラスタVagrantで作成し、RKEをデプロイしようとしました。

バージョンは以下の通り

項目 バージョン
RKE v1.3.12
kubernetes v1.23.7-rancher1-1
Docker 20.10.17
VMのOS Ubuntu 20.04

作成したVagrantfileは以下の通り。

# -*- mode: ruby -*-
# vi: set ft=ruby :

# 共通のプロビジョニングスクリプト
$configure_common = <<-SHELL

# swap off
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

# パッケージ更新
sudo apt update
sudo apt -y upgrade


# docker install 
curl https://releases.rancher.com/install-docker/20.10.sh | sh
sudo usermod -aG docker vagrant

SHELL

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/focal64"
  config.vm.box_check_update = false
  config.vm.define "master" do |cf|
    cf.vm.hostname = "master"
    cf.vm.network "private_network", ip: "192.168.56.101"
    cf.vm.provider "virtualbox" do |vb|
      vb.cpus = 2
      vb.memory = 4096
    end
    config.vm.provision "shell", inline: $configure_common
  end

(0..2).each do |n|
    config.vm.define "worker-#{n}" do |config|
        config.vm.hostname = "worker-#{n}"
        config.vm.network "private_network", ip: "192.168.56.11#{n}"
        config.vm.provider "virtualbox" do |vb|
          vb.gui = false
          vb.cpus = 2
          vb.memory = 4096
        end
    end
        config.vm.provision "shell", inline: $configure_common
  end
end

そしてRKEをデプロイするために使用するyamlは以下の通り。

nodes:
    - address: 192.168.56.101
      user: vagrant
      role:
        - controlplane
        - etcd
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path: <path_to_private_key>
      internal_address: 192.168.56.101
    - address: 192.168.56.110
      user: vagrant
      role:
        - worker
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path: <path_to_private_key>
      internal_address: 192.168.56.110
    - address: 192.168.56.111
      user: vagrant
      role:
        - worker
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path: <path_to_private_key>
      internal_address: 192.168.56.111
    - address: 192.168.56.112
      user: vagrant
      role:
        - worker
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path: <path_to_private_key>
      internal_address: 192.168.56.112
network:
  plugin: canal
  options:
    canal_iface: enp0s8

ご存じない方のために説明すると、RKE(Rancher Kubernetes Engine)はKubernetesディストリビューションの一つです。 Kubeadmのように、簡単にKubernetesをデプロイする機能も持っています。

上記のようなyamlを作成し、操作端末からrkeコマンドのバイナリをrke upと実行させればKubernetesクラスタが出来ます!

rancher.com

起きた事象

rke upすると、こんなログが出てクラスタが作成できないようです。

ERRO[0234] Host 192.168.56.101 failed to report Ready status with error: [controlplane] Error getting node 192.168.56.101:  "192.168.56.101" not found 
INFO[0234] [controlplane] Processing controlplane hosts for upgrade 1 at a time 
INFO[0234] Processing controlplane host 192.168.56.101  
INFO[0234] [controlplane] Now checking status of node 192.168.56.101, try #1 
ERRO[0259] Failed to upgrade hosts: 192.168.56.101 with error [[controlplane] Error getting node 192.168.56.101:  "192.168.56.101" not found] 
FATA[0259] [controlPlane] Failed to upgrade Control Plane: [[[controlplane] Error getting node 192.168.56.101:  "192.168.56.101" not found]] 

192.168.56.101はmaster nodeのIPアドレスで、どうもReadyにならないようだ。

RKEが作成されるとkube_config_cluster.ymlというkubectl用のconfigファイルが作成されるので、それを指定してnodeを確認。

$ kubectl --kubeconfig kube_config_cluster.yml get nodes
No resources found

ないっすよね。ですよね。困った。

おい!オレのRKE。おい!オレのRKE。 さあ、動くのかい? さあ、動かないのかい?どっちなんだい!

調べる

masterにログインしてdocker ps してみる。

vagrant@master:~$ docker ps
CONTAINER ID   IMAGE                                 COMMAND                  CREATED         STATUS         PORTS     NAMES
dcb908754bfa   rancher/hyperkube:v1.23.7-rancher1    "/opt/rke-tools/entr…"   4 minutes ago   Up 4 minutes             kube-proxy
e4db37e3c2fb   rancher/hyperkube:v1.23.7-rancher1    "/opt/rke-tools/entr…"   4 minutes ago   Up 4 minutes             kubelet
5700dbaf0cbd   rancher/hyperkube:v1.23.7-rancher1    "/opt/rke-tools/entr…"   4 minutes ago   Up 4 minutes             kube-scheduler
9ec14d8d04a2   rancher/hyperkube:v1.23.7-rancher1    "/opt/rke-tools/entr…"   4 minutes ago   Up 4 minutes             kube-controller-manager
0feac423d1a9   rancher/hyperkube:v1.23.7-rancher1    "/opt/rke-tools/entr…"   4 minutes ago   Up 4 minutes             kube-apiserver
630942af5243   rancher/rke-tools:v0.1.80             "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes             etcd-rolling-snapshots
8b33f9d622fd   rancher/mirrored-coreos-etcd:v3.5.3   "/usr/local/bin/etcd…"   5 minutes ago   Up 5 minutes             etcd

kubeletやkube-apiserverのような大事なコンテナは出来てそうだ。

docker logs kubelet をしてみる

I0801 23:49:07.271980   33070 csi_plugin.go:1063] Failed to contact API server when waiting for CSINode publishing: csinodes.storage.k8s.io "192.168.56.101" is forbidden: User "system:node" cannot get resource "csinodes" in API group "storage.k8s.io" at the cluster scope
E0801 23:49:07.272971   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:07.373336   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:07.476548   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:07.579568   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:07.689541   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:07.789736   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:07.890476   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:07.991082   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:08.091294   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"
E0801 23:49:08.192441   33070 kubelet.go:2461] "Error getting node" err="node \"192.168.56.101\" not found"

nodeが見つからない。いや君あるやないかい。どういうこと?

ググったらこれですよ

github.com

hostname_override: を入れてみろと。rkeでもできるらしい

rancher.com

修正したyamlが以下です。hostname_override: masterとか入れてます。

nodes:
    - address: 192.168.56.101
      user: vagrant
      role:
        - controlplane
        - etcd
      hostname_override: master
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path:<path_to_private_key>
      internal_address: 192.168.56.101
    - address: 192.168.56.110
      user: vagrant
      role:
        - worker
      hostname_override: worker-0
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path: <path_to_private_key>
      internal_address: 192.168.56.110
    - address: 192.168.56.111
      user: vagrant
      role:
        - worker
      hostname_override: worker-1
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path: <path_to_private_key>
      internal_address: 192.168.56.111
    - address: 192.168.56.112
      user: vagrant
      role:
        - worker
      hostname_override: worker-2
      port: 22
      docker_socket: /var/run/docker.sock
      ssh_key_path: <path_to_private_key>
      internal_address: 192.168.56.112
network:
  plugin: canal
  options:
    canal_iface: enp0s8

これで一旦vagrant destroyしてからrke up したら。

$ kubectl --kubeconfig kube_config_cluster.yml get nodes
NAME       STATUS   ROLES               AGE   VERSION
master     Ready    controlplane,etcd   12m   v1.23.7
worker-0   Ready    worker              11m   v1.23.7
worker-1   Ready    worker              11m   v1.23.7
worker-2   Ready    worker              11m   v1.23.7

できてるー。Thanks GOD !

しかしどういうこと?

考察

Githubには、証明書で使われている名前とnodeの名前の不一致が原因では?と書かれていた。

Rancher Docs: Nodesには、

hostname_overrideは、Kubernetesにノードを登録する際にRKEが使用するフレンドリーな名前を提供できるようにするために使用されます。 このホスト名はルーティング可能なアドレスである必要はありませんが、有効なKubernetesリソース名である必要があります。 hostname_overrideが設定されていない場合、Kubernetesにノードを登録する際にaddressディレクティブが使用されます。

とあります。

あー、てことは

  1. IPアドレスでノードが登録される
  2. hostnameで証明書が作成される
  3. kubeletがAPI ServerにPアドレスで通信しようとしたけど、証明書のホスト名と不一致でnot found

てこと?

昔はこんなのなかったのに不思議やわ。

まあいいか、最後までお読み頂きありがとうございました!