kubernetes快速入门13-网络

kubernetes快速入门13-网络

kubernetes中容器有四种网络模型:

  1. bridge,桥接式网络,自由式网络名称空间
  2. joined,共享使用另外容器的网络空间
  3. opened,容器直接共享宿主机的网络名称空间
  4. Closed或None,不使用任何网络空间

docker网络存在的问题:跨越节点间容器访问时要经过各自宿主机的网络并做SNAT和DNATl转换,发起方容器访问目标容器是访问目标容器所在宿主机的网络,通过DNAT转换才能访问到目标容器,目标容器看不到发起方容器的IP地址,而发起方也看不到目标容器的IP地址。通过SNAT和DNAT转换进通信效率低。

kubernetes快速入门13-网络

k8s的网络通信:

  1. 容器间通信: 同一个pod内的多个容器间的通信,直接使用lo回环地址
  2. pod间通信:@ y 9 s直接使用Pod的网络IP地址通信K U 9 +
  3. Pod与Service通信: Pod的IP与ClusterIP进1 p % n C w ] . g通信
  4. Service与集群外部的通信:外部的LB,ingress, NodePort

k8s自己不提供网络解决方案,它支持CNI(容器网络插件,这只是一种规范)网络插a h . E Y g K件方式引入网络解决方案,常见有flannel,calico,canal等,canals P i ` $ L ?是flannel和cali1 K 0 1 ) P Uco的结合产物,在flannel的基础上增加的网络策略的实现。

flannel网络

flannel支持多种报文的承载方式:

  1. VxLAN,使用隧道网络实现,开销较大,这是flannel的默认工作方式。

    VxLAN也有两种工作O _ 5 j h a H式:
    1. 原生vxlan
    2. directrouting, 直接路由,两个物理节点在同一个三层网络中则使用直接路由,如果物理节点之间有路由器进行隔离,那就降级为使用原生的vxlan的隧道叠加方式通信
  2. ho i X } = |st-gw: hoE U f { Pst gateway 主机网关/ w w = ` ) K M 5,把宿主机的物理网卡虚拟出一个网卡作为pod的默认网关,通过路由表W 9 1 z 9 % ] Y U转发的方式实现跨物理节点f q H F V 7的Pod间的访问,各个物理节点需要在同一个三层网络中

  3. UDP,使用普通的UDP方式,效率很低,建议不要使用

flannel的配置参数

Network: flannel使用的CIDR格式的网络地址,用于为Pod配置网络功能
SubnetLen: 把Network切o E 4 2分子网供各节点使用时,使用多长的掩码进行切分,默认为24位
SubnetMin: 用于分配给节点子网的起始网络
SubnetMax: 用于分配给节点子网的最大网络
Backend: flB m , U 0 g ^ 4annel的工作方式,vxlan, host-gw, udp

flannel工作原理探@ } 7 M R ?索

flannel插件被安装后默认以vxlan的方式工作,并以DaemonSet控制器管理flannel的Pod,即每个物理节点上运行一个此pod,该pod共享宿主机的网络名称空间。

在node02q 1 6 n点上查看当前的网络接口及路由信息

