在Pod中配置主机网络(hostNetwork)
背景信息
Kubernetes支持Pod直接使用主机(节点)的网络,当Pod配置为hostNetwork: true时,在此Pod中运行的应用程序可以直接看到Pod所在主机的网络接口。
配置说明
Pod使用主机网络只需要在配置中添加hostNetwork: true即可,如下所示。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
hostNetwork: true
containers:
- image: nginx:alpine
name: nginx
imagePullSecrets:
- name: default-secret
部署后可以看到Pod的IP与节点的IP相同,说明Pod直接使用了主机网络。
$ kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-6fdf99c8b-6wwft 1/1 Running 0 3m41s 10.1.0.55 10.1.0.55 <none> <none>
hostNetwork使用注意事项
Pod直接使用主机的网络会占用宿主机的端口,Pod的IP就是宿主机的IP,使用时需要考虑是否与主机上的端口冲突,因此一般情况下除非某个特定应用必须占用宿主机上的特定端口,否则不建议使用主机网络。
由于Pod使用主机网络,访问Pod需要直接通过节点端口,因此要注意放通节点安全组端口,否则会出现访问不通的情况。
另外由于占用主机端口,使用Deployment部署hostNetwork类型Pod时,要注意Pod的副本数不要超过节点数量,否则会导致一个节点上调度了多个Pod,Pod启动时端口冲突无法创建。例如上面例子中的nginx,如果服务数为2,并部署在只有1个节点的集群上,就会有一个Pod无法创建,查询Pod日志会发现是由于端口占用导致nginx无法启动。
请避免在同一个节点上调度多个使用主机网络的Pod,否则在创建ClusterIP类型的Service访问Pod时,会出现访问ClusterIP不通的情况。
$ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE nginx 1/2 2 1 67m $ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-6fdf99c8b-6wwft 1/1 Running 0 67m nginx-6fdf99c8b-rglm7 0/1 CrashLoopBackOff 13 44m $ kubectl logs nginx-6fdf99c8b-rglm7 /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh /docker-entrypoint.sh: Configuration complete; ready for start up 2022/05/11 07:18:11 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to [::]:80 failed (98: Address in use) nginx: [emerg] bind() to [::]:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to [::]:80 failed (98: Address in use) nginx: [emerg] bind() to [::]:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to [::]:80 failed (98: Address in use) nginx: [emerg] bind() to [::]:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to [::]:80 failed (98: Address in use) nginx: [emerg] bind() to [::]:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: bind() to [::]:80 failed (98: Address in use) nginx: [emerg] bind() to [::]:80 failed (98: Address in use) 2022/05/11 07:18:11 [emerg] 1#1: still could not bind() nginx: [emerg] still could not bind()