CLOVER🍀

That was when it all began.

OKD/Minishiftで、Route(HAProxy)を少し見てみる

これは、なにをしたくて書いたもの?

  • OKDにはRouteというものがあり、外部からのアクセスを受け付けてくれる
  • Routeの実体はHAProxy
  • Routeのルーティングは、Service経由ではなくPodへ直接振り分けということを最近知ったので

この内容を確認してみようと。

Route

最初にも書きましたが、OKDを使った時に外部からのリクエストを受け付ける役割を持ちます。

Routes - Networking | Architecture | OKD 3.11

Using the Default HAProxy Router - Setting up a Router | Configuring Clusters | OKD 3.11

正体は、HAProxyです。

KubernetesIngressと役割が似通っていますが、これはOpenShiftがKubernetesIngressがまだ存在しない時期に追加したもの
だからみたいですね。

Kubernetes Ingress vs OpenShift Route – Red Hat OpenShift Blog

環境

今回の環境は、こちらです。

$ minishift version
minishift v1.32.0+009893b


$ oc version
oc v3.11.0+0cbc58b
kubernetes v1.11.0+d4cacc0
features: Basic-Auth GSSAPI Kerberos SPNEGO

Server https://192.168.42.118:8443
kubernetes v1.11.0+d4cacc0

お題

デフォルトのプロジェクトにWildFlyを、別のプロジェクトを作成してKeycloakをデプロイして、それぞれにRouteを作成します。

この時、Routeがどのような構成になるか確認してみたいと思います。

確認対象のデプロイ

では、確認対象となるイメージをデプロイしていきます。

まずは、デフォルトのプロジェクトでWildFlyをデプロイします。

$ oc project
Using project "myproject" on server "https://192.168.42.118:8443".

デプロイから、Route作成まで。

$ oc run wildfly --image=jboss/wildfly
deploymentconfig.apps.openshift.io/wildfly created


$ oc scale dc wildfly --replicas=3
deploymentconfig.apps.openshift.io/wildfly scaled


$ oc expose dc wildfly --port=8080
service/wildfly exposed


$ oc expose svc wildfly
route.route.openshift.io/wildfly exposed

確認。

$ curl -s wildfly-myproject.192.168.42.118.nip.io | grep title
    <title>Welcome to WildFly</title>

Podを見てみます。

$ oc get pod
NAME              READY     STATUS    RESTARTS   AGE
wildfly-1-4bzjn   1/1       Running   0          6m
wildfly-1-f8p7n   1/1       Running   0          6m
wildfly-1-mwshd   1/1       Running   0          6m

続いて、別のプロジェクトを作成。

$ oc new-project other

Keycloakをデプロイ。

$ oc run keycloak --image=jboss/keycloak
deploymentconfig.apps.openshift.io/keycloak created


$ oc scale dc keycloak --replicas=3
deploymentconfig.apps.openshift.io/keycloak scaled


$ oc expose dc keycloak --port=8080
service/keycloak exposed


$ oc expose svc keycloak 
route.route.openshift.io/keycloak exposed

確認。

$ curl -s keycloak-other.192.168.42.118.nip.io/auth/ | grep title
    <title>Welcome to Keycloak</title>

こちらも、Podを見ておきます。

$ oc get pod
NAME               READY     STATUS    RESTARTS   AGE
keycloak-1-2vcr6   1/1       Running   0          4m
keycloak-1-drkcq   1/1       Running   0          3m
keycloak-1-l6dd5   1/1       Running   0          3m

Routeはどこに?

ところで、RouteもPodで動いているはずなのですが、どこにいるのでしょう?

答えとしては、defaultプロジェクトにいます。

$ oc get all -l router=router -n default --as system:admin
NAME                 READY     STATUS    RESTARTS   AGE
pod/router-1-t27rp   1/1       Running   0          1h

NAME                             DESIRED   CURRENT   READY     AGE
replicationcontroller/router-1   1         1         1         1h

NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                   AGE
service/router   ClusterIP   172.30.222.218   <none>        80/TCP,443/TCP,1936/TCP   1h

NAME                                        REVISION   DESIRED   CURRENT   TRIGGERED BY
deploymentconfig.apps.openshift.io/router   1          1         1         config

HAProxyの設定を、コンテナの中に入って確認してみましょう。

$ oc exec -it router-1-t27rp -n default --as system:admin bash

プロセスを確認。

$ ps -ef      
UID        PID  PPID  C STIME TTY          TIME CMD
1001         1     0  0 11:45 ?        00:00:06 /usr/bin/openshift-router
1001       204     1  0 12:42 ?        00:00:00 /usr/sbin/haproxy -f /var/lib/haproxy/conf/haproxy.config -p /var/lib/haproxy/run/haproxy.pid -x /var/lib/haproxy/run/haproxy.sock 
1001       213     0  0 12:50 ?        00:00:00 bash
1001       218   213  0 12:50 ?        00:00:00 ps -ef

