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?

More than 3 years have passed since last update.

OpenShiftクラスター外部からのHTTP要求経路について

Last updated at Posted at 2021-09-25

はじめに

IBM Cloudにおいて異なるサブネットにOpenShiftのworkerノードがあり、各workerノードにルーターPodとアプリケーションPodが配置されているとします。OpenShiftクラスター外部のclassicノードからHTTP要求したときの経路は以下となります。

・classicノード → Load Balancer → ルーターPod(subnetX) → アプリケーションPod(subnetX)

この記事では、Load Balancerのセッション維持設定、HTTPクライアントからのcookie送信有無によって、経路がどのように変化するか確認します。
image.png

環境やアプリケーションについては下記の記事を参照ください。

■ OpenShift 4.8環境

■ Spring Bootアプリケーション

1. 事前準備

1.1. classicノード設定

classicノードでLoad BalancerのIPアドレスを解決するためにdnsmasqを設定します。設定変更後、アプリケーションのFQDN(spring-liberty.apps.ocp.cloud.vpc)に対して、Load BalancerのIPアドレスが返されることが確認できます。また、HTTPクライアントツールとして、curlとhttpd(付属のab:apache bench)を導入します。

※OpenShiftはDNS Servicesを参照していますが、classicノードから参照できないため個別にDNSを構成しています。Load Balancerインスタンスの増減には対応できませんが、本記事の目的のためには十分です。

classcノード
vi /etc/hosts
### 追加箇所↓
10.244.0.7      spring-liberty.apps.ocp.cloud.vpc
10.244.64.12    spring-liberty.apps.ocp.cloud.vpc

systemctl restart dnsmasq

dig @127.0.0.1 spring-liberty.apps.ocp.cloud.vpc +short
### 標準出力↓
10.244.64.12
10.244.0.7

yum -y install curl
yum -y install httpd

ルーターPodのアクセスログをシスログとして受信するための設定をします。

classicノード
vi /etc/rsyslog.conf
### 修正箇所↓
module(load="imudp") # needs to be done just once
input(type="imudp" port="514")

### 追加箇所↓
:fromhost, isequal, "worker-0"  -/var/log/router.log
:fromhost, isequal, "worker-1"  -/var/log/router.log
:fromhost, isequal, "worker-2"  -/var/log/router.log

systemctl restart rsyslog

1.2. OpenShift設定

ルーターPod(Ingress Controller)のレプリカ数を「3」とし、アクセスログをclassicノードにシスログ転送するように設定します。分散配置するための設定はしていませんが、各subnetのworkerノードに分散配置されているので良しとします。

classicノード
oc patch IngressController default -n openshift-ingress-operator --type=merge \
  --patch='{"spec":{"replicas":3,"logging":{"access":{"destination":{"type":"Syslog","syslog":{"address":"10.192.36.132","port":514}}}}}}'

oc get pod -o wide -n openshift-ingress
### 標準出力↓
NAME                              READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
router-default-7647bc57db-58njn   1/1     Running   0          47s   10.244.128.111   worker-2   <none>           <none>
router-default-7647bc57db-csdzg   1/1     Running   0          27s   10.244.0.111     worker-0   <none>           <none>
router-default-7647bc57db-vz4k6   1/1     Running   0          5s    10.244.64.111    worker-1   <none>           <none>

アプリケーションPodも各workerノードに分散配置されている状態です。

oc get pod
### 標準出力↓
NAME                              READY   STATUS    RESTARTS   AGE    IP             NODE       NOMINATED NODE   READINESS GATES
spring-liberty-84c44ffc5b-4qj8r   1/1     Running       0          10s     10.128.2.11   worker-0   <none>           <none>
spring-liberty-84c44ffc5b-b68r5   1/1     Running       0          10s     10.129.2.50   worker-1   <none>           <none>
spring-liberty-84c44ffc5b-ff7lk   1/1     Running       0          11s     10.131.0.24   worker-2   <none>           <none>

1.3. HTTP要求経路確認

curlでHTTP要求したときのログを確認したところ、以下の経路になっていました。

・classicノード → Load Balancer(subnet2) → ルーターPod(subnet3) → アプリケーションPod(subnet1)

HTTP応答ヘッダ『set-cookie』が2行出力されています。このうち「JSESSIONID」はアプリケーションPod、「9fbc8a5f3284aea082f7cc20ad7c88d3」はルーターPodが設定したものです。

