二十二、K8s集群设置4-网络策略与校验和
一、集群环境
底层系统为ubuntu18.04,然后在每个node上安装k8s,并构建集群。Master node的IP地址为192.168.26.71/24,两个Worker node的IP地址为192.168.26.72/24、192.168.26.73/24。部署Calico网络插件,保证Node之间能够正常通信。
二、部署网络策略
Network Policy是kubernetes中的一种资源类型,可以理解为一个简单的防火墙,它从属于某个Namespace。其内容从逻辑上看包含两个关键部分,一是pod选择器,基于标签选择相同Namespace下的pod,将其中定义的规则作用于选中的pod。另一个就是规则了,就是网络流量进出pod的规则,其采用的是白名单模式,符合规则的通过,不符合规则的拒绝。
注:相对于网络策略,istio能够做到更细致的网络访问控制。
步骤1:实验环境规划
在我们集群中设置另外一个NameSpace,testns。然后在default的ns中创建2个nginx的pod,和对应的SVC。同时分别使用busybox镜像在两个NS内创建两个testpod。后续,当我们部署网络策略后,可以使用两个testpod来访问pod1和pod2,验证网络策略是否生效。
步骤2:安装metallb服务,以提供网络负载平衡器(Loadbalance)类型的SVC
官网安装步骤:https://metallb.universe.tf/installation/
首先在master上创建命名空间:
kubectl create ns metallb-system
在官网安装步奏中有最新版本的yaml文件。下载metallb.yaml文件,v0.11.0下载地址如下:
https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/metallb.yaml
修改metallb.yaml文件中两个镜像拉取的策略为IfNotPresent。然后再集群环境(所有Node)中下载需要使用的两个镜像:
root@vms71:~/route-policy# grep image metallb.yamlimage: quay.io/metallb/speaker:v0.11.0imagePullPolicy: IfNotPresentimage: quay.io/metallb/controller:v0.11.0imagePullPolicy: IfNotPresent
部署metallb:
kubectl apply -f metallb.yaml
使用如下yaml文件创建Loadbalance的地址池,下载地址:https://metallb.universe.tf/configuration/。地址池需要和自己Node在同一网段。
apiVersion: v1
kind: ConfigMap
metadata:namespace: metallb-systemname: config
data:config: |address-pools:- name: defaultprotocol: layer2addresses:- 192.168.26.240-192.168.26.250
步骤3:部署测试使用的pod和loadbalance类型的SVC
在master上创建测试使用的NameSpace:
kubectl create ns TestNs
在集群设备中下载所需的Nginx和yauritux/busybox-curl镜像:
docker pull nginxdocker pull yauritux/busybox-curl
在default namespace中创建pod1和pod2,yaml文件分别如下:
apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod1name: pod1
spec:terminationGracePeriodSeconds: 0containers:- image: nginximagePullPolicy: IfNotPresentname: pod1resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}apiVersion: v1
kind: Pod
metadata:creationTimestamp: nulllabels:run: pod2name: pod2
spec:terminationGracePeriodSeconds: 0containers:- image: nginximagePullPolicy: IfNotPresentname: pod2resources: {}dnsPolicy: ClusterFirstrestartPolicy: Always
status: {}
修改pod1主页为11111:
kubectl exec -it pod1 -- sh -c "echo 11111 > /usr/share/nginx/html/index.html"
pod2主页为22222:
kubectl exec -it pod1 -- sh -c "echo 22222 > /usr/share/nginx/html/index.html"
查看pod1和pod2是否正常运行:
root@vms71:~/route-policy# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 20m 10.244.5.205 vms72.rhce.cc <none> <none>
pod2 1/1 Running 0 20m 10.244.5.204 vms72.rhce.cc <none> <none>
创建Loadbalance类型的svc1和svc2:
kubectl expose --name=svc1 pod pod1 --port=80 --type=LoadBalancerkubectl expose --name=svc2 pod pod2 --port=80 --type=LoadBalancer
查看是否创建成功,获取到地址:
root@vms71:~/route-policy# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d
svc1 LoadBalancer 10.101.126.242 192.168.26.240 80:31482/TCP 2m34s
svc2 LoadBalancer 10.105.233.117 192.168.26.241 80:31075/TCP 2m25s
root@vms71:~/route-policy# curl 192.168.26.240
11111
root@vms71:~/route-policy# curl 192.168.26.241
22222
创建Namespac:testns:
kubectl create ns testns
分别在两个Namespace中创建2个testpod1和testpod2:
kubectl run testpod1 --image=yauritux/busybox-curl -it --rm --image-pull-policy=IfNotPresent -- sh
kubectl run testpod2 -n=testns --image=yauritux/busybox-curl -it --rm --image-pull-policy=IfNotPresent -- sh
测试目前两个testpod是否能够访问pod1和pod2:结果是都可以访问。注意,如果访问不同NameSpace中的SVC,需要在后面指明具体的NameSpace。
/home # curl svc1.default
11111
/home # curl svc2.default
22222
步骤4:创建并测试网络策略
在应用网络策略时需要注意三点:
- 应用到哪个pod上去,也就是去保护哪一个pod;
- 需要设置允许哪些客户端能访问被保护的pod;
- 设置保护的pod能够访问哪些客户端。
在官方网站上可以找到网络策略的模板:https://kubernetes.io/docs/concepts/services-networking/network-policies/。策略的模板同时激活了Ingress和Egress策略。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: test-network-policynamespace: default
spec:podSelector:matchLabels:role: dbpolicyTypes:- Ingress- Egressingress:- from:- ipBlock:cidr: 172.17.0.0/16except:- 172.17.1.0/24- namespaceSelector:matchLabels:project: myproject- podSelector:matchLabels:role: frontendports:- protocol: TCPport: 6379egress:- to:- ipBlock:cidr: 10.0.0.0/24ports:- protocol: TCPport: 5978
网络策略首先需要设定作用的Namespace:
namespace: default
其中的podSelector表示作用于namespace中的哪个pod,使用标签的方式进行匹配。如果不写的话,表示作用于namespace中的所有pods。
podSelector:matchLabels:role: db
policyType有两种,分别表示匹配入方向或者出方向的流量(以被保护的pod为基础),只有在这里激活了对应的type,后续设置的策略才会生效。
policyTypes:- Ingress- Egress
以其中演示的ingress策略为例子(允许谁能够访问被保护的pod):
ingress:- from:- ipBlock:cidr: 172.17.0.0/16except:- 172.17.1.0/24- namespaceSelector:matchLabels:project: myproject- podSelector:matchLabels:role: frontendports:- protocol: TCPport: 6379
其中有三种设置策略的方式:
- ipBlock:匹配到的IP地址可以访问,except匹配到的无法访问 ;注意, 这些应该是集群外部 IP,因为 Pod IP存在时间短暂的且随机产生。例如,所作用的源IP则可能是LoadBalancer或Pod的node等。
- podSelector:指定匹配到label的pod能够访问被保护的pod;
- namespaceSelector:指定具体命名空间内的pod能够访问被保护的pod。
注意,在 from 数组中仅包含一个元素,只允许来自标有 role=client 的 Pod 且 该 Pod 所在的NameSpace中标有 user=alice 的连接。如下:
ingress:- from:- namespaceSelector:matchLabels:user: alicepodSelector:matchLabels:role: client
在 from 数组中包含两个元素,允许来自本地NameSpace标有 role=client 的 Pod 的连接(默认为本NameSpace,也就是此策略所在的NameSpace),或 来自任何名字空间中标有 user=alice 的任何Pod的连接:
ingress:- from:- namespaceSelector:matchLabels:user: alice- podSelector:matchLabels:role: client
egress规则同理。
策略一:在pod1上启用ingress的policy,保证只有192.168.26.0/24且非192.168.26.71/32(master地址)能够访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: test-network-policynamespace: default
spec:podSelector:matchLabels:run: pod1policyTypes:- Ingressingress:- from:- ipBlock:cidr: 192.168.26.0/24except:- 192.168.26.71/32ports:- protocol: TCPport: 80
在master和worker上分别做测试:
root@vms71:~/route-policy# curl 192.168.26.240
^Z
[1]+ Stopped curl 192.168.26.240
root@vms72:~# curl 192.168.26.240
11111
测试结果可以看到,master无法访问当前的pod1。
策略二:在pod1上启用ingress的policy,保证只有当前NameSpace的pod能够访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: test-network-policynamespace: default
spec:podSelector:matchLabels:run: pod1policyTypes:- Ingressingress:- from:- namespaceSelector:matchLabels:kubernetes.io/metadata.name: default #default空间的lableports:- protocol: TCPport: 80
如果不写NameSpace的Labels的标签,表示的是任意NameSpace。分别用testpod1和testpod2进行访问。
testpod1上,可以正常访问:
/home # curl svc1
11111
testpod2上,不可以正常访问:
/home # curl svc1.default
curl: (7) Failed connect to svc1.default:80; Connection timed out
如果NameSpace写成如下的形式,则表示所有的NameSpace都可以访问
- namespaceSelector:matchLabels:
策略三:在testpod2上启用egress的policy,保证只能够访问default空间内的pod2。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: test-network-policynamespace: testns
spec:podSelector:matchLabels:run: testpod2policyTypes:- Egressegress:- to:- podSelector:matchLabels:run: pod2namespaceSelector:matchLabels:kubernetes.io/metadata.name: defaultports:- protocol: TCPport: 80- to:- namespaceSelector:matchLabels:kubernetes.io/metadata.name: kube-systemports:- protocol: UDPport: 53
注意写第二个-to策略(每个-to策略之间的关系为或)放行去往kube-system的流量DNS流量。在testpod2中,测试结果如下,说明网络策略运行正常。
/home # curl svc2.default
22222
/home # curl svc1.default
curl: (7) Failed connect to svc1.default:80; Connection timed out
策略四:如果想要保证testpod1能够访问pod1的80端口,testpod2能够访问pod1的8080端口,可以通过写两个from完成。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: test-network-policynamespace: default
spec:podSelector:matchLabels:run: pod1policyTypes:- Ingressingress:- from:- podSelector:matchLabels:run: testpod1ports:- protocol: TCPport: 80- from:- podSelector:matchLabels:run: testpod2namespaceSelector:matchLabels:kubernetes.io/metadata.name: testnsports:- protocol: TCPport: 8080
步骤5:默认策略
默认情况下,如果名字空间中不存在任何策略,则所有进出该名字空间(NameSpace)中 Pod 的流量都被允许。 以下示例使我们可以更改该名字空间中的默认行为。(注意仅作用于策略所在的NameSpace)
1.默认拒绝所有入站流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: default-deny-ingress
spec:podSelector: {}policyTypes:- Ingress
这样可以确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离。 此策略不会更改默认的出口隔离行为。
2.默认允许所有入站流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-all-ingress
spec:podSelector: {}ingress:- {}policyTypes:- Ingress
如果要允许所有流量进入某个名字空间中的所有 Pod(即使添加了导致某些 Pod 被视为 “隔离”的策略),则可以创建一个策略来明确允许该名字空间中的所有流量。
3.默认拒绝所有出站流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: default-deny-egress
spec:podSelector: {}policyTypes:- Egress
此策略可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许流出流量。 此策略不会更改默认的入站流量隔离行为。
4.默认允许所有出站流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: allow-all-egress
spec:podSelector: {}egress:- {}policyTypes:- Egress
如果要允许来自名字空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策略), 则可以创建一个策略,该策略明确允许该名字空间中的所有出站流量。
5.默认拒绝所有入口和所有出站流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: default-deny-all
spec:podSelector: {}policyTypes:- Ingress- Egress
我们以通过在该名字空间中创建以下 NetworkPolicy 来阻止所有入站和出站流量。此策略可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许入站或出站流量。
三、校验和
为了保证k8s中流量传输过程中没有被更改或者出现传输错误,我们可以使用校验和来检查。
一般来说,当我们下载文件时,在下载页面都附有对应正确的校验和值和所使用的HASH函数。我们当下载完成后,我们可以在Linux系统上重新计算校验和来对比是否有修改。
例如,我们可以使用Linux自带的MD5或者SHA校验软件来校验:
root@vms71:~/route-policy# md5sum metallb.yaml
6313083a000cfeae5403b8bcf96cc7f5 metallb.yaml
root@vms71:~/route-policy# sha512sum metallb.yaml
6ebc53703d23841fe805f2d329da95bc3a4af442eed3823f70c0a6ba9d298e85f8c3f25f0cdea2057d819d7737834a369f4267c597a834913b9c4f91a108b5ff metallb.yaml
如果和官网显示的校验值不同,则删除掉内容被修改或传输出错的文件。
整理资料来源:
《老段CKS课程》
K8s官网资料:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
二十二、K8s集群设置4-网络策略与校验和相关推荐
- 从零开始搭建K8S集群(二)-- 搭建K8S集群
一.下面我们开始搭建K8S集群 配置K8S的yum源(自v1.6.0起,Kubernetes默认启用了CRI,Container Runtime Interface,详情请查看官网:https://k ...
- K8s基础12——etcd数据备份与恢复、集群版本升级、网络策略
文章目录 一.etcd备份与恢复 1.1 kubeadm部署方式 1.1.1 备份 1.1.2 恢复 1.2 单etcd二进制部署方式 1.2.1 部署 1.2.2 备份 1.2.3 恢复 1.2.4 ...
- 总结 Underlay 和 Overlay 网络,在k8s集群实现underlay网络,网络组件flannel vxlan/ calico IPIP模式的网络通信流程,基于二进制实现高可用的K8S集群
1.总结Underlay和Overlay网络的的区别及优缺点 Overlay网络: Overlay 叫叠加网络也叫覆盖网络,指的是在物理网络的 基础之上叠加实现新的虚拟网络,即可使网络的中的容器可 ...
- 支撑 100Gbit/s K8s 集群的未来网络数据平面
总体原则:高度可扩展,极致性能. Cilium 数据平面的核心功能 Cilium + BIG TCP BIG TCP 设计目标 支持数据中心内的单个 socket 达到 100Gbps+ 带宽. 使用 ...
- 使用kubeadm安装k8s集群的完整步骤(k8sv15.1)
一.创建虚拟机 首先使用vmware15 pro创建了4台centos7虚拟机,其中,3台用来组建k8s集群,1台为master节点,2台为node节点, 剩下的一台用来安装harbor配置私有仓库( ...
- 搭建 K8S 环境:Centos7安装生产环境可用的K8S集群图文教程指南
搭建 K8S 环境:Centos7安装生产环境可用的K8S集群图文教程指南 一. K8S 简介 二. K8S 学习的几大拦路虎 2.1 K8S 安装对硬件要求比较高 2.2. K8S 对使用者来说要求 ...
- 从零开始在ubuntu上安装和使用k8s集群及报错解决
文章目录 安装docker 安装kubernetes 配置k8s集群 配置虚拟机网络 配置Master节点的k8s网络 拉取k8s需要的镜像 启动 kubeadm 和 kubelet 配置 node节 ...
- 使用Kubeadm创建k8s集群之节点部署(三十二)
前言 由于上次忘开申明原创,特再发一次. 本篇部署教程将讲述k8s集群的节点(master和工作节点)部署,请先按照上一篇教程完成节点的准备.本篇教程中的操作全部使用脚本完成,并且对于某些情况(比如镜 ...
- 纯手工搭建k8s集群-(二)核心模块部署
1. 部署ETCD(主节点) 1.1 简介 kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运行的pod,deployment,service等等.都需 ...
- 云原生(二十七) | Kubernetes篇之自建高可用k8s集群前置概念与操作
文章目录 自建高可用k8s集群前置概念与操作 一.内核升级 二.k8s集群架构
最新文章
- 酸爽! Intellij IDEA 神器居然还藏着这些实用小技巧 !
- linux7安装haproxy,Centos7 源码编译安装haproxy
- 8.正交匹配跟踪 Orthogonal Matching Pursuit (OMP)s
- 互联网时代IT系统的变革-硬件系统定制化发展
- 数据结构-判断一棵树是否为二叉排序树
- 导入mysql source_mysql导入source数据库
- java xml文件无法打开,java – 无法打开beans.xml(配置文件)因为不存在
- c语言如何写地图,自己用C语言写的扫雷地图
- javaweb课程PSP(1)
- 【Maven】1.使用myecplise配置自己的Maven配置,不使用默认的maven
- 译:在C#中使用LINQ To SQL
- SQLSERVER Tempdb的作用及优化
- html5rpg游戏策划案,HTML 5开发RPG游戏之一(地图人物实现)
- 我的系統中存在的问题
- ES6新特性箭头函数语法、如何正确使用箭头函数
- python接私活王者_Python从青铜到王者这5个实战项目要会
- 注册表的使用-入门篇
- bash文件无法运行,提示没有那个文件或目录的解决方法
- Android Jason数据解析及显示
- Keras : 训练heart心脏病诊断训练集并测试