確かに、HAProxyが動いています。設定ファイルのパスも見えますね。

確認。

$ cat /var/lib/haproxy/conf/haproxy.config

設定ファイルの末尾の方を見ると、先ほど作成したWildFlyやKeycloakのPodが並んでいることが確認できます。

# Plain http backend or backend with TLS terminated at the edge or a
# secure backend with re-encryption.
backend be_http:myproject:wildfly
  mode http
  option redispatch
  option forwardfor
  balance leastconn

  timeout check 5000ms
  http-request set-header X-Forwarded-Host %[req.hdr(host)]
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  http-request set-header X-Forwarded-Proto-Version h2 if { ssl_fc_alpn -i h2 }
  http-request add-header Forwarded for=%[src];host=%[req.hdr(host)];proto=%[req.hdr(X-Forwarded-Proto)];proto-version=%[req.hdr(X-Forwarded-Proto-Version)]
  cookie c8f20c96872329a8ed693a128f26f96a insert indirect nocache httponly
  server pod:wildfly-1-mwshd:wildfly:172.17.0.10:8080 172.17.0.10:8080 cookie cc40ac8147cd260e8c3bea2b4f640adc weight 256 check inter 5000ms
  server pod:wildfly-1-f8p7n:wildfly:172.17.0.6:8080 172.17.0.6:8080 cookie 25a2778d2c27d7ca8620e3c91494384e weight 256 check inter 5000ms
  server pod:wildfly-1-4bzjn:wildfly:172.17.0.9:8080 172.17.0.9:8080 cookie 9aea0cc8ed45593daad18ab07f01950e weight 256 check inter 5000ms

# Plain http backend or backend with TLS terminated at the edge or a
# secure backend with re-encryption.
backend be_http:other:keycloak
  mode http
  option redispatch
  option forwardfor
  balance leastconn

  timeout check 5000ms
  http-request set-header X-Forwarded-Host %[req.hdr(host)]
  http-request set-header X-Forwarded-Port %[dst_port]
  http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
  http-request set-header X-Forwarded-Proto https if { ssl_fc }
  http-request set-header X-Forwarded-Proto-Version h2 if { ssl_fc_alpn -i h2 }
  http-request add-header Forwarded for=%[src];host=%[req.hdr(host)];proto=%[req.hdr(X-Forwarded-Proto)];proto-version=%[req.hdr(X-Forwarded-Proto-Version)]
  cookie 18c824445b45c4533e54824c9aeb56b6 insert indirect nocache httponly
  server pod:keycloak-1-l6dd5:keycloak:172.17.0.12:8080 172.17.0.12:8080 cookie f7e33313456d7957447775f327dbd273 weight 256 check inter 5000ms
  server pod:keycloak-1-2vcr6:keycloak:172.17.0.13:8080 172.17.0.13:8080 cookie 916fd23d18eeaf13161646ab18a92609 weight 256 check inter 5000ms
  server pod:keycloak-1-drkcq:keycloak:172.17.0.14:8080 172.17.0.14:8080 cookie 224bcdd95633f7729a21a88cddff0b2c weight 256 check inter 5000ms

このRouteはHost名でルーティングしているようですが、その設定はどこでしょう?

このあたりのようですね。

$ grep use_backend /var/lib/haproxy/conf/haproxy.config              
  use_backend %[base,map_reg(/var/lib/haproxy/conf/os_http_be.map)]
  use_backend %[req.ssl_sni,lower,map_reg(/var/lib/haproxy/conf/os_tcp_be.map)] if sni sni_passthrough
  use_backend be_sni if sni
  #       use_backend directives below this will be processed.
  use_backend %[base,map_reg(/var/lib/haproxy/conf/os_edge_reencrypt_be.map)]
  #       use_backend directives below this will be processed.
  use_backend %[base,map_reg(/var/lib/haproxy/conf/os_edge_reencrypt_be.map)]

HTTPであれば、このようになっています。
/var/lib/haproxy/conf/os_http_be.map

^wildfly-myproject\.192\.168\.42\.118\.nip\.io(:[0-9]+)?(/.*)?$ be_http:myproject:wildfly
^keycloak-other\.192\.168\.42\.118\.nip\.io(:[0-9]+)?(/.*)?$ be_http:other:keycloak

設定はだいたいわかった感じです。

VM上ではどうなっているんでしょう?OKDが動作しているVMの中に入ってみます。

$ minishift ssh

Routeのコンテナを確認。

$ docker ps | grep router_route
f0299a418978        9bb7abed3e82                                                                                                                     "/usr/bin/openshif..."   About an hour ago   Up About an hour                        k8s_router_router-1-t27rp_default_816e3aaa-3c17-11e9-a1fe-5254006d017f_0

