1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

OpenShiftのKubernetes APIサーバー用のロードバランサーにヘルスチェックのエンドポイント(/readyz)の設定を追加する

Last updated at Posted at 2020-12-30

OpenShift(以下OCP)をベアメタルのUPIの方法で導入する際には、前提としてAPIのロードバランサーとアプリケーションIngressのロードバランサーが必要です。

少し昔のOCPのドキュメントでは、Kubernetes APIサーバー(Port: 6443)用とMachine Configサーバー(Port: 22623)用のAPIロードバランサーと、HTTPSトラフィック(Port: 443)用とHTTPトラフィック(Port: 80)用のアプリケーションIngressロードバランサーのどちらについても、ただ単にLayer 4のロードバランサーが必要で、ポート番号とバックエンドマシン(プールメンバー)の情報ぐらいしか記載がなかった様に思います。

但し、ちょっと(と言っても結構)前から、OCPのドキュメントには、これらのPort番号とバックエンドマシンの情報に加えて、Kubernetes APIサーバー(Port: 6443)用のロードバランサーについては、ヘルスチェックのエンドポイントの情報(/readyz)が記載される様になっていました。

ですので、今回はOCPのドキュメントに従ってHAProxyにヘルスチェックの設定を追加してみたいと思います。

(2022/09/21追記)
Qiita / OpenShift 4.10 ベアメタルUPI (iPXE) インストール / ロードバランサー」の方では、設定内容を少し更新しました。ただ、以下の記載自体も参考になると思いますのでそのまま残しておきます。
(追記終わり)

Kubernetes APIサーバー(Port: 6443)の/readyzエンドポイント

  • master nodeが正常な場合は「ok」と表示され、HTTPの戻り値は「200」となります。
[user01@bastion-01 ~]$ curl https://master-01.test2.example.local:6443/readyz -k
ok[user01@bastion-01 ~]$
[user01@bastion-01 ~]$
[user01@bastion-01 ~]$ curl https://master-01.test2.example.local:6443/readyz -k -o /dev/null -w '%{http_code}\n' -s
200
[user01@bastion-01 ~]$
  • master nodeに障害がある場合は返答がなく、HTTPの戻り値は「000」になります。(ステータスコードを返さない)
[user01@bastion-01 ~]$ curl https://master-01.test2.example.local:6443/readyz -k
curl: (7) Failed connect to master-01.test2.example.local:6443; 接続を拒否されました
[user01@bastion-01 ~]$
[user01@bastion-01 ~]$ curl https://master-01.test2.example.local:6443/readyz -k -o /dev/null -w '%{http_code}\n' -s
000
[user01@bastion-01 ~]$

前提の環境

今回はインターネット非接続環境でベアメタルのUPIの方法でOCP4.4を導入しています。
また、以下のQiitaの記事と同じ様に、役割ごとに専用のInfra nodeを構成しています。

node名 ノードの役割 備考
master-0[1-3] master master node
worker-0[1-2] worker worker node(アプリケーションPod用)
infra-0[1-3] infra ルーター、内部レジストリー用
infra-mon-0[1-3] infra(logging) モニタリング用
infra-log-0[1-3] infra(monitoring) ロギング用
  • 検証環境のOCPのバージョンは少し古いですが、今回のロードバランサーの設定内容はOCP 4.6のドキュメントでも同じだったため、この記事ではドキュメントのリンクはOCP 4.6のリンクを添付します。)

今までの設定 (ヘルスチェックプローブの設定なし)

検証環境でベアメタルのUPIの方法でOCPを導入する際に昔はHAProxyでは大体以下の様な設定をしていました。

  • Kubernetes APIサーバー(Port: 6443)のmodetcp(L4のロードバランサー)
  • Kubernetes APIサーバー(Port: 6443)のバックエンドはoption ssl-hello-chkのチェックのみ

(参考)

/etc/haproxy/haproxy.confの設定例

(/etc/haproxy/haproxy.conf)
(global、defaultのセクションはデフォルトのまま)

(略)

frontend K8s-api
    bind *:6443
    option tcplog
    mode tcp
    default_backend     api-6443

frontend Machine-config
    bind *:22623
    option tcplog
    mode tcp
    default_backend     config-22623

frontend Ingress-http
    bind *:80
    option tcplog
    mode tcp
    default_backend http-80

frontend Ingress-https
    bind *:443
    option tcplog
    mode tcp
    default_backend     https-443

backend api-6443
    mode tcp
    balance     roundrobin
    option  ssl-hello-chk
    # server  bootstrap-01 bootstrap-01.test2.example.local:6443 check
    server  master-01 master-01.test2.example.local:6443 check
    server  master-02 master-02.test2.example.local:6443 check
    server  master-03 master-03.test2.example.local:6443 check

