2023年7月2日日曜日

NGINXの負荷分散装置(ロードバランサ)をPacemakerで冗長化する

先日、NGINXを使って負荷分散装置(ロードバランサ)を構築してみた。

2台のサーバに対して負荷分散して通信できることで、リソースを分散させるだけでなく冗長化も図ることができたが、肝心の負荷分散装置であるNGINX自体がシングルポイントとなっているため、可用性の観点から不十分である。

しかし、OSSのNGINXではNGINXによる冗長化機能はないため、もし冗長化したい場合は別の手法を検討する必要がある。そこで、以前から本ブログで紹介したことがある「Pacemaker+Corosync」を使って、クラスタ構成による冗長化を図ることにした。

今回はPacemaker+Corosyncを使ってNGINXをクラスタ化し冗長構成された負荷分散装置(ロードバランサ)を構築する。

環境

環境としては以下の通りAlmaLinuxを利用したが、そのほかのRed Hat系のディストリビューションであれば、ほぼ同様の手順で構築できるはずだ。

  • AlmaLinux 8.5 及び AlmaLinux 9.2
  • NGINX 1.14.1

負荷分散装置の構成は以下の通りとする。クライアントからの通信と負荷分散対象サーバが同一のインタフェースとなる「ワンアーム」構成となる。なお、NGINXでは、通信は必ずSource NATされるため、ワンアーム構成としたとしても特別な設定は不要となる。

Pacemaker+CorosyncによるNGINX冗長化手順

1. 2台のサーバでNGINXを構築

Pacemaker+Corosyncでクラスタを構成する前に、事前にクラスタ対象サーバでNGINXを負荷分散装置として動作するよう構築しておこう。再掲となるが、手順は以下を参照してほしい。

2. Pacemaker+Corosyncを構築

Pacemaker+Corosyncの構築手順は、以前別記事にて記載している。こちらを参考に、クラスタの起動までできるように構築する。

補足として、AlmaLinux 8.5においては、Pacemaker+Corosyncのインストールに必要なリポジトリがHighAvailabilityではなくhaになっている。

# dnf repolist all
repo id                    repo の名前                                    状態
~(中略)~
ha                         AlmaLinux 8 - HighAvailability                 無効化
ha-debuginfo               AlmaLinux 8 - HighAvailability debuginfo       無効化
ha-source                  AlmaLinux 8 - HighAvailability Source          無効化
~(以下略)~

したがって、dnfによるインストール実施時に、リポジトリを以下のように指定して対応しよう。なお、AlmaLinux 9.2ではリポジトリ名がhighavailability(全部小文字)になっていたので、OSバージョンに合わせて適切なリポジトリを選択しよう。

# dnf --enablerepo=ha install pacemaker pcs fence-agents-all pcp-zeroconf -y

3. クラスタリソース及び制約設定

Pacemaker+Corosyncのインストールが終わったら、以下の通りクラスタリソースと制約の設定を行う。

リソース種類 リソース名 設定値
VIP rs-vip-33 ens192のインタフェースに対して192.168.33.23/24のIPアドレスを設定する。
NGINX rs-systemd-nginx NGINXをsystemdにて起動・停止する。
Ping rs-ping-33 ゲートウェイに対して各サーバからPingを実行し、Ping疎通ができないサーバではリソースを起動できないよう制約 (constraint) を設定する。
# pcs resource create rs-vip-33 ocf:heartbeat:IPaddr2 ip=192.168.33.23 cidr_netmask=24 nic=ens192 --group rg-01
# pcs resource create rs-systemd-nginx systemd:nginx --group rg-01

# pcs resource create rs-ping-33 ocf:pacemaker:ping dampen=5s multiplier=1000 host_list=192.168.33.31
# pcs resource clone rs-ping-33
# pcs constraint location rg-01 rule score=-INFINITY pingd lt 1 or not_defined pingd

最終的なリソース及び制約の設定は以下の通り。

