k8s网络服务
网络组件
三个基本条件和四大目标,pdf上面有
cni的三种模式,都是结合在一起的使用
- 配置文件,里面有如何连接apiserver的密钥文件
[root@master01 net.d]# pwd
/etc/cni/net.d
maxvlan 大二层,位于一个大的网段,跟物理机一个网段,不能使用物理机的ip,会导致冲突,k8s很少被使用,容易造成这个网络风暴
-
calico网络插件
- 就是可以写策略限制这个pod访问这个pod
-
flannel插件,不能实现这个策略,只能实现这个pod与pod之间的通信
-
ipip模式是什么,前面就讲解一下这个网络信息等等
一、网络组件介绍
1、k8s网络模型基本条件和目标
1、三个基本条件
-
所有pod可以与其他pod直接通信
- 通过cni插件(calico,flannel),每个节点维护路由表,知道哪些pod位于哪个节点
-
所有node可以与pod直接通信
- 节点通过虚拟网桥(cni0) 或者直接路由连接到pod网络
-
pod可见的ip地址与其他pod地址通信时所用
2、四个目标
-
同一个pod内容器间通信(container to container)
-
pod间的通信(pod to pod)
-
有可能在同一个节点或者跨节点访问
-
同一个节点通过cni 桥接来进行通信
-
不同节点overlay网络或者路由直接通信
-
-
service到pod间的通信(service to pod )
-
svc作为pod的稳定访问入口
-
提供了负载均衡的能力
-
解决了pod ip易变的问题
-
-
集群外部与service之间的通信(external to service)
- 允许外部客户端访问集群内的服务
2、k8s的三种网络模式
- 可以用网络插件实现下面的撒暗中
1、L2桥接模式
-
图
-
工作在数据链路层,flannel插件可以实现,性能是最高的
-
核心原理就是使用linux bridge 作为虚拟交换机,将同一个节点内的pod连接到同一个二层网络,有一个veth对
-
同一节点中的pod通信,直接二层转发(根据mac地址转发),不需要经过路由
-
跨节点通信(需要路由或封装)
-
通过网关路由到达节点,在通过bridge二层转发实现通信
-
或者直接vxlan封装
-
-
缺点
-
广播域过大,arp风暴风险
-
mac地址表有限制
-
大规模集群中mac学习开销大
-
-
插件实现
-
flannel的bridge模式可以实现
-
flannel的vxlan模式可以实现
-
2、L3路由
-
核心原理:完全基于ip路由转发,每个节点作为路由器,通过维护路由表实现pod之间的通信,不依赖mac地址学习,而是通过ip路由表决定转发路径
-
跨节点通信
- 通过纯ip路由实现
-
插件实现
-
calico的BGP模式(纯路由,bgp动态路由)
-
flannel的host-gw模式
-
3、host overlay模式
- 核心原理:Overlay 模式在物理网络之上构建一个虚拟网络,通过隧道封装技术将 Pod 的网络流量封装在物理网络的报文中传输。这使得 Pod 网络可以独立于底层物理网络拓扑。
3、cni(Container Network Interface,容器网络接口)
-
CNCF维护的容器网络配置标准接口,就是一个规矩,核心就是解耦容器运行时与网络实现
-
统一容运行时
1、calico网络插件
- 支持的网络模式vxlan,bgp,ipip
2、flannel网络插件
-
支持的网络模式 vxlan,host-gw
-
现在不常用了
3、kube-ovs
- 国产的
二、calico基本管理
1、ippool
-
用于管理pod ip分配范围的核心资源对象
-
就是分配ip地址给pod使用的
-
还可以设置ipip/vxlan等跨节点通信的方式
1、查看默认的ippool
[root@master01 ~]# kubectl get ippool
NAME AGE
default-ipv4-ippool 5d23h
# yaml显示展示
[root@master01 ~]# kubectl get ippool -o yaml
apiVersion: v1
items:
- apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
annotations:
projectcalico.org/metadata: '{"uid":"7e9a54c1-eab4-4890-ad53-a43aa3927db8","creationTimestamp":"2026-03-24T06:17:19Z"}'
creationTimestamp: "2026-03-24T06:17:19Z"
generation: 1
name: default-ipv4-ippool # ippool名称
resourceVersion: "9235"
uid: 3ec1c39d-eec1-4d14-9e05-89b0a144b4f1
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 26 # 每个节点分配26个ip块大小
cidr: 10.240.0.0/12 # pod ip网段
ipipMode: Always # ipip隧道, always/never
natOutgoing: true # pod访问外网的时候是否使用snat
nodeSelector: all() # 哪些节点使用这个池,默认所有节点
vxlanMode: Never # vxlan隧道,ipipmode和vxlan不能同时启用
kind: List
metadata:
resourceVersion: ""
selfLink: ""
-
ipipmode和vxlanmode 都有是三个参数
-
always 使用ipip模式
-
CrossSubnet BGP模式
-
Never 不使用pip模式
-
2个选项都是never就是使用bgp模式
-
| 模式 | ipipMode |
vxlanMode |
说明 |
|---|---|---|---|
| 纯 BGP | Never |
Never |
无封装,依赖底层网络路由 |
| IPIP | Always/CrossSubnet |
Never |
IP in IP 封装 |
| VXLAN | Never |
Always/CrossSubnet |
VXLAN 封装(您的当前配置) |
2、创建一个池
[root@master01 test]# cat pool.yml
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: mypool
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 26
cidr: 10.200.0.0/24 # pod网段
ipipMode: Never
natOutgoing: true
nodeSelector: all() # 这个ip池作用于所有节点
vxlanMode: CrossSubnet # 使用vxlan模式
[root@master01 ~]# kubectl get ippool
NAME AGE
default-ipv4-ippool 5d23h
mypool 8m1s
3、指定pod使用ippool
- 默认情况下是第一个ippool里面的ip地址用完了,才使用第二个,因此需要注释来进行标识使用第二个ippool
[root@master01 ~]# cat busybox1.yml
apiVersion: v1
kind: Pod
metadata:
annotations: # 注释,使用mypool池
cni.projectcalico.org/ipv4pools: "[\"mypool\"]"
creationTimestamp: null
labels:
run: busybox1
name: busybox1
spec:
containers:
- image: busybox
name: busybox1
resources: {}
command:
- /bin/sh
- -c
- "sleep 3600"
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
4、验证和通信
# 分配的ip是第二个ippool分配的
[root@master01 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox1 1/1 Running 0 32s 10.200.0.194 node <none> <none>
# 位于不同的ippool之间能互相通信
[root@master01 test]# kubectl exec -ti busybox1 -- /bin/sh
/ # ping 10.246.73.141
PING 10.246.73.141 (10.246.73.141): 56 data bytes
64 bytes from 10.246.73.141: seq=0 ttl=63 time=0.110 ms
64 bytes from 10.246.73.141: seq=1 ttl=63 time=0.073 ms
^C
--- 10.246.73.141 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.073/0.091/0.110 ms
-
为什么能通信了?
-
Calico 维护全网路由,节点知道所有 Pod 在哪里
-
可以通过后面学习的网络策略来隔离
-
5、指定固定ip
-
上面是随机分配一个ippool中的地址,还可以指定固定的ip地址
-
只能适合pod,deploy这些控制器不适合,多个副本,pod ip不能相等
[root@master01 test]# cat busybox1.yml
apiVersion: v1
kind: Pod
metadata:
annotations:
cni.projectcalico.org/ipv4pools: "[\"mypool\"]"
# 添加这一行
cni.projectcalico.org/ipAddrs: "[\"10.200.0.100\"]"
creationTimestamp: null
labels:
run: busybox1
name: busybox1
spec:
containers:
- image: busybox
name: busybox1
resources: {}
command:
- /bin/sh
- -c
- "sleep 3600"
[root@master01 test]# kubectl apply -f busybox1.yml
pod/busybox1 created
# ip地址为10.200.0.100
[root@master01 test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
b1 1/1 Running 0 4m23s 10.246.73.141 node <none> <none>
busybox1 1/1 Running 0 4s 10.200.0.100 node <none> <none>
二、网络策略
1、什么是网络策略呢?
-
用于控制pod之间的网络流量,实现隔离等等,就是默认情况下,pod之间是互相通信的,通过策略控制不能访问哪些pod
-
保护一组pod不能被谁访问,谁可以访问,然后这个pod可以访问哪些
2、策略作用域(名称空间)
-
策略只会作用于同一个名称空间下,被podSelector选中的pod
-
如果podselector是{} 则选择这个名称空间下面的所有pod
3、策略类型(入站和出站)
-
policyTypes 字段明确指定策略类型
-
Ingress:入站流量控制(谁可以访问这个 Pod)
-
Egress:出站流量控制(这个 Pod 可以访问谁)
-
spec:
policyTypes:
- Ingress # 只控制入站
- Egress # 只控制出站
# 如果两者都写,则同时控制入站和出站
# 都没有写的话就是全部放行
- 策略的默认行为
| 场景 | 入站流量(Ingress) | 出站流量(Egress) |
|---|---|---|
| 没有任何 NetworkPolicy | 全部放行(默认允许) | 全部放行(默认允许) |
| 只定义了 Ingress 规则,未定义 Egress | 只允许规则内的流量,其余拒绝 | 全部放行(Egress 未定义,保持默认) |
| 只定义了 Egress 规则,未定义 Ingress | 全部放行(Ingress 未定义,保持默认) | 只允许规则内的流量,其余拒绝 |
| 同时定义了 Ingress 和 Egress 规则 | 只允许规则内的流量 | 只允许规则内的流量 |
| 定义了策略但规则为空({}) | 全部拒绝(无规则匹配) | 全部拒绝(无规则匹配) |
4、策略yaml文件
- 官网上的
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default # 定义作用在哪一个名称空间下面
# 定义具体策略
spec:
# 选取目标
podSelector:
matchLabels: # 选中 default下面的 带有role=db标签的pod
role: db
# 定义策略
policyTypes:
- Ingress # 入站规则(谁可以访问选中的pod)
- Egress # 出站规则(选中的pod可以访问谁)
# 具体策略
ingress: # 具体的入站规则
- from: # 下面3个不同的划分,是逻辑或的关系,如果要逻辑与的关系的话,就去掉下面2个-
- ipBlock: # ip划分
cidr: 172.17.0.0/16 # 允许这个ip网段访问
except: # 不允许这个ip网段访问
- 172.17.1.0/24
- namespaceSelector: # 名称空间划分
matchLabels:
project: myproject # 选择名称空间带有这个的project=myproject下面的pod可以访问
- podSelector: # pod划分
matchLabels:
role: frontend # 选择pod带有 role=frontend的pod可以访问
ports:
- protocol: TCP # 访问我的tcp 6379端口
port: 6379
egress: # 具体的出站规则
- to:
- ipBlock: # 选中的pod可以访问 这个网段
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
5、网络策略实验
- 只允许internal空间下的pod访问命名空间的内部的80端口的pod

[root@master01 test]# kubectl create ns internal
namespace/internal created
1、定义网络策略
[root@master01 test]# cat network.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: internal
spec:
podSelector: {}
policyTypes:
- Ingress # 只需要定义入站规则即可 允许这个空间下面的pod访问这个空间下面的pod的80端口,其他空间都不能访问,没有写其他空间的划分
ingress:
- from:
- podSelector: {}
ports:
- protocol: TCP
port: 80
- protocol: UDP
port: 80
2、测试
-
在default空间下创建一个busybox
-
在internal空间下创建一个busybox,和一个nginx
[root@master01 test]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
b1 1/1 Running 0 29m 10.246.73.141 node <none> <none>
# internal空间下的pod
[root@master01 test]# kubectl get pod
NAME READY STATUS RESTARTS AGE
b1 1/1 Running 0 29m
[root@master01 test]# kubectl get pod -o wide -n internal
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox1 1/1 Running 0 5m46s 10.246.73.143 node <none> <none>
n1 1/1 Running 0 5m6s 10.246.73.144 node <none> <none>
# internal下的busybox测试
[root@master01 test]# kubectl exec -ti -n internal busybox1 -- /bin/sh
/ # telnet 10.246.73.144 80
Connected to 10.246.73.144 # 出现这个按e
e
HTTP/1.1 400 Bad Request
Server: nginx/1.29.7
Date: Mon, 30 Mar 2026 06:29:02 GMT
Content-Type: text/html
Content-Length: 157
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.29.7</center>
</body>
</html>
Connection closed by foreign host
# 这个是正常现象
# default空间下的pod访问,就会一直卡在那
/ # telnet 10.246.73.144 80
- 如果我们删除这个网络策略,看default下的pod能不能访问
# 删除网络策略
[root@master01 test]# kubectl delete -f network.yml
networkpolicy.networking.k8s.io "test-network-policy" deleted
# 发现可以访问了
[root@master01 test]# kubectl exec -ti b1 -- /bin/sh
/ # telnet 10.246.73.144 80
Connected to 10.246.73.144
e
HTTP/1.1 400 Bad Request
Server: nginx/1.29.7
Date: Mon, 30 Mar 2026 06:31:17 GMT
Content-Type: text/html
Content-Length: 157
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.29.7</center>
</body>
</html>
Connection closed by foreign host
三、calico基本命令
1、安装calico命令
git clone https://gitee.com/yftyxa/hcie-calicoctl.git
cd hcie-calicoctl/
mv calicoctl /usr/local/bin/
2、常用命令
1、节点管理
# 查看当前节点的BGP对等状态和路由表
[root@master01 test]# calicoctl node status
Calico process is running.
IPv4 BGP status
+---------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+---------------+-------------------+-------+----------+-------------+
| 192.168.50.21 | node-to-node mesh | up | 05:25:41 | Established |
| 192.168.50.22 | node-to-node mesh | up | 05:25:41 | Established |
+---------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
2、ip地址管理
# 查看 ip地址分配情况
[root@master01 test]# calicoctl ipam show
+----------+---------------+------------+------------+-------------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+---------------+------------+------------+-------------------+
| IP Pool | 10.240.0.0/12 | 1.0486e+06 | 9 (0%) | 1.0486e+06 (100%) |
+----------+---------------+------------+------------+-------------------+
# 检查ip地址分配的一致性问题
root@master01 test]# calicoctl ipam check
Checking IPAM for inconsistencies...
Loading all IPAM blocks...
Found 3 IPAM blocks. # 加载ipam块
IPAM block 10.244.59.192/26 affinity=host:master02:
IPAM block 10.246.73.128/26 affinity=host:node:
IPAM block 10.255.112.128/26 affinity=host:master01:
IPAM blocks record 9 allocations. # 9个ip被使用
Loading all IPAM pools...
10.240.0.0/12
Found 1 active IP pools.
Loading all nodes.
Found 3 node tunnel IPs.
Loading all workload endpoints.
Found 6 workload IPs.
Workloads and nodes are using 9 IPs.
Looking for top (up to 20) nodes by allocations...
node has 4 allocations
master01 has 4 allocations
master02 has 1 allocations
Node with most allocations has 4; median is 4
Scanning for IPs that are allocated but not actually in use...
Found 0 IPs that are allocated in IPAM but not actually in use.
Scanning for IPs that are in use by a workload or node but not allocated in IPAM...
Found 0 in-use IPs that are not in active IP pools.
Found 0 in-use IPs that are in active IP pools but have no corresponding IPAM allocation.
Check complete; found 0 problems.
3、查看客户端和集群版本
[root@master01 test]# calicoctl version
Client Version: v3.23.5
Git commit: 9e0398360
Cluster Version: v3.23.5
Cluster Type: k8s,bgp,kubeadm,kdd

浙公网安备 33010602011771号