服务错误地选择了侦听某些不同端口的 Pod

问题描述

我尝试了 here 中的服务定义示例。

所以,我在下面创建了服务:

apiVersion: v1
kind: Service
Metadata:
  name: service-simple-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

然后为了测试这个概念,我在 Pod 下面创建了:

apiVersion: v1
kind: Pod
Metadata:
  name: service-simple-service-pod
  labels:
    app: MyApp
spec:
  containers:
  - name: service-simple-service-pod-container-1
    image: Nginx:alpine
    ports:
      - containerPort: 9376

我可以看到为这个 Pod 创建了一个新的端点,所以到目前为止一切都很好,下面是输出

C:\Users>kubectl describe service/service-simple-service
Name:              service-simple-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=MyApp
Type:              ClusterIP
IP:                10.98.246.70
Port:              <unset>  80/TCP
TargetPort:        9376/TCP
Endpoints:         10.244.0.8:9376
Session Affinity:  None
Events:            <none>

然后为了测试否定的概念,我在 Pod 下面创建了。

apiVersion: v1
kind: Pod
Metadata:
  name: service-simple-service-pod-nouse
  labels:
    app: MyApp
spec:
  containers:
  - name: service-simple-service-pod-nouse-container-1
    image: Nginx:alpine
    ports:
      - containerPort: 9378

但令我惊讶的是,这个 Pod 也被选中了:

C:\Users>kubectl describe service/service-simple-service
Name:              service-simple-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=MyApp
Type:              ClusterIP
IP:                10.98.246.70
Port:              <unset>  80/TCP
TargetPort:        9376/TCP
Endpoints:         10.244.0.10:9376,10.244.0.8:9376
Session Affinity:  None
Events:            <none>

我对上面创建的 Service 的理解是,调度程序将查找标签app: MyApp 并在端口 9376 上运行的任何 Pod,因此我的期望是,由于该 Pod 运行在端口 {{ 1}} 所以它不会被拿起。所以,我的问题是,为什么会选择这个“service-simple-service-pod-nouse”?

如果有人说我的理解不正确,Service 只根据 Label 选择 Pod,那么我的问题是,既然“service-simple-service-pod-nouse”Pod 正在监听端口 9378 那么如何“ service-simple-service" 服务可以向这个 Pod 发送流量吗?

解决方法

服务将挑选所有标记为该服务的标签选择器的 pod。 service-simple-service 服务将选择所有标记为 MyApp 的 pod,因为您在服务选择器 (app: MyApp) 中进行了告知。这是label-selector的常见和预期行为,可以看k8s官方doc

apiVersion: v1
kind: Service
metadata:
  name: service-simple-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

更新

基本上,服务获取请求,然后将流量提供给 Pod(这些被标记为服务选择器),当服务获取 Pod 时,它会为该 Pod 打开一个端点,当流量到达服务时它在其中一个端点(基本上是去一个 Pod)发送这些流量。而容器端口基本上就是容器运行所在的pod内部的端口。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...