# pcs resource show --full
Warning: This command is deprecated and will be removed. Please use 'pcs resource config' instead.
 Group: rg-01
  Resource: rs-vip-33 (class=ocf provider=heartbeat type=IPaddr2)
   Attributes: cidr_netmask=24 ip=192.168.33.23 nic=ens192
   Operations: monitor interval=10s timeout=20s (rs-vip-33-monitor-interval-10s)
               start interval=0s timeout=20s (rs-vip-33-start-interval-0s)
               stop interval=0s timeout=20s (rs-vip-33-stop-interval-0s)
  Resource: rs-systemd-nginx (class=systemd type=nginx)
   Operations: monitor interval=60 timeout=100 (rs-systemd-nginx-monitor-interval-60)
               start interval=0s timeout=100 (rs-systemd-nginx-start-interval-0s)
               stop interval=0s timeout=100 (rs-systemd-nginx-stop-interval-0s)
 Clone: rs-ping-33-clone
  Resource: rs-ping-33 (class=ocf provider=pacemaker type=ping)
   Attributes: dampen=5s host_list=192.168.33.31 multiplier=1000
   Operations: monitor interval=10s timeout=60s (rs-ping-33-monitor-interval-10s)
               start interval=0s timeout=60s (rs-ping-33-start-interval-0s)
               stop interval=0s timeout=20s (rs-ping-33-stop-interval-0s)

# pcs constraint
Location Constraints:
  Resource: rg-01
    Constraint: location-rg-01
      Rule: boolean-op=or score=-INFINITY
        Expression: pingd lt 1
        Expression: not_defined pingd
Ordering Constraints:
Colocation Constraints:
Ticket Constraints:

4. 動作確認

クラスタリソースが稼働しているサーバをシャットダウンした際に、もう1台のサーバにフェイルオーバーすることを確認する。

フェイルオーバー前の状態は以下の通り。

# pcs status
Cluster name: clst-01
Cluster Summary:
  * Stack: corosync
  * Current DC: t3041ngnx (version 2.1.0-8.el8-7c3f660707) - partition with quorum
  * Last updated: Sun Apr 24 11:47:32 2022
  * Last change:  Sat Apr 23 08:50:12 2022 by root via cibadmin on t3041ngnx
  * 2 nodes configured
  * 4 resource instances configured

Node List:
  * Online: [ t3041ngnx t3042ngnx ]

Full List of Resources:
  * Resource Group: rg-01:
    * rs-vip-33 (ocf::heartbeat:IPaddr2):        Started t3041ngnx
    * rs-systemd-nginx  (systemd:nginx):         Started t3041ngnx
  * Clone Set: rs-ping-33-clone [rs-ping-33]:
    * Started: [ t3041ngnx t3042ngnx ]

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

稼働系のサーバをシャットダウンすると、以下の通り残りのサーバでクラスタリソースが再起動されていることがわかる。

# pcs status
Cluster name: clst-01
Cluster Summary:
  * Stack: corosync
  * Current DC: t3042ngnx (version 2.1.0-8.el8-7c3f660707) - partition with quorum
  * Last updated: Sun Apr 24 11:48:15 2022
  * Last change:  Sat Apr 23 08:50:12 2022 by root via cibadmin on t3041ngnx
  * 2 nodes configured
  * 4 resource instances configured

Node List:
  * Online: [ t3042ngnx ]
  * OFFLINE: [ t3041ngnx ]

Full List of Resources:
  * Resource Group: rg-01:
    * rs-vip-33 (ocf::heartbeat:IPaddr2):        Started t3042ngnx
    * rs-systemd-nginx  (systemd:nginx):         Started t3042ngnx
  * Clone Set: rs-ping-33-clone [rs-ping-33]:
    * Started: [ t3042ngnx ]
    * Stopped: [ t3041ngnx ]

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

以上で、Pacemaker+Corosyncを使ってNGINXをクラスタ化し冗長構成された負荷分散装置を構築する手順は完了となる。

更新履歴

  • 2022/6/11 新規作成
  • 2023/7/2 AlmaLinux 9.2の記載を追記

2023年6月25日日曜日