backend config-22623
    mode tcp
    balance     roundrobin
    # server  bootstrap-01 bootstrap-01.test2.example.local:22623 check
    server  master-01 master-01.test2.example.local:22623 check
    server  master-02 master-02.test2.example.local:22623 check
    server  master-03 master-03.test2.example.local:22623 check

backend http-80
    mode tcp
    balance     roundrobin
    server  infra-01 infra-01.test2.example.local:80 check
    server  infra-02 infra-02.test2.example.local:80 check
    server  infra-03 infra-03.test2.example.local:80 check

backend https-443
    mode tcp
    balance     roundrobin
    option      ssl-hello-chk
    server  infra-01 infra-01.test2.example.local:443 check
    server  infra-02 infra-02.test2.example.local:443 check
    server  infra-03 infra-03.test2.example.local:443 check

今回の設定 (ヘルスチェックプローブの設定あり)

要件の確認

先ほども記載した様に、最近のOCP 4.6のドキュメントでは、Kubernetes APIサーバー(Port: 6443)用のAPIロードバランサーについては、ヘルスチェックのエンドポイントとして/readyzの情報が追記されています。

(抜粋)

  1. API ロードバランサー: プラットフォームと対話およびプラットフォームを設定するためのユーザー向けの共通のエンドポイントを提供します。以下の条件を設定します。
  • Layer 4 の負荷分散のみ。これは、Raw TCP、SSL パススルー、または SSL ブリッジモードと呼ばれます。
    (略)

表1.20 API ロードバランサー

ポート バックエンドマシン (プールメンバー) 内部 外部 説明
6443 ブートストラップおよびコントロールプレーン。ブートストラップマシンがクラスターのコントロールプレーンを初期化した後に、ブートストラップマシンをロードバランサーから削除します。API サーバーのヘルスチェックプローブの /readyz エンドポイントを設定する必要があります。 X X Kubernetes API サーバー
22623 ブートストラップおよびコントロールプレーン。ブートストラップマシンがクラスターのコントロールプレーンを初期化した後に、ブートストラップマシンをロードバランサーから削除します。 X マシン設定サーバー

注記
ロードバランサーは、API サーバーが /readyz エンドポイントをオフにしてからプールから API サーバーインスタンスを削除するまで最大 30 秒かかるように設定する必要があります。/readyz の後の時間枠内でエラーが返されたり、正常になったりする場合は、エンドポイントが削除または追加されているはずです。5 秒または 10 秒ごとにプローブし、2 つの正常な要求が正常な状態になり、3 つの要求が正常な状態になりません。これらは十分にテストされた値です

(日本語の注記がよくわからない場合はちゃんと英語版のドキュメントも合わせて参照...)

NOTE
The load balancer must be configured to take a maximum of 30 seconds from the time the API server turns off the /readyz endpoint to the removal of the API server instance from the pool. Within the time frame after /readyz returns an error or becomes healthy, the endpoint must have been removed or added. Probing every 5 or 10 seconds, with two successful requests to become healthy and three to become unhealthy, are well-tested values.

設定方法

先ほどの記述だけだけだとHAProxyに具体的にどのように設定すればよいのかすぐにはわからなかったので、少し検索してみたところ、OpenShiftのinstallerのGitHubに参考になりそうな情報がありました。
(vSphereのUPIの場合のインストーラーのロードバランサーの設定のテンプレート??)

defaults
  (略)
  mode    tcp
  (略)

frontend api-server
    bind ${lb_ip_address}:6443
    default_backend api-server

(略)
backend api-server
    option  httpchk GET /readyz HTTP/1.0
    option  log-health-checks
    balance roundrobin
    %{ for addr in api ~}
    server ${addr} ${addr}:6443 weight 1 verify none check check-ssl inter 1s fall 2 rise 3
    %{ endfor ~}
(略)
  • modetcp (L4のロードバランサー)
  • ヘルスチェックのエンドポイント/readyzに関する設定として、option httpchk GET /readyz HTTP/1.0の定義を追加
  • serverではserver ${addr} ${addr}:6443 weight 1 verify none check check-ssl inter 1s fall 2 rise 3と設定
    • バックエンドのサーバーに重みはつけないので全てweight 1と設定
    • 自己署名証明書を使用するのでverify noneを追加
    • checkでヘルスチェックを有効にする
    • option httpchkとSSL checkを組み合わせて使用するため、check-sslオプションを追加
    • inter 1s fall 2 rise 3では1秒ごとにヘルスチェックをし、失敗2回でエンドポイントを削除し、成功3回でエンドポイントを追加している様に思われる

今回の設定内容

