multi-nodeなKubernetesをフルスクラッチで構築してみる

f:id:ts0818:20200426124055p:plain

ship's wheel or boat's wheel is a device used aboard a water vessel to steer that vessel and control its course. Together with the rest of the steering mechanism, it forms part of the helm.

Ship's wheel - Wikipedia

⇧ とありますように、「舵輪」は、名前からも分かる通り、舵を取るものですと。

 この形、何かに似ていませんか?

そう、Kubernetes デスネ!

 

その前に、

ospn.connpass.com

⇧ に参加して参りました~。

MongoDB+Neo4j(トキュメントタイプとグラフタイプの選び方、まとめて解説)講師:李 昌桓(クリエーションライン株式会社 シニアアーキテクト)』のセッションで、「Neo4j」っていうものも初めて知りました。

qiita.com

⇧ セッションで話されていた李さんがQiitaで、まとめてくださってます。

あと、

DockerコンテナからKubernetesとOpenShiftまで要点解説  講師:高良 真穂(たから まほ)(CNBF運営委員)』のセッションをしてくださった、高良さんは、

15Stepで習得 Dockerから入るKubernetes  コンテナ開発からK8s本番運用まで (StepUp!選書)

15Stepで習得 Dockerから入るKubernetes コンテナ開発からK8s本番運用まで (StepUp!選書)

  • 作者:高良 真穂
  • 発売日: 2019/09/27
  • メディア: 単行本(ソフトカバー)
 

 ⇧ Kubernetes の書籍も出してくださっているようです。

レビューを見る限り、最初に、Kubernetesを学ぶのにはオススメの一冊のようです。私も欲しいです! 

 

はい、脱線しましたが、

というわけで、Kubernetesにレッツトライ~。

 

Kubernetesって?

まずは、おさらいということで、そもそも、Kubernetesって何ぞ?

Kubernetesクバネティス/クバネテス/クーべネティスK8sと略記される)は、コンテナ化したアプリケーションのデプロイ、スケーリング、および管理を行うための、オープンソースのコンテナオーケストレーションシステムである

Kubernetes - Wikipedia

⇧ コンテナの管理がメインですかね。

元々Googleが設計したシステムであるが、現在はCloud Native Computing Foundationがメンテナンスを行っている。

Kubernetes - Wikipedia

Googleさん発祥です。 

何で、コンテナオーケストレーションなんてものが必要になったかというのは、

kubernetes.io

⇧ アプリケーションのデプロイ環境の変遷などが関わってますと。

 

■「Traditional Deployment」→「Virtualized Deployment」

まず、WindowsOS XMac)、Linuxと言うように、OS(Operating system)ってのは複数あるわけで、本番環境が変わってくるのは宜しくない、ってことで、アプリケーションをデプロイする先として「仮想マシン」を構築して、OS(Operating system)をフィクッスしようと。

サーバの「仮想化」が流行り出したと。

 

■「Virtualized Deployment」→「Container Deployment」

仮想マシン」でOSの問題は解消されたけど、「仮想マシン」ってメモリも大量に消費するし、もうちょいお手軽感が欲しいな~、からのDockerなど「コンテナ型仮想化」が流行り出したこともあり、ってことで、「仮想マシン」を止めて「コンテナ」の導入が進みましたと。

 

■「コンテナ」の到来で変わったこと

「コンテナ」が導入されたことにより、「マイクロサービスアーキテクチャ」って概念が注目され出して、旧来のアプリケーション構成を見直す動きが出てきましたと。

(「マイクロサービスアーキテクチャ」は「分散システムデザインパターン」の1つってことになるのかな?)

 

どういうことかというと、

旧来のアプリケーションは「モノシリック」な構成であったため、保守、管理、改修ってのが非常に大変だったんですと、俗に言う「レガシー」なシステム。

だったら、あらかじめ、アプリケーションを細かい単位に分割しておけば、保守、管理、改修ってのをし易いんじゃないかと。

アプリケーションを細かい「サービス」単位で捉えて、各々の「サービス」を連動させていこう、ってのは、まさに「マイクロサービスアーキテクチャ」って考えで、そのために「コンテナ」っていうのは都合が良かったんですな。

メモリ消費量も少なく、起動なども速いとされてる「コンテナ」に「サービス」を乗っけて、管理しちゃえと。

 

ところが、ここで、問題が。

そう、「サービス」が大量になれば、当然「コンテナ」の数も大量に必要になってきますと。

その結果、「コンテナ」の管理が無茶苦茶しんどいという状況が。

そこで、

Containers are a good way to bundle and run your applications. In a production environment, you need to manage the containers that run the applications and ensure that there is no downtime. For example, if a container goes down, another container needs to start. Wouldn’t it be easier if this behavior was handled by a system?

What is Kubernetes? - Kubernetes

⇧ 「コンテナ」の管理をシステムに任せたほうが良いよね?って考えがあり、

That’s how Kubernetes comes to the rescue! Kubernetes provides you with a framework to run distributed systems resiliently. It takes care of scaling and failover for your application, provides deployment patterns, and more. For example, Kubernetes can easily manage a canary deployment for your system.

What is Kubernetes? - Kubernetes

⇧ それを担ってくれるのが、Kubernetesですと。

Kubernetesが「コンテナオーケストレーション」と呼ばれる所以ということですかね?

 

ただ

thinkit.co.jp