AnsibleでZabbixを操作する (Ansible 8.1 [core 2.15]対応)

自宅ではAnsibleを導入してから、以下OSやソフトウェアに対して作業のコード化や自動化を行ってきた。導入手順などは以下記事を参照。

OS/ソフトウェア URL
Linux AnsibleでLinuxサーバの初期設定と単体テストを行う
Windows Server AnsibleからWindows Serverに接続するための事前作業
vSphere ESXi AnsibleでESXi上に仮想マシンを構築する

今回は、Ansibleを使ってZabbixを操作するための手順を記載する。Zabbixはcommunity.zabbixというモジュールで操作可能となる。

環境

今回手順を確認した環境は以下の通り。

  • コントロールノード
    • OS : AlmaLinux 8.5
    • Ansible : 8.1.0 [core 2.15.1]
  • Zabbix : 6.0.17

AnsibleでZabbixを操作する場合は、事前にzabbix-apiのPythonパッケージをインストールする必要があるため、pipコマンドを使って以下の通りインストールしておこう。

# pip3 install zabbix-api

Zabbixのメンテナンス期間を作成するPlaybook

community.zabbixは、Zabbix設定のための各種モジュールが提供されている。設定したい内容に応じて、以下URLより必要なモジュールを探して利用しよう。

今回は、シンプルにZabbixの「メンテナンス期間」を作成するだけのPlaybookを作成した。

以下にPlaybookの内容を説明する。

Playbook説明

変数 (vars)

Ansibleを使ってZabbixを操作する場合、ansible_userやansible_passwordではなくZabbixのログインユーザ情報とパスワードの指定が常に必要となる。それ以外の設定値の変数は、使用するZabbixモジュールに応じて追加が必要となる。

変数 設定値
ansible_user Zabbixのログインユーザを指定。今回はAdminを指定する。
ansible_httpapi_pass Zabbixのログインユーザのパスワードを指定する。
ansible_network_os community.zabbix.zabbix
ansible_connection httpapi
ansible_httpapi_port 今回はZabbixサーバはHTTPアクセスによる構成としていることから、80を指定する。
ansible_zabbix_url_path Zabbixサーバにアクセスする際のURLのパスを記載する。具体的には、http://[ZabbixサーバのIPアドレス]/[パス]の[パス]に記載の文字列を指定すればよく、通常はzabbixとなるはずだ。
ansible_host ZabbixサーバのIPアドレスを指定する。
zabbix_maintenance.name 「メンテナンス期間」に使用する名前を指定する。
zabbix_maintenance.host_name 「メンテナンス期間」で指定する監視対象ホストを指定する。
zabbix_maintenance.minutes 「メンテナンス期間」の期間を指定する。今回は「30分」を指定する。

タスク (tasks)

今回のPlaybookのタスクは、以下1個のみとなる。

タスク モジュール 説明
メンテナンス期間作成 zabbix_maintenance メンテナンス期間を作成する。「有効期間の開始日時」はタスク実行時間となり、「有効期間の終了日時」はminutesに設定した時間経過後となるため、今回は30分後となる。例えば、Ansibleを5:00に実行した場合は、5:30がメンテナンス期間の終了日時となる。

Playbook

以上をふまえ、Playbook全体は以下となる。

set_zabbix_maintenance.yml

---
- name: Set zabbix maintenance
  gather_facts: true
  hosts: zabbix_servers

  vars:
    ansible_user: Admin
    ansible_httpapi_pass: zabbix
    ansible_network_os: community.zabbix.zabbix
    ansible_connection: httpapi
    ansible_httpapi_port: 80
    ansible_zabbix_url_path: zabbix
    ansible_host: 192.168.11.24

    zabbix_maintenance:
      name: Test maintenance
      host_name: Zabbix server
      minutes: 30

  tasks:
    - name: Enable maintenance
      community.zabbix.zabbix_maintenance:
        name: "{{ zabbix_maintenance.name }}"
        host_name: "{{ zabbix_maintenance.host_name }}"
        minutes: "{{ zabbix_maintenance.minutes }}"
        collect_data: true
        state: present

