21
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kubernetes の Service の ExternalIP/NodePort を試す

Last updated at Posted at 2018-12-29

作業メモ。

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 を試す

External IPs

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

Type NodePort

ExternalIP はマニュフェストファイルに指定した Node の グローバルIP:Port で受け付けたトラフィックを転送していた。
NodePort ではすべての Node の グローバルIP:Port で受付を行い、同様にトラフィックを転送する。

sample-nodeport.yaml
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
21
25
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?