Gracely:全てがコンテナ化されるのか? という部分に関して言えば全てではないと思います。例えばAmadeusという航空券のためのシステムがありますが、このシステムでは数百のシステムと連携して航空券に関する情報を取ってきます。つまり1回のトランザクションが数ミリ秒掛かったとしてそれが数百、数千になれば検索結果を返すためにどれだけ時間がかかってしまうのかは予想できます。我々は数秒の遅れが顧客を失うことに繋がると知っていますので、そのトランザクションを実行するシステムは高速でなければならないのです。そのようなシステムを単にコンテナ化することには、あまり意味がないと思います。反対に、例えばスーパーマーケットのサプライ・チェインの中で発注のトランザクションが数秒掛かったところで、それほど弊害が出ることもないでしょう。このようにどのユースケースでどのようなニーズがあるのかをしっかり理解しておけば、全てをコンテナにするという判断はしないと言うことです。

Red HatのCTOとOpenShiftのディレクターに訊く。パックの行く先にいたRed Hatの強さ | Think IT(シンクイット)

⇧ 「コンテナ」も適材適所で利用していきましょ~、ということみたいですね。

 

Kubernetesアーキテクチャ

Kubernetesが、「コンテナオーケストレーション」を実現してくれることは分かったんだけど、どんなアーキテクトなのよ?

Wikipediaさんに掲載されてました。

全体的なイメージは、上図のような感じですかね。

Kubernetesは、マスター・スレーブアーキテクチャで構成される。Kubernetesコンポーネントは、各ノードを管理するノード(node)と、コントロールプレーンであるマスター(master)の2つに分けられる

Kubernetes - Wikipedia

⇧ 「Kubernetesは、マスター・スレーブアーキテクチャで構成される。」って言われてもね...

マスタースレーブmaster-slave)は、複数の機器が協調動作する際に、複数機器の制御・操作を司る「マスター」機と、マスター機の一方的な制御下で動作する「スレーブ」機に役割を分担する方式のこと。

マスタースレーブ - Wikipedia

⇧ 分散システムっすな。

コンピュータにおけるマスタースレーブは、通信プロトコルのモデルの一種であり、1つのハードウェアプロセスが他の1つまたは複数のデバイスやプロセスを一方的に制御することをいう。

マスタースレーブ - Wikipedia

⇧ マシンが複数要りそう。

マスタースレーブ - Wikipedia

⇧ なんか、Kubernetesに当てはまりそうな例ではなさそうね...

マスター(主人)とスレーブ(奴隷)という用語はしばしば論争の的となることがある。

マスタースレーブ - Wikipedia

⇧ そりゃ、議論にされるでしょうな。

2003年11月、ロサンゼルス郡は電子メールで出入り業者に対してこれらの用語を使った製品を納入しないよう要求した。これに対してIT業界ではばかげた主張だとして取り合わない動きが大勢を占めた。マスタースレーブという用語はデバイス内部で起きていることを正確に表した技術用語であり、かつて存在した奴隷制度とは何の関係もないというのがその理由であった(ポリティカル・コレクトネスも参照)。

マスタースレーブ - Wikipedia

⇧ 歴史が生んだ悲劇。

一方で、こうした論争を避けるため、データベースの分野ではマスタースレーブの代替語として「プライマリー」や「レプリカ」といった語句を採用するケースもある。

マスタースレーブ - Wikipedia

⇧ 忖度。

2018年には、プログラミング言語Pythonが論争の末、マスタースレーブを「ペアレント」や「ワーカー」「ヘルパー」といった語句に置き換えている。

マスタースレーブ - Wikipedia

⇧ 忖度。

っていうか、IT業界の言葉の定義の統一の無さっていうのは、こういう背景も影響してるんですかね?

まぁ、だいぶ脱線したんだけど、「node」については、

A node is a worker machine in Kubernetes, previously known as a minion. A node may be a VM or physical machine, depending on the cluster. Each node contains the services necessary to run pods and is managed by the master components. The services on a node include the container runtime, kubelet and kube-proxy. See The Kubernetes Node section in the architecture design doc for more details.

https://kubernetes.io/docs/concepts/architecture/nodes/

⇧ って言っていて、詳細は、

A running Kubernetes cluster contains node agents (kubelet) and a cluster control plane (AKA master), with cluster state backed by a distributed storage system (etcd).

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node

⇧ 「Kubernetes cluster」は「node agents」と「cluster control」を含んでいて、「Kubernetes cluster」の状態は、「distibuted storage system」で管理されとると。

っていうか、言葉を曖昧にしたまま定義するのは、IT業界の常なのかね?

この統一の無さが、認識齟齬を繰り広げるだけだっていうことを、嫌ってほど繰り返してきてると思うんだけど...まったく学習しないな~。

「内輪でしか伝わらない設計書はゴミ」って仰っている先輩がおりましたが、IT業界のドキュメントって、そういった意味では、

 I do not look down on niggers, kikes, wops or greasers. Here you are all equally worthless.

Full Metal Jacket (1987) - R. Lee Ermey as Gny. Sgt. Hartman - IMDb

⇧ 映画「フルメタルジャケット」の「ハートマン軍曹」の『すべて平等に価値が無い!』ってセリフを表してる気が...

ちなみに、「A node may be a VM or physical machine, depending on the cluster.」って言ってるのに、

kind.sigs.k8s.io

⇧ 「コンテナ」内でKubernetes構築できるって話もあり、「node」は「仮想マシン」か「物理マシン」だけじゃなかったんかい!っていうツッコミを入れたくなりますな。

 

まぁ、オンプレミス環境でのKuebernetesの構成としては、

最低限、上記の様なコンポネントが必要らしい。

あと、大枠として「Master」が1台、「Worker Node」が1台、の合わせて2つは必要でありますと。 