実行結果

Playbookの実行結果は以下の通り。

# ansible-playbook -i hosts zabbix/set_zabbix_maintenance.yml 

PLAY [Get zabbix info] *********************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [t1024cent]

TASK [Enable maintenance] ******************************************************************************************
changed: [t1024cent]

PLAY RECAP *********************************************************************************************************
t1024cent                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Zabbixの管理画面からも、メンテナンス期間が作成されたことが確認できた。22:40にAnsibleを実行したため、メンテナンス期間の終了日時は30分後の23:10となっていることがわかる。

以上で、Ansibleを使ってZabbixを操作するための手順は完了となる。

更新履歴

  • 2023/4/22 新規作成
  • 2023/6/25 Ansibleバージョンを6.0.0 -> 8.1.0へバージョンアップしたことに伴い記載を更新

2023年6月24日土曜日

AnsibleでKubernetesを操作する

自宅ではAnsibleを導入してから、以下OSやソフトウェアに対して作業のコード化や自動化を行ってきた。導入手順などは以下記事を参照。

OS/ソフトウェア URL
Linux AnsibleでLinuxサーバの初期設定と単体テストを行う
Windows Server AnsibleからWindows Serverに接続するための事前作業
vSphere ESXi AnsibleでESXi上に仮想マシンを構築する

今回は、Ansibleを使ってKubernetesを操作する手順を記載する。Kubernetesは、Ansibleに標準で導入されているkubernetes.coreというモジュールで操作可能となる。

# ansible-galaxy collection list

Collection                    Version
----------------------------- -------
~(中略)~
kubernetes.core               2.3.1  
~(以下略)~

環境

以下に今回構築する各種ソフトウェアのバージョンを記載する。

  • Ansible: 2.13.1
  • Kubernetes: v1.27.1

Ansibleコントロールノード構築やLinuxサーバの事前準備の手順は、以下記事を参照いただきたい。

Kubernetesコントロールプレーンに対する準備

AnsibleでKubernetesを操作する際は、コントロールプレーンを経由してKubernetes APIにアクセスする。その際に、コントロールプレーンのノードに対して追加のPythonモジュールが必要となる。

1. pipをインストール

Dockerを利用する際はPythonパッケージのインストールが必要となるため、pipをインストールしておく。

# dnf install python3-pip

2. pipを用いてPythonモジュールをインストール

pipを用いて、以下の通りkubernetesのPythonモジュールをインストールする。

# python3 -m pip install kubernetes

3. Ansible実行ユーザーにKubernetesクラスタの環境設定ファイルを配置

Kubernetesのコントロールプレーン構築時に、Kubernetes APIへアクセスするために環境設定ファイルをホームディレクトリに配置する作業をするが、Ansible実行ユーザーに対しても同様に実施が必要となる。

私の環境ではansibleuserとなるため、以下の通り配置作業を実施した。

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

実際にAnsibleでKubernetesを操作してみる

動作確認として、AnsibleでKubernetesにNamespaceを作成してみよう。Kubernetesのリソース操作は、kubernetes.core.k8sというモジュールで実現できる。

以下のシンプルなPlaybookを実行する。

---
- name: Create K8s namespace
  gather_facts: true
  hosts: t3051kube

  vars:
    ansible_user: ansibleuser

  tasks:
    # Namespace作成
    - name: Create namespace
      kubernetes.core.k8s:
        name: test-namespace
        api_version: v1
        kind: Namespace
        state: present

実行結果は以下の通り。

# ansible-playbook -i hosts k8s/create_k8s_namespace.yml 

PLAY [Create K8s namespace] ****************************************************************************************

TASK [Gathering Facts] *********************************************************************************************
ok: [t3051kube]

TASK [Create namespace] ********************************************************************************************
changed: [t3051kube]

PLAY RECAP *********************************************************************************************************
t3051kube                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

kubectlコマンドで確認すると、以下の通りNamespaceが作成されている。

