Contents
k8s 辨析 port、NodePort、targetPort、containerPort 区别
我的见解:
cluster 有 自己的ip和端口(port/nodePort)。
pod 也有自己的ip和端口(targetPort)。
pod中的多个container共享一套资源与环境。
那么container中暴露的端口(containerPort)与 pod 暴露的端口(targetPort)一致。
container使用的ip 与 pod 使用的ip一致。
转载来源: k8s 辨析 port、NodePort、targetPort、containerPort 区别
转载来源: https://stackoverflow.com/questions/63448062/difference-between-container-port-and-targetport-in-kubernetes
刚接触 k8s 涉及到端口到内容较多,容易混淆,这里整理如下:
目录
nodePort
nodePort 提供了集群外部客户端访问 Service 的一种方式,nodePort 提供了集群外部客户端访问 Service 的端口,通过 nodeIP:nodePort
提供了外部流量访问k8s集群中service的入口。
比如外部用户要访问k8s集群中的一个Web应用,那么我们可以配置对应service的type=NodePort
,nodePort=30001
。其他用户就可以通过浏览器http://node:30001
访问到该web服务。
而数据库等服务可能不需要被外界访问,只需被内部服务访问即可,那么我们就不必设置service的NodePort。
port
port是暴露在cluster ip上的端口,:port提供了集群内部客户端访问service的入口,即clusterIP:port
。
mysql容器暴露了3306端口(参考DockerFile),集群内其他容器通过33306端口访问mysql服务,但是外部流量不能访问mysql服务,因为mysql服务没有配置NodePort。对应的service.yaml如下:
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
ports:
- port: 33306
targetPort: 3306
selector:
name: mysql-pod
targetPort
targetPort是pod上的端口,从port/nodePort上来的数据,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。
与制作容器时暴露的端口一致(使用DockerFile中的EXPOSE),例如官方的nginx(参考DockerFile)暴露80端口。 对应的service.yaml如下:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort // 配置NodePort,外部流量可访问k8s中的服务
ports:
- port: 30080 // 服务访问端口,集群内部访问的端口
targetPort: 80 // pod控制器中定义的端口(应用访问的端口)
nodePort: 30001 // NodePort,外部客户端访问的端口
selector:
name: nginx-pod
containerPort
containerPort是在pod控制器中定义的、pod中的容器需要暴露的端口。
例如,mysql 服务需要暴露 3306 端口,redis 暴露 6379 端口
apiVersion: v1
kind: ReplicationController
metadata:
name: redis-master
labels:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
labels:
name: redis-master
spec:
containers:
- name: master
image: kubeguide/redis-master
ports:
- containerPort: 6379 # 此处定义暴露的端口
targetPort vs containerPort
In a nutshell: targetPort
and containerPort
basically refer to the same port (so if both are used they are expected to have the same value) but they are used in two different contexts and have entirely different purposes. 简而言之: targetPort
和 containerPort
基本上指的是相同的端口(因此,如果两者都使用,则预计它们具有相同的值),但它们在两个不同的上下文中使用并且具有完全不同的目的。
They cannot be used interchangeably as both are part of the specification of two distinct kubernetes resources/objects: Service
and Pod
respectively. While the purpose of containerPort
can be treated as purely informational, targetPort
is required by the Service
which exposes a set of Pods
. 它们不能互换使用,因为两者都是两个不同 kubernetes 资源/对象规范的一部分:分别是 Service
和 Pod
。虽然 containerPort
的目的可以被视为纯粹的信息性,但 Service
需要 targetPort
来公开一组 Pods
。
It’s important to understand that by declaring containerPort
with the specific value in your Pod
/Deployment
specification you cannot make your Pod
to expose this specific port e.g. if you declare in containerPort
field that your nginx Pod
exposes port 8080
instead of default 80
, you still need to configure your nginx server in your container to listen on this port. 重要的是要理解,通过使用 Pod
/ Deployment
规范中的特定值声明 containerPort
,您无法使 Pod
公开此值特定端口,例如如果您在 containerPort
字段中声明您的 nginx Pod
公开端口 8080
而不是默认的 80
,您仍然需要配置您的 nginx 服务器在您的容器中监听此端口。
Declaring containerPort
in Pod
specification is optional. Even without it your Service
will know where to direct the request based on the info it has declared in its targetPort
. 在 Pod
规范中声明 containerPort
是可选的。即使没有它,您的 Service
也会根据它在 targetPort
中声明的信息知道将请求定向到哪里。
It’s good to remember that it’s not required to declare targetPort
in the Service
definition. If you omit it, it defaults to the value you declared for port
(which is the port of the Service
itself). 请记住,不需要在 Service
定义中声明 targetPort
。如果省略它,它默认为您为 port
声明的值(这是 Service
本身的端口)。
ContainerPort in pod spec Pod 规范中的 ContainerPort
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 要从容器公开的端口列表。此处公开端口可为系统提供有关容器使用的网络连接的附加信息,但主要是提供信息。此处不指定端口并不能防止该端口被暴露
targetPort in service spec 服务规范中的 targetPort
Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod’s container ports. 服务目标 Pod 上要访问的端口号或名称。数字必须在 1 到 65535 范围内。名称必须是 IANA_SVC_NAME。如果这是一个字符串,它将在目标 Pod 的容器端口中作为命名端口进行查找。 If this is not specified, the value of the ‘port’ field is used (an identity map). 如果未指定,则使用“端口”字段的值(身份映射)。
Hence targetPort
in service needs to match the containerPort
in pod spec because that’s how service knows which container port is destination to forward the traffic to. 因此,服务中的 targetPort
需要与 pod 规范中的 containerPort
相匹配,因为这就是服务如何知道哪个容器端口是将流量转发到的目的地。
containerPort is the port, which app inside the container can be reached on. containerPort 是容器内的应用程序可以访问的端口。
targetPort is the port, which is exposed in the cluster and the service connects the pod to other services or users. targetPort 是端口,在集群中公开,服务将 pod 连接到其他服务或用户。
参考文章
kubernetes中port、target port、node port的对比分析,以及kube-proxy代理 Kubernetes中的nodePort,targetPort,port的区别和意义
发表回复