このへんも言葉が統一されてないんだよな~。

「Master」「Worker Node」は同一のマシンに同居させても良いけど、別々のマシンに配置するのが良いみたい。

Kubernetesについては、

kubernetes.io

blogs.itmedia.co.jp

⇧ 上記サイト様がまとめてくださってます。

 

Kubernetesの仕組みについては、


Kubernetes の国の愉快な小人の世界

⇧ 上記の動画でイメージが掴みやすいです。

 

multi-nodeなKubernetesを構築してみる - マシンのMACアドレスとproduct_uuidをチェック

まぁ、構築してみますか。

ありがたいことに、

www.tecmint.com

www.tecmint.com

⇧ 「CentOS 7」「CentOS 8」で構築してくれてる方がおりました。

上記サイト様によりますと、「仮想マシン」を3台用意しとくようにということなので、用意します。

 

ts0818.hatenablog.com

⇧ 手前味噌ではありますが、こちらの記事で、CentOS 8 の仮想マシン3台を作成しておきました。宜しければ、ご参照ください。

 

で、Vagrant仮想マシンが用意できていれば、vagrant up で起動しちゃいましょう。

起動できたら、起動確認しまして、ネットワークアダプターがホストオンリーアダプターの、それぞれの仮想マシンIPアドレスを確認で。

f:id:ts0818:20200417213825p:plain

んで、

MACアドレスとproduct_uuidが全てのノードでユニークであることの検証 

  • ネットワークインターフェースのMACアドレスip linkもしくはifconfig -aコマンドで取得できます。
  • product_uuidはsudo cat /sys/class/dmi/id/product_uuidコマンドで確認できます。

kubeadmを使ってクラスターを構築する - Kubernetes

⇧ それぞれのマシンで、『MACアドレス』と『product_uuid』って値がすべて異なっていないといけないらしい。

ハードウェアデバイスではユニークなアドレスが割り当てられる可能性が非常に高いですが、VMでは同じになることがあります。Kubernetesはこれらの値を使用して、クラスター内のノードを一意に識別します。これらの値が各ノードに固有ではない場合、インストール処理が失敗することもあります。

kubeadmを使ってクラスターを構築する - Kubernetes

⇧ じゃないと、Kuebernetes のインストールに失敗するって...何だろう、この言い切らない感じ...

しかも、VM、つまり仮想マシンに限った話なんですと。

あ、でも、あれか、このチェックさえすれば 100% インストール成功するって思って良いんですよね?

まぁ、でも、資本力のある上流階級の皆々様にあっては、チェックするという選択肢は無いんでしょうね。

要するに、お金持ちで、実機しか持ったこと無いんだけど~、っていう輩には縁のない話ではありますと。

勿論、お金のない私は、仮想マシンなので、確認するしかないのであった...

で、sshログインして確認します。「password: 」については、自分の場合は、キックスタートファイル(「ks.cfg」)に記載してるものを利用しています。

f:id:ts0818:20200417222117j:plain

f:id:ts0818:20200417222133j:plain

f:id:ts0818:20200417222144j:plain

一応、それぞれ、バラバラの『MACアドレス』『product_uuid』になっていることが確認できました。

 

multi-nodeなKubernetesを構築してみる - Master-NodeでHostname、FirewallSELinuxの設定

そしたらば、仮想マシンで諸々の設定をしていきます。

その前に、現在の仮想マシンの構成なんかを、図にしてみます。

elephantcat.work

qiita.com

www.nakivo.com

⇧ 上記サイト様を参考にさせていただきました。

今回、自分の環境ですと、

Master Nodeの仮想マシン
ネットワークアダプタ ネットワークインターフェース IPアドレス
No  名称  No  旧名称  新名称 
     1  lo  lo  127.0.0.1
 1  NAT  2  eth0  enp0s3  10.0.2.15/24
 2  Host-Only Adapter  3  eth1  enp0s8  192.168.31.101
Worker Node01の仮想マシン
ネットワークアダプタ ネットワークインターフェース IPアドレス
No  名称  No  旧名称  新名称 
     1  lo  lo  127.0.0.1
 1  NAT  2  eth0  enp0s3  10.0.2.15/24
 2  Host-Only Adapter  3  eth1  enp0s8  192.168.31.102
Worker Node02の仮想マシン
ネットワークアダプタ ネットワークインターフェース IPアドレス
No  名称  No  旧名称  新名称 
     1  lo  lo  127.0.0.1
 1  NAT  2  eth0  enp0s3  10.0.2.15/24
 2  Host-Only Adapter  3  eth1  enp0s8  192.168.31.103

ってことになるので、

f:id:ts0818:20200418183620p:plain

⇧ みたいなイメージになるんですかね?

ネットワークの知識が無いので、あくまでもイメージです。sshの仕組みも、改めて考えてみるとよく分からんですな。勿論、Virtualbox の仕組みもよく分かってないので。

 

まずは、Master node の仮想マシンsshログインして、root ユーザーに切り替えます。「password: 」については、自分の場合は、キックスタートファイル(「ks.cfg」)に記載してるものを利用しています。

access.redhat.com

hostnamectl ツールは、システム上で使用中の 3 つのクラスのホスト名を管理するためのものです。

6.3. hostnamectl を使用したホスト名の設定 Red Hat Enterprise Linux 7 | Red Hat Customer Portal

⇧ 「hostnamectl」は、RHEL系のLinuxディストリビューションに限ったコマンドなんかな?分からけど。

システム上のホスト名すべてを設定するには、root で以下のコマンドを実行します。

~]# hostnamectl set-hostname name