# kubectl get namespace
NAME              STATUS   AGE
default           Active   18d
kube-flannel      Active   18d
kube-node-lease   Active   18d
kube-public       Active   18d
kube-system       Active   18d
mynamespace       Active   18d
test-namespace    Active   2m5s ★Ansibleで作成されたNamespace

以上で、Ansibleを使ってKubernetesを操作する手順は完了となる。今回はNamespaceの作成を例として記載したが、kubernetes.core.k8sモジュールを使うことで、kubectlコマンドを用いて行う各種リソースの作成や、マニフェストファイルからのリソースなども実現することができる。

2023年6月17日土曜日

PostfixからGmailを経由してメール送信する手順

以前、OP25B (Outbound Port 25 Blocking)環境におけるPostfixから外部にメール送信を行う手順を記載した。

自宅検証環境は、上記手順にてインターネットサービスプロバイダーのメールサーバを経由して、監視通知メールなどの送信を行っている。しかし、最近は原因が不明だが、多くのメールがロストするという事象が発生しており、メール通知が正常にされないとう状況となっていた。

そこで、Gmailを経由してメールを送信する方針に切り替えることにした。本記事では、自宅のPostfixからGmailを経由してメール送信するための設定手順を記載する。

設定手順

1. Gmailアカウントの管理画面に移動

Googleのアカウントにログインした状態で、ホーム画面から右上のメニューを開き、「アカウント」を選択しアカウント管理画面を表示する。


2. Gmailの2段階認証プロセスを有効にする

アカウント管理画面の右メニューから、「セキュリティ」を選択し、2段階認証プロセスが有効になっていることを確認する。もし有効になっていない場合は、アプリパスワードの作成ができないため、有効化をすること(2段階認証プロセスの有効化手順は、本記事では割愛する)。

3. Gmailのアプリパスワードを作成

2段階認証プロセスが「セキュリティ」を選択し、「2段階認証プロセス」の設定画面に移動する。
※画面遷移時にパスワード確認を求められる。

「2段階認証プロセス」の設定画面の一番下に「アプリパスワード」が存在するので選択する。

「アプリパスワード」画面では、「アプリを選択」で「その他 (名前を入力)」を選択する。名前はあくまでも識別に用いるものであるため任意の名称で問題ないが、今回はPostfixという名前を付けた。

作成後、パスワードが表示されるので、メモ帳などで控えておくこと。

4. main.cfを設定

設定変更箇所を以下に抜粋する。GmailのSMTP接続先としてsmtp.gmail.comを指定し、SASL認証を有効化する。

# 受信許可ネットワークの設定
mynetworks = 127.0.0.0/8, 192.168.0.0/16

# 受付インタフェースを修正
inet_interfaces = all
inet_protocols = ipv4

# メールのリレー先サーバを指定
relayhost = [smtp.gmail.com]:587

# SMTP認証設定 (最下行に追加)
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/smtp_password
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain,login

5. パスワードファイルを作成

SASL認証に用いる認証情報をsmtp_passwordファイルに記載する。本ファイルは、以下の構文で記載する。

[smtp.gmail.com]:587 <Gmailアドレス>:<アプリパスワード>

以下記載例となる。

[smtp.gmail.com]:587 hoge@gmail.com:XXXXXXXX

パスワード情報が含まれるため、rootのみ読み書きできるように権限設定を行ったのち、postmapコマンドでhash化したDBファイルを作成する。

# chmod 600 /etc/postfix/smtp_password
# postmap /etc/postfix/smtp_password
# ls -l /etc/postfix/smtp_password*
-rw------- 1 root root    58  8月 16 06:12 /etc/postfix/smtp_password
-rw------- 1 root root 12288  8月 16 06:12 /etc/postfix/smtp_password.db

6. Postfixの設定反映

最後にPostfixを再起動し、設定を反映する。

# systemctl restart postfix

7, 動作確認

構築したPostfixからGmailを経由してメールが送信できることを動作確認してみよう。

今回はcurlを使って、以下のように送信テストを行った。

