Azure AKS容器网络详解

Azure的AKS是Azure托管的Kubernetes服务。AKS支持多种容器网络模式,可以很好的和Azure的VNET集成。AzureCNI增强版与其他云厂商的Kubernetes服务的容器网络方案相比有一定的优势,主要表现在:部署灵活、节省IP地址资源等。Azure的AKS容器网络实现有多种模式,包括:

  1. Kubenet
  2. Azure CNI
  3. Azure CNI 增强版

一 Kubenet模式

1 Kubenet实现方式

Kubenet是最基本的模式,Kubenet是最基本的模式,它使用 bridge 和host-local CNI 插件实现了基本的cbr0。

Kubenet主要有两个主要功能:

  1. 在K8s的worknode中创建cbr0的bridge,通过host-local实现container的IPAM的功能
  2. 通过ptp创建veth pair,一端放到container中,一端放到cbr0中

2 AKS Kubenet数据流

如下图中,两个Node,分别各有两个Pod,通过Kubenet创建cbr0,每个Pod通过Kubenet创建的veth pair连接到cbr0上,Node的eth0也挂载到cbr0上。具体Pod见通信流量走向如下:

  1. 同Node上Pod间通信,通过cbr0实现Pod间通讯。比如Node上,Pod1和Pod2的通讯,直接通过cbr0实现
  2. 跨Node的Pod间通信,需要在VNET中创建用户自定义路由(UDR),来实现每Node上Pod的路由。比如下图中,如果Pod1(10.0.0.1)和Pod3(10.0.1.1)进行通信,

3 AKS实现

A 创建VNET

首先创建相应的VNET:

az network vnet create -g whhk -n vnet01 \

--address-prefixes 10.0.0.0/16 -l eastus

 

az network vnet subnet create -g whhk -n vlan01 \

  --vnet-name vnet01 --address-prefixes 10.0.0.0/22

 

vnet_id=$(az network vnet show -g whhk -n vnet01 -o tsv --query id)

vlan_id=$(az network vnet subnet show -n vlan01 -g whhk \

  --vnet-name vnet01 -o tsv --query id)

 

创建Service Principal并授权:

az ad sp create-for-rbac -n whforaks --skip-assignment

appid=$(az ad sp list --display-name whforaks -o tsv --query "[0].appId")

az role assignment create --assignee $appid --scope $vnet_id --role "Network Contributor"

B 创建AKS

创建网络采用Kubenet的AKS:

az aks create \

  -g whhk \

  -n aks01 \

  -l eastus \

  --node-count 2 \

  --network-plugin kubenet \

  --service-cidr 172.16.1.0/24 \

  --dns-service-ip 172.16.1.10 \

  --pod-cidr 10.244.0.0/16 \

  --docker-bridge-address 172.17.0.1/16 \

  --vnet-subnet-id $vlan_id \

  --service-principal $appid \

  --client-secret $passwd

 

获取AKS管理权限:

az aks get-credentials -g whhk -n aks01

 

$ kubectl get node

NAME STATUS ROLES AGE VERSION

aks-nodepool1-52243381-vmss000000 Ready agent 4m54s v1.20.9

aks-nodepool1-52243381-vmss000001 Ready agent 5m40s v1.20.9

 

创建一个workload:

kubectl create deployment nginx --image nginx

kubectl scale deployment nginx --replicas=3

 

C 登录到Node上查看CNI配置

登录到一个node上:

nodename=$(kubectl get node \

  -o jsonpath='{.items[0].metadata.labels.kubernetes\.io\/hostname}')

 

kubectl debug node/$nodename -it \

  --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11

 

查看网络配置情况,kubenet默认采用cbr0的bridge,地址分配了10.244.1.0/24的地址段给这个Node的pod使用:

cd /host/etc/cni/net.d/

# cat 10-containerd-net.conflist