このコマンドは、pretty、static、および transient のホスト名を同様に変更します。static および transient ホスト名は、pretty ホスト名のシンプルな形式です。空白は-で置換され、特殊文字は削除されます。

6.3. hostnamectl を使用したホスト名の設定 Red Hat Enterprise Linux 7 | Red Hat Customer Portal

⇧ ってことらしいですと。

いや、「pretty」「static」「trasient」の関係がまったく分からんから、酷いドキュメントだな~。 

www.opensourcetech.tokyo

   なお、細かい話になりますがホスト名は --static / --transient / --prettyの3種類があります。

   --static:/etc/hostnameに記載されるホスト名

  --transient:カーネルによって保持される一時的なホスト名

  --pretty:自由形式のUTF8ホスト名

CentOS7 のホスト名設定について(hostname / nmcli / nmtui / hostnamectl / uname) - Opensourcetechブログ

⇧ 上記サイト様が説明してくださっていました。

まぁ、どちらにしろ、何で3つあるのかの理由はよく分からんのだけれど、ホスト名を設定で。

hostnamectl set-hostname [適当なホスト名]   

その後、hostsファイルを編集。

cat <<EOF>> /etc/hosts
[master nodeの仮想マシンのIPアドレス]  [適当なホスト名] 
[worker node 01の仮想マシンのIPアドレス]  [適当なホスト名]
[worker node 02の仮想マシンのIPアドレス]  [適当なホスト名]
EOF 

f:id:ts0818:20200418123831p:plain

そしたらば、worker node 01 へ疎通確認。

f:id:ts0818:20200418130915p:plain

f:id:ts0818:20200418135059p:plain

そしたらば、Selinuxを無効化で。

setenforce 0    

リブート(再起動)後も Selinux を無効化にするための設定。

sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux 

リブート(再起動)。

reboot 

f:id:ts0818:20200425175926p:plain

firewalld のサービスが動いてなかったので、有効化して起動で。

firewalldのサービス有効化。

systemctl enable firewalld

firewalldのサービス起動。

systemctl start firewalld

firewalldのサービスの状態確認。

systemctl status firewalld

f:id:ts0818:20200425180425p:plain

⇧ 状態の確認は、Ctrl + C とかで抜けれます。

続いて、Kubernetesの各コンポーネントのためのポートを解放しておきます。

kubernetes.io

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

f:id:ts0818:20200425180822p:plain

 br_netfilterモジュールを読み込む。

modprobe br_netfilter

 仮想化ブリッジのフィルタリングを有効化。

echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

 br_netfilterモジュールを読み込んでおかないと、Kubernetesの各コンポーネントへのアクセスが上手くいかなくなりそうということみたいですかね?

github.com

note.spage.jpwww.isoppe.jp

f:id:ts0818:20200425182311p:plain

 

multi-nodeなKubernetesを構築してみる - Master-NodeでDocker-CEのインストール

CentOS 8は、デフォルトの状態ではDockerがサポートされていないので、Docker-CEをインストールするためのリポジトリを追加します。

dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo

f:id:ts0818:20200425184214p:plain

Docker-CEをインストールするのに必要なものをダウンロード。

download.docker.com

x86_64の安定板のパッケージ群からダウンロードしてます。

dnf install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm

f:id:ts0818:20200425185134p:plain

f:id:ts0818:20200425185227p:plain

Docker-CEをインストール。

dnf install docker-ce

f:id:ts0818:20200425185530p:plain

f:id:ts0818:20200425190026j:plain

f:id:ts0818:20200425190114p:plain

dockerのサービスを有効化。

systemctl enable docker

dockerサービスを起動。

systemctl start docker

dockerサービスの状態の確認。

systemctl status docker

f:id:ts0818:20200425193736p:plain

 

multi-nodeなKubernetesを構築してみる - Master-NodeでKubernetes(Kubeadm)をインストール

 kubernetesをインストールするためのリポジトリを設定。

kubernetes.io

kubeadmはkubeletkubectlをインストールまたは管理しないため、kubeadmにインストールするKubernetesコントロールプレーンのバージョンと一致させる必要があります。そうしないと、予期しないバグのある動作につながる可能性のあるバージョン差異(version skew)が発生するリスクがあります。

https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#kubeadm-kubelet-kubectl%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

⇧ 基本的には、バージョンの問題があるみたい、っていうか「Kubenetesコントロールプレーン」って何のこと?

マスターコンポーネントは、クラスターのコントロールプレーンを提供します。

Kubernetesのコンポーネント - Kubernetes

⇧ 「コントロールプレーン」自体が何なのかの説明は絶対にしたくないらしい...

Cloud Native Computing Foundation(CNCF)がドキュメント管理してるとしたら、酷いな、これ...

Wikipediaさんの解釈だと、

Kubernetesコントロールプレーン(マスター)

Kubernetesのマスターは、クラスターのメインとなるコントロールユニットである。

Kubernetes - Wikipedia

⇧ 「マスターノード」==「コントロールプレーン」ってことみたいに見えますけど...

本当に、認識齟齬になるだけだから、ドキュメントを曖昧にするの止めて欲しいな...

話は、脱線しましたが、今回は、CentOS 8なので、リポジトリの設定は、「CentOS, RHEL or Fedora」のものを使用。

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

f:id:ts0818:20200425194425p:plain

リポジトリを設定したら、kubeadm のインストール。

dnf install kubeadm -y

f:id:ts0818:20200425195152j:plain 

f:id:ts0818:20200425195231p:plain