( echo "helo test.local"
echo "mail from: <zabbix@test.local>"
echo "rcpt to: <hoge@gmail.com>"
echo "data"
echo "From: zabbix@test.local"
echo "To: hoge@gmail.com"
echo "Subject: test mail"
echo "テストメール"
echo ""
echo "."
echo "quit"
) | curl -v telnet://[メールサーバのIPアドレス]:[ポート番号]

実際受け取ったメールは以下の通り。

本設定にて送信されたメールは、FromのアドレスがGmailのアドレスに変換される点に注意すること。変換前のFromアドレスは、メールのX-Google-Original-Fromというヘッダーに記載されるため、メールのソースを見れば確認可能となる。

メールのソース抜粋

From: hoge@gmail.com
X-Google-Original-From: <zabbix@test.local>
To: <宛先アドレス>

以上で、自宅のPostfixからGmailを経由してメール送信するための設定手順は完了となる。

2023年6月10日土曜日

Kubernetes構築手順④ (コントロールプレーンを冗長構成にする)

本ブログでは、数回に分けてKubernetesの構築手順を記載してきた。

今まではコントロールプレーンをシングル構成にて構築していたが、コントロールプレーン停止時にコンテナ間の通信ができなくなり、影響が発生するという問題がある。

そこで、本記事では、Kubernetesの管理機能であるコントールプレーンを冗長構成にて構築する手順を記載する。

環境

以下に今回構築する各種ソフトウェアのバージョンを記載する。

  • ホストOS : AlmaLinux 8.6
  • Docker : 23.0.1
  • cri-dockerd: 0.3.1-dev
  • Kubernetes: v1.27.1

なお、私の環境ではインターネット接続時にプロキシ接続が必要となるため、プロキシ経由で接続するための設定も併せて行っている。

今回の構成の概要図を以下に記載する。負荷分散装置にてkube-apiserverへのアクセスを冗長化する点が、大きな差異となる。

NGINXによる負荷分散装置作成

負荷分散装置は何を用いてもよいが、NGINXにて簡単に作成できる。NGINXを用いた負荷分散装置の構成手順は以下を参照いただきたい。

NGINXでロードバランサを設定する際に、 /etc/nginx/stream.conf.d/servers.stream.confという設定ファイルを作成する。kube-apiserverは待ち受けポートとなる6443となることから、負荷分散設定としては以下のとおり設定すればよい。

# kube-apiserver
upstream kube-apiserver {
    least_conn;
    server 192.168.3.51:6443;
    server 192.168.3.52:6443;
    server 192.168.3.53:6443;
}

server {
    listen       192.168.3.43:6443;
    proxy_pass   kube-apiserver;
}

Dockerインストール

今回はcri-dockerdを使ってKubernetes環境を構築する。本手順については、過去記事の手順を参照いただきたい。

Kubernetesインストール

こちらも手順については、過去記事の手順を参照いただきたい。

kubeadmコマンドを用いてKubernetesクラスター作成

1. kubeadmコマンド実行

kubeadmコマンドを用いて、Kubernetesクラスターの作成を行う。クラスターの作成はkubeadm initコマンドにて実施する。「Your Kubernetes control-plane has initialized successfully!」が表示されれば成功となる。

コントロールプレーンを冗長化する場合は、--control-plane-endpointと--upload-certsのオプションが追加となる。オプションの説明を以下に記載する。

オプション 説明
--pod-network-cidr=10.244.0.0/16 ネットワークアドオンとしてflannelを追加する際に必要となる設定となる。Pod用のクラスターネットワークのネットワークアドレスを指定する。
--cri-socket=unix:///var/run/cri-dockerd.sock CRIとしてcri-dockerdを使うことを明示的に指定するために指定する。指定しない場合、containerdとcri-dockerdの2つがインストールされていることにより、「Found multiple CRI endpoints on the host」のエラーにてクラスターの作成に失敗するので注意しよう。
--control-plane-endpoint コントロールプレーンへアクセスするためのKubernetes APIのDNS名やIPアドレスを指定する。すべてのコントロールプレーンで共通のアクセス先を指定する必要があることから、kube-apiserverへ振り分けを行う負荷分散装置のDNS名やIPアドレスを指定する。
--upload-certs 新たにコントロールプレーンが参加する際に、自動的に必要な証明書の登録を行うための設定。本オプションを省略した場合、手動による証明書のコピーが必要となる。

