作業メモ。
Kubernetes完全ガイド impress top gearシリーズを読みながら手元で確認した時のメモ。
ただし、ExternalIP についてはうまくいかず。
環境
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.3", GitCommit:"2bba0127d85d5a46ab4b778548be28623b32d0b0", GitTreeState:"clean", BuildDate:"2018-05-28T20:03:09Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"11+", GitVersion:"v1.11.5-eks-6bad6d", GitCommit:"6bad6d9c768dc0864dab48a11653aa53b5a47043", GitTreeState:"clean", BuildDate:"2018-12-06T23:13:14Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Kubernetes 環境としては EKS を利用。
ExternalIP を試す
If there are external IPs that route to one or more cluster nodes, Kubernetes services can be exposed on those externalIPs. Traffic that ingresses into the cluster with the external IP (as destination IP), on the service port, will be routed to one of the service endpoints. externalIPs are not managed by Kubernetes and are the responsibility of the cluster administrator.
Node に振られたグローバル IP アドレスを使って Pod へのルーティングを行う方法。
Node の IP を調べる
ExternalIP を使う場合、マニュフェストファイルに利用する Node のグローバル IP アドレスを記載する必要があるため、事前に確認する。
kubectl describe node
から確認可能。
$kubectl describe node |grep ExternalIP
ExternalIP: 13.113.212.75
ExternalIP: 13.113.172.56
ExternalIP: 54.168.61.99
上記例の場合、Node が3つあり、それぞれ外部から接続可能な IP は上記。
今回の例では「13.113.212.75」を使う。
マニフェストファイルを作成する
以下とほぼ同じものをつかう。
Kubernetes の Service(ClusterIP) を検証する
- sample-deployment.yaml
- sample-clusterip.yaml
今回は ExternalIP を使うため、sample-clusterip.yaml は少し変更して sample-externalip.yaml とした。
$diff sample-clusterip.yaml sample-externalip.yaml
4c4
< name: sample-clusterip
---
> name: sample-externalip
6a7,8
> externalIPs:
> - 13.113.212.75
10c12
< port: 8080
---
> port: 80
- Service 名を sample-externalip に変更
- externalIPs に Node の IP を追加
- ExternalIP で受け付けるポートを 80 に変更
# deployment を作成
$kubectl apply -f sample-deployment.yaml
deployment.apps "sample-deployment" created
# Service を作成
$kubectl apply -f sample-externalip.yaml
service "sample-externalip" created
# ExternalIP が設定されている
$kubectl get service sample-externalip
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sample-externalip ClusterIP 10.100.143.185 13.113.212.75 80/TCP 30s
# 接続できない...
$curl http://13.113.212.75
curl: (7) Failed to connect to 13.113.212.75 port 80: Connection refused
なぜか接続に失敗する。
# クラスター内の IP アドレスからの名前解決は可能(返却されるのは ClusterIP
$kubectl run testpod --image=centos:6 --restart=Never -i --rm -- dig +short sample-externalip.default.svc.cluster.local
10.100.143.185
# クラスター内からのリクエストは可能
$ kubectl run testpod --image=centos:6 --restart=Never -i --rm -- curl -s http://sample-externalip
sample-deployment-86d576464c-wkhjd
こうなると Node 側の問題?
# Node に SSH 接続する
$ssh -i ~/.ssh/xxxx.pem ec2-user@13.113.212.75
# 何も出ない
$ss -napt |grep 80
そもそもリッスンされていない。
切り分けのためにポートを80->8080 に変更して ss -napt |grep 8080
してみたがうまくいかず。
別途これは調査する
NodePort
ExternalIP はマニュフェストファイルに指定した Node の グローバルIP:Port で受け付けたトラフィックを転送していた。
NodePort ではすべての Node の グローバルIP:Port で受付を行い、同様にトラフィックを転送する。
apiVersion: v1
kind: Service
metadata:
name: sample-nodeport
spec:
type: NodePort
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
nodePort: 30080
selector:
app: sample-app
ExternalIP では 受付をおこなう Node の IP を指定していたが、NodePort の場合にはその記載は不要。
代わりに type では NodePort を設定する。
また、 nodePort を指定することで Node でリッスンするポートを指定する。
なお、ExternalIP の場合、ports.port に書いたポート番号で ClusterIP(クラスタ内)及び ExternalIP(外部からの疎通)でリッスンしていたが、NodePort の場合、ClusterIP で受け付けるポートが ports.port の番号に該当し、Node で受け付けるポートは ports.nodePort となっているので注意。
上記マニュフェストファイルの場合以下を意味する
- ClusterIP で受け付けるポート:8080
- 各 Node への IP アドレスで受け付けるポート:30080
- コンテナで受け付けるポート:80
# service を作成
$kubectl apply -f sample-nodeport.yaml
service "sample-nodeport" created
# type が NodePort となっている.CLUSTER-IP がクラスタ内からアクセスする際の仮想 IP
$kubectl get service sample-nodeport
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sample-nodeport NodePort 10.100.241.100 <none> 8080:30080/TCP 34s
# Node に SSH 接続する
$ssh -i ~/.ssh/xxxx.pem ec2-user@13.113.212.75
# nodePort で記載した番号 30080 でリッスンしている
$ss -napt |grep 30080
LISTEN0 128 *:30080 *:*
# 一つの Node の IP アドレスへリクエストするとレスポンスが返ってくる
$curl http://13.113.212.75:30080/
sample-deployment-86d576464c-x75hx
# 別の Node へのリクエストも同様
$curl http://13.113.172.56:30080/
sample-deployment-86d576464c-x75hx
# クラスター内から ClusterIP を使ってアクセスする場合には 30080 ではなく、8080 ポート
$kubectl run testpod --image=centos:6 --restart=Never -i --rm -- curl -s http://sample-nodeport:8080
sample-deployment-86d576464c-hnkm7