kubeadm がインストールされたら、kubelet という、Kubernetes Clusterのコンポーネント群にアクセスするためのサービスを有効化し、kubeletサービスの起動。 

systemctl enable kubelet
systemctl start kubelet

f:id:ts0818:20200425195431p:plain

 

multi-nodeなKubernetesを構築してみる - Master-NodeでKubernetesを有効化

で、ドキュメント に記載は無いんだけど、

swapoff -a

⇧ 「swapの無効化」しないとエラーで出て進まないっていうね...

っていうか、ドキュメントに載せんとアカンでしょ...

で、Kubernetes Cluster の初期化のコマンドも、オプション指定しないと、ネットワークがNATのほうのIPアドレスが設定されるというね...

なので、オプション設定しました。

ちなみに、オプション絡みで、

qiita.com

kubeadm で kubernetesクラスタをinstallするときにFlannelを使用する場合、pod-network-cidr は決められた値を指定する必要があるとDocumentに記載されています。

kubeadmで Pod-network-cidr を変更する - Qiita

⇧ とあり、

「pod-network-cidr」に設定できる値は、Kubernetes Clusterをインストールするときに使用するPod ネットワークプラグインによって条件が異なるらしく、

kubernetes.io

You can install only one Pod network per cluster. Below you can find installation instructions for some popular Pod network plugins:

https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network

⇧ に記載があります。

私の場合は、参考にさせていただいたサイト様が「Weave Net」ってプラグインを利用してたこともあり、特に「pod-network-cidr」に設定できるIPアドレスに制約は無いっぽいです、少なくともドキュメントからは読み取れなかった。

他にも、オプションはいろいろあるみたいです。

kubeadm init --apiserver-advertise-address [ホストオンリーアダプターのIPアドレス(マスターノード用の仮想マシン)] --pod-network-cidr [適当なIPアドレスの範囲]

f:id:ts0818:20200425220958p:plain

f:id:ts0818:20200425215802j:plain

⇧ 上記の最後に表示された、kubeadm join ~のコマンドは、後ほど、Worker nodeで実行するみたいなので、どっかテキストエディターにでもコピーしておきましょう。

 

スーパーユーザー(rootユーザー)になってるので、各コマンドに sudo を付けるのは不要っぽい、っていうか公式のドキュメントみたら、参考サイト様と違ってる...。

kubernetes.io

⇧ 私は、ドキュメント通りできてないですが、ドキュメントに合わせましょう。

以下のコマンドは、最新のドキュメント通りなってないので、ドキュメントのほうを参考ください。

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

f:id:ts0818:20200425201216p:plain

kubelet コマンドで、Kubernetes のノードの状態を確認 

kubelet get nodes

f:id:ts0818:20200425201351p:plain

⇧ 「NotReady」ってなってるのは、Podのネットワークをまだ作ってないからで、この状態は想定通りらしいです。

 

multi-nodeなKubernetesを構築してみる - Master-NodeでKubernetesのPod Networkを設定

そしたらば、「Pod ネットワークプラグイン」をインストールして、「Pod Network」を設定していきます。ここも、公式の最新のドキュメントだとワンライナーでコマンド実行してるかな...内容は変わらないです。

export kubever=$(kubectl version | base64 | tr -d '\n')
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$kubever"

f:id:ts0818:20200425201814p:plain

f:id:ts0818:20200425201904p:plain

⇧ 準備が整いました。
 

 

multi-nodeなKubernetesを構築してみる - Worker-NodeでHostname、FirewallSELinuxの設定

Worker-Node01のほうの仮想マシンにログインで。

f:id:ts0818:20200425202652p:plain

⇧ スーパーユーザーに切り替えときます。

マスターノードでの作業の時と同様に、んで、まずは、ホスト名を設定。 

hostnamectl set-hostname [適当なホスト名]   

マスターノードでの作業の時と同様に、その後、hostsファイルを編集。Master Nodeのときのhostsファイルと同じ内容にしときました。

cat <<EOF>> /etc/hosts
[master nodeの仮想マシンのIPアドレス]  [適当なホスト名] 
[worker node 01の仮想マシンのIPアドレス]  [適当なホスト名]
[worker node 02の仮想マシンのIPアドレス]  [適当なホスト名]
EOF 

f:id:ts0818:20200425202918p:plain

master node に、ping で疎通確認。

f:id:ts0818:20200425203047p:plain

マスターノードでの作業の時と同様に、Selinuxの無効化。リロード(再起動)時も設定を維持する。

f:id:ts0818:20200425203208p:plain

マスターノードでの作業の時と同様に、firewalld のサービスを有効化し、起動しときましょう。

f:id:ts0818:20200425203506p:plain

続いて、Kubernetesの各コンポーネントのためのポートを開放しておきます。このへん、開放するポートの選び方は公式のドキュメントに無さ気なので何を設定するのかは不明。参考サイト様のものを流用してます。

firewall-cmd --permanent --add-port=6783/tcp
firewall-cmd --permanent --add-port=10250/tcp
firewall-cmd --permanent --add-port=10255/tcp
firewall-cmd --permanent --add-port=30000-32767/tcp
firewall-cmd --reload

f:id:ts0818:20200425203750p:plain

マスターノードでの作業の時と同様に、 br_netfilterモジュールを読み込む。

modprobe br_netfilter

マスターノードでの作業の時と同様に、仮想化ブリッジのフィルタリングを有効化。

echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

f:id:ts0818:20200425204444p:plain

 

multi-nodeなKubernetesを構築してみる - Worker-NodeでDocker-CEのインストール

マスターノードでの作業の時と同様に、CentOS 8は、デフォルトの状態ではDockerがサポートされていないので、Docker-CEをインストールするためのリポジトリを追加します。

dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo

f:id:ts0818:20200425204914p:plain

マスターノードでの作業の時と同様に、Docker-CEをインストールするのに必要なものをダウンロード。ダウンロードするもののバージョンとかはご自分の用途に合わせてください。

dnf install https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm

f:id:ts0818:20200425204954p:plain

⇧ 「y」でEnter。

f:id:ts0818:20200425204817p:plain

 

マスターノードでの作業の時と同様に、Docker-CEをインストール。

dnf install docker-ce

f:id:ts0818:20200425205417p:plain

f:id:ts0818:20200425205612j:plain

f:id:ts0818:20200425205656p:plain

マスターノードでの作業の時と同様に、dockerのサービスを有効化。

systemctl enable docker

マスターノードでの作業の時と同様に、dockerサービスを起動。

systemctl start docker

マスターノードでの作業の時と同様に、dockerサービスの状態の確認。

systemctl status docker

f:id:ts0818:20200425205815p:plain

 

 

multi-nodeなKubernetesを構築してみる - Worker-NodeでKubernetes(Kubeadm)をインストール

マスターノードでの作業の時と同様に、Kubernetesをインストールするためのリポジトリを追加する。

今回は、CentOS 8なので、リポジトリの設定は、「CentOS, RHEL or Fedora」のものを使用。

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

f:id:ts0818:20200425210041p:plain

マスターノードでの作業の時と同様に、kubeadmをインストール。

dnf install kubeadm -y 

f:id:ts0818:20200425210703j:plain

f:id:ts0818:20200425210347p:plain

マスターノードでの作業の時と同様に、kubeadm がインストールされたら、kubelet という、Kubernetes Clusterのコンポーネント群にアクセスするためのサービスを有効化し、kubeletサービスの起動。 

systemctl enable kubelet
systemctl start kubelet 

f:id:ts0818:20200425210835p:plain

でマスターノードでの作業の時と同様に、ドキュメント に記載は無いんだけど、

swapoff -a

⇧ 「swapの無効化」しないとエラー出るので。

で、マスターノードの作業の時にテキストエディタなどにコピペしておいたコマンドを実行します。

24時間経過すると、コマンドに記載のtokenなどが無効化されるらしく、

blog.sky-net.pw

⇧ 上記サイト様が、tokenなどの再生成について、まとめてくださってます。

kubeadm join 10.0.2.15:6443 --token 6lprcx.r9s3msk7p4vabzw7 \ --discovery-token-ca-cert-hash sha256:e60e567a45c013dff7567c580407e49ebeec69053aa285d7630b43211a6351c9

f:id:ts0818:20200425224421p:plain

f:id:ts0818:20200425224636p:plain

⇧ 間違えて、worker-node-1 の中で、kubectlコマンド使ってしまった...
master-nodeの仮想マシンのほうで、kubectl コマンドでnodeを確認すると、worker-node-1のnodeもKubernetes Clusterに追加されてます。

f:id:ts0818:20200425224606p:plain

 

同様に、worker-node-2 についても、worker-node-1 でやったのと同じことを行います。

worker-node-2 用の仮想マシンにログイン。

f:id:ts0818:20200425225346p:plain

スーパーユーザー(「rootユーザー」)に切り替え。

ホスト名の設定。hostsファイルの編集。

f:id:ts0818:20200425225508p:plain

firewalld のサービスを有効化、起動。

f:id:ts0818:20200425225716p:plain

Selinuxの無効化、リロード(再起動)時も無効化を維持する。

ポートの開放。(worker-node-1 の時と同様のポートを開放しましたが、正直よく分かりません。)

f:id:ts0818:20200425230226p:plain

br_netfilterモジュールを読み込む。

仮想化ブリッジのフィルタリングを有効化。

Docker-CEをインストールするためのリポジトリを追加。

Docker-CEをダウンロード。

f:id:ts0818:20200425230552p:plain

f:id:ts0818:20200425230517p:plain

Docker-CEをインストール。 

f:id:ts0818:20200425230810p:plain

f:id:ts0818:20200425230729p:plain

Docker-CEのサービスを有効化、起動。

f:id:ts0818:20200425230913p:plain

キャプチャ画像が載せれてないけれども、マスターノードでの作業の時と同様に、Kubernetesをインストールするためのリポジトリを追加する。

今回は、CentOS 8なので、リポジトリの設定は、「CentOS, RHEL or Fedora」のものを使用。

Kubeadmをインストール。
f:id:ts0818:20200425231403j:plain

f:id:ts0818:20200425231102p:plain

 kubeketのサービスを有効化、起動。 

f:id:ts0818:20200425231532p:plain

OSのswapを無効化。

マスターノードで生成したKubernetes Clusterに、worker-node-2 を参加させます。 

f:id:ts0818:20200425231742p:plain

f:id:ts0818:20200425231816p:plain

 

 マスターノードの仮想マシンで、ノードを確認。

f:id:ts0818:20200425231858p:plain

⇧ Kuberenetes Clusterにすべてのノードが参加できました。

やっぱり、ドキュメントが整備されていないと、辛いですね...

構築した環境が上手く機能するのかも分かりませんが、ドキュメントだけの情報では構築ですらスムーズにできないんですから、Kuberenetes が本番環境で嫌煙されるのも納得な気がしました。

Cloud Native Computing Foundation(CNCF)がKubernetesを管理してると仮定するけれど、ドキュメントの管理をもうちょっと頑張って欲しいかな...

