kube-ovn 从名字不难看出其是一款云原生的网络产品,将 SDN 等能力带入云原生畛域。让 ovn/ovs 的应用更容易,屏蔽了复杂度,升高了应用的难度,并与云原生进行了联合。
借助 OVS/OVN 在 SDN 畛域成熟的能力,Kube-OVN 将网络虚拟化的丰盛性能带入云原生畛域。目前已反对子网治理,动态 IP 调配,分布式 / 集中式网关,Underlay/Overlay 混合网络,VPC 多租户网络,跨集群互联网络,QoS 治理,多网卡治理,ACL 网络管制,流量镜像,ARM 反对,Windows 反对等诸多性能。
装置 k3s
参考官网的筹备工作文档,操作系统应用 Ubuntu 20.04 以及 k3s v1.23.8+k3s2。
在装置之前确保 /etc/cni/net.d/
目录内容为空,不为空则清空其下的所有文件。kube-ovn 自身通过实现 cni 来管理网络。
在装置 k3s 须要禁用 k3s 默认的网络策略控制器和 flannel 的后端(默认是 VXLAN):
export INSTALL_K3S_VERSION=v1.23.8+k3s1
curl -sfL https://get.k3s.io | sh -s - --flannel-backend=none --disable-network-policy --disable=traefik --write-kubeconfig-mode 644 --write-kubeconfig ~/.kube/config
为了节俭资源,我也禁用了 traefik Ingress 控制器。
此时查看 pod 会发现都处于 Pending 状态,这是因为还没装置 CNI。
kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system local-path-provisioner-6c79684f77-llvhk 0/1 Pending 0 11s
kube-system metrics-server-7cd5fcb6b7-kxm5j 0/1 Pending 0 11s
kube-system coredns-d76bd69b-jd6gm 0/1 Pending 0 11s
查看 node 提醒 container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized
。
接下来就是装置 kube-ovn 了。
装置 kube-ovn
kube-ovn 的装置应用官网提供一键装置脚本:
wget https://raw.githubusercontent.com/kubeovn/kube-ovn/release-1.10/dist/images/install.sh
查看脚本中的配置:
REGISTRY="kubeovn" # 镜像仓库地址
VERSION="v1.10.6" # 镜像版本 /Tag
POD_CIDR="10.16.0.0/16" # 默认子网 CIDR 不要和 SVC/NODE/JOIN CIDR 重叠
SVC_CIDR="10.96.0.0/12" # 须要和 apiserver 的 service-cluster-ip-range 保持一致
JOIN_CIDR="100.64.0.0/16" # Pod 和主机通信网络 CIDR,不要和 SVC/NODE/POD CIDR 重叠
LABEL="node-role.kubernetes.io/master" # 部署 OVN DB 节点的标签
IFACE="" # 容器网络所应用的的宿主机网卡名,如果为空则应用 Kubernetes 中的 Node IP 所在网卡
TUNNEL_TYPE="geneve" # 隧道封装协定,可选 geneve, vxlan 或 stt,stt 须要独自编译 ovs 内核模块
k3s 的默认 POD 和 SVC CIDR 别离是:10.42.0.0/16
和 10.43.0.0/16
,能够在装置时通过参数 --cluster-cidr
和 --service-cidr
别离进行设置。下面,装置 k3s 时应用了的默认配置,因而 须要批改 install.sh
中的配置。
POD_CIDR="10.42.0.0/16"
POD_GATEWAY="10.42.0.1"
SVC_CIDR="10.43.0.0/12"
批改之后,运行脚本装置:
bash install.sh
确认所有 pod 启动并运行:
kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system ovs-ovn-trqk5 1/1 Running 0 2m37s
kube-system kube-ovn-monitor-5f8f5dbfc-plfrq 1/1 Running 0 108s
kube-system kube-ovn-controller-67bbd54575-2n87d 1/1 Running 0 108s
kube-system ovn-central-644fbb8467-xtrjc 1/1 Running 0 2m37s
kube-system kube-ovn-cni-glcfw 1/1 Running 0 108s
kube-system kube-ovn-pinger-2k72d 1/1 Running 0 71s
kube-system local-path-provisioner-6c79684f77-jh2zh 1/1 Running 0 71s
kube-system coredns-d76bd69b-w28rg 1/1 Running 0 37s
kube-system metrics-server-7cd5fcb6b7-8jgdm 1/1 Running 0 36s
查看 kube-system
下的 DaemonSet 类型利用,运行在各个 node 上负责 ovs/ovn、CNI 和网络查看 ping。
kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
ovs-ovn 1 1 1 1 1 kubernetes.io/os=linux 3m14s
kube-ovn-cni 1 1 1 1 1 kubernetes.io/os=linux 2m25s
kube-ovn-pinger 1 1 1 1 1 kubernetes.io/os=linux 2m25s
至此 kube-ovn 就装置实现了,上面简略体验下 kube-ovn 的性能。
体验
子网
后面介绍 kube-ovn 装置时提到了子网,子网 是 kube-ovn 的外围概念。
Kube-OVN 会以子网来组织 IP 和网络配置,每个 Namespace 能够归属于特定的子网,Namespace 下的 Pod 会主动从所属的子网中获取 IP 并共享子网的网络配置(CIDR,网关类型,访问控制,NAT 管制等)。
咱们部署一个 pod,能够看到 k3s 从 kube-ovn 的默认子网中调配 IP 地址。所有没有设置子网的 namespace 的 pod IP 地址都位于该网段。
kubectl run pipy --image flomesh/pipy:latest -n default
kubectl get po -o wide -n default
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pipy 1/1 Running 0 41s 10.42.0.10 ubuntu-dev1 <none> <none>
咱们手动创立一个 namespace 和新的子网:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
name: another
---
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
name: another-subnet
spec:
protocol: IPv4
cidrBlock: 10.66.0.0/16
excludeIps:
- 10.66.0.1
gateway: 10.66.0.1
gatewayType: distributed
natOutgoing: true
namespaces:
- another
EOF
接下来验证一下,在 another
namespace 下创立新的 pod:
kubectl run curl --image rancher/curl --command sleep 1d -n another
kubectl get po -o wide -n another
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
curl 1/1 Running 0 14s 10.66.0.11 ubuntu-dev1 <none> <none>
能够看到 pod curl
从新的子网中获取了 IP 地址,试着拜访之前创立的 pod:
kubectl exec -it curl -n another -- curl -i 10.42.0.10:8080
HTTP/1.1 200 OK
content-length: 11
connection: keep-alive
Hi, there!
不同的子网有什么用呢?试想这样的场景,有两个 namespace another
和 default
。要禁止 annother
中的 pod 对 default
中 pod 的拜访,第一工夫想到的是 Kubernetes 的 Network Policy,或者借助其余的利用,比方之前介绍的 应用 Cilium 加强 Kubernetes 网络安全(也是网络内核层的实现),或者服务网格的访问控制。
但当初既然用 kube-ovn,能够应用 ovn 的 ACL 规定。
子网 ACL
接下来,更新默认子网的设置,增加 ACL 规定:
kubectl apply -f - <<EOF
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
name: ovn-default
spec:
cidrBlock: 10.42.0.0/16
default: true
excludeIps:
- 10.42.0.1
gateway: 10.42.0.1
gatewayType: distributed
natOutgoing: true
protocol: IPv4
provider: ovn
vpc: ovn-cluster
acls:
- action: drop
direction: from-lport
match: ip4.src == 10.66.0.0/16 && ip
priority: 1002
EOF
这段 ACL 规定示意:抛弃(action: drop
)来自(direction: from-lport
)10.66.0.0/16
网段(match: ip4.src == 10.66.0.0/16 && ip
)的包,更多规定阐明参考 ACL 规定文档。
此时再次拜访,然而这回加上连贯超时,因为不想等太久:
kubectl exec -it curl -n another -- curl -i --connect-timeout 5 10.42.0.10:8080
curl: (28) Connection timed out after 5000 milliseconds
command terminated with exit code 28
another
namespace 下的 pod 无法访问到 default
下的 pod,合乎预期。
总结
这篇仅仅展现了 kube-ovn 很根底的性能,基于 ovs/ovn 的弱小能力,kube-ovn 还提供了其余更弱小的性能,有趣味的同学能够去参考官网的使用指南。
貌似应该要好好看看 ovs/ovn 了。
关注 ” 云原生指北 ” 微信公众号
(转载本站文章请注明作者和出处盛世浮生,请勿用于任何商业用途)