MicroshiftでRouteを使う
Microshiftは、OpenShiftを極限までダウンサイズしてIoTやリソースの限られたPC上で実行できるようにしようというプロジェクト。現在、自分はMicroshiftをGitHub Actions上で使えるようにしようとしている。
始まったばかりのプロジェクトでユーザはまだほとんどいないと思うが、自分用の備忘録としてまとめておく。
Routeを通すにはDNSの設定が必要
Microshiftはまだ出来たてのプロジェクトなので、まだMinikubeやCRCのように色々な機能がすぐ使えるようにはなっていない。
OpenshiftのRouteを作成しても、そのままではすぐに割り当てられたホスト名にアクセスできない。
(この記事ではMicroshiftをVagrantにインストールする方法を前提にする。)
試しにアプリをMicroshiftにデプロイして、ルートを公開してみる。
oc create deploy hello --image=quay.io/tasato/hello-js
oc expose deploy hello --port 8080
oc expose svc hello
サービスとルートが出来上がる。
$ oc get svc,route
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hello ClusterIP 10.43.122.106 <none> 8080/TCP 6s
...
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
route.route.openshift.io/hello hello-default.cluster.local hello 8080 None
しかし、このままだと hello-default.cluster.local
にはアクセスできない。
$ curl hello-default.cluster.local
curl: (6) Could not resolve host: hello-default.cluster.local
Routerを公開する
最初にやるのは、OpenShiftのRouterをNodePort
サービスとして公開すること。Routerはopenshift-ingress
ネームスペースに元々走っている。
$ oc get pods -n openshift-ingress
NAME READY STATUS RESTARTS AGE
router-default-6d8c9d8f57-wjfk7 1/1 Running 1 4d21h
これを30080->80
(HTTP)、30443->443
(HTTPS)でNodePort
サービスとして公開する。これでクラスタ外から30080
、30443
ポートでRouterにアクセスできるようにする。
$ cat <<EOF | oc apply -f -
apiVersion: v1
kind: Service
metadata:
name: router
namespace: openshift-ingress
spec:
type: NodePort
selector:
ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
- name: https
port: 443
targetPort: 443
nodePort: 30443
EOF
なお、今作ったrouter
サービスの他に元々router-internal-default
というClusterIP
サービスが用意されている。
$ oc get svc -n openshift-ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
router NodePort 10.43.205.107 <none> 80:30080/TCP,443:30443/TCP 4d2h
router-internal-default ClusterIP 10.43.95.166 <none> 80/TCP,443/TCP,1936/TCP 36d
Microshiftクラスタのノード内からRouteにアクセスしたいだけ(GitHub Actionsで使う場合など)なら、わざわざrouter
サービスを作らずこちらのrouter-internal-default
がそのまま使える。
クライアント側のDNSを設定する
この時点でVagrant VMの30080
ポートからhello-default.cluster.local
にアクセスできるようになっている。VMのIPアドレスを192.168.99.11
として、HTTPのHost
ヘッダにディスパッチ先のルート名を指定する。
$ curl -H 'Host: hello-default.cluster.local' 192.168.99.11:30080
Hello ::ffff:10.42.0.51 from hello-64c47c44c8-5bbjg
あとは、クライアント側でhello-default.cluster.local
にアクセスしたらVagrant VMのIPアドレス192.168.99.11
に名前解決されるようにすればいい。
dnsmasq
動的に作成されるURL *.cluster.local
に特定IPアドレスを割り当てるにはdnsmasqを使うのが簡単。dnsmasqが入っていなければインストールする。
$ sudo dnf install dnsmasq
$ sudo apt install dnsmasq
/etc/dnsmasq.conf
を編集する。Vagrant VMのIPアドレス192.168.99.11
をcluster.local
ドメインに割り振る。address=/cluster.local/192.168.99.11
を追加する。またコメントアウトされている#bind-interfaces
のコメントを外して有効にする。
address=/cluster.local/192.168.99.11
...
bind-interfaces
bind-interfaces
を有効にするのは、そうしないとsystemd-resolvedが見ている127.0.0.53:53
と競合してdnsmasqが起動しないため。
dnsmasqを再起動する。
$ sudo systemctl restart dnsmasq
systemd-resolved
最近のLinuxではsystemd-resolvedがデフォルトのDNSサービスになっている。
/etc/systemd/resolved.conf
を修正して、dnsmasq(127.0.0.1
)を見にいくようにする。
DNS=127.0.0.1 8.8.8.8
(8.8.8.8
はもしかしたら要らないかもしれない。)
/etc/resolv.conf
が/run/systemd/resolve/stub-resolv.conf
へのリンクになっているのを/run/systemd/resolve/resolv.conf
に切り替える。
$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
/etc/nsswitch.conf
Fedoraを使っている場合には、/etc/nsswitch.conf
の設定に要注意。
*.local
はmDNSに優先的に解決されるため、nsswitch.conf
でmDNSの解決後すぐにリターンするような設定になっている場合は、それを変える必要がある。
以下のようにhosts:
に[...=return]
の設定がある場合は、それを全部外して必ずdns
まで到達するように変更する。
hosts: files myhostname mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns
hosts: files myhostname mdns4_minimal resolve dns
systemd-resolvedを再起動する。
$ sudo systemctl restart systemd-resolved
VM側のポートフォーワードを設定する
ここまででhello-default.cluster.local:30080
でアプリにアクセスできるようになっている。
$ curl hello-default.cluster.local:30080
Hello ::ffff:10.42.0.51 from hello-64c47c44c8-5bbjg
curl hello-default.cluster.local
でアクセスできるようにするには、VM側で30080
→ 80
にポートフォーワードを設定する。
redir
一番簡単だったのはredirを使う方法。
redirをインストールする。
$ sudo dnf install redir
$ sudo apt install redir
VM内でredirをバックグラウンド起動する。
sudo redir -l debug :80 localhost:30080
redirのログはVM内のsyslogで確認できる。
$ sudo tail -f /var/log/syslog | grep redir
Oct 18 06:29:31 ubuntu-focal redir[142824]: peer IP is 192.168.99.1
Oct 18 06:29:31 ubuntu-focal redir[142824]: peer socket is 33402
Oct 18 06:29:31 ubuntu-focal redir[142824]: target IP address is 127.0.0.1
Oct 18 06:29:31 ubuntu-focal redir[142824]: target port is 30080
Oct 18 06:29:31 ubuntu-focal redir[50856]: target is localhost:30080
Oct 18 06:29:31 ubuntu-focal redir[50856]: Waiting for client to connect on server socket ...
Oct 18 06:29:31 ubuntu-focal redir[142824]: Connecting 192.168.99.1:33402 to 192.168.99.1:30080
Oct 18 06:29:31 ubuntu-focal redir[142824]: Entering copyloop() - timeout is 0
Oct 18 06:29:31 ubuntu-focal redir[142824]: Disconnect after 0 sec, 332 bytes in, 91 bytes out
確認
hello-default.cluster.local
でアクセスできるようになる。
$ curl hello-default.cluster.local
Hello ::ffff:10.42.0.51 from hello-64c47c44c8-5bbjg
以上。
Discussion