まぁ、オープンソースソフトウェアに、そこまで求めてはいけないと言われればそれまでですが...

 

何はともあれ、Kubernetes環境ができたので、次回は、オンプレミス環境でサーバレスな環境が構築できるらしい、CloudState をようやく試すことができそうです。(CloudState自体については、半年以上前には、その存在を把握してたんだけどね...)

 

2020年5月3日(日)追記:↓ ここから

仮想マシンを停止・再起動すると、Kubernetes Clusterも停止するみたいね。

通常は、仮想マシンが停止することはあってはならないってことなので、仮想マシンが停止するってことを想定しないってことなのかもしらんけど、「Kubernetes Cluster」の再起動が上手くいかないという...

stackoverflow.com

I had the same issue. Could not start kubelet service in master node.

Running the below command fixed my problem :

$ sudo swapoff -a

$ sudo systemctl restart kubelet.service

$ systemctl status kubelet

 

kubernetes - kubelet.service: Main process exited, code=exited, status=255/n/a - Stack Overflow

⇧ kubelet.service を再起動でイケるみたいのはずが、

f:id:ts0818:20200503195213p:plain

⇧ worker-nodeの2つ目のマシンのkubeletのサービスも落ちてる。

ログインして、

f:id:ts0818:20200503195658p:plain

f:id:ts0818:20200503200005p:plain

master-nodeの仮想マシンのほうで確認。

f:id:ts0818:20200503200155p:plain

⇧ 悪化しとるやないか~い!

ん~、毎回思うけど、ログがクソ役に立たんのよね...もうちょいまともなログメッセージにしてくれんかな...

う~ん、何か、

qiita.com

kubeadmでK8s環境を作っていて気付いたのですが、最近採用されているCoreDNSはホストの/etc/hostsを使ってくれません。すると何が困るかというと、例えばmetrics-serverのようにノードのメトリクスを取得するPodはノード名に対して接続をしようとするので、ノード名がDNSにないと名前解決ができません。

KubernetesのCoreDNSはホストの/etc/hostsを使ってくれないのでConfigMapにレコードを追加する - Qiita

⇧ CoreDNSっていうやつが原因って気がする。

とりあえず、調べてみますか。

2020年5月3日(日)追記:↑ ここまで

2020年5月4日(月)追記:↓ ここから

駄目でした...

何か、KubernetesAPI ServerとかのIPアドレスが、NATのものになってしまってるんよね。

[root@master ~]# kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                             READY   STATUS      RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
kube-system   coredns-66bff467f8-hs6dw         0/1     Completed   0          8d    <none>           master   <none>           <none>
kube-system   coredns-66bff467f8-tf2ck         0/1     Completed   0          8d    <none>           master   <none>           <none>
kube-system   etcd-master                      1/1     Running     4          8d    10.0.2.15        master   <none>           <none>
kube-system   kube-apiserver-master            1/1     Running     4          8d    10.0.2.15        master   <none>           <none>
kube-system   kube-controller-manager-master   1/1     Running     4          8d    10.0.2.15        master   <none>           <none>
kube-system   kube-proxy-hqdr7                 1/1     Running     0          8d    192.168.31.103   node-2   <none>           <none>
kube-system   kube-proxy-n956m                 1/1     Running     0          8d    192.168.31.102   node-1   <none>           <none>
kube-system   kube-proxy-tnjkn                 1/1     Running     4          8d    10.0.2.15        master   <none>           <none>
kube-system   kube-scheduler-master            1/1     Running     4          8d    10.0.2.15        master   <none>           <none>
kube-system   weave-net-6tq8m                  2/2     Running     1          8d    192.168.31.102   node-1   <none>           <none>
kube-system   weave-net-fld5h                  1/2     Running     12         8d    10.0.2.15        master   <none>           <none>
kube-system   weave-net-jj7zq                  2/2     Running     0          8d    192.168.31.103   node-2   <none>           <none>

どうやら、

github.com

github.com

kubernetes.io

⇧ 「/var/lib/kubelet/kubeadm-flags.env」ってファイルで、「--node-ip」っていうオプション追加して上げないと駄目みたい。

 

vi /var/lib/kubelet/kubeadm-flags.env

「--node-ip」のオプション追加。(IPアドレスはマスターノードのホストオンリーアダプターのに合わせる)

KUBELET_KUBEADM_ARGS="--cgroup-driver=cgroupfs --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.2 --node-ip=192.168.31.101"    

Kubeletのサービス再起動。

systemctl daemon-reload && systemctl restart kubelet 

IPアドレスは変わったけど、相変わらず、coredns が解決できてない...

[root@master ~]# kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                             READY   STATUS      RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
kube-system   coredns-66bff467f8-hs6dw         0/1     Completed   0          8d    <none>           master   <none>           <none>
kube-system   coredns-66bff467f8-tf2ck         0/1     Completed   0          8d    <none>           master   <none>           <none>
kube-system   etcd-master                      1/1     Running     4          8d    192.168.31.101   master   <none>           <none>
kube-system   kube-apiserver-master            1/1     Running     4          8d    192.168.31.101   master   <none>           <none>
kube-system   kube-controller-manager-master   1/1     Running     4          8d    192.168.31.101   master   <none>           <none>
kube-system   kube-proxy-hqdr7                 1/1     Running     0          8d    192.168.31.103   node-2   <none>           <none>
kube-system   kube-proxy-n956m                 1/1     Running     0          8d    192.168.31.102   node-1   <none>           <none>
kube-system   kube-proxy-tnjkn                 1/1     Running     4          8d    192.168.31.101   master   <none>           <none>
kube-system   kube-scheduler-master            1/1     Running     4          8d    192.168.31.101   master   <none>           <none>
kube-system   weave-net-6tq8m                  2/2     Running     1          8d    192.168.31.102   node-1   <none>           <none>
kube-system   weave-net-fld5h                  2/2     Running     13         8d    192.168.31.101   master   <none>           <none>
kube-system   weave-net-jj7zq                  2/2     Running     0          8d    192.168.31.103   node-2   <none>           <none>

