更改端口号时,kubectl port-forward 失败

kubectl port-forward fails when I change the port numbers

提问人:Vishal Balaji 提问时间:11/17/2023 更新时间:11/17/2023 访问量:65

问:

我正在关注一本书,他们有一个应用程序的配置。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  labels:
    app: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
        - name: demo
          image: cloudnatived/demo:hello
          ports:
          - containerPort: 8888

---
apiVersion: v1
kind: Service
metadata:
  name: demo
  labels:
    app: demo
spec:
  # NOTE: depending on which version of the book you have, this may say port 9999. The latest version of the book uses 8888 to match the pod.
  ports:
  - port: 8888
    protocol: TCP
    targetPort: 8888
  selector:
    app: demo
  type: ClusterIP

这工作正常。

kubectl port-forward service/demo 9999:8888
>>> Forwarding from 127.0.0.1:9999 -> 8888
Forwarding from [::1]:9999 -> 8888
Handling connection for 9999
curl localhost:9999/info 
>>> Hello, 世界

但是,如果我更改容器端口,它就不起作用了。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  labels:
    app: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
        - name: demo
          image: cloudnatived/demo:hello
          ports:
          - containerPort: 9278

---
apiVersion: v1
kind: Service
metadata:
  name: demo
  labels:
    app: demo
spec:
  # NOTE: depending on which version of the book you have, this may say port 9999. The latest version of the book uses 8888 to match the pod.
  ports:
  - port: 4269
    protocol: TCP
    targetPort: 9278
  selector:
    app: demo
  type: ClusterIP
kubectl port-forward service/demo 9999:4269
>>> Forwarding from 127.0.0.1:9999 -> 9278
Forwarding from [::1]:9999 -> 9278
Handling connection for 9999
E1117 15:59:19.151771   38005 portforward.go:409] an error occurred forwarding 9999 -> 9278: error forwarding port 9278 to pod 0c928b279bf1932972fc6724a22d8dac57ebb89696569269868959a342072b24, uid : container not running (0c928b279bf1932972fc6724a22d8dac57ebb89696569269868959a342072b24)
error: lost connection to pod
curl localhost:9999/info
>>> curl: (52) Empty reply from server

我不确定为什么这会失败。据我了解,当您这样做时,它会通过服务上的端口 9999 将我的本地端口 9279 转发到 pod 9278 中的端口。kubectl port-forward service/demo 9999:4269

我已经尝试了多次,结果相同。当我将所有内容切换回 8888 的那一刻,一切正常。

Docker Kubernetes

评论

0赞 David Maze 11/17/2023
听起来 Pod 内部的进程正在侦听端口 8888;Pod 内部的什么在端口 9278 上监听?
0赞 Vishal Balaji 11/17/2023
我以为指定会使 pod 收听 9278。难道不是这样吗?containerPort: 9278
0赞 David Maze 11/17/2023
它不会改变流程正在做什么;如果尚未将进程重新配置为侦听其他端口,则不匹配将导致此问题。在实践中,容器端口仅用作其匹配服务的目标,因此该端口号并不重要。containerPort:
0赞 Vishal Balaji 11/20/2023
通过重新配置流程,您的意思是应用更改吗?我在更改端口号后使用。我也验证过了。 给。 给出和kubectl apply -f k8s/app.yamlkubectl describe pod/POD_NAMEPort: 9278/TCPkubectl describe service/SERVICE_NAMEPort: <unset> 4269/TCPTargetPort: 9278/TCP
0赞 David Maze 11/20/2023
Pod 内部是一个容器,容器内部是一个进程,该进程具有一组命令行参数和配置文件。该进程不知道 Kubernetes 级别的配置;如果您设置了,但进程仍在侦听端口 8888,则无法正常工作。containerPort: 9278

答:

1赞 Jeong Yo Han 11/17/2023 #1

在 YAML 规范中,

image: cloudnatived/demo:hello
ports:
   - containerPort: 8888

表示您使用并公开 8888 端口作为部署。查看 https://kubernetes.io/docs/tutorials/services/connect-applications-service/#exposing-pods-to-the-clustercoludnatived/demo:hello

请注意,容器没有使用节点上的端口 80,也没有任何特殊的 NAT 规则将流量路由到 Pod。这意味着您可以在同一节点上运行多个 nginx pod,所有 pod 都使用相同的 containerPort,并使用为 pod 分配的 IP 地址从集群中的任何其他 pod 或节点访问它们。

在您的示例中,您使用副本和三个容器,暴露 9278 端口负载均衡器(在您的示例中为 Service)可以触及它。 这并不意味着您的应用程序映像正在监听 9278。

但具有讽刺意味的是,在 docs(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#container-v1-core)

ports:要从容器公开的端口列表。此处未指定端口不会阻止该端口被公开。任何侦听容器内默认“0.0.0.0”地址的端口都可以从网络访问。使用战略合并修补程序修改此数组可能会损坏数据。有关详细信息,请参阅 https://github.com/kubernetes/kubernetes/issues/108255。无法更新。

我该如何澄清这一点,我想展示一些带有以下 9278 选项的示例。 运行此 CLI。

kubectl get pods

--- pods showed ---
 
kubectl port-forward [anypod] 9999:8888

即使您的部署容器端口设置为 9278,但 Pod 可以使用 8888 访问和访问。

评论

0赞 Vishal Balaji 11/17/2023
好的,这是有道理的。但是为什么我无法访问端口 9278 上的服务?
0赞 Jeong Yo Han 11/17/2023
首先,如果要监听 9278,则需要更改容器镜像服务端口。构建新形象。但如果你再想一想,你确实不需要。为方便起见,只需使用默认的 Nginx 映像即可解决此问题。
0赞 Vishal Balaji 11/20/2023
我确实在更改端口号后构建了一个新映像。它仍然不起作用。kubectl apply -f k8s/app.yaml
0赞 Vishal Balaji 11/20/2023
我也验证过了。 给。 给出和kubectl describe pod/POD_NAMEPort: 9278/TCPkubectl describe service/SERVICE_NAMEPort: <unset> 4269/TCPTargetPort: 9278/TCP
0赞 Jeong Yo Han 11/20/2023
@VishalBalaji pod 端口 != 应用程序侦听端口。pod 是容器的集合。我说过 yaml 文件中的容器端口(存在或不存在)不会阻止该端口被公开(如上所述)。