0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【OpenShift】外部LBでAPI通信の振り分けを行う

0
Posted at

UPIインストールの場合のAPI通信

OpenShift(4.18時点)をUPI方式でインストールする場合、インストーラはLB/DNS/Compute等を自動構築しないため、API サーバ等に入ってくるトラフィックを負荷分散するLoadBlancerについても、OCP側では準備をしてくれず自前で準備する必要があります。

※IPI/UPI方式の違いについては以下参照

基本的な必要要素としては以下

・API Load Balancer(必須)

コンポーネント: kube-apiserver
用途: oc/kubectlコマンドやoperatorなど
port: TCP 6443
endpoint: control plane ノードに分散

例)
api.<cluster_name>.<base_domain>:6443
 → master-0:6443
 → master-1:6443
 → master-2:6443

・Ingress Load Balancer(必須)

コンポーネント: OpenShift Router(HAProxy router / ingress controller)
用途: console/oauth
port: TCP 80 / 443
endpoint: 全workerノード(routerPodが動くノード)

例)
*.apps.<cluster_name>.<base_domain>
 → worker-0:80/443
 → worker-1:80/443

・Machine Config Server(クラスタ作成時に必須)

コンポーネント: machine-config-server (namespace=openshift-machine-config-operator)
用途: ノード(RHCOS)が Ignition / MachineConfig を取得するためのサーバで、OS設定やkubelet設定、証明書、systemd unit などを配布
port: TCP 22623
endpoint: control plane ノードに分散

例)
Node (RHCOS)
  → https://api-int.<cluster>.<domain>:22623

主にノード側(RHCOS)が参照するOCP内部の通信。通常クライアントからは使われない

クラスタ作成時

bootstrap / master / worker の初回起動
RHCOS が起動し、IgnitionがAPI MCS(22623) にアクセスして初期設定を取得するため、22623 が通らないとインストールは失敗する

クラスタ作成直後〜運用中

以下のケースで 再び 22623 が使われる。
→Worker の追加
→Control-plane の追加
→OS / kubelet / CRI-O 更新(MachineConfig 更新)
→ノード再プロビジョニング

・DNS

OpenShiftは名前でアクセスするため、以下の名前解決が必要

api.<cluster>.<base_domain>        → API LB
api-int.<cluster>.<base_domain>    → API LB(内部通信用)
*.apps.<cluster>.<base_domain>     → Ingress LB

IPI/Assisted Installerの場合

クラスタ内にhaproxyのpodがあり、そちらに含まれています。
Node上で動作させるデーモンのような働きであるため、podには hostnetwork: true によりNodeのアドレスが付与されています。

$ oc get pod -n openshift-kni-infra -o wide
NAME                           READY   STATUS    RESTARTS        AGE    IP            NODE                                           NOMINATED NODE   READINESS GATES
coredns-worker01.internal      2/2     Running   24              178d   10.10.10.8   worker01.internal   <none>           <none>
coredns-worker02.internal      2/2     Running   22              178d   10.10.10.9   worker02.internal   <none>           <none>
coredns-master01.internal      2/2     Running   18              178d   10.10.10.5   master01.internal   <none>           <none>
coredns-master02.internal      2/2     Running   18              178d   10.10.10.6   master02.internal   <none>           <none>
coredns-master03.internal      2/2     Running   18              178d   10.10.10.7   master03.internal   <none>           <none>
haproxy-master01.internal      2/2     Running   18              178d   10.10.10.5   master01.internal   <none>           <none>
haproxy-master02.internal      2/2     Running   18              178d   10.10.10.6   master02.internal   <none>           <none>
haproxy-master03.internal      2/2     Running   19              178d   10.10.10.7   master03.internal   <none>           <none>
keepalived-worker01.internal   2/2     Running   215             178d   10.10.10.8   worker01.internal   <none>           <none>
keepalived-worker02.internal   2/2     Running   208             178d   10.10.10.9   worker02.internal   <none>           <none>
keepalived-master01.internal   2/2     Running   231 (54d ago)   178d   10.10.10.5   master01.internal   <none>           <none>
keepalived-master02.internal   2/2     Running   228 (54d ago)   178d   10.10.10.6   master02.internal   <none>           <none>
keepalived-master03.internal   2/2     Running   222 (54d ago)   178d   10.10.10.7   master03.internal   <none>           <none>