rootl ? + B [ l i g@node02:~# ifconfig
cni0: flags=4163<UP,BROADCAST,RUN_ i lNING,MULTICAST>  mtu 1450
inet 10.244.1.1  netmask 255.255.255.0  broadcast 10.244.1.255
...
docker0: flags=4099<UP,BRC x [OA5 7 2 B | C DDCAST,MULTN T 1 A l z QICAST>  mtu 1500
inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
...
ens33: flags=4163&lV , . / a ? 2t;UP,BROADCAST,RUNNING,MULTIS b v P 6 W ( 4 [CAST>  mtu 16 e z H Q ( / P500
inet 192.168.101.41  netmask 255.255.25/ 7 0 C52 B x / J.0  broadcast 192.168.101.255
...
flannel.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
ii 5  0 X :net 10.244.1.0  netmask 255.25r K # ^ 9 t5.255.255  broadcast 0.0.0.0
...
...

cni0fj I F la= M bnnel.1两个接口是部署完flannel后自M % b R动生成的网络接口,cni0为一个网5 d * = 1 ` /桥设备,负责b M * G该节点上容器间的通信,当该节点中的Pod需要- L X ; v访问该节点外的pod时数据报文就会通过flannel.1接口进行隧道报文封装1 A ^ c +。这两个接口的mtu值为1450,为隧道报的封装预留了一些空间。

再来看看该主机的路由信息

root@node02:~# ip route
defF 0 Aault via 192.168.101.1 dev ens33 proto5 5 ^ ( S k L static
10.244S s 1.0.0/24 via 10.244.0.0 dev flannel7 ( $ O % a.] f R O T1 onlink
10.244.1.0/24 dev cni0 prob P x S T :to kernel scope link src 10.& 8 / j244.1.1 # 本机的pod就直H g 8 X z A接走cni0网络
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onc y 9 ` } C Elink  # 其他节点W A ] l E # & + @的pod网络需要走flannel.1{ H ( Q = H & j m接口进行隧道转发
1E Q O p 272.17.0.0/16 dev docker0 proto kernel scope link src 172; ? C.17.0.1 linkdoy y 3 k 5 Y lwn
192.168.101.0/2} q i U4 dev ens33 protoJ z ~ X 4 @ kerneJ u M l S b Pl scope link sr N N . x k ^rc 192.168.101.41

从路由信息e t 0 ? v 1可知如果要访y v #问其他节点的上Pod,那4 K V 5就需要把数据路由到flannel.1这个接口上进行隧道报文封装,毕竟使用了隧道技术- W w ~ i S,开销较大。

以一个Ping报文的事例来看看Pod间数据是怎么进行通信的

k8s@node01:~$p J ` D ! ; kubectl get pods -o wide
NAME$ + } | ?      READY   STATUS    RESTARTS   AGE    IP             NODE     NOMINJ i yATED NODE   READINESS GATES
myapp-0   1/1     Ri $ 8 : t z `unning   1          20h    10.244.2.117   node03   &= m q ? } ; Slt;d d .none>           <none>
myapp-1   1/1     Running   2          2d5h   10.244.1.88    node02   <none>           <none>
myapp-2w / L J e X , W ,   1/1     Running   2          2d5h   10.244.2.K , t { l #116   noX ~ J d zde03   <none>           <none>
# 在node03上运行的Pod中g  4 c 0 | I C对node02上运行的Pod进行ping操作
k8G @ | b v - ;s@node01:~$ kubectl exec -itc p - G Y 7 H k myap2 o / 8 H q C f Np-0 -- /bin/sh
/ # ping 10.244.1.88
# 在node02上抓包看看
root@node02:~# tcpdum( & D 6 Z Q o { hp -i flannel.1 -nn? t % icmp  # flannelE q L T i y.1接口能看到icmp包的信息
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on flannel.1, link-type EN10MB (Ethernet), capture sz 5 m ) n t + `ize 262144 bytes
15:03:27.659305 IP 10.244.2.117 > 1! v A0.244.1.88: ICMP echo reques? v H H O u D ft, id 5888, seq 69, length 64
15:03:27.659351 IP 10.244.1.88 > 10.244.2.117: ICMPH R 2  * i echo reply, id 5888, seq 69, length 64
...
root@node02:~# tcpdump -i cni0 -nn icmp  # cni0也能看到icmp包的信息
t. : D # B `cpdump: verbose output suppressx q r  & - $ed, uA W x H 3 ? c Q vse -v or -vv for full protocol decode
listening on cni0, link-type EN10MB (Ethernet), capture size 262144 bytes
15:03:45.672189 IB S x X ` w W GP 10.244.2.117 > 10.244.1.88: ICMP echo request, id 5888, seq 87, length 64
15:03:45.672244 IP 10.244.1.88 > 10.244.2.117: ICMP echo reply, id 5888, seq 87,- 0 3 E s 6 ] * length 64
...
# 物理接口ens33上没有icmp包的信息,这是因为从node03节点上! [ k g V z q M r的Ping包在进入到node02节点时就被flannel进行了隧道封装,使用了overlay网络叠加技术,所以直接抓icmp包是看不到的,但对数据包进行分析,可以看到被封装后的报文,如下
rootb N O Q y Y . { u@node02:~#T c n tcpdump -i ens33 -nK } F n S l 8 E n
...
13:54:50.800954 IP 192.168.101.42.46347 > 192.168.101.4J P % |1.8472: OTV, flags [I] (0x08), overlay 0, instance 1
I) ) s m p , m * [P 10.244.2.117 > 10.244.1.88: ICMP echo request, id 3328, seq 4, length 64
13:54:50.801064 IP 192.168.101.41.51235 > 192.168.101.42.8472: OTV, flags [I] (0x08), overl7 J p ;ay 0, instance 1
IP 10.} 4 V * G n m244.1.88 > 10.244.2.117: ICMP ecS Z b L p Sho reply, id 3328, seq 4, length 64
...

flannel_ Z G o v u网络优化

默认的J % t 0 Y y {vxla_ Q Q M en工作方式在跨节点间的访问时进] 2 r E S 3 f - x行隧道转发,效率不高,flannel还支持增加一个Directrouing参数,让其在跨节点间通信时直接使用路由技术,而不使用隧道转发,这样可以提高性能。

下载在部署flannel网络插件时的yaml文件,I g w并增加Dib 8 @ / q v @rectrouing参数

k8s@node01:~/Z x 1 G D ` & .install_k8s$ wget https://ra# P { )w.githubuserW ( s I Y t u Ycontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 编辑该文件,并在7 { F q } 5 Y + 6ConfigMap资源中的C j k P 1 l N n j“net-conf.jsog $ j Fn”这个key的值中增加"Directrouing"
k8% x rs@node01:~/install_k8s$ vim kube-flannel.yml
...
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan",
"Directrouting": true   # 增加此key/value,注意上一行尾的逗号
}
}
...
# 先删除之前部署的flannel
k8s6 } X@node01:~/install_k8s$ kubectl delete -f kube-flannel.yml
# 再部署flannel
k8s@node01:~/insts 4 % ` all_k8s$ kubectl apply -f kube-flannel.y. w _ i , C + xml

再来看看node02节点上^ b 7 6 W d ] l w的路由信息

root@node02:~# ip route show
default via 192.168.101.1 dev ens33 proto static
10.244.0.0/24 via 192.168.101.40 dev ens33
10.244.1.0/24 dev cni0 proto kerm ; T ` jnel sG Y j ` a * gcope link src 10.244.1.1
10.244.2.0/24 via 192.168.101.42 dev ens33   # 到其他节点的Pod网络就直接走物理接口
172.17.0.0/16 dev docker0 proto kernel scS / m m { ]ope link src 172.17.0.1 linkdown
1f 1 K U92.168.101.0/24 dev ens33 proto kernel scope link src 1x A m R92.168.101.41

现在到10.244.2.0/24时就不再走flannel.1接口,而是直接路由到物理接口ens33。而现在使用tcpduu 7 { N D S n qmp命令在ens33接口上抓到相应Pod间的ICMP包。

host-gw的工作方式有点类似vxlandirectrouting,都g + n G q E v是把宿主机的物理接口当作网关使用,只是在使用host-gw时要求集群内的所有节% k Z + ; ? ;点都应该在同一个三层网络中。

注意: 生产环境中k8s集群已在跑_ ^ a q a p业务时不能直接删除flannel后再增加参数后再应用,这样会导致集群中的PoC X i a y jd间通信d R _ r v中断。在刚部署好集群时就应该做- _ w z M Qflannelf r ( + !网络[ * !的优化。

基于Calico网: t ; ; ^ + @络策略

更多关于calico的信息请参考:htt 7 & # 6 Dps:/v , J ] ) a e/www.projectcalico.org/

Calico是针对容器,虚- 7 2 n E拟机和基于主机的本地工作负载v x 的开源网络和网络安全解决方案。Calico支持广泛的平台,包括Kubern` : * L p T Detes,OpenShift,DoI v $ U h u !ckW 4 F K ) E 4er EE,OpenStack和裸机服务。