以下に実行結果を記載する。

# kubeadm init --pod-network-cidr=10.244.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock \
>         --control-plane-endpoint "t3043kube.test.local:6443" --upload-certs
[init] Using Kubernetes version: v1.27.2
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster

~(中略)~

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join t3043kube.test.local:6443 --token jf1wss.euqu6slbvc1c4kry \
        --discovery-token-ca-cert-hash sha256:abcdefgh5a4463ce8dc2761a89187036b1719abbb7a907aed96650ca8162d3d9 \
        --control-plane --certificate-key abcdefgh89a9c0d36e026014d9c9885119cd8c336e45420be92578832456a85a

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

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

kubeadm join t3043kube.test.local:6443 --token jf1wss.euqu6slbvc1c4kry \
        --discovery-token-ca-cert-hash sha256:abcdefgh5a4463ce8dc2761a89187036b1719abbb7a907aed96650ca8162d3d9

2. Kubernetesクラスター状態確認

Kubernetesの管理はkubectlコマンドを使って実施するが、そのままでは使用できない。以下の通り設定ファイルをコピーすることでkubectlによるコマンドが使えるようになる。

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

それでは、kubectlコマンドを使って、ノードとPodの状態を確認してみよう。以下の通り、各種コントロールプレーン用のPodと1台のノードが表示される。

# kubectl get node
NAME        STATUS     ROLES           AGE   VERSION
t3051kube   NotReady   control-plane   83s   v1.27.1

# kubectl get pod -A
NAMESPACE      NAME                                READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-zjw8w               1/1     Running   0          42s
kube-system    coredns-5d78c9869d-2lcjq            1/1     Running   0          6m55s
kube-system    coredns-5d78c9869d-fqbw9            1/1     Running   0          6m55s
kube-system    etcd-t3053kube                      1/1     Running   0          7m4s
kube-system    kube-apiserver-t3053kube            1/1     Running   0          7m4s
kube-system    kube-controller-manager-t3053kube   1/1     Running   0          7m4s
kube-system    kube-proxy-nhl5c                    1/1     Running   0          6m55s
kube-system    kube-scheduler-t3053kube            1/1     Running   0          7m4s

上記を見ると、corednsがPendingのステータスとなっており、NodeのステータスもNotReadyとなっている。これはPod用のネットワークアドオンがインストールされていないために発生しており、後続の手順にてflannelをインストールするとステータスがRunningになるため、現時点では気にしなくて問題ない。

ネットワークアドオンインストール (flannelインストール)

こちらも手順については、過去記事の手順を参照いただきたい。

flannelインストールが完了すると、ノードのステータスがReadyに変化する。

# kubectl get node
NAME        STATUS   ROLES           AGE     VERSION
t3053kube   Ready    control-plane   7m16s   v1.27.1

# kubectl get pod -A
NAMESPACE      NAME                                READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-zjw8w               1/1     Running   0          42s
kube-system    coredns-5d78c9869d-2lcjq            1/1     Running   0          6m55s
kube-system    coredns-5d78c9869d-fqbw9            1/1     Running   0          6m55s
kube-system    etcd-t3053kube                      1/1     Running   0          7m4s
kube-system    kube-apiserver-t3053kube            1/1     Running   0          7m4s
kube-system    kube-controller-manager-t3053kube   1/1     Running   0          7m4s
kube-system    kube-proxy-nhl5c                    1/1     Running   0          6m55s
kube-system    kube-scheduler-t3053kube            1/1     Running   0          7m4s

2台目のコントロールプレーンの追加

1. kubeadm joinコマンドにてコントロールプレーンを追加