ところで、このVMで80ポートをリッスンしているのは…

$ sudo ss -tnlp | grep 80
LISTEN     0      128          *:80                       *:*                   users:(("haproxy",pid=11251,fd=6))

HAProxyですね…。

$ ps -ef | grep 11251
1001     11251 10437  0 12:42 ?        00:00:00 /usr/sbin/haproxy -f /var/lib/haproxy/conf/haproxy.config -p /var/lib/haproxy/run/haproxy.pid -x /var/lib/haproxy/run/haproxy.sock -sf 197
docker   20087 16753  0 13:02 pts/0    00:00:00 grep --color=auto 11251

どうも、DockerコンテナがVM側から見えているような…?

$ docker exec -it k8s_router_router-1-t27rp_default_816e3aaa-3c17-11e9-a1fe-5254006d017f_0 bash
bash-4.2$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
1001         1     0  0 11:45 ?        00:00:08 /usr/bin/openshift-router
1001       204     1  0 12:42 ?        00:00:00 /usr/sbin/haproxy -f /var/lib/haproxy/conf/haproxy.config -p /var/lib/haproxy/run/haproxy.pid -x /var/lib/haproxy/run/haproxy.sock 
1001       235     0  0 13:03 ?        00:00:00 bash
1001       240   235  0 13:03 ?        00:00:00 ps -ef

VM上でKeycloakのプロセスも見えているので…どうやら、そうっぽいですね。

$ ps -ef | grep keycloak
1000160+  9434  9401  0 12:41 ?        00:00:00 /bin/sh /opt/jboss/keycloak/bin/standalone.sh -Djboss.bind.address=172.17.0.13 -Djboss.bind.address.private=172.17.0.13 -c standalone-ha.xml -b 0.0.0.0
1000160+  9572  9434  3 12:41 ?        00:00:58 /usr/lib/jvm/java/bin/java -D[Standalone] -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Dorg.jboss.boot.log.file=/opt/jboss/keycloak/standalone/log/server.log -Dlogging.configuration=file:/opt/jboss/keycloak/standalone/configuration/logging.properties -jar /opt/jboss/keycloak/jboss-modules.jar -mp /opt/jboss/keycloak/modules org.jboss.as.standalone -Djboss.home.dir=/opt/jboss/keycloak -Djboss.server.base.dir=/opt/jboss/keycloak/standalone -Djboss.bind.address=172.17.0.13 -Djboss.bind.address.private=172.17.0.13 -c standalone-ha.xml -b 0.0.0.0
1000160+  9933  9906  0 12:41 ?        00:00:00 /bin/sh /opt/jboss/keycloak/bin/standalone.sh -Djboss.bind.address=172.17.0.12 -Djboss.bind.address.private=172.17.0.12 -c standalone-ha.xml -b 0.0.0.0
1000160+ 10068  9933  5 12:41 ?        00:01:20 /usr/lib/jvm/java/bin/java -D[Standalone] -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Dorg.jboss.boot.log.file=/opt/jboss/keycloak/standalone/log/server.log -Dlogging.configuration=file:/opt/jboss/keycloak/standalone/configuration/logging.properties -jar /opt/jboss/keycloak/jboss-modules.jar -mp /opt/jboss/keycloak/modules org.jboss.as.standalone -Djboss.home.dir=/opt/jboss/keycloak -Djboss.server.base.dir=/opt/jboss/keycloak/standalone -Djboss.bind.address=172.17.0.12 -Djboss.bind.address.private=172.17.0.12 -c standalone-ha.xml -b 0.0.0.0
1000160+ 10118 10090  0 12:41 ?        00:00:00 /bin/sh /opt/jboss/keycloak/bin/standalone.sh -Djboss.bind.address=172.17.0.14 -Djboss.bind.address.private=172.17.0.14 -c standalone-ha.xml -b 0.0.0.0
1000160+ 10272 10118  5 12:41 ?        00:01:20 /usr/lib/jvm/java/bin/java -D[Standalone] -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Dorg.jboss.boot.log.file=/opt/jboss/keycloak/standalone/log/server.log -Dlogging.configuration=file:/opt/jboss/keycloak/standalone/configuration/logging.properties -jar /opt/jboss/keycloak/jboss-modules.jar -mp /opt/jboss/keycloak/modules org.jboss.as.standalone -Djboss.home.dir=/opt/jboss/keycloak -Djboss.server.base.dir=/opt/jboss/keycloak/standalone -Djboss.bind.address=172.17.0.14 -Djboss.bind.address.private=172.17.0.14 -c standalone-ha.xml -b 0.0.0.0
docker   21605 16753  0 13:06 pts/0    00:00:00 grep --color=auto keycloak

まあ、このあたりは今回はいいかな…。

とりあえず、今回はRouteを構成するHAProxyまわりが確認できたので、よしとしましょう。