上述の設定値は今回のOCPのドキュメントに記載があった設定値とは少し違いますが、設定項目は参考になると思いますので、上述の設定項目を参考に、今回のOCPのドキュメントに記載のロードバランサーの要件に従って、検証環境のHAProxyに以下の様に設定を追加してみました。

  • modetcp (L4のロードバランサー)
  • ヘルスチェックのエンドポイント/readyzに関する設定として、option httpchk GET /readyz HTTP/1.0の定義を追加
  • serverではserver ${addr} ${addr}:6443 weight 1 verify none check check-ssl inter [5|10]s fall 3 rise 2と設定
    • バックエンドのサーバーに重みはつけないので全てweight 1と設定
    • 自己署名証明書を使用するのでverify noneを追加
    • checkでヘルスチェックを有効になる。
    • option httpchkとSSL checkを組み合わせて使用するため、check-sslオプションを追加
    • OCPのドキュメントでは、ヘルスチェックの間隔は5秒または10秒で、2回成功でエンドポイントを追加し、3回失敗でエントポイントを削除するのが「これらは十分にテストされた値です」とのことなので、inter [5|10]s fall 3 rise 2と設定してみる
    • (最初は一旦10秒にしてみる)

inter 10 fall 3 rise 2の場合の/etc/haproxy/haproxy.confの設定例

(/etc/haproxy/haproxy.conf)
(global、defaultのセクションはデフォルトのまま)

(略)

frontend K8s-api
    bind *:6443
    option tcplog
    mode tcp
    default_backend     api-6443

frontend Machine-config
    bind *:22623
    option tcplog
    mode tcp
    default_backend     config-22623

frontend Ingress-http
    bind *:80
    option tcplog
    mode tcp
    default_backend http-80

frontend Ingress-https
    bind *:443
    option tcplog
    mode tcp
    default_backend     https-443

backend api-6443
    mode tcp
    option  httpchk GET /readyz HTTP/1.0
    option  log-health-checks
    balance roundrobin
    # server  bootstrap-01 bootstrap-01.test2.example.local:6443 weight 1 verify none check check-ssl inter 10s fall 3 rise 2
    server  master-01 master-01.test2.example.local:6443 weight 1 verify none check check-ssl inter 10s fall 3 rise 2
    server  master-02 master-02.test2.example.local:6443 weight 1 verify none check check-ssl inter 10s fall 3 rise 2
    server  master-03 master-03.test2.example.local:6443 weight 1 verify none check check-ssl inter 10s fall 3 rise 2

backend config-22623
    mode tcp
    balance     roundrobin
    # server  bootstrap-01 bootstrap-01.test2.example.local:22623 check
    server  master-01 master-01.test2.example.local:22623 check
    server  master-02 master-02.test2.example.local:22623 check
    server  master-03 master-03.test2.example.local:22623 check

backend http-80
    mode tcp
    balance     roundrobin
    server  infra-01 infra-01.test2.example.local:80 check
    server  infra-02 infra-02.test2.example.local:80 check
    server  infra-03 infra-03.test2.example.local:80 check

backend https-443
    mode tcp
    balance     roundrobin
    option      ssl-hello-chk
    server  infra-01 infra-01.test2.example.local:443 check
    server  infra-02 infra-02.test2.example.local:443 check
    server  infra-03 infra-03.test2.example.local:443 check

設定の反映(haproxyの再起動)

$ sudo systemctl restart haproxy
$ sudo systemctl status haproxy

稼働確認

任意のmaster nodeの1台に障害があっても、ロードバランサーが障害のあったnodeをエンドポイントから切り離し、ocコマンドなどは継続して実行できるというのがあるべき姿だと思います。

そこで、今までの設定(ヘルスチェックプローブの設定なし)の場合と、今回の設定(ヘルスチェックProbeの設定あり)の場合に、master nodeを1台再起動中にocコマンドを1秒毎に繰り返し実行して挙動を確認してみてみました。

確認手順

  1. 一秒ごとにoc get node master-01を実行し続ける。

    $ while true; do date; oc get node master-01; sleep 1; done
    
  2. 別terminalを開いてmaster-01を再起動する。

    ssh -i .ssh/<ssh key> core@master-01 sudo shutdown -r now
    
  3. oc get nodeコマンドが実行できない時間を比較してみる。

今までの設定(ヘルスチェックプローブの設定なし)の場合

  • master-01を再起動
[user01@bastion-01 ~]$ date; ssh -i .ssh/ocp_rsa core@master-01 sudo shutdown -r now
2020年 12月 30日 水曜日 20:05:10 JST
Connection to master-01 closed by remote host.
[user01@bastion-01 ~]$
  • oc get node master-01の実行結果
    • ReadyからNotReadyになる際に、実行毎に30秒から1分ぐらいコマンドが返ってこず、Unable to connect to the server: unexpected EOFError from server (Timeout): the server was unable to return a response in the time allotted, but may still be processing the request (get nodes master-01)が表示されることがありました。
    • NotReadyからReadyになる際は特に途切れはありませんでした。