{

  "cniVersion": "0.3.1",

  "name": "kubenet",

  "plugins": [{

    "type": "bridge",

    "bridge": "cbr0",

    "mtu": 1500,

    "addIf": "eth0",

    "isGateway": true,

    "ipMasq": false,

    "promiscMode": true,

    "hairpinMode": false,

    "ipam": {

      "type": "host-local",

      "subnet": "10.244.1.0/24",

      "routes": [{ "dst": "0.0.0.0/0" }]

      }

    },

  {

    "type": "portmap",

    "capabilities": {"portMappings": true},

    "externalSetMarkChain": "KUBE-MARK-MASQ"

  }]

}

 

D 采用Containerd工具crictl查看Node中的Pod

因为新版的AKS都采用containerd作为容器的runtime,我们安装containerd客户端crictl,由于是创建一个container进入的node,所以,要指定endpoint所在的位置/host/run/containerd/containerd.sock:

wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.22.0/crictl-v1.22.0-linux-amd64.tar.gz

tar vxf crictl-v1.22.0-linux-amd64.tar.gz

cp crictl /usr/local/bin

 

#crictl -r unix:///host/run/containerd/containerd.sock ps

CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID

eb53b4069ba54 81869ce15b0c7 3 minutes ago Running debugger 0 58009a9d2e180

22e1944b0c1a7 81869ce15b0c7 46 minutes ago Running debugger 0 421b2a77c8e3c

ade5453416e2f 87a94228f133e About an hour ago Running nginx 0 035488dda252d

0fac789b8c32b 87a94228f133e About an hour ago Running nginx 0 80e82d5d19e65

72bb25828d032 54b145bf08825 About an hour ago Running konnectivity-agent 0 e8d0f563161fb

a7c4e81f6250d e83e576296711 About an hour ago Running kube-proxy 0 f97a7109cbbeb

706dceab4bfae efd9c9d9e8376 About an hour ago Running azure-ip-masq-agent 0 dfdb927c75681

 

查看Pod信息:

# crictl -r unix:///host/run/containerd/containerd.sock pods

POD ID CREATED STATE NAME NAMESPACE ATTEMPT RUNTIME

58009a9d2e180 7 minutes ago Ready node-debugger-aks-nodepool1-52243381-vmss000000-r7cpt default 0

421b2a77c8e3c 50 minutes ago Ready node-debugger-aks-nodepool1-52243381-vmss000000-b9lgn default 0

035488dda252d About an hour ago Ready nginx-6799fc88d8-ltwhl default 0

80e82d5d19e65 About an hour ago Ready nginx-6799fc88d8-mr2q6 default 0

e8d0f563161fb About an hour ago Ready konnectivity-agent-7c8fdfddf4-xngd9 kube-system 0

dfdb927c75681 About an hour ago Ready azure-ip-masq-agent-k5gtp kube-system 0

f97a7109cbbeb About an hour ago Ready kube-proxy-6xznd kube-system 0

 

E 查看Pod内网络信息

进入到Pod内,查看IP和Mac地址:

# crictl -r unix:///host/run/containerd/containerd.sock exec \

-it ade5453416e2f sh

 

# ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

  inet 127.0.0.1/8 scope host lo

  valid_lft forever preferred_lft forever

  inet6 ::1/128 scope host

  valid_lft forever preferred_lft forever

3: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

  link/ether d6:12:5a:78:49:25 brd ff:ff:ff:ff:ff:ff link-netnsid 0

  inet 10.244.1.3/24 scope global eth0

  valid_lft forever preferred_lft forever

  inet6 fe80::d412:5aff:fe78:4925/64 scope link

  valid_lft forever preferred_lft forever

 

F Node上查看Bridge相关信息

再回到Node里查看bridge的mac表:

# brctl show

bridge name bridge id STP enabled interfaces

cbr0 8000.debc876c458c no vetha11a2630

vethaf749be9

 

# brctl showmacs cbr0

port no mac addr is local? ageing timer

