默认情况下,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实现节点级监控。
- 将变量 - <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:声明监听的端口,该端口号应与容器内应用实际监听的端口保持一致。
 
- 创建DaemonSet。 - kubectl apply -f node-exporter.yaml- 预期输出: - daemonset/node-exporter created
- 查看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>
- 登录节点。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。