一、hostNetwork介绍 在k8s中,若pod使用主机网络,也就是hostNetworktrue。则该pod会使用主机的dns以及所有网络配置,默认情况下是无法使用k8s自带的dns解析服务,但是可以修改DNS策略或者修改主机上的域名解析(etcresolv。conf),使主机可以用k8s自身的dns服务。一般通过DNS策略(ClusterFirstWithHostNet)来使用k8sDNS内部域名解析,k8sDNS策略如下:Default:继承Pod所在宿主机的DNS设置,hostNetwork的默认策略。ClusterFirst(默认DNS策略):优先使用kubernetes环境的dns服务,将无法解析的域名转发到从宿主机继承的dns服务器。ClusterFirstWithHostNet:和ClusterFirst类似,对于以hostNetwork模式运行的Pod应明确知道使用该策略。也是可以同时解析内部和外部的域名。None:忽略kubernetes环境的dns配置,通过spec。dnsConfig自定义DNS配置。 想了解更多的k8sDNS可以参考我这篇文章:Kubernetes(k8s)DNS(CoreDNS)介绍 一般使用主机网络就增加如下几行即可:hostNetwork:truednsPolicy:ClusterFirstWithHostNet 【示例】hostNetwork。yamlapiVersion:appsv1kind:Deploymentmetadata:name:nginxspec:replicas:1selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:使用主机网络hostNetwork:true该设置是使POD使用k8s的dns,dns配置在etcresolv。conf文件中如果不加,pod默认使用所在宿主主机使用的DNS,这样会导致容器内不能通过servicename访问k8s集群中其他PODdnsPolicy:ClusterFirstWithHostNetcontainers:name:nginximage:nginx:1。7。9ports:name:metrics如果hostNetwork:true,hostPort必须跟containerPort一样,所以hostPort一般不写,端口也是占用宿主机上的端口。hostPort:80containerPort:80apiVersion:v1kind:Servicemetadata:name:nginxspec:selector:app:nginxtype:NodePortports:name:httpport:80targetPort:80protocol:TCPnodePort:31280 hostPort和NodePort的区别: hostPort只会在运行机器上开启端口,NodePort是所有Node上都会开启端口。hostPort是由portmap这个cni提供portMapping能力,同时如果想使用这个能力,在配置文件中一定需要开启portmap。使用hostPort后,会在iptables的nat链中插入相应的规则,而且这些规则是在KUBESERVICES规则之前插入的,也就是说会优先匹配hostPort的规则,我们常用的NodePort规则其实是在KUBESERVICES之中,也排在其后。hostport可以通过iptables命令查看到,但是无法在ipvsadm中查看到。使用lsofnetstat也查看不到这个端口,这是因为hostport是通过iptables对请求中的目的端口进行转发的,并不是在主机上通过端口监听。在生产环境中不建议使用hostPort。二、k8s网络策略NetworkPolicy 如果你希望在IP地址或端口层面(OSI第3层或第4层)控制网络流量,则你可以考虑为集群中特定应用使用Kubernetes网络策略(NetworkPolicy)。NetworkPolicy是一种以应用为中心的结构,允许你设置如何允许Pod与网络上的各类网络实体通信。官方文档 网络策略是通过网络插件来实现,常用的网络插件Flannel和Calico:Flannel:只能提供网络通讯,不提供网络策略,如果需要使用网络策略,建议使用下面的Calico,关于Flannel更详细的介绍和安装可以参考我这篇文章:Kubernetes(k8s)CNI(flannel)网络模型原理。Calico:支持丰富的网络策略,Calico以其性能、灵活性而闻名。后面也会出相关文章详细介绍Calico。 更多了解更多的网络策略,可以参考官方文档:https:kubernetes。iodocsconceptsclusteradministrationaddons Pod可以通信的Pod是通过如下三个标识符的组合来辩识的:其他被允许的Pods(例外:Pod无法阻塞对自身的访问)被允许的名字空间IP组块(例外:与Pod运行所在的节点的通信总是被允许的,无论Pod或节点的IP地址)三、Pod隔离的两种类型 Pod有两种隔离:出口的隔离和入口的隔离。默认情况下,出口和入口都是非隔离的。网络策略是相加的,所以不会产生冲突。如果策略适用于Pod某一特定方向的流量,Pod在对应方向所允许的连接是适用的网络策略所允许的集合。因此,评估的顺序不影响策略的结果。要允许从源Pod到目的Pod的连接,源Pod的出口策略和目的Pod的入口策略都需要允许连接。如果任何一方不允许连接,建立连接将会失败。四、NetworkPolicy资源1)NetworkPolicy示例演示apiVersion:networking。k8s。iov1kind:NetworkPolicymetadata:name:testnetworkpolicynamespace:defaultspec:podSelector:matchLabels:role:dbpolicyTypes:IngressEgressingress:from:ipBlock:cidr:172。17。0。016except:172。17。1。024namespaceSelector:matchLabels:project:myprojectpodSelector:matchLabels:role:frontendports:protocol:TCPport:6379egress:to:ipBlock:cidr:10。0。0。024ports:protocol:TCPport:5978 必需字段:与所有其他的Kubernetes配置一样,NetworkPolicy需要apiVersion、kind和metadata字段。关于配置文件操作的一般信息,请参考配置Pod以使用ConfigMap和对象管理。spec:NetworkPolicy规约中包含了在一个名字空间中定义特定网络策略所需的所有信息。podSelector:每个NetworkPolicy都包括一个podSelector,它对该策略所适用的一组Pod进行选择。示例中的策略选择带有roledb标签的Pod。空的podSelector选择名字空间下的所有Pod。policyTypes:每个NetworkPolicy都包含一个policyTypes列表,其中包含Ingress或Egress或两者兼具。policyTypes字段表示给定的策略是应用于进入所选Pod的入站流量还是来自所选Pod的出站流量,或两者兼有。如果NetworkPolicy未指定policyTypes则默认情况下始终设置I如果NetworkPolicy有任何出口规则的话则设置Egress。ingress:每个NetworkPolicy可包含一个ingress规则的白名单列表。每个规则都允许同时匹配from和ports部分的流量。示例策略中包含一条简单的规则:它匹配某个特定端口,来自三个来源中的一个,第一个通过ipBlock指定,第二个通过namespaceSelector指定,第三个通过podSelector指定。egress:每个NetworkPolicy可包含一个egress规则的白名单列表。每个规则都允许匹配to和port部分的流量。该示例策略包含一条规则,该规则将指定端口上的流量匹配到10。0。0。024中的任何目的地。 所以,该网络策略示例:隔离default名字空间下roledb的Pod(如果它们不是已经被隔离的话)。(Ingress规则)允许以下Pod连接到default名字空间下的带有roledb标签的所有Pod的6379TCP端口:default名字空间下带有rolefrontend标签的所有Pod带有projectmyproject标签的所有名字空间中的PodIP地址范围为172。17。0。0172。17。0。255和172。17。2。0172。17。255。255(即,除了172。17。1。024之外的所有172。17。0。016)(Egress规则)允许default命名空间中任何带有标签roledb的Pod到CIDR10。0。0。024下5978TCP端口的连接。2)选择器to和from的行为 可以在ingress的from部分或egress的to部分中指定四种选择器:podSelector:此选择器将在与NetworkPolicy相同的名字空间中选择特定的Pod,应将其允许作为入站流量来源或出站流量目的地。namespaceSelector:此选择器将选择特定的名字空间,应将所有Pod用作其入站流量来源或出站流量目的地。namespaceSelector和podSelector:一个指定namespaceSelector和podSelector的tofrom条目选择特定名字空间中的特定Pod。注意使用正确的YAML语法;下面的策略:。。。ingress:from:namespaceSelector:matchLabels:user:alicepodSelector:matchLabels:role:client。。。 在from数组中仅包含一个元素,只允许来自标有roleclient的Pod且该Pod所在的名字空间中标有useralice的连接。但是这项策略:。。。ingress:from:namespaceSelector:matchLabels:user:alicepodSelector:matchLabels:role:client。。。 这里只是把官网的摘了一部分,官网介绍的比较清楚,这里就不粘贴复制了,小伙伴可以参考官方文档:https:kubernetes。iozhcndocsconceptsservicesnetworkingnetworkpolicies五、总结在k8s上网络策略是白名单机制,所谓白名单机制是指,只有明确定义的策略才会被允许放行,默认没有指定的规则就是拒绝的,即条件不匹配的都会被拒绝。其次对于ingress或egress来说,对应的from或to都是用来指定访问端或被访问端的信息。如果我们在对应的字段中没有定义namespaceSelector字段,默认ingress或egrss会匹配当前netpol所在名称空间,即在没有明确指定namespaceSelector字段时,对应的其他条件都是针对当前netpol所在名称空间。多个条件组合使用,如果多个条件都在一个列表中,则表示多个条件间是与关系,即指定的条件需要同时满足对应策略才会放行。如果多个条件不再同一个列表中,则多个条件之间是或关系,即满足其中一个条件都会被对应策略放行。