2 86:a2:71:a1:60:b4 yes 0.00

2 86:a2:71:a1:60:b4 yes 0.00

1 ae:4d:2f:54:9c:07 yes 0.00

1 ae:4d:2f:54:9c:07 yes 0.00

2 d6:12:5a:78:49:25 no 19.94

 

可以看到,pod的mac地址在cbr0的mac转发表里。

$ kubectl get pod -o wide

NAME READY STATUS RESTARTS AGE IP NODE

nginx-6799fc88d8-fd5sq 1/1 Running 0 92m 10.244.0.6 aks-xxxx-vmss000001

nginx-6799fc88d8-ltwhl 1/1 Running 0 92m 10.244.1.3 aks-xxxx-vmss000000

nginx-6799fc88d8-mr2q6 1/1 Running 0 93m 10.244.1.2 aks-xxxx-vmss000000

 

G 检查联通性

在10.244.1.3的pod上ping其他两个pod,都能够ping通:

# ping 10.244.1.2

PING 10.244.1.2 (10.244.1.2) 56(84) bytes of data.

64 bytes from 10.244.1.2: icmp_seq=1 ttl=64 time=0.059 ms

64 bytes from 10.244.1.2: icmp_seq=2 ttl=64 time=0.090 ms

64 bytes from 10.244.1.2: icmp_seq=3 ttl=64 time=0.070 ms

^C

--- 10.244.1.2 ping statistics ---

3 packets transmitted, 3 received, 0% packet loss, time 55ms

rtt min/avg/max/mdev = 0.059/0.073/0.090/0.012 ms

# ping 10.244.0.6

PING 10.244.0.6 (10.244.0.6) 56(84) bytes of data.

64 bytes from 10.244.0.6: icmp_seq=1 ttl=62 time=0.983 ms

64 bytes from 10.244.0.6: icmp_seq=2 ttl=62 time=1.02 ms

64 bytes from 10.244.0.6: icmp_seq=3 ttl=62 time=0.985 ms

^C

--- 10.244.0.6 ping statistics ---

3 packets transmitted, 3 received, 0% packet loss, time 4ms

rtt min/avg/max/mdev = 0.983/0.994/1.016/0.039 ms

在node上抓包:

# tcpdump icmp -i eth0

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes

 

10:45:01.811855 IP 10.244.1.3 > 10.244.0.6: ICMP echo request, id 488, seq 1, length 64

10:45:01.812767 IP 10.244.0.6 > 10.244.1.3: ICMP echo reply, id 488, seq 1, length 64

10:45:02.813014 IP 10.244.1.3 > 10.244.0.6: ICMP echo request, id 488, seq 2, length 64

10:45:02.813963 IP 10.244.0.6 > 10.244.1.3: ICMP echo reply, id 488, seq 2, length 64

10:45:03.814281 IP 10.244.1.3 > 10.244.0.6: ICMP echo request, id 488, seq 3, length 64

10:45:03.815166 IP 10.244.0.6 > 10.244.1.3: ICMP echo reply, id 488, seq 3, length 64

只能看到跨节点的包,node内的数据包只经过node内的Bridge,不经过eth0.

H 查看VNET中的用户自定义路由

查看VNET中的路由:

az network route-table list -g mc_whhk_aks01_eastus --query \

"[].{address:routes[].addressPrefix[],nextHop:routes[].nextHopIpAddress[]}"

 

[

{

  "address": [

    "10.244.0.0/24",

    "10.244.1.0/24"

  ],

  "nextHop": [

    "10.0.0.5",

    "10.0.0.4"

  ]

}]

可以看到指向不同node的Pod地址段。节点外访问Pod IP的路由都是有这些UDR完成的。AKS每创建一个Node,就会生成一条相应的路由。这种方式对UDR的数量有一定要求,扩展性受到一定的限制。

二 Azure CNI

1. Azure CNI的两种模式

