概要
minikubeのCHANGELOGによるとVersion 0.31.0からminikube tunnel
というコマンドが使えるようになったようなので、調査してみる。
どんな機能なのか?
minikube tunnel by balopat · Pull Request #3015 · kubernetes/minikube · GitHub
Issueから辿れるデザインドキュメントはこちら。minikube/tunnel.md at master · kubernetes/minikube · GitHub
説明書はないので、このデザインドキュメントが頼り
とりあえず最新のminikubeにする
$ minikube version
minikube version: v0.33.1
何も考えずヘルプを実行してみる
$ minikube tunnel --help
tunnel creates a route to services deployed with type LoadBalancer and sets their Ingress to their ClusterIP
Usage:
minikube tunnel [flags]
Flags:
-c, --cleanup call with cleanup=true to remove old tunnels
-h, --help help for tunnel
(略)
Serviceのtype=LoadBalancerのものが、ホストからもアクセスできるようなことが書いてある。
とりあえずやってみる
そういうサービスを作ってみる。
$ kubectl run --image=nginx nginx
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx created
$ kubectl expose deployment nginx --port 80 --type=LoadBalancer
service/nginx exposed
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 80m
nginx LoadBalancer 10.106.99.252 <pending> 80:30037/TCP 3s
そして、minikube tunnelを実行
$ minikube tunnel
Password: # <-- ルーティングをいじるために、パスワードを求められる
E0122 17:40:38.807968 51021 loadbalancer_patcher.go:108] error patching nginx with IP 10.106.99.252: %!s(<nil>)
Status:
machine: minikube
pid: 51021
route: 10.96.0.0/12 -> 192.168.99.101
minikube: Running
services: [nginx]
errors:
minikube: no errors
router: no errors
loadbalancer emulator: no errors
上手いこといったっぽい!
nginxのServiceのClusterIPである
http://10.98.236.108/
でブラウザからアクセスできるようになった。
またServiceを見て見るとEXTERNAL-IPとしてCLUSTER-IPと同じものが登録されていることが確認できた。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 81m
nginx LoadBalancer 10.106.99.252 10.106.99.252 80:30037/TCP 56m
これでminikubeでもLoadBalancerが使えるようになった。
これがどのように実現されているかというと、
デザインドキュメントにOSごとの実現方法が記載されている。
今回はMacOSXで実行しているので、このようにするとルーティングにそれっぽいエントリが追加されていることが確認できた。
$ netstat -nr -f inet
Routing tables
Internet:
Destination Gateway Flags Refs Use Netif Expire
default 192.168.152.1 UGSc 65 0 en0
10.96/12 192.168.99.101 UGSc 0 0 vboxnet # <---------これ
127 127.0.0.1 UCS 0 0 lo0
127.0.0.1 127.0.0.1 UH 6 79977 lo0
(略)
minikube tunnelはフォアグラウンドで実行され、Ctrl+Cで停止しようとすると、再びパスワードを求められた。(おそらくルーティングを掃除するためだと思われる。)
いろいろ試す
type=LoadBalancerじゃなくてもいいよね?
ルーティングを見る限りtype=LoadBalancerじゃなくても行けそう。
ということでtype=ClusterIPでも試してみる。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24m
nginx ClusterIP 10.106.99.252 <none> 80/TCP 5s
これでもホストPCからアクセスできた。
Podに直接アクセスできる?
PodはIPの範囲が違うので、アクセスできなそう
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7cdbd8cdc9-br966 1/1 Running 0 24m 172.17.0.6 minikube <none> <none>
クラスタ内DNSの名前でアクセスすることはできるか?
あまり一般的な使い方ではないかもしれないが、クラスタ内DNSでアクセスができるようにならないか?
$ kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default-http-backend NodePort 10.103.185.56 <none> 80:30001/TCP 35m
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 35m
このkube-dnsも先ほどのルーティングでホストからアクセスできるようになっているはず。
$ nslookup
> server 10.96.0.10
Default server: 10.96.0.10
Address: 10.96.0.10#53
> nginx.default.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx.default.svc.cluster.local
Address: 10.106.99.252
>
ホストからクラスタ内DNSにアクセスできた。
DNSを差し替えると・・・
ホストPCからクラスタ内DNSを利用してアクセスすることができた!
結論
この機能を使うとminikubeを実行しているホストPCから、type=LoadBalancerのサービスにアクセスすることができるようになった。
さらにクラスタ内のServiceのClusterIPに直接アクセスすることができる!
また、うまくDNSの設定を行うと、クラスタ内DNSを使うこともできることを確認した。