配置Pod使用主机网络模式(hostNetwork)

默认情况下,Pod的网络流量会经过节点内核转发,存在一定的性能损耗。将Pod配置为主机网络模式(hostNetwork)可以获得更高的网络性能,并共享节点的网络命名空间,以满足高性能CNI插件、节点级监控等需求。

重要

在生产环境中,请只为绝对必要的Pod配置主机网络模式。主机网络模式的Pod使用所在节点的网络命名空间,遭受攻击时的影响面更大。该Pod将不再受到网络策略(Network Policy)的限制,而受集群安全组规则限制。

使用方式

通过hostNetwork: true开启主机网络模式,然后配置dnsPolicy: ClusterFirstWithHostNet保证Pod可以解析集群内域名,最后设置容器端口containerPort,并确保容器内进程端口与containerPort一致。

apiVersion: v1
kind: Pod
metadata:
  ...
spec:
  hostNetwork: true # 开启主机网络模式
  dnsPolicy: ClusterFirstWithHostNet # 保证Pod可以解析集群内域名
  containers:
  - ...
    ports:
      - containerPort: 12000 # 容器监听的端口,需与容器内进程配置一致,12000仅为示例
  ...

适用范围

仅支持在新建工作负载时配置,不支持将已有Pod调整为主机网络模式。

操作步骤

下方示例DaemonSet使用主机网络模式Pod,通过node-exporter实现节点级监控。

  1. 将变量<REGION_ID>替换为集群所在地域ID之后,创建并保存名为node-exporter.yaml的文件。

    地域ID请参见地域和可用区
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: node-exporter-demo
      labels:
        app: node-exporter-demo
    spec:
      selector:
        matchLabels:
          app: node-exporter-demo
      template:
        metadata:
          labels:
            app: node-exporter-demo
        spec:
          hostNetwork: true # 开启主机网络模式
          hostPID: true 
          dnsPolicy: ClusterFirstWithHostNet # 保证Pod可以解析集群内域名
          containers:
          - name: node-exporter-demo
            image: registry-<REGION_ID>-vpc.ack.aliyuncs.com/acs/node-exporter:v0.17.0-slim # <REGION_ID>需替换为集群所在地域
            args:
            - '--path.procfs=/host/proc'
            - '--path.sysfs=/host/sys'
            - '--web.listen-address=0.0.0.0:20000'
            ports:
            - name: metrics
              containerPort: 20000
            volumeMounts:
            - name: proc
              mountPath: /host/proc
              readOnly: true
            - name: sys
              mountPath: /host/sys
              readOnly: true
            resources:
              requests:
                memory: "64Mi"
                cpu: "100m"
              limits:
                memory: "128Mi"
                cpu: "200m"
          volumes:
          - name: proc
            hostPath:
              path: /proc
          - name: sys
            hostPath:
              path: /sys
    
    • spec.hostNetwork:设置为true即可为Pod开启主机网络模式。

    • spec.dnsPolicy:需设置为ClusterFirstWithHostNet,以保证Pod可以解析集群内域名。

    • spec.containers.ports:声明监听的端口,该端口号应与容器内应用实际监听的端口保持一致。

  2. 创建DaemonSet。

    kubectl apply -f node-exporter.yaml

    预期输出:

    daemonset/node-exporter created
  3. 查看Pod信息,如Pod IP与所在节点相同,表明Pod已启用主机网络模式。

    kubectl get pod -o wide

    预期输出如下,Pod IP与所在节点相同。

    NAME                       READY   STATUS    RESTARTS   AGE     IP               NODE                      NOMINATED NODE   READINESS GATES
    node-exporter-demo-49v**   1/1     Running   0          15h     10.***.8.109     xx-xxxx.10.***.8.109      <none>           <none>
    node-exporter-demo-jdx**   1/1     Running   0          15h     10.***.203.146   xx-xxxx.10.***.203.146    <none>           <none>
    node-exporter-demo-krg**   1/1     Running   0          15h     10.***.105.151   xx-xxxx.10.***.105.151    <none>           <none>
  4. 登录节点。Pod直接监听节点的20000端口,在节点上通过localhost:20000即可访问Pod服务,成功获取节点指标数据表示配置成功。

    curl localhost:20000/metrics

常见问题

为什么Pod处于Pending状态?

下列原因都可能导致Pod长时间处于Pending状态:

  • Pod声明的端口在节点上已被占用,容器内进程无法绑定端口,导致Pod启动失败,请勿选择下列端口:

    • 集群核心组件端口:6443、9890、9099、10250、10256、30000-32767。

    • 标准服务端口:22、53、80、443。

    • 其他业务使用的自定义端口。

  • 如果使用了Pod Security Admission相关配置,可能会阻碍主机网络模式Pod的部署,使用PSA配置时,请确保命名空间使用以下标签:

    重要

    设置此标签将使Pod拥有所有高危操作的执行权,请谨慎使用。

    apiVersion: v1
    kind: Namespace
    metadata:
      name: my-privileged-ns
      labels:
        pod-security.kubernetes.io/enforce: privileged
    关于pod-security.kubernetes.io的更多配置细则,请参见Pod Security Admission
  • 如果使用容器安全策略,请确保已允许Pod使用主机网络,且Pod端口在允许范围内。

为什么Pod无法解析集群域名?

主机网络模式的Pod需配置spec.dnsPolicy: ClusterFirstWithHostNet以解析集群内域名。请参见操作步骤中的示例配置Pod。