AKS的第二种网络模式是Azure CNI模式。在Azure CNI 1.2.0之前,采用的是Bridge模式,之后采用了Transparent模式。Bridge模式中会存在Kube-DNS的5s延迟问题,而在Transparent模式中得到了解决。这两种模式的逻辑结构如下,可以看出在Transparent模式下,Azure CNI采用的是三层路由的方式:

           Bridge模式:                                                        Transparent模式:

在Azure CNI方案中,Pod和Node都在同一个VNET的Subnet中,Node在创建时,会预先预留Node中Pod所有所需要的地址。比如每个Node支持30个Pod,那每个Node创建时,就在VNET中预留30个IP地址给Pod使用。

2 Azure CNI网络互通实现方式

Pod的IP地址在VNET中是可见的,所以在VNET中的网络节点可以直接访问Pod,而不需要用户自定义路由(UDR)来帮助实现。

具体如下图:

可以看到VM和Pod的地址是在相同网段中的。Azure VNET中SDN的Network Manager会根据Pod的IP地址把流量转发到相应的Node上。

3 AKS实现

A 创建Azure CNI的AKS集群

创建VNET:

az network vnet create -g aks -n cni-vnet \

  --address-prefixes 10.0.0.0/16 -l eastus

创建Subnet:

az network vnet subnet create -g aks -n vlan01 \

  --vnet-name cni-vnet --address-prefixes 10.0.0.0/20

获取VNET和Subnet的值:

vnet_id=$(az network vnet show -g aks -n cni-vnet -o tsv --query id)

 

vlan_id=$(az network vnet subnet show -n vlan01 -g aks \

  --vnet-name cni-vnet -o tsv --query id)

 

B 创建AKS

创建AKS:

az aks create \

  -g aks -n aks-cni -l eastus \

  --network-plugin azure \

  --vnet-subnet-id $vlan_id \

  --docker-bridge-address 172.17.0.1/16 \

  --dns-service-ip 10.2.0.10 \

  --service-cidr 10.2.0.0/24 \

  --node-count 2

获取AKS管理密钥:

az aks get-credentials -g aks -n aks-cni

查看Node信息:

$ kubectl get node

NAME STATUS ROLES AGE VERSION

aks-nodepool1-14830056-vmss000000 Ready agent 3m21s v1.20.9

aks-nodepool1-14830056-vmss000001 Ready agent 3m51s v1.20.9

创建Deployment:

kubectl create deployment nginx --image nginx

kubectl scale deployment nginx --replicas=10

 

C 登录Node查看CNI配置

登录Node:

nodename=$(kubectl get node \

  -o jsonpath='{.items[0].metadata.labels.kubernetes\.io\/hostname}')

 

kubectl debug node/$nodename -it \

  --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11

 

查看CNI的配置信息:

$ cd /host/etc/cni/net.d/

$ cat 10-azure.conflist

{

  "cniVersion":"0.3.0",

  "name":"azure",

  "plugins":[

  {

    "type":"azure-vnet",

    "mode":"transparent",

    "ipsToRouteViaHost":["169.254.20.10"],

    "ipam":{

      "type":"azure-vnet-ipam"

      }

  },

  {

    "type":"portmap",

    "capabilities":{

    "portMappings":true

  },

    "snat":true

  }

  ]

}

可以看到地址管理不再是host-local,而是有Azure-vnet-ipam来管理。CNI的类型也给成了Azure-vnet。

D 查看地址预留

查看Azure-vnet-ipam的日志,可以看到Node在启动时,从VNET中预留的地址。Kubenet默认时110个pod每Node,Azure CNI默认是30个Pod每Node。在日志中我们看到了预留的30个地址。由于Vnet的Subnet是新创建的,所以预留的地址是连续的:

$ more /host/var/log/azure-vnet-ipam.log

