入門Kubernetes の メモ1 の続きです。
ラベル付けとサービス公開まで行います。Mac で minikube で動かしています。
ラベル
仕様など
- key=value で複数表記できる。
- キーも値も最大 63 文字。
- キーにスラッシュ区切りでプレフィックスを指定できる
- 例: example.com/app-version
example.com がプレフィックス。プレフィックスは DNS サブドメインである必要があり、最大 253 文字
- 例: example.com/app-version
ラベルを追加して起動
※--labels=
内で、カンマの後にスペースを入れるとエラーになるので注意
$ kubectl run alpaca-prod \
--image=gcr.io/kuar-demo/kuard-amd64:1 \
--replicas=2 \
--labels="ver=1,app=alpaca,env=prod"
$ kubectl run alpaca-test
--image=gcr.io/kuar-demo/kuard-amd64:1
--replicas=2
--labels="ver=2,app=alpaca,env=test"
ラベルを表示
$ kubectl get deployments --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
alpaca-prod 2/2 2 2 94s app=alpaca,env=prod,ver=1
alpaca-test 1/1 1 1 60s app=alpaca,env=test,ver=2
ラベル env=test を検索
$ kubectl get deployments --selector="env=test"
NAME READY UP-TO-DATE AVAILABLE AGE
alpaca-test 1/1 1 1 12m
ラベル env=test を削除
$ kubectl delete deployment --selector="env=test"
deployment.extensions "alpaca-test" deleted
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
alpaca-prod 2/2 2 2 16m
サービスディスカバリ
Service 作成
expose で Service を作成
$ kubectl run alpaca-prod \
--image=gcr.io/kuar-demo/kuard-amd64:1 \
--replicas=3 \
--port=8080 --labels="ver=1,app=alpaca,env=prod"
$ kubectl expose deployment alpaca-prod
service/alpaca-prod exposed
kubernetes というサービスも自動で作成される。
Service は クラスタ IP と呼ばれる仮想 IP アドレスが割当られる。
$ kubectl get services -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
alpaca-prod ClusterIP 10.104.169.174 <none> 8080/TCP 8s app=alpaca,env=prod,ver=1
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 32d <none>
ポートフォワード
$ ALPACA_POD=$(kubectl get pods -l app=alpaca \
-o jsonpath='{.items[0].metadata.name}')
$ kubectl port-forward $ALPACA_POD 48858:8080
localhost:48858 を開くと alpaca にアクセスできる。
DNS Query メニューをクリックし、Name: alpaca-prod を入力して QUERY をクリック。
DNS レコードが返ってくることを確認します。
kubernetes は内部でこのような DNS サーバーを持っているのですね。

DNS Query が動かない時
$ minicube delete && minicube start
すると直るかもです。
restart: waiting for k8s-app=kube-proxy: timed out waiting for the condition

レスポンスに下記が返ってくる。
read udp 172.17.0.7:50306->10.96.0.10:53: read: no route to host
その結果 JSON パースエラー。
Uncaught (in promise) SyntaxError: Unexpected token r in JSON at position 0
起動中の Pod の YAML を編集する
$ kubectl edit deployment/alpaca-prod
vim が立ち上がる。
Service を公開
$ kubectl edit service alpaca-prod
spec:
clusterIP: 10.104.169.174
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: alpaca
env: prod
ver: "1"
sessionAffinity: None
type: NodePort // ClusterIp -> NodePort に変更する
今回だとポート 32315 が alpaca-prod Service に割り当てられました。
AkihisanoMacBook-Pro:kuard$ kubectl describe service alpaca-prod | grep NodePort
Type: NodePort
NodePort: <unset> 32315/TCP
Service を公開 (クラウドのみ)
$ kubectl edit service alpaca-prod
spec:
clusterIP: 10.104.169.174
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: alpaca
env: prod
ver: "1"
sessionAffinity: None
type: LoadBalancer // LoadBalancer に変更する
IP らしきものが振られました。
$ kubectl describe service alpaca-prod | grep IP
IP: 10.104.169.174
私は minikube でローカルで動かしているので上記は無効ですが、
サポートされているクラウドで動かしている場合はアクセスできるのだと思います。すごいですね。
クラスタ IP はどうやって実現している?
クラスタ内に kube-proxy と呼ばれるコンポーネントがいて、API サーバを通じてクラスタ内の Service を監視し、 ホストのカーネルの iptables を書き換えることで実現しているみたいです。
出典
Kubernetes: Up and Running, by Kelsey Hightower, Brendan Burns, and Joe Beda (O'Reilly), 978-1-491-93567-5. (日本語版「入門 Kubernetes」 Kelsey Hightower, Brendan Burns, Joe Beda 著、オライリー・ジャパン、ISBN 978-4-87311-840-6)