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

img

[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


posted @ 2026-03-30 14:41  乔的港口  阅读(2)  评论(0)    收藏  举报