网络基本管理

calico基本管理

1. ippool

[root@master ~]# kubectl get ippool
NAME                  CREATED AT
default-ipv4-ippool   2024-01-07T05:14:31Z

导出这个ippool的yaml文件

[root@master ~]# kubectl get ippools/default-ipv4-ippool -o yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  creationTimestamp: "2024-01-07T05:14:31Z"
  name: default-ipv4-ippool
  resourceVersion: "3096"
  uid: f0951e80-722d-4c49-8aac-2254baea12a9
spec:
  allowedUses:
  - Workload
  - Tunnel
  blockSize: 26              
  cidr: 10.244.0.0/16
  ipipMode: Never
  natOutgoing: true
  nodeSelector: all()
  vxlanMode: CrossSubnet

  • blockSize: 26 分配给每个节点的子网
  • cidr: 10.244.0.0/16 当前池的podcidr
  • ipipMode: Never 是否使用ipip模式
  • ipipMode和vxlanMode都有3个模式可选
    1. Always:使用ipip模式
    2. CrossSubnet:BGP模式
    3. Never:不适用IPIP

1.1 创建一个池

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: mypool
spec:
  allowedUses:
  - Workload
  - Tunnel
  blockSize: 26              
  cidr: 10.200.0.0/24
  ipipMode: Never
  natOutgoing: true
  nodeSelector: all()
  vxlanMode: CrossSubnet
[root@master euler]# kubectl apply -f pool.yaml 
ippool.projectcalico.org/mypool created
[root@master euler]# 
[root@master euler]# kubectl get ippools.
NAME                  CREATED AT
default-ipv4-ippool   2024-01-07T05:14:31Z
mypool                2024-06-17T02:44:06Z

现在ippool已经被创建出来了

1.2 指定pod使用ippool

在k8s里面标签的作用是非常多的,我们可以指定唯一标识来让某个pod落在指定的ippool里面,早期也确实是这么用的,但是这样操作的话,标签会变得越来越多,不方便查看。还有没有其他方式可以像标签一样唯一标识一个资源呢?有,annotations(注释)就可以,所以需要指定pod落在哪个池的话需要给他加上一个注释

1.2.1 生成一个pod模板

[root@master euler]# kubectl run web01 --image nginx --image-pull-policy IfNotPresent --dry-run=client -o yaml > select_pool.yaml

1.2.2 修改pod模板

[root@master euler]# vim select_pool.yaml

apiVersion: v1
kind: Pod
metadata:
# 需要加上这一段
  annotations:
    cni.projectcalico.org/ipv4pools: "[\"mypool\"]"
# 到这里结束
  creationTimestamp: null
  labels:
    run: web01
  name: web01
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: web01
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

1.2.3 验证pod的ip

[root@master euler]# kubectl get pods/web01 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
web01   1/1     Running   0          58s   10.200.0.128   node1   <none>           <none>

可以看到这个pod的IP他就是我们刚刚指定的pool里面的一个地址了

1.2.4 测试pod之间的连通性

[root@master euler]# kubectl exec -it pod01 -- bash
root@pod01:/# curl 10.200.0.128
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
…………省略部分信息

可以看到,他与其他池的pod的网络也是通的

1.3 指定固定ip

依然是使用刚刚的pod模板

[root@master euler]# cp select_pool.yaml ipadd.yaml
[root@master euler]# vim ipadd.yaml 
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/ipv4pools: "[\"mypool\"]"
    # 加上这一行
    cni.projectcalico.org/ipAddrs: "[\"10.200.0.100\"]"
  creationTimestamp: null
  labels:
    run: web01
  name: web01
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: web01
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}


[root@master euler]# kubectl get pods/web01 -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
web01   1/1     Running   0          29s   10.200.0.100   node1   <none>           <none>

不过这个功能比较鸡肋,只能使用在pod上,因为使用在deployment上有10个副本,你如何去给我指定10个一样的地址呢?对吧

2. 定义网络策略

这是从官网抄的yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
# 定义具体策略
spec:
  # 选取目标
  podSelector:
    matchLabels:
      role: db
  # 定义策略
  policyTypes:
  - Ingress
  - Egress
  # 具体策略
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

网络策略是命名空间级别的资源,只能用于管理某个命名空间下的pod

上面的示例中选择的pod是标签为role: db,如果需要选取有,那么podSelector:{}这样写就是选取所有

具体的策略有ingress和egress,分别对应入站策略和出站策略,并且写了策略而没有写具体策略那么就是拒绝的策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
# 定义具体策略
spec:
  # 选取目标
  podSelector:
    matchLabels:
      role: db
  # 定义策略
  policyTypes:
  - Ingress
  - Egress

如果直接这样写,是不会报错的,并且所有的流量都被拒绝掉,也就是说,规则都是针对于拒绝去写的,没有定义的都是允许,但是如果使用之前的那个yaml文件,他就会允许172.17.0.0/16这个网段,但是172.17.1.0/24这个网段也是不可以访问的,并且只允许访问tcp的6379端口

2.1 网络策略实验

只允许internal命名空间下的pod访问命名空间内部的80端口的pod

# 创建命名空间
[root@master euler]# kubectl create ns internal

2.1.1 定义网络策略

我们只允许访问80端口,并且是internal命名空间下,所以我们只用写ingress的策略,因为默认不写egress就是全部放行,并且不用写命名空间,因为这个策略就是在internal命名空间内的,

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: internal
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}
    ports:
    - protocol: TCP
      port: 80
    - protocol: UDP
      port: 80
[root@master euler]# kubectl apply -f mynetworkpolicy.yaml 

2.1.2 创建pod测试

我们只放行了80端口,那我们可以开一个nginx和一个mysql来看差别,使用busybox来测试

[root@master euler]# kubectl run nginx --image nginx --image-pull-policy IfNotPresent 
[root@master euler]# kubectl run mysql --image mysql --image-pull-policy IfNotPresent --env "MYSQL_ROOT_PASSWORD=123"
[root@master euler]# kubectl run busybox --image busybox --image-pull-policy IfNotPresent -- sleep 3600

# 查看 pod ip
[root@master euler]# kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE    IP              NODE    NOMINATED NODE   READINESS GATES
busybox   1/1     Running   0          101s   10.244.104.22   node2   <none>           <none>
mysql     1/1     Running   0          50s    10.200.0.67     node1   <none>           <none>
nginx     1/1     Running   0          118s   10.244.104.46   node2   <none>           <none>


# 进入busybox使用telnet测试
[root@master euler]# kubectl exec -it busybox -- sh
/ # 
/ # telnet 10.200.0.67 3306

使用telnet连接mysql的3306 端口会一直卡在这

尝试连接80端口

/ # telnet 10.244.104.46 80
Connected to 10.244.104.46
# 出现这个显示按一下 e
e
HTTP/1.1 400 Bad Request
Server: nginx/1.25.4
Date: Mon, 17 Jun 2024 05:20:37 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.25.4</center>
</body>
</html>
Connection closed by foreign host

按完e之后他就会显示一个400的报错,这个是正常的,我们只是用telnet来测试端口

可以来个更加直观的测试

# 直接删除网络策略
[root@master euler]# kubectl delete -f mynetworkpolicy.yaml 
networkpolicy.networking.k8s.io "test-network-policy" deleted

# 再尝试连接
/ # telnet 10.200.0.67 3306
Connected to 10.200.0.67
I
8.2.0	%d9,Sÿ3a
                MS&R5P
                      caching_sha2_password

这个时候你会发现他并不会卡在那了,直接会有信息输出

posted @ 2024-06-17 13:25  FuShudi  阅读(14)  评论(0编辑  收藏  举报