一、集群环境


底层系统为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:创建并测试网络策略

在应用网络策略时需要注意三点:

  1. 应用到哪个pod上去,也就是去保护哪一个pod;
  2. 需要设置允许哪些客户端能访问被保护的pod;
  3. 设置保护的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

其中有三种设置策略的方式:

  1. ipBlock:匹配到的IP地址可以访问,except匹配到的无法访问 ;注意, 这些应该是集群外部 IP,因为 Pod IP存在时间短暂的且随机产生。例如,所作用的源IP则可能是LoadBalancer或Pod的node等。
  2. podSelector:指定匹配到label的pod能够访问被保护的pod;
  3. 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-网络策略与校验和相关推荐

  1. 从零开始搭建K8S集群(二)-- 搭建K8S集群

    一.下面我们开始搭建K8S集群 配置K8S的yum源(自v1.6.0起,Kubernetes默认启用了CRI,Container Runtime Interface,详情请查看官网:https://k ...

  2. 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 ...

  3. 总结 Underlay 和 Overlay 网络,在k8s集群实现underlay网络,网络组件flannel vxlan/ calico IPIP模式的网络通信流程,基于二进制实现高可用的K8S集群

    1.总结Underlay和Overlay网络的的区别及优缺点 Overlay网络:  Overlay 叫叠加网络也叫覆盖网络,指的是在物理网络的 基础之上叠加实现新的虚拟网络,即可使网络的中的容器可 ...

  4. 支撑 100Gbit/s K8s 集群的未来网络数据平面

    总体原则:高度可扩展,极致性能. Cilium 数据平面的核心功能 Cilium + BIG TCP BIG TCP 设计目标 支持数据中心内的单个 socket 达到 100Gbps+ 带宽. 使用 ...

  5. 使用kubeadm安装k8s集群的完整步骤(k8sv15.1)

    一.创建虚拟机 首先使用vmware15 pro创建了4台centos7虚拟机,其中,3台用来组建k8s集群,1台为master节点,2台为node节点, 剩下的一台用来安装harbor配置私有仓库( ...

  6. 搭建 K8S 环境:Centos7安装生产环境可用的K8S集群图文教程指南

    搭建 K8S 环境:Centos7安装生产环境可用的K8S集群图文教程指南 一. K8S 简介 二. K8S 学习的几大拦路虎 2.1 K8S 安装对硬件要求比较高 2.2. K8S 对使用者来说要求 ...

  7. 从零开始在ubuntu上安装和使用k8s集群及报错解决

    文章目录 安装docker 安装kubernetes 配置k8s集群 配置虚拟机网络 配置Master节点的k8s网络 拉取k8s需要的镜像 启动 kubeadm 和 kubelet 配置 node节 ...

  8. 使用Kubeadm创建k8s集群之节点部署(三十二)

    前言 由于上次忘开申明原创,特再发一次. 本篇部署教程将讲述k8s集群的节点(master和工作节点)部署,请先按照上一篇教程完成节点的准备.本篇教程中的操作全部使用脚本完成,并且对于某些情况(比如镜 ...

  9. 纯手工搭建k8s集群-(二)核心模块部署

    1. 部署ETCD(主节点) 1.1 简介 kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运行的pod,deployment,service等等.都需 ...

  10. 云原生(二十七) | Kubernetes篇之自建高可用k8s集群前置概念与操作

    文章目录 自建高可用k8s集群前置概念与操作 一.内核升级 二.k8s集群架构

最新文章

  1. 酸爽! Intellij IDEA 神器居然还藏着这些实用小技巧 !
  2. linux7安装haproxy,Centos7 源码编译安装haproxy
  3. 8.正交匹配跟踪 Orthogonal Matching Pursuit (OMP)s
  4. 互联网时代IT系统的变革-硬件系统定制化发展
  5. 数据结构-判断一棵树是否为二叉排序树
  6. 导入mysql source_mysql导入source数据库
  7. java xml文件无法打开,java – 无法打开beans.xml(配置文件)因为不存在
  8. c语言如何写地图,自己用C语言写的扫雷地图
  9. javaweb课程PSP(1)
  10. 【Maven】1.使用myecplise配置自己的Maven配置,不使用默认的maven
  11. 译:在C#中使用LINQ To SQL
  12. SQLSERVER Tempdb的作用及优化
  13. html5rpg游戏策划案,HTML 5开发RPG游戏之一(地图人物实现)
  14. 我的系統中存在的问题
  15. ES6新特性箭头函数语法、如何正确使用箭头函数
  16. python接私活王者_Python从青铜到王者这5个实战项目要会
  17. 注册表的使用-入门篇
  18. bash文件无法运行,提示没有那个文件或目录的解决方法
  19. Android Jason数据解析及显示
  20. Keras : 训练heart心脏病诊断训练集并测试

热门文章

  1. 详解中文维基百科数据处理流程及脚本代码
  2. 笔记-Attention机制
  3. NLP—4.如何阅读paper
  4. 排序算法之——选择排序分析
  5. 每周荐书:Swift、Java、React(评论送书)
  6. 快速了解Druid——实时大数据分析软件
  7. 万里航行总舵手——业务测试架构的设计
  8. 随机过程:鞅与马尔科夫过程的理解
  9. python 动态语言 优美_Python动态语言之魅力大揭秘
  10. mysql连接字符串 .net_.net MYSQL连接字符串参数详细解析