classicノード
curl -v http://spring-liberty.apps.ocp.cloud.vpc/
### 標準出力↓
< HTTP/1.1 200 OK
…
< set-cookie: JSESSIONID=0000A4zWGo-VFMYZqghisaTdX4g:d3042f50-318e-4ae5-8177-63cf09146c4b; Path=/; HttpOnly
…
< set-cookie: 9fbc8a5f3284aea082f7cc20ad7c88d3=f29c864d162458e5e2097fdaef677fa3; path=/; HttpOnly
…

tail -1 /var/log/router.log
### 標準出力↓
Sep 22 04:20:57 worker-2 haproxy[132]: 10.244.64.12:9832 [22/Sep/2021:04:20:57.042] public be_http:spring-liberty:spring-liberty-xpnqv/pod:spring-liberty-84c44ffc5b-4qj8r:spring-liberty::10.128.2.11:9080 0/0/1/2/3 200 718 - - --NI 1/1/0/0/0 0/0 "GET / HTTP/1.1"

HTTP要求経路を確認し易いようにシェルも作成しました。

log.sh
grep "spring-liberty" /var/log/router.log | while read line
do
  node=`echo "${line}" | awk '{print $4}'`
  router=`echo "${line}" | awk '{print $6}' | awk -F: '{print $1}'`
  appl=`echo "${line}" | awk -F":" '{print $14}'`
  echo ${router} ${node} ${appl}
done

HTTP要求経路毎のアクセス件数を確認することができます。

実行例
log.sh | sort | uniq -c
### 標準出力↓
    111 10.244.64.12 worker-0 10.128.2.11
    …
### 各列の意味↓
    1列目: アクセス件数
    2列目: LoadBalancerのIPアドレス
    3列目: ルーターPodの稼働するworkerノード名 
    4列目: アプリケーションPodのIPアドレス

2. classicノードからのHTTP要求経路確認

2.1. Load Balancerセッション維持なし、cookie送信なし

abコマンドでHTTP要求したとき、以下の結果になりました。
(1) Load Balancerは各subnetのルーターPodへ負荷分散する。
(2) ルーターPodは各subnetのアプリケーションPodへ負荷分散する。