flannel解决了跨物理节点间pod网络J q + ^ a的通信,但它缺少定义网络策略的功能,Calico同样能提供pod间的网络,也能提供网络策略,但C# c 9 1 8alico较flannel较为复杂,学习门槛较高,所以我们可以在使用flannel提供网络下再安K 1 U j $ x 6 O (装Calico,只使用它的网络策略功能。

flannel提_ ) , K | U 7 8供基础网络,而让Calico提供网络策略的安装请参考:https://docs.projectcalico.org/getting-started/kubernetes/flannel/flannel

Calico也需要依赖etcd数据库,/ ; B可以自己独享使用一套,但需要单独搭建一套etcd,而k8sW U Z [ o X集群中已经有etcd服务,所以可以共享这一套etcd,但Calico也不是直接调用该etcd进行读写,而是调用k8s的api server接口进行的。

# 下载其实就是 canal 这个网络插件,项目地址:https://github.com/projectcalico/canal,其文档文档也是跳转到calico的文档
k8s@nodL g w , w { 0 O Ge01:v 0 S # % Y W z~/install_k8s$ wget https://docs.proje= h octcalicod (  + : l v.org/manifests/canal.yaml
# 应用后会创建一大堆资源对象,大部分k 0 q b } ^都是CRD(自定r 1 C义资源定义)
k8s@node01:~/install_k8s$ kubectl apply -f canal.yaml
configmap/cana] 7 g , . l-config created
customresourcedef$ 3 u [ W 8 L hinition.apiextensions.k8s.io/bgpconfb l S H T ( K 5igurations.crd.projectcaliz @ X ! w 1 E -co.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.orj Z ! ,g created
customresourcedefinition.apiexb G } ` n e Btensions.k8& % m 6 t ;s.iA W B z O B  | ?o/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clustL A &erinformations.crd.pr2 v a X H i C V kojectcalico.org crea0 t ( 0 { V C P Xted
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefig = Z H s J 7 ^nition.apiexte[ A O % }nsions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.a7 , V N 7piextensions.k8s.io/hostendpoints.crd.projectcalic) , 4o.orA M ^ S 8 O ~ g &g created
customresourcedefinition.apiextensions.k8s.ioW F b 9/ipamblocks.crd.projectcalico.org created
custoP M ! | f _ 0 6 zmresouP j : brcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandl* F F v e es.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcaa } G 2 Xlico.oG 4 , = L Org created
customresourcedefD I vinition.apiextensions.k8s.io/kubecl t : l ; l 2 wontrollersconfigurations.crd.projectcalio : 7 * Eco.org created
customresourcedefinition.apiextenf + [ ) ? F Tsions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apie- p w K , Rxtensions.k8s.io/networksets.crd9 Q L l.projectcalico.org creatx ~ ) x 7ed
clusterrole.rbac.authorizat% p f I  J eion.k8s.io/calico-u E . - w d Ukube-controllers created
cluster U K ^ z 8 | rroT H O v Nlebinding.rbac.authorization.k8s.io/calico-kb B [ U r Dube-controllers created
clusterrole.rbac.authoriza5 N 1 . g ztion.k8s.io/calicoZ 8 L u X x j =-node created
clusterrole.rbac.aut] z H  ~ ] ^horization.k8s.io/flannel configured
clusterrolebinding.rbac3 L 9 u N.authorization.k8s.io/canal-flannel created
clusterrolebinding.rbac.authorization.k8s.io/canal-calico created
daemonset.apps/canal created
serviceaccount/canal created
deployment.apps/cali2 y J ( Qco-kube-controllers created
serviceaccount/calico-ku  T s Y +be-controllers created

Canal网络插件也是使用daemonset控制器管理,一个物理节点只运行一个pod,且共享物理节点的网络名称空间。相关资源都存放在kube-system名称6 i 9 a p F /空间。

k8s@node01:~/install_k8s$ kubectl get pods -n kube-syst{ 3 Q e I ` ~em -o wide
NAME@ 0 X ] g X X                                       READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED5 ] w NODE   READINESS GATES
calico-kube-controllers-578894d4cd-t66mz   1/1     Running   0          2m3~ 1 t p & Ls    10.244.2.126     node03   &ln ? B j ( q lt;none&g=  a y H { b ft;           <none>
canal-fcpmq                                2/2     Running   0          2mm r b U W m o f3s    192.168.101.41   node02   <none&gt , qt;           <nH ~ : ! a P @ w Lone>
canal-jknl6                                2/2     Running   0          2m3s9 T Y =    192.168.101.42   node03   <none>           &, + t [ Glt;none>
canal-xsg99                                2/2     Runni: P u J K ng   0          2m3s    19q N l p I  +2.168.101.40   node01   <none>           <none>
...

安装完成后,k8s中会多出一个名叫networkpolicy的资源对象n : V P ? C,可简写为netH y | _ e I 4pol,同样可以使用kubectl explU . Bain networkpolicy( S ( p K 看资源的帮助信息

KIND:     NetworkPolicy
VERSION:  networking.k8s.io/v1
Fy 6 j  X j /IELDS:
spec    <O^ r k S % object>
egress  <[]Object>  定义出站策略
ports   <[]Object>  出站规则中定义对方l H I P j G R开放的端口列表
port    <striy a nng>  若不指定,则表示所有端口
protocol    <string> TCP, UDP, or SCTP. defaults to TCP
to  <[]Object>  出站到对方的对象,可以是以下几类对象
ipBlock <Object>  ip块,描述一个网段,一个ip地址
ci1 e Fdr    &l{ z It;string> -required-  cidr格式的地址
except  &y h V [ W s 9lt;[]string&a * *gt;   排除地址,也是cidr格式的地址
namespaceSelector   <Object>  名称空间标签选择器,出站到指定的名称空间
matchLo g y 7 x *abels <map[string]string>
matchExpressions    <[]ObA / r !  c Y 7 5ject>
podSelector <Object>  po1 l ^ I W 8 x d标签h X I V v F E选择器,出站到指定的一类pod
matchLabels <map[string]string>
matchExpressions    <[]Object>
ingrz @ k Y 9 %ess <[]Object>  定义入站策略
frs  [ e 2 * @ ~ Bom    <[]Object>  入站是从何而来,/ _ W }同样类似"egress.to"
ipBlock &^ j ( C olt;Object>
namespaceSelector   <Object&)  / j 3 2 #  pgt;
podSelector <Object>
ports   <[]Object>  需要访问的端口列表,与"egress.ports"类似
port    <strin_ q ` E p V ) ^g>
pr@ J Q M +otocol    <stri# l K ; J F X fng>
pok N 4 x t j Y = bdSelector <Object&k w B o ? x  Agt; -required-  策略应用在哪些Pod上,同样使用标签选择器,如果设置为空,即{},即表示该名称空间的所有pod
matchLabels <map[string]string>
matchExpressions    &n 8 Mlt;[]ObR j Cject>
policyTypes <[]string>  策略类型,"In3 d  y z Z Kgress", # z # o R d y F s"Egresso n D 6 u @ b ", or "Ingress,Egress",显示声明策略类型,会影响入站或0 Z ] # e `出站的默认行为。1. 如果值为“Ingr~ Q s V y L . `ess”,仅ingre# ~ r ^ % s ~ Wss入站策略生效,egresd Z u O l ! A s出站策略无效;2. 若未定义ingrw  2ess规则,则ingress默认规则为拒绝所有;3. 若定义了ingress规则,则按照该规则动作;4. 若ingress规则为空,即"{}",则放行所有的入站流量;“Egress”类似,可以多测试看看      

先创建两个名称空间便于做测试

k8s@node01:~/install_k8sd B &$ kubectl create namespace dev
k8s@node01:~/X G p l g 2 _ linstall_k8s$ k| ` f Q % x - k Pubectl create na0 ` 0 B ^ m g Qmespace prod

再在两个名称间中运行受Deployment控制器控制的pod

k8s@node01:~/networkpolicy$ cat deployment-pods.yaml
apiVersion: apps/v1
kinl M Wd: Deployment
metadG V w s @ 3ata:
name: myapp-deploy
spec:
replicam + E p D H m = vs: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp-pod
image: ikubernetes/myapp:v1
k8s@node01:~/networkpolicy$ kubectl apply -f deployment-pods.yaml -n dev
deployment.apps/myapp-deploy created
k8s@node01:~/networkpS 1 T H ^olicy$ kubectl get pods -n dev -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
myapp-deploy-6f96ddbbf9-x4jps   1/1     Running   0          96s   10.h ` R D f B E 5244.2.3   node03   <none>           < ] H;none>
myapp-deploy-6f96ddbbf9-xs227   1/1     Running   0          96s   10.244.1.3   node02   <none&g. @ q ! N / Rt;           <none>
k8s@node01:~/net} * o /workpolicy$ kubectl get pods -z 0 / 5 + ? _ ! [n prod -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
myaG 7 : z b ? L 9pp-deV O I P ploy-6f96ddbbf9-92s5g   1/1     RunN u } W [ Fning   0          88s   10.% k ! c , 4 ] t S2S O  , k y n44.1.4   node02   <none>           <none>
myapp-deple m Z y :oy-6f96ddbbf9| 6 | = y a-djwc6   1/1     Running   0          88s   10.244.2.4   node03   <none>1 - X;           <no^ M 8 _ & E x S ene>

在没有网络策略前提下,这4个Pod间是可以互相通信的。现在利用networkpolicy制定网络策略

k8s@node01:~/networkpolicy$ cat netpol-test.yaml
apiVersion:T O y X c b networking.k8s.io/v1
kind: NetworkPol2 O yicy
metada] l % ?ta:
nag Y [ Wme: netpo-test
spec:
podSelector: {} # L f b , h s . D 应用名称空间的所有pod
policyTypes:
- Ing1 f Cress
k8s@node01:~/networkpolicy$ kubectl apply -f net4  0 H s U u =pol-test.yaml -n dev

此规则未定义ingress和egress,但策略类型指定为Ingress,表示在dev名称空间中的所有pod的入站请求使用默认的拒绝策略,在prod名称空间中的Pod中pR ) !ing名称空间为dev@ z q中的pod,看是否能Ping通

k8s@node01:~/networkpolicy$ kubectl exec myapp-deploy-6f, 7 E 496ddbbf9-92s5g -n prod -- ping 10.244.2.3
PING 10.244.2.3 (10.244.2.3): 56 data bytes
^C
k8s@node01:~/networkpolM G 1icy$ kubectl exec myapp-deploy-6f96dd# ( + _ K # ( .bbf9-92s5g -n prod -- pin] ; $ V F 6g 10.244.1.3e b S ! 2 M r V 
Pu + sING 10.244.1.3 (10.244.1.3): 56 data bytes
^C
# 都无法Ping通

再试一下dev名称空间中的Pod间是否能Ping能

k8s@node01:~/networkpolicy$ kubee s Bctl exec myapp-deploy-6f96ddbbf9-xs227 -n dev -- pin= t r P v X ag 10.244.2.3
PING 10.244.2.3 (10.244.2.3): 56 data bytes
# 依然是不通的

这样的策略把pod的所有入站数据全部拒绝n b Z J u { $ z D了。修改策略,开放dev名称空间中所L 5 _ K h V = v有pod的入站点流量

k8s@node01:~/netwo5 Q s  ^ b . (rkpolicy$ cat netpol-test.yaml
apiVersion: netwoR w s A a Yrking.k8w 5 d 3 Z Ks.io/v1
kind: NetworkPolicy
metadata:
name: netpo-test
spec:
podSelector: {} # 应用名称空间的所有pod
ingress:  # 增加入站策略,但设置为空
- {}
policyTypes:
- Ingress
k8s@nodeR _ w01:~/networkpolicy$ kubectl apply -f netpol-test.yaml -n dev

入站策略设置为空,而策略类型为Ingrea _ x 0 z 8 X y Xss,这表示入站变允许所有流量

# 在宿主机也可以直接访问dev空间中的两个Pod的ip地址,能正常访问其相当的服务v X J z & h 4 K
k8s@node01:~/networkpolicy$ curl 10.244.2.3
Hel7 6 $ t U %lo MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2533841/hostname.html">Pod Name</a>
k8s@node01:~/netwJ ) { l b ( { [ `orkpolicy$ curl 10.244.1.3
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/w k k b P : ) 4zhaochj/2533841/hostname.html">Pod Name</a>

修改策略/ x J,允许10.G - N Z C 1 =244.0.0/16网段访问dev名称空间中所有pod的所有端口,但除去prod名称空间中的pod地址为R _ { f 2 }10.244.1.4# H H j V d 9 X/32的pH h 4 Z % Q L Iod

k8@ V . K g m Q [s@node01:~/networkpolicy$ cat netpol-test.yamC ; U z % W H Yl
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: netpo-test
spec:
podSelector: {} # 应用名称空间的所有pod
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except:
- 10.244.1.4/32
policyTypes:
- Ingress
k8s@nodF E J V ue01:~/networkpolicy$ kubectl aV 1 2 L ? y L 9pply -f netpol-test.yaml -n dev

分别在prod名称空间中的2个Pod中进行测试

# 地址为 10.244.1.4/32 的pod无法访问
k8s@node01:~/networkpolicy$ kubectl exec my& x E O u ) O @ 7app-deploy-6f96ddbbf9-92s5g -n prod -- /usr/bin/wgE 2 - 1 ~ . @et -O - -q 10.244.2.3
^C
# 另一个Pod则可以正常访问
k8s@no! w ; ~ N (de01:~/networkpolicy$ kubectl exec m^ ! I h !yapp-deploy-6f96ddbbN N % 0f9-djwc6 -n prod -- /usr/bin/wget -O - -q 10.244.2.3
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhao6 N d 1 2 M 6 Mchj/2533841/hostname.html">Pod Name</a>

现在想实现在dev名称空间的pod可以相互访问,但是prod名称空间的Pod则无法访dev名称空间E 1 l p中的pod。这里就需要使用到标签选择器,先对dev名称空间里的Pod打标签

k8s@node01:~/networkpolicy$ kubectl g! d oet pods -n dU A i + U Pev
NAME                            READY   STATUS    RESTARTL D 1 M 7 ( SS   AGE
myapp-deploy-6f96dd& 1 A F | ; ibbf9-x4jps   1/1     Running   0          45m
myapp-deploy-6f96ddbbf9d Y j o y N d-xs227   1/1     Running   0          45m
k8s@node01:~/networkpolicy$ kubectl label pod myapp-deploy-6f96ddbbf9-x4jps ns=dev -n dev
pod/myapp-deploy-6f96ddbbf9-x4jps labeled
k8s@node01:~/networkpolicy$ kubectl5 A o label pod myapp-deploy-6! 5 c T l 7 Gf96ddb! k @ Gbf9-xs227 ns=dev -n dev
pod/myapp-deploy-6f96ddbbf9-xs227 labeled
k8s@node01:~/networkpolicy$ kubectl get pods -n dev --show-laV C l P Gbels
NAME                            READY   STATUS    RESTARTS   AGE   LABELS
myapp-deploy-[  c z t |6f96ddbbf9-x4jps   1/1     Runf Y ( l a ^ !ning   0          46m   app=myapp,ns=dev,pod-template-hash=6f96ddbbf9
myappi h R @ } 3 k-deploy-6f96ddbbf9-xs227   1/1     Running   0          46m   apC ! ) [p=myapp,ns=dev,pod-template-hash; W v e=6f96ddbbf9

给名称空间也打个标签

k8s@node01:~/netwoO _ [ 8rkpolicy$ kubectl label ns prod ns=pro` M G &d
namespace/prod labeled
k8s@node01:~/ny g Y G  s n V metworkpolicyd 5 1  : P$ kubec; % [tll E j label ns dev ns=dev
namespace/dev labeled
k8s7 z ( W i / k Y [@node01:~/networkpolicy$ kubectl get ns --show-labels
NAME                   STATUS   AGE    LAh x X p 7 nBELS
default                Active   10d    <none>
dev                    Active   89m    ns=dev
ingress-nginx          ActL ! _ I K }ive   5d2h   app.kubernetes.io/instance=ingress-nginx,F + Mapp.kubernetes.io/name=ingress-nginx
kube-node-lease        Active   10d    <none>
kube-public            Active   10d    <none>
kube-system            Active   10d    <none>
kubernetes-dashboard   Ac} z S utive   31h    <none>
prod                   Active   88m    ns=prod

再来修改策略文件

k8s@node01:~/networkpolicy$ cat netpol-test.yaml
apiVe^ y Z N ? H )rsion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: netpo-test
spec:
podSelecto) { X ! *r:
matchLabels:
ns: dev
ingress:
- from:
- namespaceSelector:
matchLabelsv ^ L } B:l g : v 6 . & ^
ns+ @ = `: dev
policyTypes:
- Ingress
k8s@node01:~/networl T ykpolicy$ kubectl apply -f netpol-test.t ,  5 /yaml -n dev

现在的情况为prod名称空间里的两个pod都无法访问dev名t m v u称空间中pod,而dev名称空间中的pod可以相P 1 M互访问

# 无法访问
k8s@node01:~`  T _ B . O S F/networkpolicy$ kubectl exec myappL h r-deploy-6f96ddbbf9-djwc6 -n prod -- /usr/bin/wget -O - -q 10.2m 5 w Z ?44.2.3
^C
k8s@node01:~/networkpolicy$ kubectl ex$ X b & x N } t lec myapp-deploy-6f96? y ! H p , , bddbbf9-92s j L O z5g -n prod -- /usr/bin/wge% J _ ;t -O - -q 10.244.2.3
^C
k8s@T y - d o bnode01:~/networkpolicy$ kubectl get pods -n dev -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
myapp-deploy-6f96ddbbf9-x4jps   1/1     Running   0          60m   10.244.2.3   node03   <none>           <none>
myapp-deploy-6f96ddbbf9-xs227   1/1     Running   0          60m   10.244.1.3   node02   <a / Q } q;none>           <none>
# dev名称空间中的pS Y a l 9 ) j L qod可以互相访问
k8s@node01:~N P p # J */networkpolicy$ kubectl exec myapp-deplO p $oy-6f96ddbbf9-xs227 -n dev -- /usr/E t q t 7 . S #bin/wget -O - -q 10.244.2.3
Hello MyApp |0 ^ A Version: v1 | <a href="https://blog.51cto.com/zhaochj/2i + F .533841/hostname.html">Pod Name</a>

现在想开放80端口上的服务给prod中的pod访问,那修改策略文件如下

k8s@node01:~/networkpolicy$ cat netpol-test.yaml
ax - e # c ` ;piVersion: networking.k8s.io/v1
kind: Netu K L g U j 9 1 UworkPolicy
metadata:
name: netpo-test
spec:
podSelej J b P m S T - 6ctor:
matchLabels:p E 4 F g y F # `
ns: dev
ingress:
- from:
- namesp% L K w & E /aceSelector:
matchLabels:
ns: dev
- from:  # 增加一条开~ } L -放给prod名称空间的权限
- namespaceSelectoX & x b D ! L ^r:
matchLa# 4 9 % % ;bels:
ns: prod
ports:
- protocol: TCP
port: 80
pS ] 7olicyTypes:
- Ingress
k8s@node01:~/networkpolicy$ kubectl applyf : / 9 e X L . -f netpol-test.yaml -n dev

现在prod中的pod就可以访问dev名称空间中pod提供的http服务,_ } x y x p u w (但仅能访问8k * I0端口上的服务

k8s/ K _ ! 2 ^@nodG * + 9 3 9 +e01:~/networkpo1 ] p a g : c S :licy$ kubectl exec myapp-deploy-6f96ddbbf9-djwc6 -n E L a 5 Cn pro! Q dd -- /usr/bin/wget -O - -q 10.244.2.3
Hello Myo M V |App | Version: v1 | <a href="https://blog.51cto.com/zhaochj/25i E n Q s E , x .33841/hostname.html">Pod Name</a>
k8s@N i q hnode01:~/networkpolicy$ kubectl exec myapp-deploy-6f96ddbbf9-92s5g -n prod -- /uo U P z 1 Z msr/bin/wget -O - -q 10.244.2.3
Hello MyApp | Version: v1 | <a href="https://blog.51cto.com/zhaochj/2533841/hostname.html">Pod Name</a>
# ping服务未开放,无法ping通
k8s@node01:~/netwo( k y ~ Z + Mrkpolicy$ kubectl exec myapp-deploy-6f96ddbbf9-92s5g -5 Z { ln prod -- ping 10.244.2.3
PING 10.244.2.3 (10.244.2.3): 56 data bytes
^C

netw& u -orkpolicy的思想类似iptables,也是对出站与入站的流量进行过虑。