はじめに
この手順では、UPI(User Provisioned Infrastructure)
を使って OCP(OpenShift Container Platform)
の環境を構築していきます。省略系のOCP
だとわかりにくいので、ここではOpenShift
と呼ぶ事にします。
OpenShiftとは
OpenShift
とは、Red Hat
が提供する商用版の Kubernetes
です。
オープンソースのKubernetes
に、運用に必要な独自機能を追加したり、オープンソースの運用管理ツールや、開発ツールをバンドルした製品です。もちろんサポートが付いているのも大きな違いです。
例えば、監視用のOSSであるPrometheus
や、ログ収集用のEFK
(ElasticSearch
/Fluented
/Kafka
)等の他に、CI/CD
ツールであるJenkis
、Tekton
もバンドルされています。
また、Red Hat
の Middleware群もOpenShift
上での使用に限り、提供されており、とりあえず OpenShift
を持っていればコンテナ環境を構築・運用するためのツール類が一通り揃っている。という形になっています。
UPIインストール
UPI(User Provisioned Infrastructure)
インストールとは、ユーザーが自分で OpenShift
の環境構築に必要な、OSをインストールしたノードや、DNS
の設定、ロードバランサーなどの環境をまず整え、その上にソフトウェアとしてのOpenShift
(Kubernetes
と、運用に必要な各種ツール)をインストールする方法です。
IPI環境へのインストール
UPI
の対義語としてIPI(Installer Provisioned Infrastructure)
という言葉があります。こちらは、AWS
、Azure
、GCP
のような Public Cloud Providerが持っているインフラ構築用の APIを使用して UPI
で手作業で行っていた、ノードの作成、ロードバランサーの設定、DNS
の設定等をOpenShift
のインストーラーが自動で行う方法です。
正確を期すと、Public Cloud Provider
のアカウントを準備しておく事と、OpenShift
で使用するドメインの取得と取得したドメインを、そのPublic Cloud Provider
のDNS
サービスに登録しておく事は事前にする必要があります。
IPI
は、インストーラーを実行すると指定した数のノード
をデプロイし、DNSサーバー
も自動で構成されるなど非常に楽なので、私もテストなどではこの方法を使用しています。
が、構成に細かなカスタマイズが必要な場合や、OpenShift
のインストーラーがIPI
に対応してない環境(例えばオンプレミス)に環境を作成したい場合は、UPI
によるOpenShift
のインストールが必要になります。
IPI
インストールができる環境は、DNSサーバー
やLoad Balancer
や、ネットワークの構成をインストーラーからAPIを使用して構築・構成する必要があります。そのためIPIがサポートしている環境はAWS
やAzure
、GCP
等の環境に限られています。が、後述しますがIPI
の意味する所は最近、少し広がってきたようで、Baremetal IPI
という言葉も出てきました。
IPI環境、UPI環境へのインストール
物理環境では厳密な意味での完全なIPI
インストールというのはあり得ません。例えば物理環境では、少なくてもルーターやサーバーを設置してケーブルを配線するという環境準備が必要です。
しかし、OpenShift 4.6
では、ネットワークの環境が整っていれば、OpenStack
のIronic
等で利用されているBare Metal Provisioning
の技術を利用する事でインストーラーからノード
のOS
のデプロイを実行できるようになりました。これもBare Metal IPI
と呼ぶようになりました。ただこの場合も、DNSやルーティングなどは、事前に手動でセットアップする必要があるので、Public Cloud Provider
上のIPI
とはできる範囲が違います。
参考:Deploying Installer Provisioned Infrastructure (IPI) of OpenShift on Bare Metal - 4.6
この手順で実行する内容
この手順では、物理環境であればどこにでも適用できるインストール方法であるBaremetal
環境への UPI(User Provisioned Infrastructure)
インストールをOpenShift 4.5
を使用して実行してみます。
UPI(User Provisioned Infrastructure)
ですので、自分で、OpenShiftt
を稼働させるためのDNS
サーバー、Load Balancer
、Kubernetes
のMasterノード
、Workerノード
等のインストールなどの周辺環境をProvision
してあげる必要があります。
BareMetal
と書いていますが、仮想マシンを物理マシンと同等とみなせる仮想化環境でも手順は同じです。
※VMware
環境の場合は、OpenShift
4.5から、VMWare vSphere IPI
インストールという方式が出てきました。機会があれば別記事で触れたいと思います。
1.環境のセットアップ
1.1.環境を設計する
この手順では上記のような構成を構築しています。
手元の実験環境を作るものというよりは、本番環境で最低限必要なコンポーネントを何かを考えて、冗長化が必要なコンポーネントは分割しています。
この手順の制限
DNS(BIND)
、LoadBalancer(HA Proxy)
は、本番環境であれば冗長化するべき所ですが、手順が冗長になってしまい複雑になってしまうため、この手順の中では、触れていません。
また ID管理のコンポーネントであるIdM
は、OpenShift
の動作確認後、後から追加構築できる部分でもあるので、時間的都合もありこの手順書では触れていません(後から追加できれば追加します)。
この構成のメリット・デメリット
この構成のメリットは、実際のフルの運用環境と比べると比較的構成が小さい事です。
一方で、OCPクラスタの中に監視やログ収集のコンポーネントやストレージまでが含まれています。そのため、頻繁に発生するKuberentes
のアップデート時において、監視やログ収集がまともに機能しません。
OpenShift
は、クリック一つで全体をバージョンアップできるOTA(Over The Air)
アップデートができますが、監視システムもまとめてアップデートされるためアップデート中にいろいろなWarning
やエラーが上がっても、状況がつかめませんでした。
もともと物理サーバーの時代より監視サーバーは、監視対象と同じプラットフォームに同居させてはいけないというのは先人の知恵から言われていた事ですが、実際には仮想化が普及しはじめてから、同じ仮想化プラットフォーム上に監視サーバーが載っている例も多かったと思います。
これはvMontion
やLive Migration
と言ったハイパーバイザー
のアップデート時にコンポーネントを待避させる仕組みや、監視サーバーの分離度が仮想マシンという形で他と大きく分離しているという観点で、現実的に監視が停止する確率がそれほど高くなかったためだと思います。
一方で現状、3ヶ月に一回アップデートが走るKubernetes
の世界では、監視は監視対象が乗るプラットフォームと分割するという原則は本番環境では特に守った方が良いと思いました。
が、いずれにしてもこの手順では、リソースの都合で、そこまでの環境を整備する事までは行っておらず、OpenShift
とOpenShift
に含まれているOSS
製品の構築方法、分散ストレージであるOCS(OpenShift Container Storage)
の構築の作業手順やその雰囲気を届ける事を目的としたいと思います。
1.1.1.Infraノード
OpenShift
では、ログ収集用の ElasticSearch
や、コンテナを保管するためのContainer Registry
、監視用の Prometheus
さらに OpenShift
のIngress
実装であるRouter
と呼ばれるKubernetes
を管理するための運用コンポーネントがあります。
こう言った運用コンポーネントは、ユーザーのアプリケーションに影響を与えないようにInfraノード
に分離する事にします。
つまり以下のようなイメージです。
Infraノード
は、こういった運用コンポーネントのみを配置する Workerノード
を区別するためのOpenShift
独自の呼び方ですが、技術的にはWorkerノード
と同じものです。
ちなみに、Kubernetes
では、Master
のみが正式に定義されているノード
のRole
でWorkerノード
という言葉はしばしば用いられますが、正式なRole
としては定義されていません。(Kubernetes
のWorkerノード
のkubectl get node
の Role
欄は <none>
と表示されます)
OpenShift 4.x
では、Master
とWorker
がインストール時にノード
のRole
として事前に定義されており、さらにこの手順では追加でInfra
というRole
を定義します。
1.1.2. PV 用の Storage の選択
ユーザーアプリケーションだけでなく、Elasticsearch
や、Container Registry
を構成するには、PV(Persistent Volume)
を必要とします。Prometheus
については、PV
がなくてもインストールは可能(OpenShift
をインストールすると自動で一緒にインストールされています)ですが、実際の運用を考えた場合、永続データ保管のためのPV
は必要だと思います。
ストレージの選択は、ユーザー環境によって様々だと思います。
この手順では、分散ストレージであるOCS(OpenShift Container Storage)
を使用する事にします。
ストレージ部分は、アーキテクチャーとしては疎結合なので、OCS
の構築以外の部分の手順については、他のストレージを使用した場合もほぼ共通になります。
この手順で目指す最終構成は上記なようなものになります。OCS
用のノード
は3本用意する事にします。
1.1.3. ネットワークの設計
ここでは4つのネットワークを定義しています。
-
Intra Network(社内ネットワーク)
: 192.168.124.0/24 -
Inter-Node Network(ノード間)ネットワーク
:172.16.0.0/24 -
Cluster Network
:10.128.0.0/14 -
Service Network
:172.30.0.0/16
1)は社内のネットワークの想定です。
2)は Kubernetes
のノード間を結ぶためのネットワーク + 外部からのリクエストを受け付ける LBもこのネットワークに所属させました。ネットワーク構成の取り方はいろいろな構成がありうるのですが、ここでは「外向け」ロードバランサーと「内向け」ロードバランサーを一体化して構成サーバーを減らす事に重点を置いて、このような構成を取りました。
3)と4)は OpenShift
の内部で使用されている、仮想ネットワークです。3)と4)に関しては、Red Hat社が提供するマニュアルのサンプルで用いられているレンジをそのまま使用しています。マニュアルとの比較のしやすさも考えると、他と衝突していない限りこのまま使用するのをお勧めします。
1.1.4.Firewallの設計
この環境では、Inter-Node Network
と名付けたネットワークに全ての関連コンポーネントをつなぐ事にしたので、OpenShift
関連の通信にFirewall
が挟まるような構成になっておらず、特にコンポーネント間のFirewall
に関する実験はしていません。
一方で、OpenShift
のコンポーネント間の通信で使用するポートについては以下に詳細があります。
1.1.5.IPアドレスのレンジについて
前述の 1)~4)は、どれもプライベートアドレスであるはずなので、グローバルIPと被っていると予期せぬ動作を引き起こす可能性があります。
プライベートIPアドレスとして使用できる範囲はRFC 1918で規定されているので、以下から取得されていて、社内の他のネットワークとも1)~4)で使用するレンジが被ってない事を確認します。
クラスA: 10.0.0.0
~10.255.255.255/8
クラスB: 172.16.0.0
~172.31.255.255/12
クラスC: 192.168.0.0
~192.168.255.255/16
参考 :プライベートネットワーク
1.1.6. ルーティングテーブルの設定
この手順では、クラスターのノード間ネットワーク
(Kubernetes
の各ノード間をつなぐネットワークをそう名付けます)は、プライベートアドレスレンジである172.16.0.0/24
としています。
172.16.0.0/24
から、インターネットにアクセスできる必要がありますが、プライベートのアドレスであるため、そのままでは、このネットワークからパケットが外に出る事はできても、社内ネットワークまでは戻ってくる事ができますが、その後の帰り道がわかりません。
そのため、社内ネットワークに戻ってきた際に、172.16.0.0/24
のネットワークへのルーティングを教えてあげる必要があります。
ここでは、社内と社外をつなぐ FW Router
で以下のコマンドを実行して、ルーティングを追加しています。
route add -net 172.16.0.0 netmask 255.255.255.0 gw 192.168.124.254 eno1.342
1.1.7.ノードのサイジング
ここでは以下のような CPU
/Memory
/Disk
サイズのノードを使用しました。あくまでこのくらいのスペックがあれば、インストール、OpenShift の基本操作に問題がないように見える。というレベルなので、使用状況によって必要なスペックが違う事については留意して下さい。
1.1.7.1.OpenShift 関連ノードのサイジング
サーバー | vCPU(HT-on) | Memory | Disk | OS | ホスト名 | IP Address | note |
---|---|---|---|---|---|---|---|
BootStrapノード | 4vCPU | 16GByte | 120G | CoreOS | bs.ocp45.example.localdomain | 172.16.0.11 | 一時的 |
Masterノード | 4vCPU | 16GByte | 120G | CoreOS | m1.ocp45.example.localdomain | 172.16.0.21 | |
4vCPU | 16GByte | 120G | CoreOS | m2.ocp45.example.localdomain | 172.16.0.22 | ||
4vCPU | 16GByte | 120G | CoreOS | m3.ocp45.example.localdomain | 172.16.0.23 | ||
Workerノード | 2vCPU | 8GByte | 120G | CoreOS | w1.ocp45.example.localdomain | 172.16.0.31 | |
2vCPU | 8GByte | 120G | CoreOS | w2.ocp45.example.localdomain | 172.16.0.32 | ||
2vCPU | 8GByte | 120G | CoreOS | w3.ocp45.example.localdomain | 172.16.0.33 | ||
Infraノード | 4VCPU | 32GByte | 120G | CoreOS | i1.ocp45.example.localdomain | 172.16.0.41 | |
4VCPU | 32GByte | 120G | CoreOS | i2.ocp45.example.localdomain | 172.16.0.42 | ||
4VCPU | 32GByte | 120G | CoreOS | i3.ocp45.example.localdomain | 172.16.0.43 |
※各ノード
のスペックは、OpenShift 4.5 のマニュアルを基準にしています。Minimum resource requirements
BootStrapノード
BootStrapノード
は、Masterノード
をセットアップするために必要なサーバーで、Masterノード
のセットアップが完了した後は必要の無い、一時的なノードです。
BootStrapノード
とMasterノード
は、CoreOS
が必須です。Workerノード
とInfraノード
は、RHEL
もしくはCoreOS
が選択できるのですが、この手順ではせっかくなのでコンテナ専用のOSであるCoreOS
を使用します。
Masterノード
Masterノード
は、3ノード必要です。
Workerノード
Workerノード
は、ユーザーのアプリケーション・コンテナが載るノード
です。最低2ノード
からですが、この手順では3ノード
作ります。
OpenShift
としての最小構成ではMasterノード
とWorkerノード
を統合して合計で3ノード
にする方法もありますが、この手法はEdge
ロケーションでHWリソースが潤沢に取れない場合などのユースケースが想定されているため、この手順では採用しませんでした。
Infraノード
Infraノード
と言う言葉は、OpenShift
独自の呼び方で、実体はWorkerノード
です。Kubernetes
の運用管理コンポーネントを、ユーザーアプリと分離したノード
導入するために用意するノード
です。
Infraノード
には、Elastic Search
や、Kibana
、Prometheus
等のコンポーネントが導入されます。これらのコンポーネントは大量にリソースを消費しやすいため、ユーザーアプリが使用するノード
とは分けて導入する事がベストプラクティスです。
1.1.7.2.周辺インフラ・サーバーのサイジング
サーバー | vCPU(HT-on) | Memory | Disk | OS | ホスト名 | IP Address | note |
---|---|---|---|---|---|---|---|
踏み台(bastion) | 2vCPU | 4GByte | 60G | RHEL 8.2 | bastion.example.localdomain | 172.16.0.101 | |
DNS / DHCP | 2vCPU | 4GByte | 60G | RHEL 8.2 | ns1.example.localdomain | 172.16.0.102 | |
2vCPU | 4GByte | 60G | RHEL 8.2 | ns2.example.localdomain | 172.16.0.103 | 冗長用 | |
LoadBalancer | 2vCPU | 4GByte | 60G | RHEL 8.2 | lb1.example.localdomain | 172.16.0.110/111 | |
2vCPU | 4GByte | 60G | RHEL 8.2 | lb2.example.localdomain | 172.16.0.120/121 | 冗長用 |
Kubernetes
には含まれていませんが、Kubernetes
を動かすために必要なサーバー群です。
踏み台(bastion)
OpenShift
インストール時に作業の起点となるサーバーです。kubectl
、oc
コマンドなどの実行場所です。
この例では、ノード
に対するインストール・イメージなどの配布用にTFTPサーバー
や、HTTPサーバー(nginx)
も導入します。
可用性は必要無いので、冗長化は行っていません。
Load Balancer
この例では、ノード
間の負荷分散装置のめに、Load Balancer
として、HA Proxy
を使用しています。
クラスター内部のノード
間通信の負荷分散用と、クラスター外部から来るアクセスの負荷分散の2種類のLoad Balancer
が必要になります。
ここでは、内部
用の Load Balancer
と外部
用の Load Balancer
で一つのサーバーに別々のIPをアサインする設計にしています。
設計として冗長構成にするために、2本のLoad Balancer
を用意していますが、構築手順としてはこの手順の中では触れていません。
DNS/DHCP
この手順ではInter-Node
ネットワークに所属するサーバーの名前解決のためのDNSサーバー
としてBIND
を使用しています。
DHCPサーバー
は、Masterノード
、Workerノード
、Infraノード
に対して、DNSサーバー
や、gateway
のIPアドレスを教えるため等に使われます。
DHCPサーバー
は使用しますが、UPI
インストールでは、これらのノード
間の負荷分散を行うために、各ノード
のIPアドレス
、もしくは名前を事前にLoad Balancer
に登録して置く必要があります。
そのため、DHCP
で自由にIPアドレス
を割り当てるのではなく、各ノード
の MACアドレス
を使用して、固定IPアドレスを割り振っています。
設計として冗長構成にするために、2本のDNS/HDCPサーバー
を用意していますが、構築手順としてはこの手順の中では触れていません。
またDHCPサーバー
は、ノード
のセットアップ時にのみ使用されるため、大半の要件であれば、冗長化の必要は無いでしょう。
1.1.7.3. OpenShiftのDNS要件
以下の6つのドメイン名がOpenShift
ととして必要になります。
ドメイン名 | この手順の名前 | 用途 |
---|---|---|
api.<cluster_name>.<base_domain>. | api.ocp45.example.localdomain. | Kubernetes API |
api-int.<cluster_name>.<base_domain>. | api-int.ocp45.example.localdomain. | Kubernetes API |
*.app.<cluster_name>.<base_domain>. | *.ocp45.example.localdomain. | Routes |
この手順書では、
<cluster_name> = ocp45
<base_domain>= example.localdomain
としました。これらの値は、後でDNS
に登録していきます。
また、この値は、インストール用の yaml
のマニフェストファイルを作成する時にもう一度使うので覚えておきます。
ここまでで、環境の基本設計は出そろったので、図にまとめると以下のようになります(再掲)。
薄い灰色になっているHA Proxy
とDNS BIND
の冗長化構成の部分は、この手順では取り扱っていません。
1.2.必要なドメインをセットアップする
1.2.1 BIND サーバーをセットアップする
以下の手順を参考にして BIND
サーバーをセットアップします。
RHEL8 上に BIND を構築する - Qiita
1.2.2.DNSサーバーの構成ファイルのカスタマイズ
/etc/named.conf
、/etc/named/named.example.localdomain.zone
、/etc/named/0.16.172.in-addr.arpa.zone
を作成します。
IP逆引きの設定も必要です。
BIND設定ファイル(named.conf)
<前半は特に変更していないので省略>
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
<順引き用の設定ファイルを参照>
zone "example.localdomain" {
type master;
file "/etc/named/named.example.localdomain.zone";
};
<逆引き用の設定ファイルを参照>
zone "0.16.172.in-addr.arpa" in {
type master;
file "/etc/named/0.16.172.in-addr.arpa.zone";
};
順引き用の設定ファイル
$ORIGIN example.localdomain.
$TTL 3600
@ IN SOA ns1.example.localdomain. root.example.localdomain.(
2000091802 ; Serial
3600 ; Refresh
900 ; Retry
3600000 ; Expire
3600 ) ; Minimum
IN NS ns1.example.localdomain.
bs.ocp45.example.localdomain. IN A 172.16.0.11
m1.ocp45.example.localdomain. IN A 172.16.0.21
m2.ocp45.example.localdomain. IN A 172.16.0.22
m3.ocp45.example.localdomain. IN A 172.16.0.23
w1.ocp45.example.localdomain. IN A 172.16.0.31
w2.ocp45.example.localdomain. IN A 172.16.0.32
w3.ocp45.example.localdomain. IN A 172.16.0.33
api-int.ocp45.example.localdomain. IN A 172.16.0.110
api.ocp45.example.localdomain. IN A 172.16.0.111
*.apps.ocp45.example.localdomain. IN A 172.16.0.111
逆引き用の設定ファイル
$TTL 3600
@ IN SOA ns1.example.local. root.example.local.(
2000091803 ; Serial
3600 ; Refresh
900 ; Retry
3600000 ; Expire
3600 ) ; Minimum
IN NS ns1.example.local.
;
11 IN PTR bs.ocp45.example.localdomain.
21 IN PTR m1.ocp45.example.localdomain.
22 IN PTR m2.ocp45.example.localdomain.
23 IN PTR m3.ocp45.example.localdomain.
31 IN PTR w1.ocp45.example.localdomain.
32 IN PTR w2.ocp45.example.localdomain.
33 IN PTR w3.ocp45.example.localdomain.
設定ファイルを作成したら、リロードして有効化させます。
named-checkconf -z /etc/named.conf # named.conf の書式確認 (書いた設定ファイルにエラーが無いか確認するコマンド)
systemctl reload named # 設定のリロード
1.3.Load Balancerをセットアップする
この手順では、Load Balancer
として HA Proxy
を使用します。
1.3.1.HA Proxyをセットアップする
以下の手順を参考にして HA Proxy
をセットアップします。
RHEL 8 HA Proxy の設定方法
1.3.2.構成ファイルを編集する
一般的なセットアップが完了したら、構成ファイルを以下のように書き替えます。
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# localdomain2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
# mode http
mode tcp
log global
# option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
# 以下はコメントアウト
# frontend main
# bind *:5000
# acl url_static path_beg -i /static /images /javascript /stylesheets
# acl url_static path_end -i .jpg .gif .png .css .js
# use_backend static if url_static
# default_backend app
frontend kubeapi
default_backend kube_api
mode tcp
bind *:6443
frontend machineconfig
default_backend machine_config
mode tcp
bind *:22623
frontend workerhttp
default_backend worker_http
mode tcp
bind *:80
frontend workerhttps
default_backend worker_https
mode tcp
bind *:443
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
# backend static
# balance roundrobin
# server static 127.0.0.1:4331 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
# 以下はコメントアウト (SELinux に怒られる)
# backend app
# balance roundrobin
# server app1 127.0.0.1:5001 check
# server app2 127.0.0.1:5002 check
# server app3 127.0.0.1:5003 check
# server app4 127.0.0.1:5004 check
# internal domains is ocp45.example.localdomain
backend kube_api
mode tcp
balance roundrobin
option ssl-hello-chk
server bs bs.ocp45.example.localdomain:6443 check
server m1 m1.ocp45.example.localdomain:6443 check
server m2 m2.ocp45.example.localdomain:6443 check
server m3 m3.ocp45.example.localdomain:6443 check
backend machine_config
mode tcp
balance roundrobin
server bs bs.ocp45.example.localdomain:22623 check
server m1 m1.ocp45.example.localdomain:22623 check
server m2 m2.ocp45.example.localdomain:22623 check
server m3 m3.ocp45.example.localdomain:22623 check
backend worker_http
mode tcp
balance source
server w1 w1.ocp45.example.localdomain:80 check
server w2 w2.ocp45.example.localdomain:80 check
server w3 w3.ocp45.example.localdomain:80 check
backend worker_https
mode tcp
balance source
server w1 w1.ocp45.example.localdomain:443 check
server w2 w2.ocp45.example.localdomain:443 check
server w3 w3.ocp45.example.localdomain:443 check
balance
をroundrobin
とsource
で分けていますが、はっきりとした意図はありません。使用しながらチューニングする必要があるかどうか見ていこうと思っています。
ここで行った設定を図に起こすと以下のようになります。
図中のclient
は、OpenShift
クラスター内部のノード
の場合もありますし、クラスター外部からのアクセスである場合もあります。
また、あくまでこれは初期構成で、インストールが進むにつれて構成を変更していきます。例えば、boostrap Node は、途中で要らなくなるので取り外します。
1.3.3.firewalld の設定
http(80)
/https(443)
/api-server(6443)
を通すように設定します。これらはデフォルトで「サービス」として事前定義されています。
この環境でNIC
は、public
ゾーンに所属しているので、pbulic
ゾーンに穴開けを行います。
firewall-cmd --add-service=https --zone=public --permanent
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --add-service=kube-apiserver --zone=public --permanent
22623 tcp
も開ける必用がありますが、これについては事前定義されていないため新規に定義します。
ここでは、「machine-config
」という22623 /tcp
を使う新しいサービスを作成してみます。
新しいサービス名の追加します。
firewall-cmd --permanent --new-service machine-config
「サービス」「machine-config
」の説明を追加します。
firewall-cmd --permanent --service=machine-config --set-description="OpenShift machine config access"
新しい「サービス」「machine-config
」のポート定義を追加します。
firewall-cmd --service=machine-config --add-port=22623/tcp --permanent
作成された新しい「サービス」のファイルを読み込みます。
firewall-cmd --reload
作成した「サービス」を firewalld
を透過させる「サービス」として、ここではpublic
ゾーンに追加します。
firewall-cmd --add-service=machine-config --zone=public
1.3.4.SELinuxの設定
デフォルトでは、Kubernetes
のAPIアクセスに使用するポートへの haproxy
のアクセスが許可されていません。そのため、systemctl
でHA Proxy
を起動しようとすると以下のようなエラーがでるはずです。
$ systemctl restart haproxy.service
Job for haproxy.service failed because the control process exited with error code.
See "systemctl status haproxy.service" and "journalctl -xe" for details.
$
以下のコマンドを実行する事で、行うべき SELinux
の設定を提案してくれます。ここでは、my-haproxy
というファイル名に設定内容の提案を出力します。
$ ausearch -c 'haproxy' --raw | audit2allow -M my-haproxy
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i my-haproxy.pp
$ ls -ltr
-rw-r--r--. 1 root root 308 Oct 8 11:12 my-haproxy.te
-rw-r--r--. 1 root root 969 Oct 8 11:12 my-haproxy.pp
$
引き続き、次のコマンドを実行る事で、提案された SELinux
の設定が適用されます。
semodule -i my-haproxy.pp
これで HA Proxy
が起動するようになっているはずです。
1.4.踏み台サーバーをセットアップする
OpenShift
クラスターのインストール作業をするための踏み台サーバー
を作成します。
特に構成に決まりは無いのですが、この例では、この踏み台サーバー
には、OpenShift
クラスターのセットアップ時だけ動いていれば良いコンポーネントをインストールします。
例えば、インストールプログラムはもちろん、導入イメージや、導入イメージ配布用の HTTPサーバー
、TFTPサーバー
などをインストールします。インストールプログラムを実行する起点ともなります。導入イメージとは言っても、ここで配置する以外にもインターネット上のContainer Registry
にも導入コンテナのイメージを取得しに行くので、インターネットアクセスは必要になります。
踏み台サーバー
は、インストール時しか使用しないため、ノートPC等でも代用もできますが、セットアップ後もノードの追加などにも使用するサーバーとなるので、実際の運用では恒久的に必要なサーバーになると思います。
OpenShift
のノードに直接SSH
してアクセスできるサーバーにもなりますので、セキュリティ的にもしっかりとした対処が必要です。
インストール時だけでなく、運用時にも作業起点のサーバーになるのが、この踏み台サーバー
です。
SSH Key の作成
踏み台サーバー上で、SSH Key
のペアを作成します。
Privateキー
は、踏み台サーバーに保管され、Publicキー
は後でインストールプログラムに渡す事で、各ノード
にインストールされます。
どのディレクトリで作業しても良いのですが、手順のわかりやすさを考慮して
/root/openshift
ディレクトリを作成して、そこで作業する事にします。
$ mkdir /root/openshift # 作業ディレクトリを作成
$ cd /root/openshift # 作業ディレクトリに移動
ssh
のkeyペア
を作成します。
ここで作成された公開鍵は、後で、BootStrapノード
、Masterノード
、Workerノード
のCoreOS
インストール時に、CorOS
側に登録されます。
[root@bastion openshift]# ssh-keygen -t rsa -b 4096 -N ''
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): # 鍵はデフォルトでは root の Homeディレクトリの .ssh 配下に作成される
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:hjrslmiGF7Et3Eua44VH9yEZPitlPQK0vp1ik9qIB4E root@bastion
The key's randomart image is:
+---[RSA 4096]----+
| . |
| . . |
|. o . |
|E .. o = |
| o =o @ S |
|. =++O O o |
| o.B&o+ . |
|..XO+= |
|.*+oo |
+----[SHA256]-----+
[root@bastion openshift]#
鍵は root
のHome
ディレクトリの.ssh
配下に生成されています。
/root/.ssh/id_rsa # 秘密鍵
/root/.ssh/id_rsa.pub # 公開鍵
作成したkeyペア
は、後でインストールするCoreOS
ノードにログインできる鍵になります。
2. iPXE 環境の作成
iPXE
というネットワークブートの方法を使用して、Bootstrap
/ Master
/ Worker
ノードの RHEL CoreOS
をインストールしていきます。
(この手順は、ネットワーク経由CoreOS
をインストールする方法です。ISOイメージ
による CoreOS
インストールを選択した場合は、この手順は必要ありません)
当初はISOイメージ
によるインストールを行おうとしていたのですが、リモートワークの環境では何故かブート時のコンソールが上手く操作できない。と言う環境上の問題に出くわして、iPXE
での環境構築を行う事になりました。構築はそれなりに手間なので、本番環境で幾つもクラスターを継続的に作成していく需要がなければおすすめしません。
当初は想定していなかったのですが、この後、環境を破壊して、全てのノード
を作り直さなければいけなくなる事が何度もありました。その時に、iPXE
によるネットワークインストールにより、かなり時間を節約する事ができました。
実運用を考えるとiPXE
等によるネットワークブートでOSをインストールする環境を作成しておく事をおすすめします。
##2.1.必要なサーバーのインストール
以下を参考にして環境を構築します。
リンク先の汎用的な iPXE
環境のサーバー構成は、この手順で想定しているサーバー構成と同じです。
##2.2.DHCPサーバーを使った固定IPアドレスの割り振り
汎用的な手順でiPXE
環境を構築した後、OpenShift
クラスターをインストールするためのカスタマイズを施します。
UPI
インストールでは、事前にロードバランサーに BootStratp
/ Master
/ Workerノード
を登録しておく必要があるため、それぞれの固定のIPが必要になります。
/etc/dhcp/dhcpd.conf
を編集して、ノードの MACアドレス
を基準して固定IPを割り振る設定をします。
どの部分を追加したかは設定ファイルの中にコメントで区切っています。
<省略>
# PXE Boot - start
class "pxeclients" {
match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
next-server 172.16.0.101; # TFTP Server address
if option arch = 00:07 { # x86-64
# Chain loading.
# 1st time, tell iPXE image place as boot file on TFTP server.
# 2nd time, tell iPXE script place on HTTP server.
if exists user-class and option user-class = "iPXE" { # the 2nd time. Go to HTTP Server to get iPXE script
filename "http://172.16.0.101/pxeboot.ipxe";
} else { # the 1st time. Go to TFTP to get iPXE.
filename "efi/ipxe.efi";
# filename "undionly.kpxe";
}
} else {
# filename "pxelinux/pxelinux.0";
filename "pxelinux.cfg/default";
# filename "menu/boot.ipxe";
}
}
# PXE Boot - end
# ここから MACアドレスに対して固定 IPを割り振る設定
host bs{
hardware ethernet 00:50:56:96:11:c2;
fixed-address 172.16.0.11;
}
host m1{
hardware ethernet 00:50:56:96:37:c8;
fixed-address 172.16.0.21;
}
host m2{
hardware ethernet 00:50:56:96:ec:a7;
fixed-address 172.16.0.22;
}
host m3{
hardware ethernet 00:50:56:96:e5:2f;
fixed-address 172.16.0.23;
}
host w1{
hardware ethernet 00:50:56:96:6b:da;
fixed-address 172.16.0.31;
}
host w2{
hardware ethernet 00:50:56:96:c1:c5;
fixed-address 172.16.0.32;
}
host w3{
hardware ethernet 00:50:56:96:e3:f5;
fixed-address 172.16.0.33;
}
}
MACアドレス
は、実際にCoreOS
のインストール対象のサーバーのNIC
のMACアドレス
を確認し、実際の環境にあわせて書き替えて下さい。
2.3.CoreOSのインストールイメージを入手する
iPXE
ブートで使用するCoreOS
のファイルを手に入れます。
以下より
https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.5/
1)compressed metal RAW image
2)knernel
3)initramfs
をダウンロードします。
似たような名前のファイルが幾つかありますが、以下のフォーマットで名前が付いているものをダウンロードします。
Compressed metal RAW image: rhcos-<version>metal.<architecture>.raw.gz
kernel: rhcos-<version>-installer-kernel-<architecture>
initramfs: rhcos-<version>-installer-initramfs.<architecture>.img
ここでは、以下のファイルをダウンロードします。
rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
rhcos-4.5.6-x86_64-installer-kernel-x86_64
rhcos-4.5.6-x86_64-metal.x86_64.raw.gz
※ISO
ファイルであるrhcos-<version>-installer.<architecture>.iso
は、ISO
ブートで CoreOS
をインストールする時に使用します。この手順(iPXE
ブート)では使用しません。
2.2.1.ダウンロードしたファイルを HTTP サーバー(踏み台サーバー)にコピーする
これらのファイルも HTTP サーバー
(踏み台サーバー
に同じ) のディレクトリに配置します。ここでは nginx のルート(/usr/share/nginx/html
)ディレクトリに配置しています。
cp * /usr/share/nginx/html
2.2.2.ファイルのアクセスを確認する。
HTTP サーバー
上のファイルがアクセスできるか確認します。
以下のコマンドで HTTP 200 が返ってくれば OK です。
[root@bastion ~]# curl -D - -s -o /dev/null http://bastion.example.localdomain/rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
[root@bastion ~]# curl -D - -s -o /dev/null http://bastion.example.localdomain/rhcos-4.5.6-x86_64-installer-kernel-x86_64
[root@bastion ~]# curl -D - -s -o /dev/null http://bastion.example.localdomain/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz
bastion.example.localdomain
は、この環境でのHTTP サーバー
(=踏み台サーバー
)のホスト名です。
2.4.iPXEスクリプトの作成
iPXE
インストール時の作業を記したiPXE
スクリプトを作成します。内容はiPXE ブート環境をセットアップするのサンプルと同じものです。
/usr/share/nginx/html/pxeboot.ipxe
#!ipxe
# dhcp
# Some menu defaults
set menu-timeout 300000
isset ${menu-default} || set menu-default exit
:start
menu Please choose an type of node you want to install
item --gap -- -------------------------- node type -------------------------
item --key b bootstrap Install Bootstrap Node
item --key m master Install Master Node
item --key w worker Install Worker Node
item --gap -- -------------------------- Advanced Option --------------------
item --key c config Configure settings
item shell Drop to iPXE shell
item reboot Reboot Computer
choose --timeout ${menu-timeout} --default ${menu-default} selected || goto cancel
goto ${selected}
:bootstrap # ここはインストールしたい OS毎に異なる
kernel http://172.16.0.101/rhcos-4.5.6-x86_64-installer-kernel-x86_64 ip=dhcp rd.neednet=1 initrd=rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=sda coreos.inst.image_url=http://172.16.0.101/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://172.16.0.101/bootstrap.ign
initrd http://172.16.0.101/rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
boot
:master # ここはインストールしたい OS毎に異なる
kernel http://172.16.0.101/rhcos-4.5.6-x86_64-installer-kernel-x86_64 ip=dhcp rd.neednet=1 initrd=rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=sda coreos.inst.image_url=http://172.16.0.101/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://172.16.0.101/master.ign
initrd http://172.16.0.101/rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
boot
:worker # ここはインストールしたい OS毎に異なる
kernel http://172.16.0.101/rhcos-4.5.6-x86_64-installer-kernel-x86_64 ip=dhcp rd.neednet=1 initrd=rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=sda coreos.inst.image_url=http://172.16.0.101/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://172.16.0.101/worker.ign
initrd http://172.16.0.101/rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
boot
:exit
exit
:cancel
echo You cancelled the menu, dropping you to a shell
:shell
echo Type 'exit' to get the back to the menu
shell
set menu-timeout 0
goto start
:reboot
reboot
:exit
exit
最終的な上記のようなスクリプトを作成すれば良いのですが、各ラベル毎の解説をします。
2.4.1.BootStrap用の記述
:bootstrap
kernel http://172.16.0.101/rhcos-4.5.6-x86_64-installer-kernel-x86_64 ip=dhcp rd.neednet=1 initrd=rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=sda coreos.inst.image_url=http://172.16.0.101/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://172.16.0.101/bootstrap.ign
initrd http://172.16.0.101/rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
boot
この例で172.16.0.101
は、踏み台サーバー
(HTTPサーバー
/TFTPサーバー
が同居)のIPアドレス
です。
rhcos-4.5.6-x86_64-installer-kernel-x86_64
rhcos-4.5.6-x86_64-metal.x86_64.raw.gz
rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
は、/usr/share/nginx/html
(Nginxのルート) に配置されたCoreOS
関連のファイル名ですが、実際にダウンロードしてきたファイル名に合わせます。
bootstrap.ign
は、後の手順で作成し、/usr/share/nginx/html
に配置します。
※2020/10/06時点でOCP4.5のマニュアルに記載されている iPXE用のスクリプトのサンプルの記述に誤記があり、そのままでは動作しないのでご注意下さい。Bug 1741922 - [DOCS] Failed to open file error during iPXE install
2.4.2.Master用の記述
:master
kernel http://172.16.0.101/rhcos-4.5.6-x86_64-installer-kernel-x86_64 ip=dhcp rd.neednet=1 initrd=rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=sda coreos.inst.image_url=http://172.16.0.101/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://172.16.0.101/master.ign
initrd http://172.16.0.101/rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
boot
基本的に :boostratp
のラベル部分の記述と同じですが、Master 用の ignition ファイルmaster.ign
を参照している部分が違います。
master.ign
は、後の手順で作成し、/usr/share/nginx/html
に配置します。
2.4.3.Worker用の記述
:worker
kernel http://172.16.0.101/rhcos-4.5.6-x86_64-installer-kernel-x86_64 ip=dhcp rd.neednet=1 initrd=rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=sda coreos.inst.image_url=http://172.16.0.101/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz coreos.inst.ignition_url=http://172.16.0.101/worker.ign
initrd http://172.16.0.101/rhcos-4.5.6-x86_64-installer-initramfs.x86_64.img
boot
基本的に :boostratp
、:master
のラベル部分の記述と同じですが、Worker 用の ignition ファイルworker.ign
を参照している部分が違います。
worker.ign
は、後の手順で作成し、/usr/share/nginx/html
に配置します。
3.OpenShift の CLIコマンドとインストーラーを手に入れる
インストール・プログラムを配布しているcloud.redhat.comにアクセスします。(Red Hat のアカウントが必要です)
ここでは、ベアメタル(「Run on Bare Metal」のアイコン)を選びます。
①にリストされている以下のものを、踏み台サーバー
上にダウンロードします。合計で3つのファイルがあります。
- OpenShift installer (ここでは Linux を選択)
- Pull Secret
- Command line interface (ここでは Linux を選択)
以下もダウンロードできるようになっていますが、既にセクション「2.3.CoreOsのインストールイメージを入手する」でダウンロードしているので必要ありません。
- ISOイメージ / RAW イメージ
ファイルは、セクション「1.4.踏み台サーバーをセットアップする」で作成した /root/openshift
にダウンロードする事にします。
ダウロードしたものを解凍、必要無くなったtar.gz
を削除すると以下のように見えるはずです。
$pwd
/root/openshift/
$ ls -ltr
total 604284
-rwxr-xr-x. 2 root root 78595112 Jul 28 12:00 oc # OpenShift の CLI コマンド
-rwxr-xr-x. 2 root root 78595112 Jul 28 12:00 kubectl
-rwxr-xr-x. 1 root root 368259072 Jul 28 12:13 openshift-install # OpenShift のインストーラーコマンド
-rw-r--r--. 1 root root 706 Jul 28 12:13 README.md
-rw-r--r--. 1 root root 2723 Aug 16 00:54 pull-secret.txt
oc
コマンドと kubectl
コマンドがパス無しで実行できるように PATH
変数に展開場所を追加しておきます。
$ export=$PATH:/root/openshift/ # <ocコマンドとkubectlのファイルの場所>
$ oc version # PATHが通って oc コマンドが実行できる事を念のため確認
Client Version: 4.5.5
$
4.installに必要な設定ファイルを作成する
この作業は、踏み台サーバー
上での作業です。ステップが多いですが、作業の流れは以下のようになります。
最終的に生成されるignitionファイル
は、CoreOS
の構成用のファイルで、インストール時に使用されます。
4.1.installation configuration file (YAML) を作成する
セクション「1.4.踏み台サーバーをセットアップする」 で作成した踏み台サーバー
上の作業ディレクトリに移動します。
$ cd /root/openshift # 作業ディレクトリに移動
以下のような isntall-config.yaml
と言うファイルを作成します。
[root@bastion openshift]# vi install-config.yaml
# 以下のようなファイルを作成します。
apiVersion: v1
baseDomain: example.localdomain (1)
compute:
- hyperthreading: Enabled (2)(3)
name: worker
replicas: 0 (4)
controlPlane:
hyperthreading: Enabled (2)(3)
name: master
replicas: 3 (5)
metadata:
name: ocp45 (6)
networking:
clusterNetwork:
- cidr: 10.128.0.0/14 (7)
hostPrefix: 23 (8)
networkType: OpenShiftSDN
serviceNetwork:
- 172.30.0.0/16 (9)
machineNetwork:
- cidr: 172.16.0.0/24 (10)
platform:
none: {} (11)
fips: false (12)
pullSecret: '{"auths": ...}' (13)
sshKey: 'ssh-ed25519 AAAA...' (14)
(1) ベースとなるドメイン名です。
(2) compute
セクションの頭には-
が必要な事に注意してください。controlPlane
セクションには-
は要りません。現状ではどちらのセクションの一つmachine pool
しか定義できませんが、将来的に複数のcompute
のmachine pool
が指定できる可能性があるためこうなっています。
(3) Hyper Threading の設定です。サーバーのハードウェアが対応していれば、ONにしておきます。
(4) Worker ノードは、0 にしておきます。UPI (User Provisioned Infrastructure) の時は、この値は機能せず、後で Worker ノードを手動でデプロイする事になります。
(5) Masterノードの数です。3にします。
(6) 作成されるクラスターの名前です。(1)のベースドメイン名のサブドメイン名として使用されます。
(7) Pod のネットワークに使われる IPアドレスレンジです。クラスター内部のプライベートなネットワークです。公開されるネットワークでは無いので問題なければこの値をそのまま使います。(デフォルト値です)
(8) 個々の Node にアサインされるサブネットの Prefix です。23
の場合、個々のノードに一つの/23のサブネットが cidr
からアサインされます。2^(32-23)-2 = 510
のアドレスが Pod 用に使用できます。
(9) (7)と同じで Cluster内部のプライベートなネットワーク用のアドレスレンジです。公開されるネットワークでは無いので問題なければこの値をそのまま使います。(デフォルト値です)
(10) Master/Worker/Bootstrap Node 間のネットワークです
(11) bare metalでは指定できないので、ここはnone
でなければいけません。
(12) FIPSモードの有効化です。デフォルトではfalse
です。
(13) ダウンロードした Pull Secret を貼り付けます。
(14) 作成したSSHの公開鍵を貼り付けます。前の手順で作成した/root/.ssh/id_rsa.pub
の中身です。
※初出時にはじめの設計と絵とここの YAMLのアドレスレンジがずれておりました。お詫びして訂正致します。
4.2.Kubernetes manifest と Ignition config filesを作成する。
4.2.1.manifest ファイルの作成
インストール用のファイルがたくさん生成されるので、インストールファイル用のディレクトリを作っておきます。
installdir
というディレクトリ名にします。
$ cd /root/openshift/ # この手順での、作業ディレクトリに移動
$ mkdir installdir
先ほど作成した install-config.yaml
ファイルを installdir
にコピーします。
コピーしたinstall-config.yaml
ファイルは、後の作業で消えてしまうので、オリジナルのinstall-config.yaml
は再インストール時用に保管しておくために mv
ではなく、cp
にしておくのがおすすめです。
$ cp install-config.yaml ./installdir/install-config.yaml
install-config.yaml
を元にインストールファイル群を installdir
内に作成します。
以下のコマンドでインストール用のファイル群が作成されます。
$ ./openshift-install create manifests --dir=installdir
INFO Consuming Install Config from target directory
WARNING Making control-plane schedulable by setting MastersSchedulable to true for Scheduler cluster settings
$
installdir
配下に新しいディレクトリが出来ている事を確認します。このディレクトリの中にインストール用の manifest
ファイル(yaml)が大量に生成されているはずです。確認してみてください。
$ ls -ltr installdir/ # Directory が2つ出来ている
total 8
drwxr-x---. 2 root root 4096 Aug 16 02:10 manifests
drwxr-x---. 2 root root 4096 Aug 16 02:10 openshift
$ ls -ltr ./installdir/manifests/ # yml が生成されている。
-rw-r-----. 1 root root 444 Sep 28 20:51 cluster-infrastructure-02-config.yml
-rw-r-----. 1 root root 154 Sep 28 20:51 cluster-dns-02-config.yml
<出力略>
$ ls -ltr ./installdir/openshift/ # yml が生成されている。
-rw-r-----. 1 root root 2602 Sep 28 20:51 99_openshift-cluster-api_master-user-data-secret.yaml
-rw-r-----. 1 root root 1277 Sep 28 20:51 99_openshift-machineconfig_99-worker-ssh.yaml
<出力略>
4.2.2.control plane への Pod schedule の無効化
前段のステップで生成された manifest
ファイルの一部を変更します。
通常、Kubernetes
では、Master
ノードにユーザーアプリの Pod
を配置する事はありませんが、OpenShift
では、最小構成の3ノード構成を取る場合に、Master
にも ユーザーアプリの Pod
を配置できるようになりました。デフォルトの設定はこの最小3ノード構成を取るように構成されます。
この手順では、一般的であるWorker
ノードを持った構成にしたいため、Master
ノードに ユーザーPod
をスケジュール(配置)しないように構成を変更します。
installdir/manifests/cluster-scheduler-02-config.yml
を編集します。
apiVersion: config.openshift.io/v1
kind: Scheduler
metadata:
creationTimestamp: null
name: cluster
spec:
mastersSchedulable: false # true を false に変更
policy:
name: ""
status: {}
もしくは、一ヶ所の編集なので sed -i
コマンドで置き換えてしまいます。
sed -i -e 's/mastersSchedulable: true/mastersSchedulable: false/' installdir/manifests/cluster-scheduler-02-config.yml
4.2.3.ignition ファイルの作成 (manifestファイルのignitionファイルへの変換)
ignition
ファイルという CoreOS のインストール時に使用するファイルをコマンドで生成します。
ignition
ファイル は、前のステップで作成された manifest
ファイルを変換して作成されるファイルですが、manifest
ファイルと違い可読困難なファイルです。ignition
ファイル群は、後の手順で、CoreOSのブート時に、CoreOSに渡されます。
OpenShift の boostrap
、master
、worker
ノード用にそれぞれ別の ignition
ファイルが生成されます。
$ cd /root/openshift/ # この手順での、作業ディレクトリに移動
$ ./openshift-install create ignition-configs --dir installdir
INFO Consuming Openshift Manifests from target directory
INFO Consuming Master Machines from target directory
INFO Consuming Worker Machines from target directory
INFO Consuming OpenShift Install (Manifests) from target directory
INFO Consuming Common Manifests from target directory
$
*.ign
というファイルが作成されているはずです。
$ tree installdir/
installdir/
├── auth
│ ├── kubeadmin-password
│ └── kubeconfig
├── bootstrap.ign
├── master.ign
├── metadata.json
└── worker.ign
1 directory, 6 files
$
ここで作成した .ing
ファイルには、X509形式の証明書が含まれています。
証明書の期限は24時間になっており、24時間を超えて *.ign
を使い回す事はできませんので、その場合は *.ign
ファイルを再作成して下さい。
##4.3.oc コマンド実行環境のセットアップ
踏み台サーバー
上で、oc
コマンドが使えるようにセットアップしておきましょう。この例では /root/openshift
に oc
コマンドを置いてあるので PATH
変数に追加しておきます。
export PATH=$PATH:/root/openshift
また、oc
コマンドがクラスターにアクセスするための認証情報は、この例だと /root/openshift/installdir/auth/kubeconfig
にあります。このパスを export
しておきます。
export KUBECONFIG=/root/openshift/installdir/auth/kubeconfig
これらの export
の設定は、結局何度も使用する事になるので、.bash_profile
等にあらかじめ書いてしまって、ログイン時に自動設定されるようにしておくのがおすすめです。
5.インストールに必要な設定ファイルを HTTPサーバーに配置する
この作業は、踏み台サーバー
(=HTTPサーバー
) 上での作業です。
5.1.ignition ファイルを HTTP Serverにコピーする。
HTTP Server(踏み台サーバー)
に、インストールに必要なイメージファイルや、作成したインストール用の構成ファイルをコピーします。
この例の場合は作業しているサーバー自体が HTTP Serverをインストールしているので、HTTP Server(踏み台サーバー)
のディレクトリに RAW イメージと *.ign
をコピーします。
[root@bastion openshift]# cp ./installdir/*.ign /usr/share/nginx/html/
※ダウンロードしたRAWイメージは、別途 /usr/share/nginx/html/
に配置しておきます。
5.2 アクセスができる確認する
HTTPサーバー(踏み台サーバー)
のディレクトリーに配置したファイルがアクセスできるか確認します。
ファイルに HTTP アクセスできるか、適当なファイルを使って確かめます。
curl -I
オプションは HTTP の HEAD リクエストなので、実際のいダウンロードはしません。
master.ign
ファイルを使って確かめます。200 が返ってきていたらOKです。
[root@bastion openshift]# curl -I http://localhost/master.ign
HTTP/1.1 200 OK # 200 が返ってきていたらOK
Server: nginx/1.14.1
Date: Sun, 16 Aug 2020 07:32:45 GMT
Content-Type: application/octet-stream
Content-Length: 1835
Last-Modified: Sun, 16 Aug 2020 06:43:15 GMT
Connection: keep-alive
ETag: "5f38d583-72b"
Accept-Ranges: bytes
[root@bastion openshift]#
5.3 SELinux の落とし穴
Webサーバー上に配置したファイルで、rhcos-4.5.2-x86_64-metal.x86_64.raw.gz
だけは、アクセスしようとすると 403 (forbitten) が返ってくるはずです。
[root@bastion openshift]# curl -I http://localhost/rhcos-4.5.6-x86_64-metal.x86_64.raw.gz
HTTP/1.1 403 Forbidden
Server: nginx/1.14.1
Date: Sun, 16 Aug 2020 08:21:42 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
これはSELinux が原因です。セキュリティコンテキストを確認してみます。
# SELinux のコンテキストの確認
$ ls -lZ /usr/share/nginx/html/work/
total 874428
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 298610 Aug 16 02:43 bootstrap.ign
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 1835 Aug 16 02:43 master.ign
-rwxrwxrwx. 1 root root unconfined_u:object_r:admin_home_t:s0 895104623 Aug 16 03:14 rhcos-4.5.2-x86_64-metal.x86_64.raw.gz
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 1835 Aug 16 02:43 worker.ign
rhcos-4.5.2-x86_64-metal.x86_64.raw.gz だけが、`[admin_home_t]` という「タイプ」を持っている事がわかる。
これを他のファイルと同じように、タイプを [httpd_sys_content_t]
に変更します。
# タイプを変更
$ semanage fcontext -a -t httpd_sys_content_t /usr/share/nginx/html/work/rhcos-4.5.2-x86_64-metal.x86_64.raw.gz
# semanage コマンドを実行しただけだと変わらない
$ ls -lZ /usr/share/nginx/html/work/
total 874428
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 298610 Aug 16 02:43 bootstrap.ign
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 1835 Aug 16 02:43 master.ign
-rwxrwxrwx. 1 root root unconfined_u:object_r:admin_home_t:s0 895104623 Aug 16 03:14 rhcos-4.5.2-x86_64-metal.x86_64.raw.gz
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 1835 Aug 16 02:43 worker.ign
# restorecon コマンドで反映
$ restorecon /usr/share/nginx/html/work/rhcos-4.5.2-x86_64-metal.x86_64.raw.gz
[root@bastion openshift]# restorecon /usr/share/nginx/html/work/rhcos-4.5.2-x86_64-metal.x86_64.raw.gz
# もう一度確認。無事タイプが変更になっている。
[root@bastion openshift]# ls -lZ /usr/share/nginx/html/work/
total 874428
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 298610 Aug 16 02:43 bootstrap.ign
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 1835 Aug 16 02:43 master.ign
-rwxrwxrwx. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 895104623 Aug 16 03:14 rhcos-4.5.2-x86_64-metal.x86_64.raw.gz
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 1835 Aug 16 02:43 worker.ign
6.ネットワーク環境の疎通確認
手順が非常に長い上に、フルスタックな作業のため、どうしてもセットアップでミスをしがちです。
OpenShift
クラスターの導入に移る前に正しくノードがセットアップされているかできるだけ確認しておきます。
Inter-Node
ネットワーク上のサーバーで以下のコマンドを実行してネットワークの設定を確認します。
ping -c 2 api.ocp45.example.localdomain # ロードバランサーで解決される
ping -c 2 api-int.ocp45.example.localdomain # ロードバランサーで解決される
ping -c 2 test.apps.ocp45.example.localdomain # ロードバランサーで解決される
dig +short bs.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short m1.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short m2.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short m3.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short w1.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short w2.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short w3.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +norec -x 172.16.0.11 +short # Bootsrap Node のIPの逆引き
dig +norec -x 172.16.0.21 +short # Masterノード 1 のIPの逆引き
dig +norec -x 172.16.0.22 +short # Masterノード 2 のIPの逆引き
dig +norec -x 172.16.0.23 +short # Masterノード 3 のIPの逆引き
dig +norec -x 172.16.0.31 +short # Workerノード 1 のIPの逆引き
dig +norec -x 172.16.0.32 +short # Workerノード 2 のIPの逆引き
dig +norec -x 172.16.0.33 +short # Workerノード 3 のIPの逆引き
# インターネットアクセス
wget https://quay.io/v2/
(CoreOSが、必要なモジュールをダウンロードする時に、ここにアクセスします。401 UNAUTHORIZED。が返ってくればOK)
名前の逆引きは、現時点でマニュアルに要件が載っていませんでしたが、この逆引きの値がoc get nodes
コマンドを実行した時のノード
名に使われているように見えます。逆引き設定が無い場合は、ノード
が、localhost
になってしまい、インストールが失敗しました。
もし一つでも上手くいかない場合は、もう一度ネットワーク環境を確認してみてください。
7.OpenShift クラスターのインストール
7.1.CoreOS のインストールの概要
iPXE
環境が正しく設定されていれば、物理サーバーの起動スイッチを押すだけで、CoreOS
がインストールされるはずです。
少し複雑ですが、以下の図にかかれている作業がサーバーの電源ON後、自動で実行されます。
トラブルが起きない限りは、TFTPサーバー
には、iPXEファームウェア
を取りに行く、HTTPサーバー
には、CoreOS
のインストールに必要なものを取りに行く。という事だけイメージできれば大丈夫だと思います。
この要領で、まずは 合計7本 (Bootstrap
x 1、Master
x 3、Worker
x 3) の CoreOS
ノードを準備します。
7.2.Cluter Node インストールの概要
あくまでOpenShift
4.5 のインストーラーの動きを外部やログから観察した限りでの動きですが、OpenShift Cluster
に所属するノード
のインストール時の動きは以下のように動いているように見えます。
※Masterノード以降は直接 Internet 行ってるのかは未確認!(いつかトレースを取って確認したい)
各ノード
の電源をONにするとiPXE
により CoreOS
のインストールがはじまり、その後、必要なContainer
のインストールがはじまります。
Masterノード
は、途中で次のステップに進むためにBoot Strap
の準備が整っているか確認を行います。
Worker(Infra) ノード
は、途中で次のステップに進むためにMasterノード
の準備が整っているか確認を行います。このようにBootStrap
=>Master
=>Worker
は、それぞれ依存関係にあります。
順番に自動でタイミングを見ながらインストールが進みますが、各ノード
の起動タイミングは、大体順番に起動していく程度の緩い感覚で開始して行けば大丈夫です。経験上、連続で立ちあげていって、起動順序が多少前後しても、依存相手の準備完了を待つだけなので問題ありません。
また、Worker(Infra)ノード
は、インストールの途中でユーザーが手動でCSR(Certificate Signing Request)
という証明書の元になる情報に署名approve
を行って証明書を作成してあげる必要があります。
7.3.BootStrapノードの起動
BootStrapノード
を起動して、iPXE
ブートメニューに進みます。
メニューを選択したら後は、待つだけです。
以下のエラーがでるかもしれませんが、無視できるものだそうです。
7.4.Masterノードの起動
Masterノード
を起動して iPXE
ブートメニューに進みます。
メニューを選択したら後は待つだけです。
Masterノード
でも BootStrap
と同様に、以下のエラーがでるかもしれませんが、無視できるものだそうです。
動きとしてMasterノード
は BootStrapノード
の準備ができるのを待ち続け、その後、自らのインストールを開始します。BootStrapノード
とMasterノード
の起動が多少前後しても問題はありません。Masterノード
を素早く立ちあげても、BootStrapノード
の準備完了まで待つ事になります。
Masterノード
は、3本あるので、この作業を後2回繰り返します。特に Masterノード
間に依存関係があるわけではないので、3本のノード
をさくさくとONにして大丈夫です。
経験側ですが、このMasterノード
のインストール作業時の2本目、3本目の Masterノード
のブートは手早く行った方が良いと思います。再現試験はしていませんが、あまり間を開けると失敗する事があるような気がします。
##7.5.「openshift-install ~ wait-for bootstrap-complete」の実行
※インストール時間を短縮したい場合は、先にセクション「7.6.Workerノードの起動」を実行して、ここに戻ってきても大丈夫です。
BootStrap
の起動シークエンスをモニターするコマンドを実行します。
このコマンドでは、BootStrapノード
が立ち上がり、その後、3本の Masterノード
が立ち上がるまでをモニターします。
./openshift-install --dir=installdir wait-for bootstrap-complete --log-level=debug
[root@bastion openshift]# ./openshift-install --dir=installdir wait-for bootstrap-complete --log-level=debug
INFO Waiting up to 20m0s for the Kubernetes API at https://api.ocp45.example.localdomain:6443...
<省略>
DEBUG Still waiting for the Kubernetes API: the server could not find the requested3/version?timeout=32s: EOF resource resource
DEBUG Still waiting for the Kubernetes API: Get https://api.ocp45.example.local:644 resource 3/version?timeout=32s: EOF resource
DEBUG Still waiting for the Kubernetes API: Get https://api.ocp45.example.local:6443/version?timeout=32s: EOF 3/version?timeout=32s: EOF 3/version?timeout=32s: EOF
INFO API v1.18.3+b0068a8 up
INFO Waiting up to 40m0s for bootstrapping to complete...
DEBUG Bootstrap status: complete
INFO It is now safe to remove the bootstrap resources
DEBUG Time elapsed per stage:
DEBUG Bootstrap Complete: 14m54s
DEBUG API: 6m13s
INFO Time elapsed: 14m54s
[root@bastion openshift]#
コマンドが終了しれば、BootSrap
のシークエンスは完了です。この時点で、BootSrtap Node
が作成され、それを元に Msater Node
が作成される所までが完了しています。
全体が完了しているわけではないので、次のステップに進みます。
7.6.Workerノードの起動
Workerノード
の CoreOS
のインストールも BootStrap
, Master
同様です。が、後述しますが、少し追加の手順が必要になります。
まずは、BootStrap
、Master
と同じようにインストールを開始します。
Workerノード
の起動時に以下のログが表示されますが、これはMasterノード
の起動を確認している時のログで、これ自体はエラーではありません。
7.7.Workerノード のCSRの approve
この手順は、セクション「7.5.「openshift-install ~ wait-for bootstrap-complete」の実行」で実行したコマンドが完了し、セクション「7.6.Workerノードの起動」も開始している事が前提になります。
CSR(Certificate Signing Request)
は証明書の元になる情報への署名要求で、approve をする事で署名され、証明書になります。oc get csr
コマンドを実行して Pending
になっているものを探します。
これらの CSR
は、Workerノード
に紐付くもので、Workerノード
がクラスターに参加する時に必ず行う必要があります。
もしPending
が表示されていない場合は、Workerノード
の準備が整うと必ず表示されるものなので、Workerノード
の起動後、数分待って再度コマンドを実行してみて下さい。
oc get csr
[root@bastion openshift]# oc get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-7ftsc 25m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-8557v 24m kubernetes.io/kubelet-serving system:node:m1.ocp45.example.local Approved,Issued
csr-8cjss 11m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending
csr-8v6ns 24m kubernetes.io/kubelet-serving system:node:m3.ocp45.example.local Approved,Issued
csr-nnzww 10m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending
csr-qqh7s 24m kubernetes.io/kubelet-serving system:node:m2.ocp45.example.local Approved,Issued
csr-wtcdk 25m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-zlrhb 25m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
[root@bastion openshift]#
oc adm certificate approve
コマンドで Pending
状態のものを approve します。
[root@bastion openshift]# oc adm certificate approve csr-8cjss csr-nnzww
certificatesigningrequest.certificates.k8s.io/csr-8cjss approved
certificatesigningrequest.certificates.k8s.io/csr-nnzww approved
[root@bastion openshift]#
上記の例では、コピペで、approve 対象の CSR名を一つ一つコピペで貼り付けていますが、マニュアルには以下のワンライーナーのコマンドを使う方法も紹介されています。
oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approve
approve すると、今度はすぐに別の Pending
のCSR
が出てきます。Peding
が無くなるまで、approve を繰り返します。
初めの CSR の approve から数分以内に次の Pending
が表示されるはずです。oc get csr
コマンドを使って確認し、新しい Pending
の状態のものが確認できたら approve します。
一つの Workerノード
(Infraノード
) 辺り、2回 CSR
の approve を要求されます。(クライアント・リクエストCSR
と、サーバー・リクエストCSR
と言うようです)
もしWroker Node
が 6本ある場合は、12回 CSR
のapproveが必要になるはずです。
一つ approve してみます。
[root@bastion openshift]# oc get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-7ftsc 27m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-8557v 27m kubernetes.io/kubelet-serving system:node:m1.ocp45.example.local Approved,Issued
csr-8cjss 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-8v6ns 27m kubernetes.io/kubelet-serving system:node:m3.ocp45.example.local Approved,Issued
csr-frwfk 1s kubernetes.io/kubelet-serving system:node:w1.ocp45.example.local Pending
csr-nnzww 12m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-qqh7s 27m kubernetes.io/kubelet-serving system:node:m2.ocp45.example.local Approved,Issued
csr-wtcdk 27m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-zlrhb 27m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
[root@bastion openshift]# oc adm certificate approve csr-frwfk #
certificatesigningrequest.certificates.k8s.io/csr-frwfk approved
approve すると、以下のようにすぐに別の Pending が現れるはずです。1つのWorkerノード
につき2回要求されます。
[root@bastion openshift]# oc get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-7ftsc 27m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-8557v 27m kubernetes.io/kubelet-serving system:node:m1.ocp45.example.local Approved,Issued
csr-8cjss 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-8v6ns 27m kubernetes.io/kubelet-serving system:node:m3.ocp45.example.local Approved,Issued
csr-frwfk 22s kubernetes.io/kubelet-serving system:node:w1.ocp45.example.local Approved,Issued
csr-hpw9z 15s kubernetes.io/kubelet-serving system:node:w2.ocp45.example.local Pending
csr-nnzww 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-qqh7s 27m kubernetes.io/kubelet-serving system:node:m2.ocp45.example.local Approved,Issued
csr-wtcdk 27m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-zlrhb 27m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
[root@bastion openshift]# oc adm certificate approve csr-hpw9z
certificatesigningrequest.certificates.k8s.io/csr-hpw9z approved
Pending
状態のものが無くなれば完了です。
[root@bastion openshift]# oc get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-7ftsc 28m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-8557v 28m kubernetes.io/kubelet-serving system:node:m1.ocp45.example.local Approved,Issued
csr-8cjss 14m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-8v6ns 28m kubernetes.io/kubelet-serving system:node:m3.ocp45.example.local Approved,Issued
csr-frwfk 44s kubernetes.io/kubelet-serving system:node:w1.ocp45.example.local Approved,Issued
csr-hpw9z 37s kubernetes.io/kubelet-serving system:node:w2.ocp45.example.local Approved,Issued
csr-nnzww 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-qqh7s 28m kubernetes.io/kubelet-serving system:node:m2.ocp45.example.local Approved,Issued
csr-wtcdk 28m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
csr-zlrhb 28m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Approved,Issued
[root@bastion openshift]#
通常であれば、CSR を approve した直後に、Worker ノードが oc get nodes
で表示されるはずです。
CSR
を全て approve したら、oc get nodes
を実行して Workerノード
が Ready
になるのを確認します。
[root@bastion openshift]# oc get nodes
NAME STATUS ROLES AGE VERSION
m1.ocp45.example.local Ready master 31m v1.18.3+47c0e71
m2.ocp45.example.local Ready master 31m v1.18.3+47c0e71
m3.ocp45.example.local Ready master 31m v1.18.3+47c0e71
w1.ocp45.example.local Ready worker 4m13s v1.18.3+47c0e71
w2.ocp45.example.local Ready worker 4m5s v1.18.3+47c0e71
[root@bastion openshift]#
全てのノードのReady
が確認できたらセットアップはほぼ完了です。
7.8.「openshift-install ~ wait-for install-complete」のコマンドの実行
これまでの手順で全てのインストール手順は完了のように見えますが、クラスター内部では、まだコンテナ等のインストールが続いていて、Cluster としては Readyにはなっていません。
OpenShift
のコンソール用のPod
などは、Workerノード
に配置されるため、Workerノード
のCSR
が approveされてから Pod
の作成が始まります。
残りのPod
の作成の完了(Cluster Ready
)を暫く待つ必要があります。
7.8.1.「openshift-install ~ wait-for install-complete」の実行
OpenShift
ClusterがReady
になるまでをモニターするためのコマンド ./openshift-install --dir=installdir wait-for install-complete
を実行します。
以前使用した BootStrapプロセスの完了のモニターに使用したコマンドとは、後半の wait-for install-complete
の部分が違っているので注意して下さい。
./openshift-install --dir=installdir wait-for install-complete
[root@bastion openshift]# ./openshift-install --dir=installdir wait-for install-complete
INFO Waiting up to 30m0s for the cluster at https://api.ocp45.example.local:6443 to initialize...
INFO Waiting up to 10m0s for the openshift-console route to be created...
INFO Install complete!
INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/root/openshift/installdir/auth/kubeconfig'
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.ocp45.example.local
INFO Login to the console with user: "kubeadmin", and password: "KBB5q-7reSE-gUKSf-ssZPx"
INFO Time elapsed: 5m19s
[root@bastion openshift]#
コマンドを実行した後は待つだけです。上記の例では 5分ほどで完了しています。
7.8.2.「openshift-install ~ wait-for install-complete」実行中の観察
インストールの手順としては、前述のステップで完了ですが、インストール中に、インストール中の実行状況を確認する方法について補足します。
7.8.2.1.実行ログ
./openshift-install --dir=installdir wait-for install-complete
のログは installdir/.openshift_install.log
として作られます。もう一つターミナルを開いて、このログを横からtail
する事で、進捗を見ることができます。ただし、このログから得られる情報は、それほど多くはありません。
[root@bastion installdir]# tail -f .openshift_install.log
time="2020-09-23T04:18:08-04:00" level=debug msg="OpenShift Installer 4.5.5"
time="2020-09-23T04:18:08-04:00" level=debug msg="Built from commit 01f5643a02f154246fab0923f8828aa9ae3b76fb"
time="2020-09-23T04:18:08-04:00" level=info msg="Waiting up to 20m0s for the Kubernetes API at https://api.ocp45.example.localdomain:6443..."
time="2020-09-23T04:18:08-04:00" level=debug msg="Still waiting for the Kubernetes API: Get https://api.ocp45.example.localdomain:6443/version?timeout=32s: http: server gave HTTP response to HTTPS client"
time="2020-09-23T04:18:38-04:00" level=debug msg="Still waiting for the Kubernetes API: Get https://api.ocp45.example.localdomain:6443/version?timeout=32s: http: server gave HTTP response to HTTPS client"
time="2020-09-23T04:19:08-04:00" level=debug msg="Still waiting for the Kubernetes API: Get https://api.ocp45.example.localdomain:6443/version?timeout=32s: http: server gave HTTP response to HTTPS client"
上記のログはインストールが完了を、API Server の応答が確認できるまで待っているログです。一見エラーに見えますが、定期的な起動確認チェックですので、これ自体はインストールの失敗を示すものではありません。(もちろん、ずっとこの状態が続くとインストールが失敗します)
7.8.2.2.Podの状態の観察
以下の方法でも、インストール中の進捗を確認する事ができます。
以下は oc get pods --all-namespaces
で Running
と Completed
以外の状態のPod
を確認する事で、進捗を確認している例です。
最終的に全て Running
が Completed
になるので、Cluster Ready 時には、 Running
と Completed
以外の状態のPod
は、なくなります。
[root@bastion openshift]# oc get pods --all-namespaces | grep -v Running | grep -v Completed
NAMESPACE NAME READY STATUS RESTARTS AGE
openshift-console console-86bfd57fc9-k8sbm 1/1 Terminating 0 3m52s
openshift-kube-apiserver kube-apiserver-m1.ocp45.example.local 0/4 Init:0/1 0 54s
[root@bastion openshift]#
もし状態が Completed
や Running
にならないPod
がある場合は、以下のコマンドでログを確認できます。
oc logs <pod_name> -n <namespace>
また、Pod
の状況調査には以下のコマンドも有効です。出力量は多いですが、Pod
の各種設定やイベント等も表示されます。
oc describe pods <pod_name> -n <namespace>
いずれのコマンドも<namespace>
の指定を忘れると、Podがありません
のようなメッセージが返ってくるので注意しましょう。
7.8.2.3.Operatorの状態の観察
oc get clusteroperators
で、Operator のインストール状況を確認できます。AVAILABLE
の欄が最終的に全てTRUE
になります。
[root@bastion openshift]# oc get clusteroperators
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE
authentication Unknown Unknown True 11m
cloud-credential 4.5.11 True False False 16m
cluster-autoscaler 4.5.11 True False False 3m14s
config-operator 4.5.11 True False False 3m26s
console 4.5.11 Unknown True False 5m17s
csi-snapshot-controller
dns 4.5.11 True True True 10m
etcd 4.5.11 True False False 10m
image-registry 4.5.11 True False False 4m48s
ingress False True True 4m46s
insights 4.5.11 True False False 4m48s
kube-apiserver 4.5.11 True True False 9m22s
kube-controller-manager 4.5.11 True False False 9m9s
kube-scheduler 4.5.11 True False False 9m11s
kube-storage-version-migrator 4.5.11 False False False 11m
machine-api 4.5.11 True False False 4m47s
machine-approver 4.5.11 True False False 5m34s
machine-config 4.5.11 True False False 10m
marketplace 4.5.11 True False False 4m7s
monitoring Unknown True Unknown 4m47s
network 4.5.11 True True False 12m
node-tuning 4.5.11 True False False 11m
openshift-apiserver 4.5.11 True False False 5m49s
openshift-controller-manager 4.5.11 True False False 4m36s
openshift-samples 4.5.11 True False False 3m8s
operator-lifecycle-manager 4.5.11 True False False 10m
operator-lifecycle-manager-catalog 4.5.11 True False False 10m
operator-lifecycle-manager-packageserver 4.5.11 True False False 6m25s
service-ca 4.5.11 True False False 11m
storage 4.5.11 True False False 4m46s
[root@bastion openshift]#
これらの情報を使用して、インストールが上手く進行しているか確認する事ができます。
7.8.3.コンソールアクセスの確認。
OpenShift
Cluster が Ready
になるとコマンドが終了し、https://console-openshift-console.apps.ocp45.example.local
のようなコンソールのログインURLと、password: "KBB5q-7reSE-gUKSf-ssZPx"
のように kubeadmin
のパスワードが表示されます。
[root@bastion openshift]# ./openshift-install --dir=installdir wait-for install-complete
<省略>
KUBECONFIG=/root/openshift/installdir/auth/kubeconfig' <= 環境の情報
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.ocp45.example.local <= Console URL
INFO Login to the console with user: "kubeadmin", and password: "KBB5q-7reSE-gUKSf-ssZPx" <= userid / password
INFO Time elapsed: 5m19s
[root@bastion openshift]#
コンソールの URL にアクセスすると、以下のような警告が出ますが、これは OpenShift
が使用している証明書が安全だとは、ブラウザが判断できないために表示されるものです。これは証明書の発行者がOpenShift
クラスターであり、ブラウザーに事前登録されているCA(Certification Authority:認証局)
の一覧にないためです。この警告は無視して構いません。
kubadmin
でログインできれば、Cluster のセットアップはひとまず完了です。
ちなみに、ログインのためのパスワードを忘れてしまった時は
./openshift-install --dir=installdir wait-for install-complete
をもう一度実行すると表示されます。
7.8.4.OpenShift Consoleにアクセスできない場合
OpenShift Consoele
は、OpenShift
の ingress(HTTP LB)
実装であるRouter
経由で外部からアクセスされます。
このRouter
は、Workerノード
にスケジュールされ、外部LoadBalacer
(この環境ではHA Proxy
)からトラフィクを割り振られなければいけません。
OpenShift Console
にアクセスできない場合は、Router
のPod
がどこにあるか以下のように確認できます。
# はじめに ingress の Pod名を突き止める。
[root@bastion ~]# oc describe node | grep ingress
openshift-ingress-operator ingress-operator-56f5778d85-ddncf 20m (0%) 0 (0%) 40Mi (0%) 0 (0%) 14h
openshift-ingress router-default-55596bdcbb-n87pm 100m (0%) 0 (0%) 256Mi (0%) 0 (0%) 14h
openshift-ingress router-default-55596bdcbb-xsgv6 100m (0%) 0 (0%) 256Mi (0%) 0 (0%) 14h
# Node名 を確認
[root@bastion ~]# oc describe pod router-default-55596bdcbb-n87pm -n openshift-ingress | grep Node:
Node: s2.ocp45.example.localdomain/172.16.0.52
# Node名 を確認
[root@bastion ~]# oc describe pod router-default-55596bdcbb-xsgv6 -n openshift-ingress | grep Node:
Node: s3.ocp45.example.localdomain/172.16.0.53
例えば初期インストール時に、ユーザーアプリケーション用のWorkerノード
と、分散ストレージ用に使う予定のWorkerノード
を同時に作成した場合、Router
がストレージ用のノード
に配置されてしまう事がありえます。
そして、もし、そのストレージ用のノード
がLoad Balancer
配下に入ってない場合、OpenShift Console
にアクセスできないばかりか、ユーザーのアプリにも外部からアクセスできない事になります。
7.8.5.OpenShift Consoleの証明書エラーを消す
OpenShift
のConsole
で使用されているHTTPS
証明書は、自己証明書です。
証明書の署名をしているCA(Certificate Authority)
は、ブラウザーにインストールされてないため、通常以下のような警告がでます。
このルートCA
の証明書は、Router(Ingress)
により発行されています。実体はSecret
に保存されていて以下の方法で取り出す事ができます。
oc get secret router-ca -n openshift-ingress-operator -o jsonpath="{.data.tls\.crt}" | base64 -d > router-ca.crt
作成したrouter-ca.crt
をブラウザーにインストールします。ブラウザによって手順は違いますが、Firefox
の場合は、オプション
→プライバシーとセキュリティ
から証明書を表示
をクリックします。
インポートから、作成したrouter-ca.crt
をインポートします。
この認証局によるウェブサイトの識別を信頼する
をチェックします。
ingress-operator@xxxxxxx
が証明書名と発行者名
に表示されていればOKです。
これで Webブラウザでアクセス時の警告が表示されなくなります。
警告が表示されなくなるのは、router-ca.crt
を導入した端末だけである事に注意して下さい。
7.8.6.bootstrapサーバーの除去
クラスターのセットアップが完了したらBoostrapサーバー
は削除して問題ありません。
またロードバランサーのHaproxy
の設定からも忘れずに取り除いて下さい。
<省略>
# server app4 127.0.0.1:5004 check
# internal domains is ocp45.example.localdomain
backend kube_api
mode tcp
balance roundrobin
option ssl-hello-chk
# server bs bs.ocp45.example.localdomain:6443 check # Entryから Boostratp Serverを除去
server m1 m1.ocp45.example.localdomain:6443 check
server m2 m2.ocp45.example.localdomain:6443 check
server m3 m3.ocp45.example.localdomain:6443 check
backend machine_config
mode tcp
balance roundrobin
# server bs bs.ocp45.example.localdomain:22623 check # Entryから Boostratp Serverを除去
server m1 m1.ocp45.example.localdomain:22623 check
server m2 m2.ocp45.example.localdomain:22623 check
server m3 m3.ocp45.example.localdomain:22623 check
<省略>
8.クラスターインストール完了後の作業
これまでのステップでとりあえずOpenShift
のクラスターとしては稼働するようになりました。コンテナもデプロイする事ができます。
ですが、現実の使える環境をを考えると、もう少しセットアップを続ける必要があります。
この章では、PV(Persistent Volume)
用のストレージを準備し、運用のコンポーネントを載せるためのOpenShift
用語でInfraノード
と呼ばれるWorkerノード
を作成します。
その後、Container Registry
、Elasticsearch(Cluster Logging)
を構成します。
これらの各種運用コンポーネントは、Infraノード
に配置します。
また、Prometheus
や、Router(Ingress)
と言ったコンポーネントは、OpenShift
クラスターインストール時に既に作成されていますが、これらも運用コンポーネントですので、Infraノード
に移動させます。
8.1. PV用のストレージの作成
PV
用のストレージに何を使うかは環境次第ですが、この手順では、OCS
を作成する事にします。以下の手順を参考にOCS(OpenShift Container Storage)
を作成します。
OCS(OpenShift Container Storage)をインターナルモードで作成する
8.2.Infraノードの作成
OpenShift
の運用コンポーネントを配置するためのInfraノード
を作成します。
Infraノード
は、あくまでOpenShift
の世界での用語です。技術的にはWorkerノード
と同じものです。
Workerノード
を新規に3本作成します。IPアドレスなどは、セクション「1.1.7.ノードのサイジング」に書いてある通りです。
手順になれていれば、Workerノード
の作成時に同時にInfraノード
を作成しても良いのですが、作業に慣れていない時に、一度に大量のWorkerノード
を作成すると作業ミスした時のリカバリーが大変なので敢えて後から追加で構成する手順にしました。
まずは、通常のWorkerノード
と同様に以下の手順を実行します。
1.Infraノード
用のIPアドレスを決定
2.DHCPサーバー
に、MACアドレスに結びつけてInfraノード
に固定IPを配れるように設定
3.DNSサーバー
にInfraノード
として使用するWorkerノード
のホスト名を DNSに登録 (逆引きも設定)
4.CoreOS
のインストール。Workerノード
の Inginiton file
を使って Workerノード
として構成
5.Woker Node
のCSR
をapprove
ここでは、i1.ocp45.example.localdomain
、i2.ocp45.example.localdomain
、i3.ocp45.example.localdomain
という3本のInfraノード
を作成します。ここで作成するInfraノード
のスペックは1.1.7.1.OpenShift 関連ノードのサイジングで設計した通りに、以下の通りです。
サーバー | vCPU(HT-on) | Memory | Disk | OS | ホスト名 | IP Address | note |
---|---|---|---|---|---|---|---|
Infraノード | 4VCPU | 16GByte | 120G | CoreOS | i1.ocp45.example.localdomain | 172.16.0.41 | |
4VCPU | 16GByte | 120G | CoreOS | i2.ocp45.example.localdomain | 172.16.0.42 | ||
4VCPU | 16GByte | 120G | CoreOS | i3.ocp45.example.localdomain | 172.16.0.43 |
Infraノード
のCoreOS
のインストールに取りかかる前に、ネットワークの設定が取れているか確認しておく事をおすすめします。
dig +short i1.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short i2.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +short i3.ocp45.example.localdomain # ノードが無いと ping は返ってこないが、dig で名前解決はできる
dig +norec -x 172.16.0.41 +short # Infraノード 1 のIPの逆引き
dig +norec -x 172.16.0.42 +short # Infraノード 2 のIPの逆引き
dig +norec -x 172.16.0.43 +short # Infraノード 3 のIPの逆引き
8.2.1.Infraノードとしてのラベルを貼る
Workerノード
が完成したら、Infraノード
としてのラベルを振ります。
# oc label node i1.ocp45.example.localdomain node-role.kubernetes.io/infra=
# oc label node i2.ocp45.example.localdomain node-role.kubernetes.io/infra=
# oc label node i3.ocp45.example.localdomain node-role.kubernetes.io/infra=
検索するとWorkerノード
としてのRole
を外す手順が出てくる場合がありますが、worker
Role のラベルは外さなくても大丈夫です。
(worker
ラベルを外す場合は、Maching Config Pool
という追加リソースを作成する必要がでてきます。)
infra
ラベルが貼られている事を確認します。
[root@bastion openshift]# oc get nodes
NAME STATUS ROLES AGE VERSION
i1.ocp45.example.localdomain Ready infra,worker 15h v1.18.3+47c0e71
i2.ocp45.example.localdomain Ready infra,worker 15h v1.18.3+47c0e71
i3.ocp45.example.localdomain Ready infra,worker 15h v1.18.3+47c0e71
m1.ocp45.example.localdomain Ready master 15h v1.18.3+47c0e71
m2.ocp45.example.localdomain Ready master 15h v1.18.3+47c0e71
m3.ocp45.example.localdomain Ready master 15h v1.18.3+47c0e71
s1.ocp45.example.localdomain Ready infra,worker 66m v1.18.3+47c0e71
s2.ocp45.example.localdomain Ready infra,worker 66m v1.18.3+47c0e71
s3.ocp45.example.localdomain Ready infra,worker 66m v1.18.3+47c0e71
w1.ocp45.example.localdomain Ready worker 15h v1.18.3+47c0e71
w2.ocp45.example.localdomain Ready worker 15h v1.18.3+47c0e71
w3.ocp45.example.localdomain Ready worker 15h v1.18.3+47c0e71
[root@bastion openshift]#
8.2.2 Load Balancer の設定にInfraノードを追加する。
Infraノード
に各種コンポーネントを移動させるので、この環境でのLoad Balancer
であるHA Proxy
に、Infraノード
を登録します。
Load Balancer
である HA Proxy
サーバーに移動して、/etc/haproxy/haproxy.cfg
を編集します。
<省略>
backend machine_config
mode tcp
balance roundrobin
server bs bs.ocp45.example.localdomain:22623 check
server m1 m1.ocp45.example.localdomain:22623 check
server m2 m2.ocp45.example.localdomain:22623 check
server m3 m3.ocp45.example.localdomain:22623 check
backend worker_http
mode tcp
balance source
server i1 i1.ocp45.example.localdomain:80 check # 追加
server i2 i2.ocp45.example.localdomain:80 check # 追加
server i3 i3.ocp45.example.localdomain:80 check # 追加
server w1 w1.ocp45.example.localdomain:80 check
server w2 w2.ocp45.example.localdomain:80 check
server w3 w3.ocp45.example.localdomain:80 check
backend worker_https
mode tcp
balance source
server i1 i1.ocp45.example.localdomain:443 check # 追加
server i2 i2.ocp45.example.localdomain:443 check # 追加
server i3 i3.ocp45.example.localdomain:443 check # 追加
server w1 w1.ocp45.example.localdomain:443 check
server w2 w2.ocp45.example.localdomain:443 check
server w3 w3.ocp45.example.localdomain:443 check
設定を変更したら、有効化します。
systemctl restart haproxy
8.2.3 Infraノードに taint を付ける
以下のコマンドで、Infraノード
にtaint
を付けます。
taint
は、Kubernetes
のPod
のスケジューリングを意図通りに行うために使われるテクニックの一つです。(参考:TaintとToleration)
taint
を付ける前に、OpenShift Console
のHome
→Overview
でAlert
が上がってないか確認し作業前の状態に問題が無いか確認して下さい。
taint
を付ける事でコンテナの移動が発生する事があり、一時的な警告などが表示される事があります。元から出ていた警告・エラーなのか、taint
の追加により発生した警告・エラーなのか判別するために事前に状態を確認しておきます。
taint
は、Key=Value:Effect
の形式で表されますが、ここではInfraノード
に
infra
=reserved
:NoSchedule
infra
=reserved
:NoExecute
の2つのtaint
を付けます。
oc adm taint node i1.ocp45.example.localdomain infra=reserved:NoSchedule infra=reserved:NoExecute
oc adm taint node i2.ocp45.example.localdomain infra=reserved:NoSchedule infra=reserved:NoExecute
oc adm taint node i3.ocp45.example.localdomain infra=reserved:NoSchedule infra=reserved:NoExecute
taint
は以下のコマンドで確認できます。
oc describe node <node名>
<省略>
CreationTimestamp: Sat, 10 Oct 2020 01:00:40 +0900
Taints: infra=reserved:NoExecute
infra=reserved:NoSchedule
Unschedulable: false
<省略>
taint
を付ける事で、これまでInfraノード
上に配置されていた、toleration
の無い一部のコンテナがInfraノード
外に追い出されます。
OpenShift Console
のHome
->Overview
で状態が落ち着くまでAlert
を確認して下さい。
特に問題が無さそうであればInfraノード
のセットアップは完了です。
8.3.Cluster Logging のセットアップ
この手順はPV
を作成できるようになっている事が前提です。
OpenShift
では、ロギングにEKF(ElastictSearch/Fluented/Kibana)
スタックを使用しています。OpenShift
ではこれをひとまとめにCluster Logging
と読んでいます。
以下の手順を参考にCluster Logging
をインストールします。独立した手順として成り立たせるために、Infraノード
の作成についても書いてますが、その部分は、セクション「8.2.infraノードの作成」 と同じなのでスキップして大丈夫です。
OpenShift 上に Cluster Logging (EFK) をインストールする
8.4.Container Registry の作成
OpenShift
上にOpenShift
標準のContainer Registry
を作成します。
この手順は、OCS
がインターナルモード(OpenShift
のクラスター内のノード
として稼働)で作成されている事が前提です。
(OCS
で無いストレージを使用している場合は、Storage Class
名が、使用するストレージが提供しているStorage Class
名になります)
8.4.1.Registry 用 Storage Class と PVC の実行
既存のOCS
のFileSystem
用のStorageClass
の定義ocs-storagecluster-cephfs
を元に、新しいStroageClass
を作成します。
oc get sc ocs-storagecluster-cephfs -o yaml > my-sc-fs.yaml
上記で出力したStorage Class
の定義を元に編集して、Storage Class
名my-registry-fs-sc
を作成します。
デフォルトで用意されているStorage Class
は、Reclaim Policy
が、Delete
です。
一応、Cotainer Registry
に保管されるデータは、その企業の資産とも言えるので、Reclaim Policy
をRetain
に書き替えた新しいStorage Class
を作ります。
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: my-registry-fs-sc # my-registry-fs-sc という名前を付けます。
parameters:
clusterID: openshift-storage
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: openshift-storage
csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
csi.storage.k8s.io/node-stage-secret-namespace: openshift-storage
csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: openshift-storage
fsName: ocs-storagecluster-cephfilesystem
provisioner: openshift-storage.cephfs.csi.ceph.com
reclaimPolicy: Retain # ここを Delete から Retainに
volumeBindingMode: Immediate
作成したmy-sc-fs.yaml
を適用します。
oc apply -f my-sc-fs.yaml
新しいSC(Storage Class)
ができた事を確認します
# oc get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
localblock kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 2d12h
my-registry-fs-sc openshift-storage.noobaa.io/obc Retain Immediate false 2m16s
ocs-storagecluster-ceph-rbd openshift-storage.rbd.csi.ceph.com Delete Immediate true 2d12h
ocs-storagecluster-ceph-rgw openshift-storage.ceph.rook.io/bucket Delete Immediate false 2d12h
ocs-storagecluster-cephfs openshift-storage.cephfs.csi.ceph.com Delete Immediate true 2d12h
openshift-storage.noobaa.io openshift-storage.noobaa.io/obc Delete Immediate false 2d12h
Storage Class
名、my-registry-fs-sc
が作成されています。
次に作成したStorage Class
を使ってPV
をClaim
するために、以下のような、PVC(Persistent Volume Claim)
定義ファイルmy-pvc-fs.yaml
を作ります。PVC
名は、image-registry-storage
で、サイズは100Gi
にしています。
apiVersion: "v1"
kind: "PersistentVolumeClaim"
metadata:
name: "image-registry-storage"
spec:
accessModes:
- "ReadWriteMany"
resources:
requests:
storage: "100Gi"
storageClassName: "my-registry-fs-sc" # 先ほど作成した Storage Class
以下のコマンドで、作成したmy-pvc-fs.yaml
を適用しPVC
を作成します。
# oc project openshift-image-registry # まず Registry の Project に移動します。
# oc apply -f my-pvc-fs.yaml
PVC
が出来た事を確認します。
# oc get pvc -n openshift-image-registry
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
image-registry-storage Bound pvc-4a3e0b7e-8b30-4753-98aa-95d92d244e26 100Gi RWX my-registry-fs-sc 4s
Status
がBound
になっていればOKです。
8.4.2.Registryの構成
configs.imageregistry.operator.openshift.io
のmanagedState
をManged
に変更します。
oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"managementState":"Managed"}}'
念のためopenshift-image-registry
ネームスペースのPod
が問題なく稼働している事を確認します。
[root@bastion openshift]# oc get pod -n openshift-image-registry
NAME READY STATUS RESTARTS AGE
cluster-image-registry-operator-56d78bc5fb-fckwp 2/2 Running 0 19h
image-registry-58876b649-v48xk 1/1 Running 0 5m51s
node-ca-c5v7p 1/1 Running 0 5h15m
node-ca-cxn2g 1/1 Running 0 19h
node-ca-db25w 1/1 Running 0 19h
node-ca-f2nk8 1/1 Running 0 19h
node-ca-gvng5 1/1 Running 0 19h
node-ca-gzh4m 1/1 Running 0 5h15m
node-ca-j7nxd 1/1 Running 0 19h
node-ca-k652z 1/1 Running 0 19h
node-ca-ls9rp 1/1 Running 0 19h
node-ca-s5v4f 1/1 Running 0 5h15m
node-ca-tg2hz 1/1 Running 0 19h
node-ca-vnq7j 1/1 Running 0 19h
[root@bastion openshift]#
先ほど作成したPVC
が、 configs.imageregistry.operator.openshift.io
から参照されるように設定します。
oc edit configs.imageregistry.operator.openshift.io
<省略>
spec:
httpSecret: 4c0857824322cf083be5198d5ca486eeed9afb18c2870fcdef3a78efe21168e545a192ab6b1030c86870ef45072fcbcef0a359c0d435ad04f6cfa2475a0f027e
logging: 2
managementState: Managed
proxy: {}
replicas: 1
requests:
read:
maxWaitInQueue: 0s
write:
maxWaitInQueue: 0s
rolloutStrategy: RollingUpdate
storage: # {} を削除
pvc: # 追加
claim: image-registry-storage # 追加 (前段で作成したPVC名。空欄にした場合でも、この名前が自動でセットされる)
status:
conditions:
- lastTransitionTime: "2020-10-09T15:57:45Z"
reason: AsExpected
status: "False"
<省略>
image-registry Operator
のステータスを確認します。
# oc get clusteroperator image-registry
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE
image-registry 4.5.13 True False True 6m17s
AVAILABLE
がTrue
になるまで待ちます。数分かかるはずです。
8.4.3.Container Registry のInfraノードへの移動
以下のコマンドで、Container Regsitry
をInfraノード
に移動させます。
oc patch configs.imageregistry.operator.openshift.io/cluster --type=merge -p '{"spec":{"nodeSelector": {"node-role.kubernetes.io/infra": ""},"tolerations": [{"effect":"NoSchedule","key": "infra","value": "reserved"},{"effect":"NoExecute","key": "infra","value": "reserved"}]}}'
ワンライナーでちょっと読みにくいですが、nodeSelector
でInfraノード
を指定し、Infraノード
のtaint
に弾かれないようにtolerations
を付けています。
確認してみます。
[root@bastion openshift]# oc get pod -n openshift-image-registry
NAME READY STATUS RESTARTS AGE
cluster-image-registry-operator-56d78bc5fb-6kflj 2/2 Running 0 15h
image-pruner-1604016000-2hhx7 0/1 Completed 0 6h34m
image-registry-58579b74c5-pbwr4 1/1 Running 0 2m24s
node-ca-58d7m 1/1 Running 0 14h
node-ca-5h2x9 1/1 Running 0 5h32m
node-ca-5ngxk 1/1 Running 0 14h
node-ca-8cvd6 1/1 Running 0 14h
node-ca-92xtj 1/1 Running 0 14h
node-ca-cxn5g 1/1 Running 0 15h
node-ca-drgkr 1/1 Running 0 15h
node-ca-jdlrd 1/1 Running 0 5h32m
node-ca-jtsls 1/1 Running 0 5h32m
node-ca-n9gl5 1/1 Running 0 14h
node-ca-qbwqc 1/1 Running 0 14h
node-ca-zvtq8 1/1 Running 0 15h
[root@bastion ~]#
どのコンポーネントが何かというのは、見た目で判断するしかないのですが、各ノード毎に置かれているコンポーネント以外の配置について確認してみます。
[root@bastion openshift]# oc describe pods cluster-image-registry-operator-56d78bc5fb-6kflj -n openshift-image-registry | grep Node:
Node: m2.ocp45.example.localdomain/172.16.0.22
[root@bastion openshift]# oc describe pods image-registry-58579b74c5-pbwr4 -n openshift-image-registry | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion openshift]# oc describe pods image-pruner-1604016000-2hhx7 -n openshift-image-registry | grep Node:
Node: s3.ocp45.example.localdomain/172.16.0.53
cluster-image-registry-operator-xxxx
は、Masterノード
上に配置されていますが、Controller
だと思われるので、これで良い事にします。
image-pruner-xxxx
が、Workerノード
上で実行された形跡がありますが、これは一時的なPod
なので後で問題なさそうですが、後で追求してみます。
この例だとimage-registry-58876b649-v48xk
が、Infraノード
上にあれば問題なさそうなので、これで良い事にします。
Image Registry の
8.5. RouterのInfraノードへの移動
この手順は、Infraノード
が作成されている事が前提になります。
8.5.1.nodeSelectorとtolerationの設定
Infraノード
に、Podをスケジュールするには、nodeSelector
で、Infraノード
を選択させます。
またInfraノード
にユーザーアプリケーションがスケジュールされないように、最終的にInfraノード
にtaint
を付けます。そのtaint
を無視できるようにtoleration
もInfraノード
にスケジュールするコンポーネントに付ける必要があります。
まとめると、Infraノード
にスケジュールする、コンポーネントには、以下の記述をspec
に追加します。
spec:
nodePlacement:
nodeSelector:
matchLabels:
node-role.kubernetes.io/infra: ""
tolerations:
- effect: NoSchedule
key: infra
value: reserved
- effect: NoExecute
key: infra
value: reserved
Router
に上記のnodeSelector
とtoleration
を追加するために以下のコマンドを実行します。
oc patch ingresscontroller/default -n openshift-ingress-operator --type=merge -p '{"spec":{"nodePlacement": {"nodeSelector": {"matchLabels": {"node-role.kubernetes.io/infra": ""}},"tolerations": [{"effect":"NoSchedule","key": "infra","value": "reserved"},{"effect":"NoExecute","key": "infra","value": "reserved"}]}}}'
さらにデフォルトでは、Router
は、2つしか Replica を持たないので、Infraノード
の数に合わせるため3つにします。
oc patch ingresscontroller/default -n openshift-ingress-operator --type=merge -p '{"spec":{"replicas": 3}}'
8.5.2.スケジュールの確認
oc describe node | grep ingress
で、ingress
関連のコンポーネントの名前を見つけます。
root@bastion openshift]# oc describe node | grep ingress
openshift-ingress router-default-cbbf5f64-fxpzf 100m (2%) 0 (0%) 256Mi (0%) 0 (0%) 4m25s
openshift-ingress router-default-cbbf5f64-m4mhp 100m (2%) 0 (0%) 256Mi (0%) 0 (0%) 4m45s
openshift-ingress router-default-cbbf5f64-g4tvj 100m (2%) 0 (0%) 256Mi (0%) 0 (0%) 4m59s
openshift-ingress-operator ingress-operator-56f5778d85-ddncf 20m (0%) 0 (0%) 40Mi (0%) 0 (0%) 15h
[root@bastion openshift]#
一つ一つ配置を確認してみます。
[root@bastion openshift]# oc describe pod ingress-operator-56f5778d85-ddncf -n openshift-ingress-operator | grep Node:
Node: m2.ocp45.example.localdomain/172.16.0.22
[root@bastion openshift]# oc describe pod router-default-cbbf5f64-fxpzf -n openshift-ingress | grep Node:
Node: i1.ocp45.example.localdomain/172.16.0.41
[root@bastion openshift]# oc describe pod router-default-cbbf5f64-m4mhp -n openshift-ingress | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion openshift]# oc describe pod router-default-cbbf5f64-g4tvj -n openshift-ingress | grep Node:
Node: i3.ocp45.example.localdomain/172.16.0.43
[root@bastion openshift]#
ingress-operator-xxxx
は、Masterノード
で、その他はinfraノード
なので問題なさそうです。
以上で、Router
の設定は完了です。
Router
の設定は以下のKBを参考にしました。
参考:Configuring Infrastructure Nodes with Taint in OpenShift 4
このKBは、他のコンポーネントのinfraノード
へのスケジュール方法も書いてますが、気づいた範囲ではPrometheus
部分で、Thanos
の設定が抜けているようです。
8.6. Prometheus の構成
Prometheus
関連のコンポーネントは、OpenShift
ではCluster Monitoring
と呼ばれています。
OpenShift
のインストールと一緒にPrometheus
は既にインストールされて稼働しています。
ここではPrometheus
のメインコンポーネントを、Infraノード
に移動させデータ保管用にPV
を作成します。
この作業はPrometheus
設定用のConfigMap
を作成する事で実現できます。
8.6.1. Prometheus 用のPVの作成とInfraノードへの移動
以下のcluster-monitoring-configmap.yaml
を作成します。
Promethues
の各コンポーネントに、nodeSelector
を使ってInfraノード
に配置するよう指定する事と、Infraノード
に付いているtaint
を無視するようにtoleration
を付けたConfigMap
リソースを作成しています。
ここではログ保管用に40Gi
のPVC
をしていいます。事前にPVC
をする事でPV
が作成される環境である事を想定しています。
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-monitoring-config
namespace: openshift-monitoring
data:
config.yaml: |+
alertmanagerMain:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
prometheusK8s:
volumeClaimTemplate: # volumeCliaimTemplate
spec: # 追加
storageClassName: ocs-storagecluster-cephfs # Ceph FileSystem の Storage Class
volumeMode: Filesystem # FileSystem
resources: # 追加
requests: # 追加
storage: 40Gi # Size はとりあえず 40Gi
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
prometheusOperator:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
grafana:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
k8sPrometheusAdapter:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
kubeStateMetrics:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
telemeterClient:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
openshiftStateMetrics:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
thanosQuerier:
nodeSelector: # nodeSelectorでinfraを選ぶ
node-role.kubernetes.io/infra: ""
tolerations: # toleration を付ける
- key: infra
value: reserved
effect: NoSchedule
- key: infra
value: reserved
effect: NoExecute
作成したファイルを適用します。
oc create -f cluster-monitoring-configmap.yaml
PVC
ができているか確認します。
# oc get pvc -n openshift-monitoring
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
prometheus-k8s-db-prometheus-k8s-0 Bound pvc-78175f98-d22e-4023-96ac-6bf2a92b973b 40Gi RWO ocs-storagecluster-cephfs 36s
prometheus-k8s-db-prometheus-k8s-1 Bound pvc-22975d1f-47ed-40a5-b1d6-5131c22dab36 40Gi RWO ocs-storagecluster-cephfs 35s
2つPVC
が出来ていてStatus
がBound
になっていればOKです。
各コンポーネントの配置を確認してみます。
[root@bastion ~]# oc get pods -n openshift-monitoring
NAME READY STATUS RESTARTS AGE
alertmanager-main-0 5/5 Running 0 20h
alertmanager-main-1 5/5 Running 0 20h
alertmanager-main-2 5/5 Running 0 20h
cluster-monitoring-operator-79d58c4598-hqrc7 2/2 Running 2 39h
grafana-859c496b85-84rnh 2/2 Running 0 20h
kube-state-metrics-ff7bbdd5c-bwjwt 3/3 Running 0 20h
node-exporter-2ptbn 2/2 Running 0 39h <== これは Node毎にある。
node-exporter-65ckx 2/2 Running 0 39h
node-exporter-94kpv 2/2 Running 0 25h
node-exporter-9gfrm 2/2 Running 0 39h
node-exporter-bmfmb 2/2 Running 0 39h
node-exporter-g5pt6 2/2 Running 0 25h
node-exporter-l7qsx 2/2 Running 0 39h
node-exporter-mmw2f 2/2 Running 0 39h
node-exporter-rvq5j 2/2 Running 0 25h
node-exporter-rvs6h 2/2 Running 0 39h
node-exporter-z7pbv 2/2 Running 0 39h
node-exporter-zzhv6 2/2 Running 0 39h
openshift-state-metrics-674b677b97-5m9bk 3/3 Running 0 20h
prometheus-adapter-ccfbd8b84-wbvbk 1/1 Running 0 16h
prometheus-adapter-ccfbd8b84-xx8mc 1/1 Running 0 16h
prometheus-k8s-0 7/7 Running 0 5h18m
prometheus-k8s-1 7/7 Running 0 5h19m
prometheus-operator-7bf95c767d-9b9wp 2/2 Running 0 20h
telemeter-client-76966457-8k5g6 3/3 Running 0 20h
thanos-querier-867c77f45d-d8gg2 4/4 Running 0 4m56s
thanos-querier-867c77f45d-k4h84 4/4 Running 0 5m15s
ノード
毎に必要なexporter
以外の配置を確認してみます。
[root@bastion ~]# oc describe pods alertmanager-main-0 -n openshift-monitoring | grep Node:
Node: i1.ocp45.example.localdomain/172.16.0.41
[root@bastion ~]# oc describe pods alertmanager-main-1 -n openshift-monitoring | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion ~]# oc describe pods alertmanager-main-2 -n openshift-monitoring | grep Node:
Node: i3.ocp45.example.localdomain/172.16.0.43
[root@bastion ~]# oc describe pods cluster-monitoring-operator-79d58c4598-hqrc7 -n openshift-monitoring | grep Node:
Node: m2.ocp45.example.localdomain/172.16.0.22
[root@bastion ~]# oc describe pods grafana-859c496b85-84rnh -n openshift-monitoring | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion ~]# oc describe pods kube-state-metrics-ff7bbdd5c-bwjwt -n openshift-monitoring | grep Node:
Node: i1.ocp45.example.localdomain/172.16.0.41
[root@bastion ~]# oc describe pods kube-state-metrics-ff7bbdd5c-bwjwt -n openshift-monitoring | grep Node:
Node: i1.ocp45.example.localdomain/172.16.0.41
[root@bastion ~]# oc describe pods openshift-state-metrics-674b677b97-5m9bk -n openshift-monitoring | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion ~]# oc describe pods prometheus-adapter-ccfbd8b84-wbvbk -n openshift-monitoring | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion ~]# oc describe pods prometheus-adapter-ccfbd8b84-xx8mc -n openshift-monitoring | grep Node:
Node: i3.ocp45.example.localdomain/172.16.0.43
[root@bastion ~]# oc describe pods prometheus-k8s-0 -n openshift-monitoring | grep Node:
Node: i3.ocp45.example.localdomain/172.16.0.43
[root@bastion ~]# oc describe pods prometheus-k8s-1 -n openshift-monitoring | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion ~]# oc describe pods prometheus-operator-7bf95c767d-9b9wp -n openshift-monitoring | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion ~]# oc describe pods telemeter-client-76966457-8k5g6 -n openshift-monitoring | grep Node:
Node: i1.ocp45.example.localdomain/172.16.0.41
[root@bastion openshift]# oc describe pods thanos-querier-867c77f45d-d8gg2 -n openshift-monitoring | grep Node:
Node: i2.ocp45.example.localdomain/172.16.0.42
[root@bastion openshift]# oc describe pods thanos-querier-867c77f45d-k4h84 -n openshift-monitoring | grep Node:
Node: i1.ocp45.example.localdomain/172.16.0.41
[root@bastion openshift]#
概ね必要なコンポーネントは、Infraノード
に配置されているようです。
cluster-monitoring-operator-xxx
がMasterノード
に配置されていましたが、これは指定方法がマニュアルになかったのと、このままで良さそうなので設計通りなのかもしれません。
概ねInfraノード
に配置されているという事で、良い事にします。
参考: 1.1. About cluster monitoring
8.7. Workerノード の Load Balancer からの削除
HTTP/HTTPS トラフィックは、この環境でのLoad Balancer
であるHA Proxy
から、Infraノード
上のRouter
で一旦受けた後、Pod
に割り振られます。
Workerノード
でLoad Balancer(HA Proxy)
から直接トラフィックを受け取る必要がないので、HA Proxy
の設定からWorkerノード
を取り外します。
また、好みの問題ですが、xxxxx_workerhttp(s) だった部分 をxxxxx_infrahttp(s)に置き換えています。
<省略>
frontend infrahttp # 名前の変更
default_backend infra_http # 名前の変更
mode tcp
bind *:80
frontend infrahttps # 名前の変更
default_backend infra_https # 名前の変更
mode tcp
bind *:443
<省略>
backend infra_http # 名前の変更
mode tcp
balance source
server i1 i1.ocp45.example.localdomain:80 check
server i2 i2.ocp45.example.localdomain:80 check
server i3 i3.ocp45.example.localdomain:80 check
backend infra_https # 名前の変更
mode tcp
balance source
server i1 i1.ocp45.example.localdomain:443 check
server i2 i2.ocp45.example.localdomain:443 check
server i3 i3.ocp45.example.localdomain:443 check
設定を変更したら、有効化します。
haproxy -f /etc/haproxy/haproxy.cfg -c # 構成の確認
systemctl restart haproxy # 再起動
現在、OpenShift Console
の入り口となるRouter
(OpenShift
のIngress
)は、Infraノード
に配置されているはずなので、アクセスできるかどうか確認してみてください。(OpneShift
のConsole
のPod
は、、Masterノード
に配置されています。)
9.(番外編) OpenShift クラスタ-インストール時のDebug
OpenShift
クラスターのインストールは、手順が多いのでミスをしないで進めることはなかなか大変です。
ここでは、クラスターのインストール時に使えそうなデバック手法について、幾つか解説します。
9.1. ignition ファイルの期限切れ
はじめのインストールは時間がかかります。そうこうしているうちにセクション[「4.2.3.ignition ファイルの作成 (manifestファイルのignitionファイルへの変換)」] (#423ignition-ファイルの作成-manifestファイルのignitionファイルへの変換)で作成した ignition ファイルが期限切れしている事があります。これらのファイルの期限は24時間ですので、もし24時間経過していたらこのファイルを再作成する必要があります。
9.2. ネットワークの設定確認
経験上、エラーの殆どはネットワーク設定に起因します。
UPI
インストールは、OpenShift
のIPI
インストールよりも、周辺サーバーの構築が作業の殆どのウェイトを占めるためミスを誘発する要素を大量に含んでいます。
沼に吸い込まれる前に、まずはネットワークの確認を(面倒でも)確認して足下を固めましょう。
1.ロードバランサーは正しく構成されているか
2.ドメイン名は正しく解決されるか
3.ポートは正しく開いているか(firewalld
が邪魔していないか)
4.SELinuxが動作を邪魔していないか
5.必要なファイルは、boostrap/master/workerノードから正しくアクセスできているか
これらの確認方法に決まった手順があるわけではないので、これまでの知識を総動員して動きを確認してみましょう。
また、セクション「6.ネットワーク環境の疎通確認」に記載されているネットワークの疎通確認は、是非とももう一度試して見て下さい。いろいろいじっているうちに構成を変更してしまい、上手く動いてない可能性もあります。
9.3. oc get nodes コマンドを打ってみる
以下は、host名の逆引きができない状態でインストールを行い、インストールが失敗した時に oc get nodes
を実行してみた時の結果です。
[root@bastion openshift]# oc get nodes
NAME STATUS ROLES AGE VERSION
localhost Ready master,worker 32m v1.18.3+47c0e71
[root@bastion openshift]#
通常は、node のホスト名が入る場所に localhost
と入ってます。ここから「もしかして名前の逆引きができる必要があるのでは?」と推理を働かせる事ができます。(その推理が当たっているかどうかは定かではありませんが)
oc describe node localhost
で、この node の IPが何なのか情報が取れます。
[root@bastion openshift]# oc describe node localhost
Name: localhost
Roles: master,worker
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=localhost
kubernetes.io/os=linux
node-role.kubernetes.io/master=
node-role.kubernetes.io/worker=
node.openshift.io/os_id=rhcos
Annotations: machineconfiguration.openshift.io/currentConfig: rendered-master-42e06c66fbcaf5796b9413e85dc2d752
machineconfiguration.openshift.io/desiredConfig: rendered-master-42e06c66fbcaf5796b9413e85dc2d752
machineconfiguration.openshift.io/reason:
machineconfiguration.openshift.io/state: Done
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Fri, 02 Oct 2020 17:12:17 +0900
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: localhost
AcquireTime: <unset>
RenewTime: Fri, 02 Oct 2020 17:47:27 +0900
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Fri, 02 Oct 2020 17:47:24 +0900 Fri, 02 Oct 2020 17:12:17 +0900 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Fri, 02 Oct 2020 17:47:24 +0900 Fri, 02 Oct 2020 17:12:17 +0900 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Fri, 02 Oct 2020 17:47:24 +0900 Fri, 02 Oct 2020 17:12:17 +0900 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Fri, 02 Oct 2020 17:47:24 +0900 Fri, 02 Oct 2020 17:14:18 +0900 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 172.16.0.21
Hostname: localhost
Capacity:
<略>
InternalIP: 172.16.0.21
とあり、これはこの環境では、Masterノード
のIPとして提供したものなので、この謎のlocalhost
は、Masterノード
であるようです。
このことから「Masterノード
が上がってきているという事は、BootStrapノード
は正しくセットアップされた。という可能性が高いな」と想像する事ができます。(これもまたその推理が正しいか保証はありませんが)
こういった情報が、実際、どんな役に立つかは状況次第ですが、こう言った情報を集めてどの辺りが悪そうか当たりをつけていきましょう。
9.4. インストール中の CoreOS 内のログの観察
インストール中の Boostrap Node
や Masterノード
にログインしてインストールの経過を見る事ができます。
もしインストールが上手く行かなかった場合 BootStrapノード
にログインして状況を確認すると何か原因のヒントがつかめるかもしれません。
CoreOS
は core
というユーザーと、インストール時に作成した公開鍵、秘密鍵の秘密鍵
を使って ssh
ログインする事ができます。
BootStrap
ノードのログイン画面がでたらすかさず以下のコマンドで、踏み台サーバー
(通常 SSHキーをそこに保存して、ここからインストールコマンドを実行していると思います) から SSH ログインします。(ログイン画面からはログインできません)
[root@bastion .ssh]# ssh core@bs -i <作成した秘密鍵>
※bs
=この環境での BootStrapノード
です。ここでは bs
で bootstrap
のノードIPに名前解決されるように /etc/hosts
に登録済みです。この解説を読んでいる時点で、あなたは既に魔物に囚われているはずです。そうそう抜け出せないので/etc/hosts
には、各ノード
のホスト名を登録して起きましょう。これからの長い修行(デバッグ)が楽になります。
※ノード
を作り直した場合は、bastion
サーバー上の ./ssh/known_hosts
から、bootstrap
サーバーの登録を削除する必要があります。
CoreOS
内では、journalctl
コマンドでログが確認できます。例えば、bootkube
サービスのログを見るには以下のようにします。
journalctl -b -f -u release-image.service -u bootkube.service
CoreOS 内のサービス・ログの読み方の注意
以下は、bootstrap
ノードでjournalctl -b -f -u release-image.service -u bootkube.service
コマンドで、bootkube
サービスのログを確認した時の抜粋です。
途中に大量に fail
という文字がでて[#171] failed to create some manifests:
というような文字も見えます。
Sep 28 13:38:24 localhost bootkube.sh[2632]: Failed to create "openshift-install-manifests.yaml" configmaps.v1./openshift-install-manifests -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: Failed to create "secret-initial-kube-controller-manager-service-account-private-key.yaml" secrets.v1./initial-service-account-private-key -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: [#170] failed to create some manifests:
Sep 28 13:38:24 localhost bootkube.sh[2632]: "99_openshift-machineconfig_99-master-ssh.yaml": unable to get REST mapping for "99_openshift-machineconfig_99-master-ssh.yaml": no matches for kind "MachineConfig" in version "machineconfiguration.openshift.io/v1"
Sep 28 13:38:24 localhost bootkube.sh[2632]: "99_openshift-machineconfig_99-worker-ssh.yaml": unable to get REST mapping for "99_openshift-machineconfig_99-worker-ssh.yaml": no matches for kind "MachineConfig" in version "machineconfiguration.openshift.io/v1"
Sep 28 13:38:24 localhost bootkube.sh[2632]: "configmap-admin-kubeconfig-client-ca.yaml": failed to create configmaps.v1./admin-kubeconfig-client-ca -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "configmap-csr-controller-ca.yaml": failed to create configmaps.v1./csr-controller-ca -n openshift-config-managed: namespaces "openshift-config-managed" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "configmap-initial-etcd-serving-ca.yaml": failed to create configmaps.v1./initial-etcd-ca -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "configmap-kubelet-bootstrap-kubeconfig-ca.yaml": failed to create configmaps.v1./kubelet-bootstrap-kubeconfig -n openshift-config-managed: namespaces "openshift-config-managed" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "configmap-sa-token-signing-certs.yaml": failed to create configmaps.v1./sa-token-signing-certs -n openshift-config-managed: namespaces "openshift-config-managed" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "etcd-ca-bundle-configmap.yaml": failed to create configmaps.v1./etcd-ca-bundle -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "etcd-client-secret.yaml": failed to create secrets.v1./etcd-client -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "etcd-metric-client-secret.yaml": failed to create secrets.v1./etcd-metric-client -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "etcd-metric-serving-ca-configmap.yaml": failed to create configmaps.v1./etcd-metric-serving-ca -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "etcd-metric-signer-secret.yaml": failed to create secrets.v1./etcd-metric-signer -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "etcd-serving-ca-configmap.yaml": failed to create configmaps.v1./etcd-serving-ca -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "etcd-signer-secret.yaml": failed to create secrets.v1./etcd-signer -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "kube-apiserver-serving-ca-configmap.yaml": failed to create configmaps.v1./initial-kube-apiserver-server-ca -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "openshift-config-secret-pull-secret.yaml": failed to create secrets.v1./pull-secret -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "openshift-install-manifests.yaml": failed to create configmaps.v1./openshift-install-manifests -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: "secret-initial-kube-controller-manager-service-account-private-key.yaml": failed to create secrets.v1./initial-service-account-private-key -n openshift-config: namespaces "openshift-config" not found
Sep 28 13:38:24 localhost bootkube.sh[2632]: Created "configmap-admin-kubeconfig-client-ca.yaml" configmaps.v1./admin-kubeconfig-client-ca -n openshift-config
Sep 28 13:38:24 localhost bootkube.sh[2632]: Created "configmap-csr-controller-ca.yaml" configmaps.v1./csr-controller-ca -n openshift-config-managed
Sep 28 13:38:25 localhost bootkube.sh[2632]: Created "configmap-initial-etcd-serving-ca.yaml" configmaps.v1./initial-etcd-ca -n openshift-config
Sep 28 13:38:25 localhost bootkube.sh[2632]: Created "configmap-kubelet-bootstrap-kubeconfig-ca.yaml" configmaps.v1./kubelet-bootstrap-kubeconfig -n openshift-config-managed
Sep 28 13:38:25 localhost bootkube.sh[2632]: Created "configmap-sa-token-signing-certs.yaml" configmaps.v1./sa-token-signing-certs -n openshift-config-managed
Sep 28 13:38:25 localhost bootkube.sh[2632]: Created "etcd-ca-bundle-configmap.yaml" configmaps.v1./etcd-ca-bundle -n openshift-config
Sep 28 13:38:25 localhost bootkube.sh[2632]: Created "etcd-client-secret.yaml" secrets.v1./etcd-client -n openshift-config
Sep 28 13:38:26 localhost bootkube.sh[2632]: Created "etcd-metric-client-secret.yaml" secrets.v1./etcd-metric-client -n openshift-config
Sep 28 13:38:26 localhost bootkube.sh[2632]: Created "etcd-metric-serving-ca-configmap.yaml" configmaps.v1./etcd-metric-serving-ca -n openshift-config
Sep 28 13:38:26 localhost bootkube.sh[2632]: Created "etcd-metric-signer-secret.yaml" secrets.v1./etcd-metric-signer -n openshift-config
Sep 28 13:38:26 localhost bootkube.sh[2632]: Created "etcd-serving-ca-configmap.yaml" configmaps.v1./etcd-serving-ca -n openshift-config
Sep 28 13:38:26 localhost bootkube.sh[2632]: Created "etcd-signer-secret.yaml" secrets.v1./etcd-signer -n openshift-config
Sep 28 13:38:27 localhost bootkube.sh[2632]: Created "kube-apiserver-serving-ca-configmap.yaml" configmaps.v1./initial-kube-apiserver-server-ca -n openshift-config
Sep 28 13:38:27 localhost bootkube.sh[2632]: Created "openshift-config-secret-pull-secret.yaml" secrets.v1./pull-secret -n openshift-config
Sep 28 13:38:27 localhost bootkube.sh[2632]: Created "openshift-install-manifests.yaml" configmaps.v1./openshift-install-manifests -n openshift-config
Sep 28 13:38:27 localhost bootkube.sh[2632]: Created "secret-initial-kube-controller-manager-service-account-private-key.yaml" secrets.v1./initial-service-account-private-key -n openshift-config
Sep 28 13:38:27 localhost bootkube.sh[2632]: [#171] failed to create some manifests:
Sep 28 13:38:27 localhost bootkube.sh[2632]: "99_openshift-machineconfig_99-master-ssh.yaml": unable to get REST mapping for "99_openshift-machineconfig_99-master-ssh.yaml": no matches for kind "MachineConfig" in version "machineconfiguration.openshift.io/v1"
Sep 28 13:38:27 localhost bootkube.sh[2632]: "99_openshift-machineconfig_99-worker-ssh.yaml": unable to get REST mapping for "99_openshift-machineconfig_99-worker-ssh.yaml": no matches for kind "MachineConfig" in version "machineconfiguration.openshift.io/v1"
Sep 28 13:38:27 localhost bootkube.sh[2632]: Created "99_openshift-machineconfig_99-master-ssh.yaml" machineconfigs.v1.machineconfiguration.openshift.io/99-master-ssh -n
Sep 28 13:38:28 localhost bootkube.sh[2632]: Created "99_openshift-machineconfig_99-worker-ssh.yaml" machineconfigs.v1.machineconfiguration.openshift.io/99-worker-ssh -n
ここで
Sep 28 13:38:24 localhost bootkube.sh[2632]: "configmap-admin-kubeconfig-client-ca.yaml": failed to create configmaps.v1./admin-kubeconfig-client-ca -n openshift-config: namespaces "openshift-config" not found`
という一行に注目してみると、failed to create
になっていますが、数行下の同じタイムスタンプで、以下の様に Created
とでています。
Sep 28 13:38:24 localhost bootkube.sh[2632]: Created "configmap-admin-kubeconfig-client-ca.yaml" configmaps.v1./admin-kubeconfig-client-ca -n openshift-config
fail
は、問題が無い場合でもログ内に大量に記録されているので、その後に何らかの成功ログが無いか注意して判別する必要があります。
エラーでは無いエラーを追いかけると、間違った方向に連れてかれてしまうので、読むのは大変ですが3K(気合いと根性と感性) を使って頑張りましょう。
9.5. HAProxy の動作の観察
ロードバランサー(HAProxy)
には、インストール中、踏み台サーバー
、BootStrap
、Master
からのアクセスが集まってきます。
Sep 29 16:02:59 localhost haproxy[69855]: Connect from 172.16.0.23:55618 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:03 localhost haproxy[69855]: Connect from 172.16.0.21:36944 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:03 localhost haproxy[69855]: Connect from 172.16.0.22:45350 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:04 localhost haproxy[69855]: Connect from 172.16.0.23:55620 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:08 localhost haproxy[69855]: Connect from 172.16.0.21:36946 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:08 localhost haproxy[69855]: Connect from 172.16.0.22:45352 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:08 localhost haproxy[69855]: Server machine_config/bs is UP, reason: Layer4 check passed, check duration: 0ms. 1 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.
Sep 29 16:03:09 localhost haproxy[69855]: Connect from 172.16.0.23:55622 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:12 localhost haproxy[69855]: Connect from 192.168.124.201:58070 to 192.168.124.110:6443 (kubeapi/TCP)
Sep 29 16:03:13 localhost haproxy[69855]: Connect from 172.16.0.21:36948 to 172.16.0.110:22623 (machineconfig/TCP)
Sep 29 16:03:13 localhost haproxy[69855]: Connect from 172.16.0.22:45354 to 172.16.0.110:22623 (machineconfig/TCP)
Message from syslogd@localhost at Sep 29 03:03:15 ...
haproxy[69855]: backend kube_api has no server available!
Sep 29 16:03:15 localhost haproxy[69855]: Server kube_api/bs is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Sep 29 16:03:15 localhost haproxy[69855]: backend kube_api has no server available!
Sep 29 16:03:17 localhost haproxy[69855]: Connect from 192.168.124.201:58072 to 192.168.124.110:6443 (kubeapi/TCP)
Sep 29 16:03:19 localhost haproxy[69855]: Connect from 192.168.124.201:58074 to 192.168.124.110:6443 (kubeapi/TCP)
172.16.0.21~23
は、Master1
~Master3
のIPアドレスで、何らかの活動中である事が見て取れます。
上記のログを見ると、途中で
haproxy[69855]: backend kube_api has no server available!
Sep 29 16:03:15 localhost haproxy[69855]: Server kube_api/bs is DOWN, reason: Layer4 connection problem, info: "Connection refused"
のようなログが上がっています。
kube_api
は今回の例で、ロードバランサー(HA Proxy)
に定義した 6443 ポートへのアクセスを Booststrap
/Master1
~Master3
に割り振るための定義ですが、kube_api/bs is DOWN
(bs
はこの環境での boostrapサーバーの名前)なので、bs
との通信が途絶した事が見て取れます。
インストール中のノード
は、度々再起動がされるため、この手のログは良くでます。通信途絶自体は問題ありませんが、このまま起動してこないと bs
(boostrap) で問題が起きている可能性があります。
10. 変更履歴
2020/11/1 : 初版
2021/08/30 : 9.1を追加