注意看spec.hostNetwork = true这个是干啥的?
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx
spec:
template:
metadata:
labels:
app: nginx
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
这玩意就可以让Pod中容器内的进程,对接暴露在宿主机所在物理网络上,换句话说,就好像容器内的进程是直接运行在宿主机上,比如这里是一个nginx,那完全可以直接在宿主机上启动一个nginx。
所以一旦指定了spec.hostNetwork:true,那么宿主机所在局域网内的其他机器,就可以直接访问到这个nginx容器了,上面的containerPort: 80,就会在宿主机上占用80端口,我怎么感觉这就是让nginx就是直接裸奔跑在宿主机上了嘛,只不过nginx被容器包了一层,然后又被Pod包了一层,这样可以受k8s的监控和调度(比如容器挂了,k8s会自动把它拉起来,或者干脆调度到其它物理机上)
spec.dnsPolicy: ClusterFirstWithHostNet,这也非常重要,指定Pod的DNS策略,其实就是会影响到Pod容器内的/etc/resolv.conf文件,设定为ClusterFirstWithHostNet,意思是使用k8s集群范围内的DNS服务,这样的话,pod就可以通过ServiceName访问集群内的其他Pod了。
比如你的K8S集群有N台物理主机组成,然后呢上面部署了一些Service,比如Service1,Service2,Service3……等等,Service1由10个Pod组成,这10个Pod是通过一个Deployment资源描述yaml文件创建的,创建的时候如果不指定spec.dnsPolicy: ClusterFirstWithHostNet,那么这10个Pod就无法通过Service2这个服务名称访问到Service2提供的服务,比如RPC调用。
本质上指定spec.dnsPolicy: ClusterFirstWithHostNet,核心是修改容器/etc/resolv.conf文件中的dns服务器的IP地址,如果设定为k8s集群内dns服务,因为每次创建Service的时候,都会去DNS服务上注册,所以如果指定k8s集群内的dns服务,那么必然是可以通过Servicename互相访问的。
本质上,Kubernetes的hostNetwork,hostPort,NodePort,LoadBalancer和Ingress功能都可以对外暴露服务,让集群外的客户端可以访问运行在k8s集群内的Pod,Pod中的所有容器就直接暴露在宿主机的网络环境中,这时候,Pod的PodIP就是其所在Node的IP,但是我们一般不这样干呀,因为让Pod的IP设置为所在Node的IP,就失去了网络虚拟化所带来的好处呀,而且多租户的情况下也是操蛋的呀,这种就不适合多租户了。
而且如果是这种模式,就没法在1个宿主机上启动同一个Deployment中的2个Pod副本了,因为这样会导致端口冲突,比如上面的nginx,如果直接通过spec.hostNetwork:true,那么2个进程都要占用80端口,就不好弄了。
这个spec.hostNetwork:true,所谓的主机网络模式,不是让我们写的容器应用程序可以从群集外部访问的好方法,不建议使用。