A 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.
⇧ とありますように、「舵輪」は、名前からも分かる通り、舵を取るものですと。
この形、何かに似ていませんか?
そう、Kubernetes デスネ!
その前に、
⇧ に参加して参りました~。
『MongoDB+Neo4j(トキュメントタイプとグラフタイプの選び方、まとめて解説)講師:李 昌桓(クリエーションライン株式会社 シニアアーキテクト)』のセッションで、「Neo4j」っていうものも初めて知りました。
⇧ セッションで話されていた李さんがQiitaで、まとめてくださってます。
あと、
『DockerコンテナからKubernetesとOpenShiftまで要点解説 講師:高良 真穂(たから まほ)(CNBF運営委員)』のセッションをしてくださった、高良さんは、
15Stepで習得 Dockerから入るKubernetes コンテナ開発からK8s本番運用まで (StepUp!選書)
- 作者:高良 真穂
- 発売日: 2019/09/27
- メディア: 単行本(ソフトカバー)
⇧ Kubernetes の書籍も出してくださっているようです。
レビューを見る限り、最初に、Kubernetesを学ぶのにはオススメの一冊のようです。私も欲しいです!
はい、脱線しましたが、
というわけで、Kubernetesにレッツトライ~。
Kubernetesって?
まずは、おさらいということで、そもそも、Kubernetesって何ぞ?
Kubernetes(クバネティス/クバネテス/クーべネティス、K8sと略記される)は、コンテナ化したアプリケーションのデプロイ、スケーリング、および管理を行うための、オープンソースのコンテナオーケストレーションシステムである。
⇧ コンテナの管理がメインですかね。
元々Googleが設計したシステムであるが、現在はCloud Native Computing Foundationがメンテナンスを行っている。
⇧ Googleさん発祥です。
何で、コンテナオーケストレーションなんてものが必要になったかというのは、
⇧ アプリケーションのデプロイ環境の変遷などが関わってますと。
■「Traditional Deployment」→「Virtualized Deployment」
まず、Windows、OS X(Mac)、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?
⇧ 「コンテナ」の管理をシステムに任せたほうが良いよね?って考えがあり、
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.
⇧ それを担ってくれるのが、Kubernetesですと。
Kubernetesが「コンテナオーケストレーション」と呼ばれる所以ということですかね?
ただ
Gracely:全てがコンテナ化されるのか? という部分に関して言えば全てではないと思います。例えばAmadeusという航空券のためのシステムがありますが、このシステムでは数百のシステムと連携して航空券に関する情報を取ってきます。つまり1回のトランザクションが数ミリ秒掛かったとしてそれが数百、数千になれば検索結果を返すためにどれだけ時間がかかってしまうのかは予想できます。我々は数秒の遅れが顧客を失うことに繋がると知っていますので、そのトランザクションを実行するシステムは高速でなければならないのです。そのようなシステムを単にコンテナ化することには、あまり意味がないと思います。反対に、例えばスーパーマーケットのサプライ・チェインの中で発注のトランザクションが数秒掛かったところで、それほど弊害が出ることもないでしょう。このようにどのユースケースでどのようなニーズがあるのかをしっかり理解しておけば、全てをコンテナにするという判断はしないと言うことです。
Red HatのCTOとOpenShiftのディレクターに訊く。パックの行く先にいたRed Hatの強さ | Think IT(シンクイット)
⇧ 「コンテナ」も適材適所で利用していきましょ~、ということみたいですね。
Kubernetesのアーキテクチャ
Kubernetesが、「コンテナオーケストレーション」を実現してくれることは分かったんだけど、どんなアーキテクトなのよ?
⇧ Wikipediaさんに掲載されてました。
全体的なイメージは、上図のような感じですかね。
Kubernetesは、マスター・スレーブアーキテクチャで構成される。Kubernetesのコンポーネントは、各ノードを管理するノード(node)と、コントロールプレーンであるマスター(master)の2つに分けられる
⇧ 「Kubernetesは、マスター・スレーブアーキテクチャで構成される。」って言われてもね...
マスタースレーブ(英: master-slave)は、複数の機器が協調動作する際に、複数機器の制御・操作を司る「マスター」機と、マスター機の一方的な制御下で動作する「スレーブ」機に役割を分担する方式のこと。
⇧ 分散システムっすな。
⇧ マシンが複数要りそう。
- クライアントサーバモデルでは、クライアントがマスター、サーバがスレーブである。
- データベースレプリケーションでは、正式とされているマスターデータベースにスレーブデータベースを同期させる。
- コンピュータバスでは、一般にCPUがマスター、周辺機器がスレーブである。ただし、バス上のトランザクションを発行するものがその時点のマスターとなる方式もある。
⇧ なんか、Kubernetesに当てはまりそうな例ではなさそうね...
マスター(主人)とスレーブ(奴隷)という用語はしばしば論争の的となることがある。
⇧ そりゃ、議論にされるでしょうな。
2003年11月、ロサンゼルス郡は電子メールで出入り業者に対してこれらの用語を使った製品を納入しないよう要求した。これに対してIT業界ではばかげた主張だとして取り合わない動きが大勢を占めた。マスタースレーブという用語はデバイス内部で起きていることを正確に表した技術用語であり、かつて存在した奴隷制度とは何の関係もないというのがその理由であった(ポリティカル・コレクトネスも参照)。
⇧ 歴史が生んだ悲劇。
一方で、こうした論争を避けるため、データベースの分野ではマスタースレーブの代替語として「プライマリー」や「レプリカ」といった語句を採用するケースもある。
⇧ 忖度。
⇧ 忖度。
っていうか、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.
⇧ って言っていて、詳細は、
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).
⇧ 「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.」って言ってるのに、
⇧ 「コンテナ」内でKubernetes構築できるって話もあり、「node」は「仮想マシン」か「物理マシン」だけじゃなかったんかい!っていうツッコミを入れたくなりますな。
まぁ、オンプレミス環境でのKuebernetesの構成としては、
- Master
- kube-api-server
- kube-controller-manager
- kube-scheduler
- etcd
- Worker Node
- kubelet
- kube-proxy
- Container Runtime( Docker, containerd, cri-o, rktlet および全ての Kubernetes CRI (Container Runtime Interface) 実装)
最低限、上記の様なコンポネントが必要らしい。
あと、大枠として「Master」が1台、「Worker Node」が1台、の合わせて2つは必要でありますと。
このへんも言葉が統一されてないんだよな~。
「Master」「Worker Node」は同一のマシンに同居させても良いけど、別々のマシンに配置するのが良いみたい。
Kubernetesについては、
⇧ 上記サイト様がまとめてくださってます。
Kubernetesの仕組みについては、
⇧ 上記の動画でイメージが掴みやすいです。
multi-nodeなKubernetesを構築してみる - マシンのMACアドレスとproduct_uuidをチェック
まぁ、構築してみますか。
ありがたいことに、
⇧ 「CentOS 7」「CentOS 8」で構築してくれてる方がおりました。
上記サイト様によりますと、「仮想マシン」を3台用意しとくようにということなので、用意します。
⇧ 手前味噌ではありますが、こちらの記事で、CentOS 8 の仮想マシン3台を作成しておきました。宜しければ、ご参照ください。
で、Vagrantで仮想マシンが用意できていれば、vagrant up で起動しちゃいましょう。
起動できたら、起動確認しまして、ネットワークアダプターがホストオンリーアダプターの、それぞれの仮想マシンのIPアドレスを確認で。
んで、
MACアドレスとproduct_uuidが全てのノードでユニークであることの検証
- ネットワークインターフェースのMACアドレスは
ip link
もしくはifconfig -a
コマンドで取得できます。 - product_uuidは
sudo cat /sys/class/dmi/id/product_uuid
コマンドで確認できます。
⇧ それぞれのマシンで、『MACアドレス』と『product_uuid』って値がすべて異なっていないといけないらしい。
ハードウェアデバイスではユニークなアドレスが割り当てられる可能性が非常に高いですが、VMでは同じになることがあります。Kubernetesはこれらの値を使用して、クラスター内のノードを一意に識別します。これらの値が各ノードに固有ではない場合、インストール処理が失敗することもあります。
⇧ じゃないと、Kuebernetes のインストールに失敗するって...何だろう、この言い切らない感じ...
あ、でも、あれか、このチェックさえすれば 100% インストール成功するって思って良いんですよね?
まぁ、でも、資本力のある上流階級の皆々様にあっては、チェックするという選択肢は無いんでしょうね。
要するに、お金持ちで、実機しか持ったこと無いんだけど~、っていう輩には縁のない話ではありますと。
勿論、お金のない私は、仮想マシンなので、確認するしかないのであった...
で、sshログインして確認します。「password: 」については、自分の場合は、キックスタートファイル(「ks.cfg」)に記載してるものを利用しています。
一応、それぞれ、バラバラの『MACアドレス』『product_uuid』になっていることが確認できました。
multi-nodeなKubernetesを構築してみる - Master-NodeでHostname、Firewall、SELinuxの設定
そしたらば、仮想マシンで諸々の設定をしていきます。
その前に、現在の仮想マシンの構成なんかを、図にしてみます。
⇧ 上記サイト様を参考にさせていただきました。
今回、自分の環境ですと、
ネットワークアダプター | ネットワークインターフェース | 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 |
ネットワークアダプター | ネットワークインターフェース | 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 |
ネットワークアダプター | ネットワークインターフェース | 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 |
ってことになるので、
⇧ みたいなイメージになるんですかね?
ネットワークの知識が無いので、あくまでもイメージです。sshの仕組みも、改めて考えてみるとよく分からんですな。勿論、Virtualbox の仕組みもよく分かってないので。
まずは、Master node の仮想マシンにsshログインして、root ユーザーに切り替えます。「password: 」については、自分の場合は、キックスタートファイル(「ks.cfg」)に記載してるものを利用しています。
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」の関係がまったく分からんから、酷いドキュメントだな~。
なお、細かい話になりますがホスト名は --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
そしたらば、worker node 01 へ疎通確認。
そしたらば、Selinuxを無効化で。
setenforce 0
リブート(再起動)後も Selinux を無効化にするための設定。
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
リブート(再起動)。
reboot
firewalld のサービスが動いてなかったので、有効化して起動で。
firewalldのサービス有効化。
systemctl enable firewalld
firewalldのサービス起動。
systemctl start firewalld
firewalldのサービスの状態確認。
systemctl status firewalld
⇧ 状態の確認は、Ctrl + C とかで抜けれます。
続いて、Kubernetesの各コンポーネントのためのポートを解放しておきます。
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
br_netfilterモジュールを読み込む。
modprobe br_netfilter
仮想化ブリッジのフィルタリングを有効化。
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
br_netfilterモジュールを読み込んでおかないと、Kubernetesの各コンポーネントへのアクセスが上手くいかなくなりそうということみたいですかね?
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
Docker-CEをインストールするのに必要なものをダウンロード。
⇧ 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
Docker-CEをインストール。
dnf install docker-ce
dockerのサービスを有効化。
systemctl enable docker
dockerサービスを起動。
systemctl start docker
dockerサービスの状態の確認。
systemctl status docker
multi-nodeなKubernetesを構築してみる - Master-NodeでKubernetes(Kubeadm)をインストール
kubernetesをインストールするためのリポジトリを設定。
kubeadmはkubelet
やkubectl
をインストールまたは管理しないため、kubeadmにインストールするKubernetesコントロールプレーンのバージョンと一致させる必要があります。そうしないと、予期しないバグのある動作につながる可能性のあるバージョン差異(version skew)が発生するリスクがあります。
⇧ 基本的には、バージョンの問題があるみたい、っていうか「Kubenetesコントロールプレーン」って何のこと?
⇧ 「コントロールプレーン」自体が何なのかの説明は絶対にしたくないらしい...
Cloud Native Computing Foundation(CNCF)がドキュメント管理してるとしたら、酷いな、これ...
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
リポジトリを設定したら、kubeadm のインストール。
dnf install kubeadm -y
kubeadm がインストールされたら、kubelet という、Kubernetes Clusterのコンポーネント群にアクセスするためのサービスを有効化し、kubeletサービスの起動。
systemctl enable kubelet
systemctl start kubelet
multi-nodeなKubernetesを構築してみる - Master-NodeでKubernetesを有効化
で、ドキュメント に記載は無いんだけど、
swapoff -a
⇧ 「swapの無効化」しないとエラーで出て進まないっていうね...
っていうか、ドキュメントに載せんとアカンでしょ...
で、Kubernetes Cluster の初期化のコマンドも、オプション指定しないと、ネットワークがNATのほうのIPアドレスが設定されるというね...
なので、オプション設定しました。
ちなみに、オプション絡みで、
kubeadm で kubernetesクラスタをinstallするときにFlannelを使用する場合、pod-network-cidr は決められた値を指定する必要があるとDocumentに記載されています。
⇧ とあり、
「pod-network-cidr」に設定できる値は、Kubernetes Clusterをインストールするときに使用するPod ネットワークプラグインによって条件が異なるらしく、
You can install only one Pod network per cluster. Below you can find installation instructions for some popular Pod network plugins:
⇧ に記載があります。
私の場合は、参考にさせていただいたサイト様が「Weave Net」ってプラグインを利用してたこともあり、特に「pod-network-cidr」に設定できるIPアドレスに制約は無いっぽいです、少なくともドキュメントからは読み取れなかった。
他にも、オプションはいろいろあるみたいです。
kubeadm init --apiserver-advertise-address [ホストオンリーアダプターのIPアドレス(マスターノード用の仮想マシン)] --pod-network-cidr [適当なIPアドレスの範囲]
⇧ 上記の最後に表示された、kubeadm join ~のコマンドは、後ほど、Worker nodeで実行するみたいなので、どっかテキストエディターにでもコピーしておきましょう。
スーパーユーザー(rootユーザー)になってるので、各コマンドに sudo を付けるのは不要っぽい、っていうか公式のドキュメントみたら、参考サイト様と違ってる...。
⇧ 私は、ドキュメント通りできてないですが、ドキュメントに合わせましょう。
以下のコマンドは、最新のドキュメント通りなってないので、ドキュメントのほうを参考ください。
mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config
kubelet コマンドで、Kubernetes のノードの状態を確認
kubelet get nodes
⇧ 「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"
⇧ 準備が整いました。
multi-nodeなKubernetesを構築してみる - Worker-NodeでHostname、Firewall、SELinuxの設定
Worker-Node01のほうの仮想マシンにログインで。
⇧ スーパーユーザーに切り替えときます。
マスターノードでの作業の時と同様に、んで、まずは、ホスト名を設定。
hostnamectl set-hostname [適当なホスト名]
マスターノードでの作業の時と同様に、その後、hostsファイルを編集。Master Nodeのときのhostsファイルと同じ内容にしときました。
cat <<EOF>> /etc/hosts [master nodeの仮想マシンのIPアドレス] [適当なホスト名] [worker node 01の仮想マシンのIPアドレス] [適当なホスト名] [worker node 02の仮想マシンのIPアドレス] [適当なホスト名] EOF
master node に、ping で疎通確認。
マスターノードでの作業の時と同様に、Selinuxの無効化。リロード(再起動)時も設定を維持する。
マスターノードでの作業の時と同様に、firewalld のサービスを有効化し、起動しときましょう。
続いて、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
マスターノードでの作業の時と同様に、 br_netfilterモジュールを読み込む。
modprobe br_netfilter
マスターノードでの作業の時と同様に、仮想化ブリッジのフィルタリングを有効化。
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
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
マスターノードでの作業の時と同様に、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
⇧ 「y」でEnter。
マスターノードでの作業の時と同様に、Docker-CEをインストール。
dnf install docker-ce
マスターノードでの作業の時と同様に、dockerのサービスを有効化。
systemctl enable docker
マスターノードでの作業の時と同様に、dockerサービスを起動。
systemctl start docker
マスターノードでの作業の時と同様に、dockerサービスの状態の確認。
systemctl status docker
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
マスターノードでの作業の時と同様に、kubeadmをインストール。
dnf install kubeadm -y
マスターノードでの作業の時と同様に、kubeadm がインストールされたら、kubelet という、Kubernetes Clusterのコンポーネント群にアクセスするためのサービスを有効化し、kubeletサービスの起動。
systemctl enable kubelet
systemctl start kubelet
でマスターノードでの作業の時と同様に、ドキュメント に記載は無いんだけど、
swapoff -a
⇧ 「swapの無効化」しないとエラー出るので。
で、マスターノードの作業の時にテキストエディタなどにコピペしておいたコマンドを実行します。
24時間経過すると、コマンドに記載のtokenなどが無効化されるらしく、
⇧ 上記サイト様が、tokenなどの再生成について、まとめてくださってます。
kubeadm join 10.0.2.15:6443 --token 6lprcx.r9s3msk7p4vabzw7 \ --discovery-token-ca-cert-hash sha256:e60e567a45c013dff7567c580407e49ebeec69053aa285d7630b43211a6351c9
⇧ 間違えて、worker-node-1 の中で、kubectlコマンド使ってしまった...
master-nodeの仮想マシンのほうで、kubectl コマンドでnodeを確認すると、worker-node-1のnodeもKubernetes Clusterに追加されてます。
同様に、worker-node-2 についても、worker-node-1 でやったのと同じことを行います。
worker-node-2 用の仮想マシンにログイン。
スーパーユーザー(「rootユーザー」)に切り替え。
ホスト名の設定。hostsファイルの編集。
firewalld のサービスを有効化、起動。
Selinuxの無効化、リロード(再起動)時も無効化を維持する。
ポートの開放。(worker-node-1 の時と同様のポートを開放しましたが、正直よく分かりません。)
br_netfilterモジュールを読み込む。
仮想化ブリッジのフィルタリングを有効化。
Docker-CEをインストールするためのリポジトリを追加。
Docker-CEをダウンロード。
Docker-CEをインストール。
Docker-CEのサービスを有効化、起動。
キャプチャ画像が載せれてないけれども、マスターノードでの作業の時と同様に、Kubernetesをインストールするためのリポジトリを追加する。
今回は、CentOS 8なので、リポジトリの設定は、「CentOS, RHEL or Fedora」のものを使用。
Kubeadmをインストール。
kubeketのサービスを有効化、起動。
OSのswapを無効化。
マスターノードで生成したKubernetes Clusterに、worker-node-2 を参加させます。
マスターノードの仮想マシンで、ノードを確認。
⇧ Kuberenetes Clusterにすべてのノードが参加できました。
やっぱり、ドキュメントが整備されていないと、辛いですね...
構築した環境が上手く機能するのかも分かりませんが、ドキュメントだけの情報では構築ですらスムーズにできないんですから、Kuberenetes が本番環境で嫌煙されるのも納得な気がしました。
Cloud Native Computing Foundation(CNCF)がKubernetesを管理してると仮定するけれど、ドキュメントの管理をもうちょっと頑張って欲しいかな...
まぁ、オープンソースソフトウェアに、そこまで求めてはいけないと言われればそれまでですが...
何はともあれ、Kubernetes環境ができたので、次回は、オンプレミス環境でサーバレスな環境が構築できるらしい、CloudState をようやく試すことができそうです。(CloudState自体については、半年以上前には、その存在を把握してたんだけどね...)
2020年5月3日(日)追記:↓ ここから
仮想マシンを停止・再起動すると、Kubernetes Clusterも停止するみたいね。
通常は、仮想マシンが停止することはあってはならないってことなので、仮想マシンが停止するってことを想定しないってことなのかもしらんけど、「Kubernetes Cluster」の再起動が上手くいかないという...
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 を再起動でイケるみたいのはずが、
⇧ worker-nodeの2つ目のマシンのkubeletのサービスも落ちてる。
ログインして、
master-nodeの仮想マシンのほうで確認。
⇧ 悪化しとるやないか~い!
ん~、毎回思うけど、ログがクソ役に立たんのよね...もうちょいまともなログメッセージにしてくれんかな...
う~ん、何か、
kubeadmでK8s環境を作っていて気付いたのですが、最近採用されているCoreDNSはホストの/etc/hostsを使ってくれません。すると何が困るかというと、例えばmetrics-serverのようにノードのメトリクスを取得するPodはノード名に対して接続をしようとするので、ノード名がDNSにないと名前解決ができません。
KubernetesのCoreDNSはホストの/etc/hostsを使ってくれないのでConfigMapにレコードを追加する - Qiita
⇧ CoreDNSっていうやつが原因って気がする。
とりあえず、調べてみますか。
2020年5月3日(日)追記:↑ ここまで
2020年5月4日(月)追記:↓ ここから
駄目でした...
何か、KubernetesのAPI 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>
どうやら、
⇧ 「/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
いや~、分からん...
何か、
マスタノード上で以下のコマンドを実行すると、Weave NetのAPIを叩いて状態を確認できる。
⇧ 上記サイト様を参考に確認してみる。
⇧ ってなってて、
- ‘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の初期化からやり直しました...
⇧ 上記サイト様を参考に、「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>
それにしても、仮想マシンを再起動する度に、Kubeadmの初期化をするしか方法が無いってことなのかな?
...Kubernetesって一体...
2020年5月4日(月)追記:↑ ここまで
今回はこのへんで。
NG集
kubeadm init をオプション付けずに間違って実行して、
⇧ ネットワークがNATのIPアドレスが指定されてしまってるとね...
っていうかオプションあるなんて知らんし...
やり直すはめになったんだが、
⇧ 公式の通りやってみたところ、
⇧ なんか、残骸が残るらしい...
リカバリー方法をもうちょっと考えて欲しいもんですが...
とりあえず、指示にある通り、「$HOME/.kube/config」を削除しました。
あと、「etc/cni/net.d」ってフォルダも削除しました。
iptablesとかの設定も残ってしまうようなんですかね...
まっさらな状態に戻せないのが辛いな...