CRIとしてcri-dockerdを用いる場合は、--cri-socketのオプション追加が必要となるため注意すること。

# kubeadm join t3043kube.test.local:6443 --token jf1wss.euqu6slbvc1c4kry \
        --discovery-token-ca-cert-hash sha256:abcdefgh5a4463ce8dc2761a89187036b1719abbb7a907aed96650ca8162d3d9 \
        --control-plane --certificate-key abcdefgh89a9c0d36e026014d9c9885119cd8c336e45420be92578832456a85a \
        --cri-socket=unix:///var/run/cri-dockerd.sock
# kubeadm join t3043kube.test.local:6443 --token jf1wss.euqu6slbvc1c4kry \
        --discovery-token-ca-cert-hash sha256:abcdefgh5a4463ce8dc2761a89187036b1719abbb7a907aed96650ca8162d3d9 \
        --cri-socket=unix:///var/run/cri-dockerd.sock

2. Kubernetesクラスター状態確認

1台目のコントロールプレーンと同様、以下の通り設定ファイルをコピーすることで、2台目のコントロールプレーンにおいてもkubectlによるコマンドが使えるようになる

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

ノードとPodの状態を確認すると、ノードのROLESがcontorol-planeとなっており、各ノードにて、etcd、kube-apiserver、kube-controller-manager、kube-schedulerが起動していることが確認できる(kube-proxyはワーカーノードにおいても起動する)。

# kubectl get node
NAME        STATUS   ROLES           AGE   VERSION
t3052kube   Ready    control-plane   47s   v1.27.1
t3053kube   Ready    control-plane   15m   v1.27.1

# kubectl get pod -A
NAMESPACE      NAME                                READY   STATUS    RESTARTS      AGE
kube-flannel   kube-flannel-ds-xtq5b               1/1     Running   0             59s
kube-flannel   kube-flannel-ds-zjw8w               1/1     Running   0             9m27s
kube-system    coredns-5d78c9869d-2lcjq            1/1     Running   0             15m
kube-system    coredns-5d78c9869d-fqbw9            1/1     Running   0             15m
kube-system    etcd-t3052kube                      1/1     Running   0             58s
kube-system    etcd-t3053kube                      1/1     Running   0             15m
kube-system    kube-apiserver-t3052kube            1/1     Running   0             59s
kube-system    kube-apiserver-t3053kube            1/1     Running   0             15m
kube-system    kube-controller-manager-t3052kube   1/1     Running   0             59s
kube-system    kube-controller-manager-t3053kube   1/1     Running   1 (48s ago)   15m
kube-system    kube-proxy-nhl5c                    1/1     Running   0             15m
kube-system    kube-proxy-zq88d                    1/1     Running   0             59s
kube-system    kube-scheduler-t3052kube            1/1     Running   0             59s
kube-system    kube-scheduler-t3053kube            1/1     Running   1 (44s ago)   15m

参考:コントロールプレーンにおいても管理用Pod「以外」を起動させる設定 (taintの解除)

初期設定時は、コントロールプレーンにおいては管理用Podのみ起動できる設定が入っている。これは「taint (汚れ、汚染という意味)」と呼ばれる設定において制御されている。

検証用途などにおいては、コントロールプレーンにおいても管理用Pod「以外」を起動したい場合は、以下コマンドでtaintを解除する。
※今回は説明しないが、Pod側の設定で「toleration (耐える、黙認という意味)」という対となる設定をすることでも対処できる。

# kubectl taint node t3051kube node-role.kubernetes.io/control-plane:NoSchedule-
# kubectl taint node t3052kube node-role.kubernetes.io/control-plane:NoSchedule-

taintの設定を戻す場合は、以下の通り行う(解除コマンドの最後の-を取る)。

# kubectl taint node t3051kube node-role.kubernetes.io/control-plane:NoSchedule
# kubectl taint node t3052kube node-role.kubernetes.io/control-plane:NoSchedule

以上で、Kubernetesの管理機能であるコントールプレーンを冗長構成にて構築する手順は完了となる。

人気の投稿