classicノード
# ログファイル初期化後に1000回HTTP要求
ab -n 1000 -c 10 http://spring-liberty.apps.ocp.cloud.vpc/
### 標準出力↓
…
Requests per second:    357.65 [#/sec] (mean)# ログ集計
log.sh | sort | uniq -c
### 標準出力↓
    111 10.244.64.12 worker-0 10.128.2.11
    111 10.244.64.12 worker-0 10.129.2.50
    111 10.244.64.12 worker-0 10.131.0.24
    111 10.244.64.12 worker-1 10.128.2.11
    112 10.244.64.12 worker-1 10.129.2.50
    111 10.244.64.12 worker-1 10.131.0.24
    111 10.244.64.12 worker-2 10.128.2.11
    111 10.244.64.12 worker-2 10.129.2.50
    111 10.244.64.12 worker-2 10.131.0.24

2.2. Load Balancerセッション維持あり、cookie送信なし

abコマンドでHTTP要求したとき、以下の結果になりました。
(1) Load Balancerは(今回は)subnet1のルーターPodのみへHTTP要求を送信する。
(2) subnet1のルーターPodは各subnetのアプリケーションPodへ負荷分散する。

classicノード
# ログファイル初期化後に1000回HTTP要求
ab -n 1000 -c 10 http://spring-liberty.apps.ocp.cloud.vpc/
### 標準出力↓
…
Requests per second:    334.73 [#/sec] (mean)# ログ集計
log.sh | sort | uniq -c
### 標準出力↓
    333 10.244.64.12 worker-0 10.128.2.11
    334 10.244.64.12 worker-0 10.129.2.50
    333 10.244.64.12 worker-0 10.131.0.24

■ IBM Cloudコンソール設定
image.png

2.3. Load Balancerセッション維持あり、cookie送信あり

abコマンドでcookieを付加してHTTP要求したとき、以下の結果になりました。
(1) Load Balancerは(今回は)subnet2のルーターPodのみへHTTP要求を送信する。
(2) subnet2のルーターPodは(今回は)各subnet1のアプリケーションPodのみへHTTP要求を送信する。

classicノード
# ログファイル初期化後に1000回HTTP要求
cookie=9fbc8a5f3284aea082f7cc20ad7c88d3=f29c864d162458e5e2097fdaef677fa3
ab -n 1000 -c 10 -C "${cookie}" http://spring-liberty.apps.ocp.cloud.vpc/
### 標準出力
…
Requests per second:    402.08 [#/sec] (mean)# ログ確認
log.sh | sort | uniq -c
### 標準出力↓
   1000 10.244.64.12 worker-0 10.128.2.11

2.4. HTTP要求経路まとめ

確認結果をまとめます。
ケース3ではsubnetをまたぐ通信が少ないためか、HTTP要求/秒が最大になりました。
image.png
今回、RouteでなくIngressを作成したのですが、デフォルトでルーターPodがcookieを発行していました。

classicノード
oc get ing,route
### 標準出力↓
NAME                                       CLASS    HOSTS                               ADDRESS                             PORTS   AGE
ingress.networking.k8s.io/spring-liberty   <none>   spring-liberty.apps.ocp.cloud.vpc   router-default.apps.ocp.cloud.vpc   80      32h

NAME                                            HOST/PORT                           PATH   SERVICES         PORT    TERMINATION   WILDCARD
route.route.openshift.io/spring-liberty-xpnqv   spring-liberty.apps.ocp.cloud.vpc   /      spring-liberty   <all>                 None
spring-liberty.yaml(Ingress部分のみ)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: spring-liberty
spec:
  rules:
    - host: spring-liberty.apps.ocp.cloud.vpc
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: spring-liberty
                port:
                  number: 80

ルーターPodがcookieを発行するか否かはIngressのanotationで設定可能です。cookieを発行しない場合は、ケース3のようにHTTP要求にルーターPodのcookieを付加することはできませんし、JSESSIONIDを指定してもルーターPodは参照しません。

ルータPodのcookieあり
oc annotate ing spring-liberty haproxy.router.openshift.io/disable_cookies=false --overwrite
curl -v http://spring-liberty.apps.ocp.cloud.vpc/
### 標準出力↓
…
< HTTP/1.1 200 OK
< x-powered-by: Servlet/3.1
< content-type: text/html;charset=UTF-8
< content-language: en-US
< set-cookie: JSESSIONID=0000EiQOYjZwegeppYdfM_zIf2N:d3042f50-318e-4ae5-8177-63cf09146c4b; Path=/; HttpOnly
< transfer-encoding: chunked
< date: Thu, 23 Sep 2021 10:40:34 GMT
< expires: Thu, 01 Dec 1994 16:00:00 GMT
< cache-control: no-cache="set-cookie, set-cookie2"
< set-cookie: 9fbc8a5f3284aea082f7cc20ad7c88d3=f29c864d162458e5e2097fdaef677fa3; path=/; HttpOnly
< cache-control: private
…
ルータPodのcookieなし
oc annotate ing spring-liberty haproxy.router.openshift.io/disable_cookies=true --overwrite
curl -v http://spring-liberty.apps.ocp.cloud.vpc/
### 標準出力↓
…
< HTTP/1.1 200 OK
< x-powered-by: Servlet/3.1
< content-type: text/html;charset=UTF-8
< content-language: en-US
< set-cookie: JSESSIONID=0000UO_TiSCbO2snErS_71KsS0b:d3042f50-318e-4ae5-8177-63cf09146c4b; Path=/; HttpOnly
< transfer-encoding: chunked
< date: Thu, 23 Sep 2021 10:40:45 GMT
< expires: Thu, 01 Dec 1994 16:00:00 GMT
< cache-control: no-cache="set-cookie, set-cookie2"

おわりに

本記事は、Podの分散配置について調査したことを契機に作成しました。当初、ルーターPodの連携先としてsubnet内のアプリケーションPodを優先選択したかったのですが、これを実現するためのService TopologyもTopology Aware HintsもOpenShift 4.8(kubernetes v1.21ベース)のFeatureGateで有効化される機能ではありませんでした。

■ kubernetes v1.17でアルファ、v1.21で非推奨

■ kubernetes v1.21でアルファ

■ OpenShift 4.8のFeatureGate機能

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?