2021/11/04 09:54:50 [18965] [ipam] Pool request completed with pool:&{as:0xc0002bf740 Id:10.0.0.0/20 IfName:

eth0 Subnet:{IP:10.0.0.0 Mask:fffff000} Gateway:10.0.0.1 Addresses:map[

10.0.0.10:0xc000309180 10.0.0.11:0xc0003091c0 10.0.0.12:0xc000309200

10.0.0.13:0xc000309240 10.0.0.14:0xc000309280 10.0.0.15:0xc0003092c0

10.0.0.16:0xc000309300 10.0.0.17:0xc000309340 10.0.0.18:0xc000309380

10.0.0.19:0xc0003093c0 10.0.0.20:0xc000309400 10.0.0.21:0xc000309440

10.0.0.22:0xc000309480 10.0.0.23:0xc0003094c0 10.0.0.24:0xc000309500

10.0.0.25:0xc000309540 10.0.0.26:0xc000309580 10.0.0.27:0xc0003095c0

10.0.0.28:0xc000309600 10.0.0.29:0xc000309640 10.0.0.30:0xc000309680

10.0.0.31:0xc0003096c0 10.0.0.32:0xc000309700 10.0.0.33:0xc000309740

10.0.0.34:0xc000309780 10.0.0.5:0xc000309040 10.0.0.6:0xc000309080

10.0.0.7:0xc0003090c0 10.0.0.8:0xc000309100 10.0.0.9:0xc000309140]

addrsByID:map[] IsIPv6:false Priority:0 RefCount:1 epoch:0} err:<nil>.

查看Pod的IP地址,在vmss000000上的Pod,IP地址在预留的地址范围内:

E 检测网络连通性

Ping VNET中的其他Node和Pod,可以看到在没有用户自定义路由的情况下,网络都是通的:

root@hello-675bdb4bf9-9qxc7:/app# ifconfig eth0 | grep inet | grep -v inet6

inet 10.0.0.11 netmask 255.255.240.0 broadcast 0.0.0.0

 

root@hello-675bdb4bf9-9qxc7:/app# ping 10.0.0.4

PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.

64 bytes from 10.0.0.4: icmp_seq=1 ttl=64 time=0.040 ms

64 bytes from 10.0.0.4: icmp_seq=2 ttl=64 time=0.081 ms

64 bytes from 10.0.0.4: icmp_seq=3 ttl=64 time=0.054 ms

^C

--- 10.0.0.4 ping statistics ---

3 packets transmitted, 3 received, 0% packet loss, time 48ms

rtt min/avg/max/mdev = 0.040/0.058/0.081/0.018 ms

 

root@hello-675bdb4bf9-9qxc7:/app# ping 10.0.0.35

PING 10.0.0.35 (10.0.0.35) 56(84) bytes of data.

64 bytes from 10.0.0.35: icmp_seq=1 ttl=63 time=1.05 ms

64 bytes from 10.0.0.35: icmp_seq=2 ttl=63 time=1.13 ms

64 bytes from 10.0.0.35: icmp_seq=3 ttl=63 time=1.13 ms

^C

--- 10.0.0.35 ping statistics ---

3 packets transmitted, 3 received, 0% packet loss, time 4ms

rtt min/avg/max/mdev = 1.051/1.100/1.126/0.051 ms

 

root@hello-675bdb4bf9-9qxc7:/app# ping 10.0.0.37

PING 10.0.0.37 (10.0.0.37) 56(84) bytes of data.

64 bytes from 10.0.0.37: icmp_seq=1 ttl=62 time=1.08 ms

64 bytes from 10.0.0.37: icmp_seq=2 ttl=62 time=1.11 ms

^C

--- 10.0.0.37 ping statistics ---

2 packets transmitted, 2 received, 0% packet loss, time 2ms

rtt min/avg/max/mdev = 1.077/1.095/1.113/0.018 ms

三 Azure CNI增强版

1 Azure CNI存在的问题