Openshiftとして、クラスタ全体の名前解決で使われるcoredns(namespace:openshift-dns)とは別で、
namespace:openshift-kni-infraでもcorednsのpodが全ノードに配布されていますが、こちらはノード自身(hostNetwork)、IPI BareMetal の内部経路で使用されているものです。

BareMetal IPI(KNI系)では openshift-kni-infra に haproxy/keepalived/coredns 相当が配置される一方で、UPIでは外部LB/DNSを自前で用意するため、これらのPodに依存しません。

外部LBとしてはいくつか方法がありますが、今回はHaproxyをAlmaLinuxのVM上にインストールし、API/Ingress用のvIPをもたせてMasterNodeに振り分けてみます。
また、Haproxyは2VMで冗長化しておきます。

image.png

外部のDNS登録

クライアントから参照するDNSで対象のクラスタの名前解決(haproxyのVIPアドレス)ができるようにしておく。
なお、IPIの場合は一般的にAPI用/ingress用で通常は分けるが、今回は外部HAProxyがポートで振り分けるため、VIPを共用しても成立する。

api.<cluster>.<base_domain>        → API LB
api-int.<cluster>.<base_domain>    → API LB(内部通信用)
*.apps.<cluster>.<base_domain>     → Ingress LB

Haproxy/keepalived インストール

インストール

# dnf install -y haproxy keepalived

バージョン確認

# haproxy -v
HAProxy version 2.4.22-f8e3218 2023/02/14 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.22.html
Running on: Linux 5.14.0-570.12.1.el9_6.x86_64 #1 SMP PREEMPT_DYNAMIC Tue May 13 06:11:55 EDT 2025 x86_64

# keepalived --version
Keepalived v2.2.8 (04/04,2023), git commit v2.2.7-154-g292b299e+

Copyright(C) 2001-2023 Alexandre Cassen, <acassen@gmail.com>

Built with kernel headers for Linux 5.14.0
Running on Linux 5.14.0-570.12.1.el9_6.x86_64 #1 SMP PREEMPT_DYNAMIC Tue May 13 06:11:55 EDT 2025
Distro: AlmaLinux 9.6 (Sage Margay)

Haproxy設定

振り分けの設定
127.0.0.1:8080はkeepalived用のヘルスチェック用,localhostからのみ待ち受ける
OCP向けの 6443/22623/80/443 はすべて mode tcp(TLS終端しない)
statsだけHTTP

/etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2                # syslog 経由でログファイルに出力
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats
    ssl-default-bind-ciphers PROFILE=SYSTEM
    ssl-default-server-ciphers PROFILE=SYSTEM

defaults
    mode                    http
    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

listen api-server-6443
  bind *:6443
  mode tcp
  server master01.internal 10.10.10.5:6443 check inter 60s
  server master02.internal 10.10.10.6:6443 check inter 60s
  server master03.internal 10.10.10.7:6443 check inter 60s
listen machine-config-server-22623
  bind *:22623
  mode tcp
  server master01.internal 10.10.10.5:22623 check inter 60s
  server master02.internal 10.10.10.6:22623 check inter 60s
  server master03.internal 10.10.10.7:22623 check inter 60s
listen ingress-router-443
  bind *:443
  mode tcp
  balance source
  server worker01.internal 10.10.10.8:443 check inter 60s
  server worker02.internal 10.10.10.9:443 check inter 60s