ログを見た感じ、hostの解決ができてないっぽい...

[root@master ~]# kubectl logs coredns-66bff467f8-hs6dw -n kube-system
.:53
[INFO] plugin/reload: Running configuration MD5 = 4e235fcc3696966e76816bcd9034ebc7
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[ERROR] plugin/errors: 2 7785293665766098738.705096105008474652. HINFO: read udp 10.32.0.4:40644->10.0.2.3:53: read: no route to host
[ERROR] plugin/errors: 2 7785293665766098738.705096105008474652. HINFO: read udp 10.32.0.4:56378->10.0.2.3:53: i/o timeout
[INFO] SIGTERM: Shutting down servers then terminating
[INFO] plugin/health: Going into lameduck mode for 5s

いや~、分からん...

何か、

www.kaitoy.xyz

マスタノード上で以下のコマンドを実行すると、Weave NetのAPIを叩いて状態を確認できる。

# curl http://localhost:6784/status

Kubernetes 1.10のクラスタにWeave Netをデプロイする | To Be Decided

⇧ 上記サイト様を参考に確認してみる。

f:id:ts0818:20200504175427p:plain

⇧ ってなってて、

www.weave.works

  • ‘Status’ - allocator state
    • ‘awaiting consensus’ - an attempt to achieve consensus is ongoing, triggered by an allocation or claim request; allocations will block. This state persists until a quorum of peers are able to communicate amongst themselves successfully.

https://www.weave.works/docs/net/latest/tasks/ipam/troubleshooting-ipam/

⇧ って言うか、Weave Net も失敗してるんじゃない、これ。

原因はネットワーク周りだとは思うんだけど、どうすりゃ良いかサッパリですわ...

毎回、kubeadmの初期化とかしないといかんってことなのかね...

だとしたら、Kuberentes ってかなり残念過ぎる...

 

残念過ぎるけど、Kubeadmの初期化からやり直しました...

tjtjtj.hatenablog.com

⇧ 上記サイト様を参考に、「Pot network plugin」だけ、「Weave Net」を使いました。メモリに余裕のないパソコンを使っている人は、「swapoff -a」とかのコマンドも忘れずに。

結果、各Podは、NATのIPアドレスになるのが正解みたい、corednsについては、「Weave Net」がIPアドレスを割り振るみたい、よく分からん...

[root@master ~]# kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                             READY   STATUS    RESTARTS   AGE     IP          NODE             NOMINATED NODE   READINESS GATES
kube-system   coredns-66bff467f8-7lppj         1/1     Running   0          16m     10.32.0.2   master           <none>           <none>
kube-system   coredns-66bff467f8-9clj2         1/1     Running   0          16m     10.32.0.3   master           <none>           <none>
kube-system   etcd-master                      1/1     Running   0          16m     10.0.2.15   master           <none>           <none>
kube-system   kube-apiserver-master            1/1     Running   0          16m     10.0.2.15   master           <none>           <none>
kube-system   kube-controller-manager-master   1/1     Running   0          16m     10.0.2.15   master           <none>           <none>
kube-system   kube-proxy-2fp2s                 1/1     Running   0          8m59s   10.0.2.15   worker-node-01   <none>           <none>
kube-system   kube-proxy-dl76l                 1/1     Running   0          8m40s   10.0.2.15   worker-node-02   <none>           <none>
kube-system   kube-proxy-f4fj4                 1/1     Running   0          16m     10.0.2.15   master           <none>           <none>
kube-system   kube-scheduler-master            1/1     Running   0          16m     10.0.2.15   master           <none>           <none>
kube-system   weave-net-8s8bz                  2/2     Running   1          8m59s   10.0.2.15   worker-node-01   <none>           <none>
kube-system   weave-net-mgqjv                  2/2     Running   0          10m     10.0.2.15   master           <none>           <none>
kube-system   weave-net-pvzlt                  2/2     Running   1          8m40s   10.0.2.15   worker-node-02   <none>           <none>

f:id:ts0818:20200504185546p:plain

それにしても、仮想マシンを再起動する度に、Kubeadmの初期化をするしか方法が無いってことなのかな?

...Kubernetesって一体...

 

2020年5月4日(月)追記:↑ ここまで

 

今回はこのへんで。

 

 

NG集

kubeadm init をオプション付けずに間違って実行して、

f:id:ts0818:20200425200111p:plain

f:id:ts0818:20200425200322j:plain

⇧ ネットワークがNATのIPアドレスが指定されてしまってるとね...

っていうかオプションあるなんて知らんし...

 

やり直すはめになったんだが、

kubernetes.io

⇧ 公式の通りやってみたところ、

f:id:ts0818:20200425213539p:plain

f:id:ts0818:20200425213644p:plain

⇧ なんか、残骸が残るらしい...

リカバリー方法をもうちょっと考えて欲しいもんですが...

とりあえず、指示にある通り、「$HOME/.kube/config」を削除しました。

f:id:ts0818:20200425214629p:plain

あと、「etc/cni/net.d」ってフォルダも削除しました。

iptablesとかの設定も残ってしまうようなんですかね...

まっさらな状態に戻せないのが辛いな...