Azure CNI虽然解决了Pod地址采用VNET地址的问题,使得Pod可以和VNET中的网络节点进行通信。但Azure CNI有以下一些问题:

  1. Azure CNI会大量占用VNET地址段的地址,每个Node创建时,都会预留大量的Pod地址。即使Pod没有创建,这些地址仍然不能使用
  2. AKS Azure CNI的Pod地址段与Node地址段在一起。没有办法针对Pod或Node进行安全配置
  3. Pod地址段是固定的,必须开始就设置大段地址,如果地址使用完,也不能追加新的地址段

2 增强版的Azure CNI

为了解决上面提到的几个问题,AKS推出了增强版的Azure CNI

增强版Azure CNI中,网卡和Pod的IP地址分别属于不同的Subnet,同时Node创建时不会预留大量的IP地址,每创建Pod时再获取相应的Pod IP地址:

目前Pod Subnet必须和Node的Subnet在一个VNET中,将来可以位于不同的VNET中。

Azure的Host Network采用VFP的方式实现主机的虚拟交换,增强版的Azure CNI模式下,VFP把同一个主机的Node和Pod作为两个不同的Network Container来进行处理,等于同一个VM上有两组不同的网络规则,如下图:

3 AKS实现

A 创建VNET

创建VNET,以及Node Subnet和Pod Subnet:

az group create -n cni -l eastus

az network vnet create -g cni -n whkubenet \

  --address-prefixes 10.1.0.0/16 -l eastus

 

az network vnet subnet create -g cni -n podvlan \

  --vnet-name whkubenet --address-prefixes 10.1.0.0/22

az network vnet subnet create -g cni -n nodevlan \

  --vnet-name whkubenet --address-prefixes 10.1.4.0/24

 

vnet_id=$(az network vnet show -g cni -n whkubenet -o tsv --query id)

 

podvlan=$(az network vnet subnet show -n podvlan -g cni \

  --vnet-name whkubenet -o tsv --query id)

nodevlan=$(az network vnet subnet show -n nodevlan -g cni \

  --vnet-name whkubenet -o tsv --query id)

B 安装AKS Preview的扩展插件

目前增强的Azure CNI是Preview阶段,需要安装Preview的扩展插件:

az extension add --name aks-preview

az extension update --name aks-preview

 

az feature register --namespace "Microsoft.ContainerService" \

  --name "PodSubnetPreview"

az feature list -o table \

  --query "[?contains(name, 'Microsoft.ContainerService/PodSubnetPreview')].{Name:name,State:properties.state}"

 

C 创建AKS集群

创建AKS集群:

az aks create -n akscni -g cni -l eastus \

  --max-pods 250 \

  --node-count 2 \

  --network-plugin azure \

  --vnet-subnet-id $nodevlan \

  --pod-subnet-id $podvlan

获取管理权限:

az aks get-credentials -n akscni -g cni

 

创建workload:

kubectl create deployment nginx --image nginx

kubectl scale deployment nginx --replicas=5

D 查看地址分配

查看Pod IP地址分配,Pod分配在两个Node上,地址段是预先定义的Pod地址段,与Node地址段不相同。

E 登录Node查看CNI信息

登录Node,

nodename=$(kubectl get node \

  -o jsonpath='{.items[0].metadata.labels.kubernetes\.io\/hostname}')

 

kubectl debug node/$nodename -it \

  --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11

查看CNI信息,可以看到和普通的Azure CNI配置相同:

# cat 10-azure.conflist

{

  "cniVersion":"0.3.0",

  "name":"azure",

  "plugins":[

  {

    "type":"azure-vnet",

    "mode":"transparent",

    "ipsToRouteViaHost":["169.254.20.10"],

    "ipam":{

      "type":"azure-cns"

  }

  },

  {

    "type":"portmap",

    "capabilities":{

    "portMappings":true

  },

    "snat":true

  }

  ]

}

查看/host/var/log/zure-vnet.log,可以看到Node给Pod分配IP地址、添加路由等日志。