listen ingress-router-80
  bind *:80
  mode tcp
  balance source
  server worker01.internal 10.10.10.8:80 check inter 60s
  server worker02.internal 10.10.10.9:80 check inter 60s

listen stats
  bind 127.0.0.1:8080
  mode http
  stats enable
  stats uri /status
  stats refresh 10s

ログローテートの設定
1日毎で10日分保存。

/etc/logrotate.d/haproxy
/var/log/haproxy.log {
    daily
    rotate 10
    missingok
    notifempty
    compress
    sharedscripts
    postrotate              # ローテートした後、syslog/rsyslog に HUP シグナルを送る
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        /bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

keepalivedの設定

keepalived で VRRP を使って “VIP(仮想IP) を2台以上のLBノード間で冗長化する” 設定

/etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
vrrp_script check_haproxy {
   script "/opt/tool/keepalived/chk_haproxy.sh"    # 0を返せば正常、0以外なら異常 と判定される
   interval 5                                      # 5秒ごとにチェック
   rise 1                                          # 1回成功したら “正常” とみなす
   fall 1                                          # 1回失敗したら “異常” とみなす
}
vrrp_instance VI_1 {
   state BACKUP
   interface eth0                                  # VIP を付与する NIC を指定
   nopreempt                                       # 一度 BACKUP 側に切り替わった後、元の高優先度機が復帰しても MASTER を奪い返さない設定
   virtual_router_id 51                            # VRRPグループID。冗長化ペアの keepalived は 同じ値にする
   priority 101                                    # priority の高い方が MASTER になる。2号機はpriorityを50にする
   advert_int 1
   vrrp_garp_interval 0
   authentication {
     auth_type PASS
     auth_pass 1111
   }
   virtual_ipaddress {                             # VIPアドレス
     10.10.10.10
   }
   track_script {                                  # vrrp_script↓ の結果が VRRP の状態に影響する
     check_haproxy
   }
}

vrrp_script check_haproxyで指定しているスクリプトを作成する。
HAProxy が“応答できる状態か”を HTTP レベルで確認する

/opt/tool/keepalived/chk_haproxy.sh
#!/bin/bash
if ! timeout 2s curl -sf http://127.0.0.1:8080/status > /dev/null; then
    exit 1
else
    exit 0
fi

実行権付与

# chmod +x /opt/tool/keepalived/chk_haproxy.sh

確認

設定反映

# systemctl restart haproxy
# systemctl restart keepalived

確認

# systemctl status haproxy
● haproxy.service - HAProxy Load Balancer
     Loaded: loaded (/usr/lib/systemd/system/haproxy.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-08-26 07:53:59 UTC; 3 months 13 days ago
   Main PID: 1268 (haproxy)
      Tasks: 5 (limit: 101849)
     Memory: 13.6M
        CPU: 10h 55min 21.142s
     CGroup: /system.slice/haproxy.service
             tq1268 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d -p /run/haproxy.pid
             mq1270 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d -p /run/haproxy.pid


# systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
     Loaded: loaded (/usr/lib/systemd/system/keepalived.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-08-26 07:54:10 UTC; 3 months 13 days ago
   Main PID: 1278 (keepalived)
      Tasks: 2 (limit: 101849)
     Memory: 5.1M
        CPU: 3h 55min 37.056s
     CGroup: /system.slice/keepalived.service
             tq1278 /usr/sbin/keepalived --dont-fork -D
             mq1280 /usr/sbin/keepalived --dont-fork -D
# curl http://127.0.0.1:8080/status
→エラーがなく返ってくること.以下の情報がわかる
・HAProxy プロセスが生きているか
・各 listen / backend の状態
・各サーバ(master / worker)の UP / DOWN
・セッション数、エラー数

1号機がVIPを持っている

# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:60:1c:51:d5:9e brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 10.10.10.3/24 brd 10.10.10.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 10.10.10.10/32 scope global eth0
       valid_lft forever preferred_lft forever

参考

UPIの負荷分散要件

haproxyの設定

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?