k8s部署hostport模式pod报错端口冲突

最近有客户在使用hostport的模式部署deployment的时候,有出现这个错误0/4 nodes are available: 4 node(s) didn't have free ports for the requested pod ports,导致deployment部署失败,从报错看是端口冲突了。

因为hostport是用的占用的node节点的端口,既然是端口冲突,我们到节点上查看下对应端口是否有监听,登录节点用netstat查看对应端口的监听,发现并没有被占用,端口没有被占用,为什么会出现部署失败报错端口被占用的问题。

后面我根据报错的yaml进行测试下,具体现象如下

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: hostport-test
    qcloud-app: hostport-test
  name: hostport-test
  namespace: tke-test
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: hostport-test
      qcloud-app: hostport-test
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        k8s-app: hostport-test
        qcloud-app: hostport-test
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: hostport-test
        ports:
        - containerPort: 80
          hostPort: 80
          name: http
          protocol: TCP
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 250m
            memory: 256Mi
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: qcloudregistrykey
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

部署了hostPort的pod后,我们登录节点查看80端口的监听,发现并没有被监听

[root@VM-0-10-centos ~]# netstat -an | grep tcp | grep 80
tcp        0      0 0.0.0.0:30080           0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:32580           0.0.0.0:*               LISTEN
tcp        0      0 10.0.0.10:46548         169.254.0.71:80         ESTABLISHED
tcp        0      0 10.0.0.10:33762         169.254.0.71:80         ESTABLISHED

接下来我们接着往hostport-test所在的节点部署一个hostport模式的pod看看

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: hostport-new
    qcloud-app: hostport-new
  name: hostport-new
  namespace: tke-test
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: hostport-new
      qcloud-app: hostport-new
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        k8s-app: hostport-new
        qcloud-app: hostport-new
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - 10.0.0.10
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: hostport-new
        ports:
        - containerPort: 80
          hostPort: 80
          name: http
          protocol: TCP
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 250m
            memory: 256Mi
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      hostNetwork: true
      imagePullSecrets:
      - name: qcloudregistrykey
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

我们看下hostport-new的事件,看下是否有出现报错

[root@VM-0-10-centos ~]# kubectl describe  pod -n tke-test hostport-new-86786bc46f-kl8ph
Name:           hostport-new-86786bc46f-kl8ph
Namespace:      tke-test
.................
Events:
  Type     Reason                        Age                   From                  Message
  ----     ------                        ----                  ----                  -------
  Normal   FailedSchedulingOnEkletNodes  7m49s (x16 over 12m)  admission-controller  node(s) didn't match node selector
  Warning  FailedScheduling              65s (x10 over 12m)    default-scheduler     0/5 nodes are available: 1 Too many pods, 2 node(s) didn't have free ports for the requested pod ports, 2 node(s) didn't match node selector.

从事件日志看,部署报错,也是报错端口没法使用,但是我们到节点查看80端口的确没有被监听,这是怎么回事呢?

hostport-test配置的hostport,但是没有配置hostNetwork,k8s的hostport,并不是直接在节点启动对应的监听端口,但是这里还是可以通过节点ip+端口进行访问,这是因为节点的iptables规则会将节点hostport的请求转发到pod上,所以到节点上查看80端口没有被监听,但是实际可以访问通。

所以hostport实际是生效的,如果你已经有pod通过hostport占用了端口,后续再配置同样的端口,则会提示端口冲突。

参考文档

https://cloud.tencent.com/developer/article/2008146

© vishon all right reserved,powered by GitbookUpdated at 2024-01-09 09:53:51

results matching ""

    No results matching ""