在Node中查看路由信息,可以看到每个Pod都有相应的静态路由:

4 添加Node Pool

增强版的CNI中,可以每个Node Pool采用不同的Pod Subnet,如下图:

新Node Pool的Node地址仍然在Node的Subnet中,但通过创建新的Pod地址段,新建Node Pool中的Pod,会采用新的地址段。

A 创建Pod Subnet

az network vnet subnet create -g cni -n podvlan2 \

  --vnet-name whkubenet --address-prefixes 10.1.8.0/22

 

podvlan2=$(az network vnet subnet show -n podvlan2 -g cni \

  --vnet-name whkubenet -o tsv --query id)

B 创建AKS Node Pool

az aks nodepool add --cluster-name akscni -g cni -n newnodepool \

  --max-pods 250 \

  --node-count 2 \

  --vnet-subnet-id $nodevlan \

  --pod-subnet-id $podvlan2 \

  --no-wait

 

C 查看IP地址分配

Node IP地址:

Pod IP地址:

可以看到,新的Node Pool中的Pod采用了新的地址段。

通过这种方法,可以非常方便的规划、扩展计算资源池,解决Pod地址不够用的问题。

D 测试安全规则

通过创建安全规则,允许第一个Node Pool中的Pod访问Node,禁止第二个Node Pool中的Pod访问Node。

I 创建NSG

创建NSG规则:

az network nsg create -n aksnsg -g cni -l eastus

az network nsg rule create -g cni \

  --nsg-name aksnsg \

  --name icmp_permit \

  --priority 200 \

  --source-address-prefixes '10.1.0.0/22' \

  --destination-address-prefixes '10.1.4.0/24' \

  --access Allow \

  --protocol ICMP \

  --direction Inbound

 

az network nsg rule create -g cni \

  --nsg-name aksnsg \

  --name icmp_deny \

  --priority 300 \

  --source-address-prefixes '10.1.8.0/22' \

  --destination-address-prefixes '10.1.4.0/24' \

  --access Deny \

  --protocol ICMP \

  --direction Inbound

 

az network vnet subnet update -n nodevlan \

  --vnet-name whkubenet -g cni \

  --network-security-group aksnsg

II Node Pool1中的Pod测试

登录第一个Node Pool的Pod:

地址段是10.1.0.0/22地址段的Pod,是第一个Node Pool中的Pod。

可以Ping通Node地址段中的VM。

III Node Pool2中的Pod测试

登录第二个Node Pool的Pod:

地址段是10.1.8.0/22地址段的Pod,是第二个Node Pool中的Pod。

Ping Node地址段的VM,网络不通,被NSG规则Deny。

由于Node Pool的Pod采用不同的Subnet,可以非常方便的对Workload进行一些规则的定义,实现精选的安全设计和部署。

 

四 结束语

Azure的AKS有多种容器网络的实现方式,包括:

  1. Kubenet:Kubenet的方式,实现起来简单,PodIP地址在创建AKS时指定。但每创建一个Node就需要增加一条UDR路由,使得扩展性受限

  2. Azure CNI:Azure CNI非常好的解决了Pod地址暴露在VNET的问题。VNET中的网络节点可以非常方便的和Pod进行通信。但这种方案PodIP地址消耗VNET地址段相对较多。在每个Node创建时,都要预留相应的IP地址段在Node中。同时不能追加Pod地址段,使得扩展性也受到一定的限制

  3. Azure CNI增强版:Azure CNI增强版非常好的解决了上面两种方法的问题,通过分离Node和Pod的Subnet,在新的NodePool中添加新的PodSubnet的方式,方便的实现了AKS网络层面的扩展需求,同时可以节约大量的IP地址段。

AKS的用户,可以根据业务的实际需求,可以选择不同的方式进行部署。

 

posted @ 2021-11-13 23:26  衡子  阅读(2132)  评论(0编辑  收藏  举报