# 网络calico
## BGP进阶
```sh
cd /usr/local/bin/
curl -o calicoctl -O -L https://github.com/projectcalico/calicoctl/releases/download/v3.20.2/calicoctl
[00:41:57 root@master1 bin]#chmod +x calicoctl
[22:39:36 root@master1 calico]#cat /etc/calico/calicoctl.cfg
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
datastoreType: "kubernetes"
kubeconfig: "/etc/kubernetes/admin.conf"
# 测试
[22:40:04 root@master1 calico]#calicoctl get nodes
NAME
master1
master2.noisedu.cn
master3.noisedu.cn
node1.noisedu.cn
node2.noisedu.cn
# 关联kubectl
[22:42:05 root@master1 calico]#cd /usr/local/bin/
[22:42:25 root@master1 bin]#cp -p calicoctl kubectl-calico
[00:43:00 root@master1 bin]#kubectl calico node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.0.0.51 | node-to-node mesh | up | 16:41:21 | Established |
| 10.0.0.52 | node-to-node mesh | up | 16:41:20 | Established |
| 10.0.0.53 | node-to-node mesh | up | 16:41:20 | Established |
| 10.0.0.54 | node-to-node mesh | up | 16:41:20 | Established |
+--------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
```
## 更改ipip model从always到CrossSubnet。
```sh
# 当前通信我们是双层嵌套IP,即ipip模式,会自动生成一个tune0网卡,所有的流量都从这个网卡通信
[22:48:57 root@master1 cmd]#ifconfig
tunl0: flags=193<UP,RUNNING,NOARP> mtu 1480
inet 10.244.0.1 netmask 255.255.255.255
tunnel txqueuelen 1000 (IPIP Tunnel)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[22:54:58 root@master1 cmd]#ip route list
default via 10.0.0.2 dev eth0 proto static
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.50
blackhole 10.244.0.0/24 proto bird
10.244.0.5 dev calif478a5ea502 scope link
10.244.0.6 dev cali260b8463b8f scope link
10.244.0.7 dev cali21f5341d0ac scope link
10.244.3.0/24 via 10.0.0.53 dev tunl0 proto bird onlink
10.244.4.0/24 via 10.0.0.54 dev tunl0 proto bird onlink
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
[22:45:00 root@master1 cmd]#kubectl calico get ipPools default-ipv4-ippool -o yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
creationTimestamp: "2021-12-11T15:49:12Z"
name: default-ipv4-ippool
resourceVersion: "2012"
uid: 894ee240-f66d-47a0-96ca-b634d20f2803
spec:
blockSize: 24
cidr: 10.244.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
# 更改网卡模式到CrossSubnet,即通过实际的物理网卡eth0通信
[22:51:05 root@master1 cmd]#cat default-ipv4-ippool.yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
blockSize: 24
cidr: 10.244.0.0/16
ipipMode: CrossSubnet
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
[22:55:39 root@master1 cmd]#kubectl calico apply -f default-ipv4-ippool.yaml
Successfully applied 1 'IPPool' resource(s)
[22:55:41 root@master1 cmd]#ip route list
default via 10.0.0.2 dev eth0 proto static
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.50
blackhole 10.244.0.0/24 proto bird
10.244.0.5 dev calif478a5ea502 scope link
10.244.0.6 dev cali260b8463b8f scope link
10.244.0.7 dev cali21f5341d0ac scope link
10.244.3.0/24 via 10.0.0.53 dev eth0 proto bird
10.244.4.0/24 via 10.0.0.54 dev eth0 proto bird
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
```
## 反射器角色 - 从BGP peer到BGP reflecter
### 0 查看现在的node网络状态,是点对点模式
```sh
[00:44:06 root@master1 cmd]#kubectl calico node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.0.0.51 | node-to-node mesh | up | 16:41:21 | Established |
| 10.0.0.52 | node-to-node mesh | up | 16:41:20 | Established |
| 10.0.0.53 | node-to-node mesh | up | 16:41:20 | Established |
| 10.0.0.54 | node-to-node mesh | up | 16:41:20 | Established |
+--------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
```
### 1 定义反射器角色
```sh
[23:10:14 root@master1 calico]#cat 01-calico-reflector-master.yaml
apiVersion: projectcalico.org/v3
kind: Node
metadata:
labels:
route-reflector: true
name: master1
spec:
bgp:
ipv4Address: 10.0.0.50/16
ipv4IPIPTunnelAddr: 10.244.0.1
routeReflectorClusterID: 1.1.1.1
[23:10:55 root@master1 calico]#kubectl calico apply -f 01-calico-reflector-master.yaml
Successfully applied 1 'Node' resource(s)
```
### 2 后端节点使用反射器
```sh
# 更改到BGP reflecter网络模型
[23:11:04 root@master1 calico]#cat 02-calico-reflector-bgppeer.yaml
kind: BGPPeer
apiVersion: projectcalico.org/v3
metadata:
name: bgppeer-demo
spec:
nodeSelector: all()
peerSelector: route-reflector=="true"
[23:12:09 root@master1 calico]#kubectl calico apply -f 02-calico-reflector-bgppeer.yaml
Successfully applied 1 'BGPPeer' resource(s)
# 查看node状态,同时存在点对点和反射网络模型
[00:44:58 root@master1 calico]#kubectl calico node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.0.0.51 | node-to-node mesh | up | 16:41:22 | Established |
| 10.0.0.52 | node-to-node mesh | up | 16:41:21 | Established |
| 10.0.0.53 | node-to-node mesh | up | 16:41:21 | Established |
| 10.0.0.54 | node-to-node mesh | up | 16:41:21 | Established |
| 10.0.0.51 | node specific | start | 16:44:58 | Idle |
| 10.0.0.52 | node specific | start | 16:44:58 | Idle |
| 10.0.0.53 | node specific | start | 16:44:58 | Idle |
| 10.0.0.54 | node specific | start | 16:44:58 | Idle |
+--------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
```
### 3 关闭默认的网格效果
```sh
[23:13:19 root@master1 calico]#cat 03-calico-reflector-defaultconfig.yaml
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
logSeverityScreen: Info
nodeToNodeMeshEnabled: false
asNumber: 63400
[23:13:50 root@master1 calico]#kubectl calico apply -f 03-calico-reflector-defaultconfig.yaml
Successfully applied 1 'BGPConfiguration' resource(s)
# 查看node状态,检查是否删除了点对点网络
[00:45:25 root@master1 calico]#kubectl calico node status
Calico process is running.
IPv4 BGP status
+--------------+---------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+---------------+-------+----------+-------------+
| 10.0.0.51 | node specific | up | 16:45:26 | Established |
| 10.0.0.52 | node specific | up | 16:45:25 | Established |
| 10.0.0.53 | node specific | up | 16:45:26 | Established |
| 10.0.0.54 | node specific | up | 16:45:26 | Established |
+--------------+---------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
```
## 网络策略
### 准备环境
```sh
[22:06:09 root@master1 calico]#cat 04-calico-deployment-test.yaml
apiVersion: v1
kind: Namespace
metadata:
name: develop
labels:
kubernetes.io/metadata.name: develop
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: pod-deployment1
name: pod-deployment1
namespace: develop
spec:
replicas: 3
selector:
matchLabels:
app: pod-deployment1
template:
metadata:
labels:
app: pod-deployment1
spec:
containers:
- image: 10.0.0.55:80/mykubernetes/pod_test:v0.1
name: pod-test
---
apiVersion: v1
kind: Service
metadata:
labels:
app: pod-deployment1
name: pod-deployment1
namespace: develop
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: pod-deployment1
type: ClusterIP
[22:12:35 root@master1 calico]#kubectl get pods -n develop -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-deployment1-85bd7684f6-grsw9 1/1 Running 0 32s 10.244.3.4 node1.noisedu.cn <none> <none>
pod-deployment1-85bd7684f6-njn6x 1/1 Running 0 32s 10.244.3.5 node1.noisedu.cn <none> <none>
pod-deployment1-85bd7684f6-p9plh 1/1 Running 0 32s 10.244.4.5 node2.noisedu.cn <none> <none>
# 皆能正常访问
[22:12:47 root@master1 calico]#curl 10.244.3.4
kubernetes pod-test v0.1!! ClientIP: 10.0.0.50, ServerName: pod-deployment1-85bd7684f6-grsw9, ServerIP: 10.244.3.4!
[22:13:01 root@master1 calico]#curl 10.244.3.5
kubernetes pod-test v0.1!! ClientIP: 10.0.0.50, ServerName: pod-deployment1-85bd7684f6-njn6x, ServerIP: 10.244.3.5!
[22:13:09 root@master1 calico]#curl 10.244.4.5
kubernetes pod-test v0.1!! ClientIP: 10.0.0.50, ServerName: pod-deployment1-85bd7684f6-p9plh, ServerIP: 10.244.4.5!
```
### 默认策略
```sh
# 采用默认规则,虽然policy type定义了ingress和egress,但是未定义任何的ingress字段
[22:13:12 root@master1 calico]#cat 05-calico-networkpolicy-denyall.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: develop
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
[22:20:08 root@master1 calico]#kubectl apply -f 05-calico-networkpolicy-denyall.yaml
networkpolicy.networking.k8s.io/deny-all-ingress created
# 测试,皆ping不通
[22:20:20 root@master1 calico]#curl 10.244.3.4
^C
[22:21:51 root@master1 calico]#curl 10.244.3.5
^C
[22:22:01 root@master1 calico]#curl 10.244.4.5
^C
# 设置默认的允许pod管控策略,ingress和egress未写字段,默认允许所有字段
[22:23:01 root@master1 calico]#cat 06-calico-networkpolicy-denyall.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: develop
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- {}
ingress:
- {}
[22:23:06 root@master1 calico]#kubectl apply -f 06-calico-networkpolicy-denyall.yaml
networkpolicy.networking.k8s.io/deny-all-ingress created
# 测试
[22:23:20 root@master1 calico]#curl 10.244.3.4
kubernetes pod-test v0.1!! ClientIP: 10.0.0.50, ServerName: pod-deployment1-85bd7684f6-grsw9, ServerIP: 10.244.3.4!
[22:23:28 root@master1 calico]#curl 10.244.3.5
kubernetes pod-test v0.1!! ClientIP: 10.0.0.50, ServerName: pod-deployment1-85bd7684f6-njn6x, ServerIP: 10.244.3.5!
[22:23:30 root@master1 calico]#curl 10.244.4.5
kubernetes pod-test v0.1!! ClientIP: 10.0.0.50, ServerName: pod-deployment1-85bd7684f6-p9plh, ServerIP: 10.244.4.5!
# 仅当前命名空间的所有节点可访问
[22:27:31 root@master1 calico]#cat 07-calico-networkpolicy-denyall.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: develop
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- to:
- podSelector: {}
ingress:
- from:
- podSelector: {}
[22:27:33 root@master1 calico]#kubectl apply -f 07-calico-networkpolicy-denyall.yaml
networkpolicy.networking.k8s.io/deny-all-ingress created
[22:28:03 root@master1 calico]#curl 10.244.3.4
^C
[22:28:37 root@master1 calico]#kubectl get svc -n develop
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
pod-deployment1 ClusterIP 10.101.254.69 <none> 80/TCP 16m
# 测试,在主机ping不通
[22:29:00 root@master1 calico]#curl 10.101.254.69
^C
# 在一个同命名空间可通
[22:29:28 root@master1 calico]#kubectl run pod-test --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
kubernetes pod-test v0.1!! ClientIP: 10.244.3.6, ServerName: pod-deployment1-85bd7684f6-grsw9, ServerIP: 10.244.3.4!
```
### 同ns策略
```sh
# 创建两个测试pod
[22:39:10 root@master1 ~]#cd ~
[22:39:10 root@master1 ~]#kubectl run pod-test1 --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
#
[22:39:12 root@master1 ~]#cd ~
[22:39:12 root@master1 ~]#kubectl run pod-test --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
#
[22:40:04 root@master1 calico]#kubectl get pod -n develop -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-test 1/1 Running 0 26s 10.244.4.6 node2.noisedu.cn <none> <none>
pod-test1 1/1 Running 0 21s 10.244.3.7 node1.noisedu.cn <none> <none>
# 应用策略,仅当前命名空间的所有节点可访问,并且拒绝10.244.4.6的访问
[22:41:56 root@master1 calico]#cat 08-calico-networkpolicy-denyall.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: develop
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
egress:
- to:
- podSelector: {}
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except:
- 10.244.4.6/32
- podSelector:
matchLabels:
run: pod-test1
ports:
- protocol: TCP
port: 80
# 测试应用前
[22:39:12 root@master1 ~]#kubectl run pod-test --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
kubernetes pod-test v0.1!! ClientIP: 10.244.4.6, ServerName: pod-deployment1-85bd7684f6-grsw9, ServerIP: 10.244.3.4!
#
[22:39:10 root@master1 ~]#kubectl run pod-test1 --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
kubernetes pod-test v0.1!! ClientIP: 10.244.3.7, ServerName: pod-deployment1-85bd7684f6-njn6x, ServerIP: 10.244.3.5!
#
# 应用策略
[22:41:59 root@master1 calico]#kubectl apply -f 08-calico-networkpolicy-denyall.yaml
networkpolicy.networking.k8s.io/deny-all-ingress created
# 测试应用后,pod-test1成功,pod-test失败
[22:39:10 root@master1 ~]#kubectl run pod-test1 --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
kubernetes pod-test v0.1!! ClientIP: 10.244.3.7, ServerName: pod-deployment1-85bd7684f6-njn6x, ServerIP: 10.244.3.5!
# curl 10.101.254.69
kubernetes pod-test v0.1!! ClientIP: 10.244.3.7, ServerName: pod-deployment1-85bd7684f6-p9plh, ServerIP: 10.244.4.5!
#
[22:39:12 root@master1 ~]#kubectl run pod-test --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
kubernetes pod-test v0.1!! ClientIP: 10.244.4.6, ServerName: pod-deployment1-85bd7684f6-grsw9, ServerIP: 10.244.3.4!
# curl 10.101.254.69
# 增加出栈规则,允许udp 53端口和tcp80端口
[22:45:14 root@master1 calico]#cat 09-calico-networkpolicy-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-controller
namespace: develop
spec:
podSelector:
matchLabels:
run: pod-test1
policyTypes: ["Egress"]
egress:
- to:
ports:
- protocol: UDP
port: 53
- to:
- podSelector:
matchLabels:
run: pod-test1
ports:
- protocol: TCP
port: 80
```
### 跨ns策略
```sh
# 允许不是default的ns访问,其他拒绝
[22:46:50 root@master1 calico]#cat 10-calico-networkpolicy-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ingress-controller
namespace: develop
spec:
podSelector: {}
policyTypes: ["Ingress"]
ingress:
- from:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values: [develop, kube-system, logs]
- from:
- namespaceSelector:
matchExpressions:
- {key: kubernetes.io/metadata.name, operator: NotIn, values: ["default"]}
[22:46:53 root@master1 calico]#kubectl apply -f 10-calico-networkpolicy-ingress.yaml
networkpolicy.networking.k8s.io/ingress-controller created
# 测试
[22:49:01 root@master1 ~]#kubectl run pod-test --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
kubernetes pod-test v0.1!! ClientIP: 10.244.4.7, ServerName: pod-deployment1-85bd7684f6-grsw9, ServerIP: 10.244.3.4!
#
[22:49:07 root@master1 ~]#kubectl run pod-test1 --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
^C
#
# networkpolcy
```
### NetworkPolicy
```sh
[22:51:22 root@master1 calico]#cat 11-calico-networkpolicy-global.yaml
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: namespaces-default
spec:
order: 0.0
namespaceSelector: name not in {"kube-system","kubernetes-dashboard","logs","monitoring"}
types: ["Ingress", "Egress"]
ingress:
- action: Allow
source:
namespaceSelector: name in {"kube-system","kubernetes-dashboard","logs","monitoring"}
egress:
- action: Allow
[22:51:24 root@master1 calico]#kubectl apply -f 11-calico-networkpolicy-global.yaml
globalnetworkpolicy.crd.projectcalico.org/namespaces-default created
[22:52:00 root@master1 calico]#kubectl get globalnetworkpolicies.crd.projectcalico.org
NAME AGE
namespaces-default 8s
[22:52:08 root@master1 calico]#kubectl get globalnetworkpolicy
NAME AGE
namespaces-default 17s
[22:52:17 root@master1 calico]#kubectl describe globalnetworkpolicies.crd.projectcalico.org namespaces-default
Name: namespaces-default
Namespace:
Labels: <none>
Annotations: <none>
API Version: crd.projectcalico.org/v1
Kind: GlobalNetworkPolicy
Metadata:
Creation Timestamp: 2022-01-02T14:52:00Z
Generation: 1
Managed Fields:
API Version: crd.projectcalico.org/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:egress:
f:ingress:
f:namespaceSelector:
f:order:
f:types:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2022-01-02T14:52:00Z
Resource Version: 126481
UID: 31210e0b-b665-4a82-bafb-c400d3d0b248
Spec:
Egress:
Action: Allow
Ingress:
Action: Allow
Source:
Namespace Selector: name in {"kube-system","kubernetes-dashboard","logs","monitoring"}
Namespace Selector: name not in {"kube-system","kubernetes-dashboard","logs","monitoring"}
Order: 0
Types:
Ingress
Egress
Events: <none>
# 测试,都是超时,因为是defaul的ns,这个global设置不允许default的pod访问。
[22:49:07 root@master1 ~]#kubectl run pod-test1 --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
^C
[22:49:01 root@master1 ~]#kubectl run pod-test --image=10.0.0.55:80/mykubernetes/nginx:1.21.3 -n develop --rm -it --command -- sh
If you don't see a command prompt, try pressing enter.
# curl 10.101.254.69
^C
#
```