(以下は50秒ぐらいでerror: You must be logged in to the server (Unauthorized)が出力された例)

[user01@bastion-01 ~]$ while true; do date; oc get node master-01; sleep 1; done

(略)

2020年 12月 30日 水曜日 20:05:15 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 20:05:16 JST
error: You must be logged in to the server (Unauthorized)
2020年 12月 30日 水曜日 20:06:06 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8

(略)

2020年 12月 30日 水曜日 20:07:24 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 20:07:25 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 20:07:27 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8

(以下は60秒ぐらいでError from server (Timeout): the server was unable to return a response in the time allotted, but may still be processing the request (get nodes master-01)が出力された例)

2020年 12月 30日 水曜日 20:23:00 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 20:23:01 JST
Error from server (Timeout): the server was unable to return a response in the time allotted, but may still be processing the request (get nodes master-01)
2020年 12月 30日 水曜日 20:24:02 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8

今回の設定(ヘルスチェックプローブの設定あり)の場合

ヘルスチェック間隔10秒の場合

  • master-01を再起動
[user01@bastion-01 ~]$ date; ssh -i .ssh/ocp_rsa core@master-01 sudo shutdown -r now
2020年 12月 30日 水曜日 19:35:46 JST
Connection to master-01 closed by remote host.
[user01@bastion-01 ~]$
  • oc get node master-01の実行結果
    • ReadyからNotReadyになる際に、大体30秒ぐらいコマンドが返ってこず、1-2回error: You must be logged in to the server (Unauthorized)のメッセージが表示されました。
    • NotReadyからReadyになる際は特に途切れはありませんでした。

(以下は30秒ぐらいでerror: You must be logged in to the server (Unauthorized)が出力された例)

[user01@bastion-01 ~]$ while true; do date; oc get node master-01; sleep 1; done

(略)

2020年 12月 30日 水曜日 19:35:51 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 19:35:52 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 19:35:53 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 19:35:54 JST
error: You must be logged in to the server (Unauthorized)
2020年 12月 30日 水曜日 19:36:25 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 19:36:26 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8

(略)

2020年 12月 30日 水曜日 19:38:00 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 19:38:01 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8

ヘルスチェック間隔5秒の場合

  • master-01を再起動
[user01@bastion-01 ~]$ date; ssh -i .ssh/ocp_rsa core@master-01 sudo shutdown -r now
2020年 12月 30日 水曜日 22:45:56 JST
Connection to master-01 closed by remote host.
[user01@bastion-01 ~]$
  • oc get node master-01の実行結果
    • ReadyからNotReadyになる辺りで、大体は30-50秒ぐらいコマンドが返ってこず、1-2回error: You must be logged in to the server (Unauthorized)のメッセージが表示されました。
    • NotReadyからReadyになる際は特に途切れはありませんでした。

(以下は30秒ちょっとでerror: You must be logged in to the server (Unauthorized)が出力された例)

$ while true; do date; oc get node master-01; sleep 1; done

(略)

2020年 12月 30日 水曜日 22:46:04 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 22:46:06 JST
error: You must be logged in to the server (Unauthorized)
2020年 12月 30日 水曜日 22:46:39 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 22:46:40 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8

(略)

2020年 12月 30日 水曜日 22:48:11 JST
NAME        STATUS     ROLES    AGE   VERSION
master-01   NotReady   master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 22:48:12 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8
2020年 12月 30日 水曜日 22:48:13 JST
NAME        STATUS   ROLES    AGE   VERSION
master-01   Ready    master   59d   v1.17.1+c5fd4e8

まとめ

OCPのドキュメントにあるKubernetes APIサーバー(Port: 6443)用のロードバランサーのヘルスチェックのエンドポイントとして/readyzをHAProxyに設定してみました。

コマンドが戻ってこない時間などは以前と比べて多少は改善した(様な気がする)ものの、/readyzへのヘルスチェックを間隔10秒、失敗3回、成功2回に設定した場合も、間隔5秒、失敗3回、成功2回にした場合のいずれも30秒程度コマンドが返ってこないタイミングがありました。
(やってみた感じでは、間隔5秒の場合はコマンドが返ってくるタイミングはまちまちでしたが、間隔10秒の場合は30秒程度でコマンドが返ってくる感じで、大体同じ挙動をしていました。)

もし、ocコマンドなどでステータスを取得するような運用スクリプトなどを作成している場合は、このあたりの検証結果を参考に、コマンドのリトライ間隔や回数などを検討する必要があると思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?