containers.portsの意味
こちらのドキュメント内で示されているこちらdeployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
これを始めとして、kubernetesのmanifestは基本的に、サービスを公開するportに対して、containers.ports.containerPort
を設定しています
この設定は直感的に、dockerコマンドの-pオプションのような、設定しないとアクセスできないもののように思えます
(なんなら上のドキュメントでは、コンテナポートの仕様を指定していることに注意してください、とわざわざ書いてあります)
が、実はアクセスするだけならこれは必要というわけではありません
これを設定しなくてもコンテナがlistenしているポートは勝手にクラスタ内に公開されてしまいます
試しに以下のようなcontainer.ports
を設定しないmanifestをapplyして
apiVersion: apps/v1
kind: Deployment
metadata:
name: test
labels:
app.kubernetes.io/name: test
spec:
selector:
matchLabels:
app.kubernetes.io/name: test
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: test
spec:
containers:
- name: nginx-80
image: nginx:latest
volumeMounts:
- mountPath: /etc/nginx/conf.d
name: nginx-80
- name: nginx-8080
image: nginx:latest
volumeMounts:
- mountPath: /etc/nginx/conf.d
name: nginx-8080
volumes:
- name: nginx-80
configMap:
name: nginx-80
- name: nginx-8080
configMap:
name: nginx-8080
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-80
data:
default.conf: |
server {
listen 80;
server_name localhost;
location / {
return 200 'port:80 ok\n';
}
}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-8080
data:
default.conf: |
server {
listen 8080;
server_name localhost;
location / {
return 200 'port:8080 ok\n';
}
}
他のコンテナからアクセスすると、port:80もport:8080も問題なくレスポンスが返ります
bash-5.1# curl 10.1.0.54:80
port:80 ok
bash-5.1# curl 10.1.0.54:8080
port:8080 ok
もちろんservice経由でもアクセスできます
apiVersion: v1
kind: Service
metadata:
name: test
spec:
selector:
app.kubernetes.io/name: test
ports:
- port: 80
name: "80"
- port: 8080
name: "8080"
bash-5.1# curl test.default.svc:80
port:80 ok
bash-5.1# curl test.default.svc:8080
port:8080 ok
じゃあこのcontainers.ports
は何の設定なのかという話ですが
kubectl explain pods.spec.containers.ports
とやるとdescriptionにあります
List of ports to expose from the container. Exposing a port here gives the
system additional information about the network connections a container
uses, but is primarily informational. Not specifying a port here DOES NOT
prevent that port from being exposed. Any port which is listening on the
default "0.0.0.0" address inside a container will be accessible from the
network. Cannot be updated.
ContainerPort represents a network port in a single container.
参考:https://github.com/kubernetes/kubernetes/issues/4332
だからと言って、じゃあ無駄だから書かない、なんてことにはならないんですけどね
そんなの困る
その動作は許されないという方は、networkPolicyを使って制御するしかなさそうですね
(networkPolicyの詳細に関しては、記事がたくさんあるのでそちらで)