使用flannel+canal实现k8s的NetworkPolicy
1、NetworkPolicy概述
官方说明:网络策略(NetworkPolicy)是一种关于pod
间及pod
与其他网络端点间所允许的通信规则的规范。
简单来说,NetworkPolicy
就是对pod
进行网络策略控制。用于为Kubernetes
实现更为精细的流量控制,实现租户隔离机制。Kubernetes
使用标准的资源对象NetworkPolicy
供管理员按需定义网络访问控制策略。
2、NetworkPolicy策略模型
使用network policy
资源可以配置pod
的网络,networkPolicy
是namespace scoped
的,他只能影响某个namespace
下的pod
的网络出入站规则。
metadata
描述信息。podSelector
pod选择器,选定的pod
所有的出入站流量要遵循本networkpolicy
的约束。policyTypes
策略类型。包括了Ingress
和Egress
,默认情况下一个policyTypes
的值一定会包含Ingress
,当有egress
规则时,policyTypes
的值中会包含Egress
。ingress
入站,即由其他网络端点发往特定Pod
组的流量 ,通常由流量发出的源站点from
和流量的目标端口所定义 。egress
出站,即由特定的Pod
组发往其他网络端点的流量 ,通常由流量的目标网络端点to
和端口ports
来进行定义 。port
端口,TCP
或UDP
的端口号。to,from
端点,流量目标和流量源相关的组件, 它可以是CIDR
格式的IP
地址块ipBlock
、网络名称空间选择器namespaceSelector
匹配的名称空间, 或Pod
选择器podSelector
匹配的Pod
组。
对官方示例的说明:
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
该例子的效果如下:
1、default namespace
下label
包含role=db
的pod
,都会被隔绝,他们只能建立满足networkPolicy
的ingress
和egress
描述的连接。即2-5点:
2、所有属于172.17.0.0/16
网段的ip,除了172.17.1.0/24
中的ip,其他的都可以与上述pod
的6379
端口建立tcp
连接。
3、所有包含label:project=myproject
的namespace
中的pod
可以与上述pod
的6379
端口建立tcp
连接;
4、所有default namespace
下的label
包含role=frontend
的pod
可以与上述pod
的6379
端口建立tcp
连接;
5、允许上述pod
访问网段为10.0.0.0/24
的目的ip
的5978
端口。
3、NetworkPolicy默认策略
默认情况下,如果名称空间中不存在任何策略,则所有进出该名称空间中的Pod的流量都被允许。以下示例用于更改该名称空间中的默认行为。
- 默认拒绝所有入口流量
通过创建选择所有容器但不允许任何进入这些容器的入口流量的NetworkPolicy
来为名称空间创建default
隔离策略。这样可以确保即使容器没有选择其他任何NetworkPolicy
,也仍然可以被隔离。此策略不会更改默认的出口隔离行为。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- 默认允许所有入口流量
如果要允许所有流量进入某个命名空间中的所有Pod
(即使添加了导致某些Pod
被视为“隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
- 默认拒绝所有出口流量
通过创建选择所有容器但不允许来自这些容器的任何出口流量的NetworkPolicy
来为名称空间创建default egress
隔离策略。这样可以确保即使没有被其他任何NetworkPolicy
选择的Pod
也不会被允许流出流量。此策略不会更改默认的ingress
隔离行为。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Egress
- 默认允许所有出口流量
如果要允许来自命名空间中所有Pod
的所有流量(即使添加了导致某些Pod
被视为“隔离”的策略),则可以创建一个策略,该策略明确允许该命名空间中的所有出口流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
- 默认拒绝所有入口和所有出口流量
为名称空间创建default
策略,以通过在该名称空间中创建以下NetworkPolicy
来阻止所有入站和出站流量。这样可以确保即使没有被其他任何NetworkPolicy
选择的Pod
也不会被允许进入或流出流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
4、NetworkPolicy的实现
kubernetes
的网络策略功能本身并不支持,依赖其所使用的网络插件实现。因此,仅在使用那些支持网络策略功能的网络插件时才能够配置网络策略,企业内部可以使用简单的flannel
、weave
、kube-router
等,适合公有云的方案则有calico
等。不同的网络实现原理vethpair
、bridge
、macvlan
等并不能统一地支持network policy
。每种解决方案各有其特定的网络策略实现方式,它们的实现或依赖于节点自身的功能,或借助于Hypervisor
的特性,也可能是网络自身的功能 。究其最终的底层实现原理,目前是基于linux iptables
实现,使用类似于nf_conntrack
检查记录网络流量session
从而决定流量是否阻断。
5、使用flannel+canal实现k8s的NetworkPolicy
Flannel
是解决容器网络方案最为普遍和简单的方案,Canal
代表了针对云原生应用程序的最佳网络策略解决方案,旨在让用户轻松的将Calico
和Flannel
网络部署在一起作为统一的网络解决方案,将Calico
的网络策略执行和Flannel
的叠加及非叠加网络连接选项的丰富功能相结合。
在Calico
的官方文档的相应部分中描述到此种方案是:用于策略的Calico
和用于网络的Flannel
相组合。官方文档见:https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/flannel
5.1、实验环境说明
实验k8s环境是kubeadm
搭建的1master+2node最新版本1.16.2版本k8s,cni
版本为0.3.1,flannel
版本为0.11.0,flannel
后端是vxlan
模式并且已经开启了Directrouting
。
[root@k8s-master-01 ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}
[root@k8s-master-01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready master 4d1h v1.16.2
k8s-node-01 Ready <none> 4d v1.16.2
k8s-node-02 Ready <none> 4d v1.16.2
[root@k8s-master-01 ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-58cc8c89f4-bd6s8 1/1 Running 2 4d1h
coredns-58cc8c89f4-bv5rl 1/1 Running 2 4d1h
etcd-k8s-master-01 1/1 Running 2 4d1h
kube-apiserver-k8s-master-01 1/1 Running 2 4d1h
kube-controller-manager-k8s-master-01 1/1 Running 2 4d1h
kube-flannel-ds-amd64-grzvh 1/1 Running 1 2d22h
kube-flannel-ds-amd64-hrd4h 1/1 Running 1 2d22h
kube-flannel-ds-amd64-l8rtk 1/1 Running 1 2d22h
kube-proxy-bp98z 1/1 Running 2 4d
kube-proxy-kvwgh 1/1 Running 2 4d
kube-proxy-n8lj6 1/1 Running 2 4d1h
kube-scheduler-k8s-master-01 1/1 Running 2 4d1h
5.2、安装canal
按照官方文档说明安装:https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/flannel
部署时canal支持将数据存储于etcd中,支持选择专用的etcd存储,也能够以kubernetes api server作为后端存储,这里选择以后种方式进行。
结合flannel
工作时,Calico
提供的默认配置清单中是以flannel
默认使用的10.244.0.0/16
为Pod
网络,因此,请确保kube-controller-manager
程序在启动时通过--clustr-cidr
选项设置使用了此网络地址,并且--allocate-node-cidrs
的值应设置为true
。在使用kubeadm
安装的此版本集群中,此选项均已配置。
如果集群cidr网络地址不是默认值,需要修改配置再进行部署。
[root@k8s-master-01 canal]# curl https://docs.projectcalico.org/v3.10/manifests/canal.yaml -O
[root@k8s-master-01 canal]# kubectl apply -f canal.yaml
configmap/canal-config created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrole.rbac.authorization.k8s.io/flannel configured
clusterrolebinding.rbac.authorization.k8s.io/canal-flannel created
clusterrolebinding.rbac.authorization.k8s.io/canal-calico created
daemonset.apps/canal created
serviceaccount/canal created
[root@k8s-master-01 ~]# kubectl get pods -n kube-system -o wide|grep canal
canal-rxb97 2/2 Running 0 4h25m 192.168.2.12 k8s-node-02 <none> <none>
canal-tdcgf 2/2 Running 0 4h25m 192.168.2.10 k8s-master-01 <none> <none>
canal-vll8z 2/2 Running 0 4h25m 192.168.2.11 k8s-node-01 <none> <none>
5.3、应用示例
5.3.1、创建默认服务
运行一组nginx
pod并暴露80端口
[root@k8s-master-01 ~]# kubectl run nginx --image=nginx --replicas=3 --port=80 --expose
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
service/nginx created
deployment.apps/nginx created
[root@k8s-master-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5578584966-8spqk 1/1 Running 0 15s
nginx-5578584966-sjlvc 1/1 Running 0 15s
nginx-5578584966-xm4pb 1/1 Running 0 15s
[root@k8s-master-01 ~]# kubectl get svc nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.1.8.146 <none> 80/TCP 16s
5.3.2、测试访问
[root@k8s-master-01 ~]# kubectl run busy1 --rm -it --image=busybox /bin/sh
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.1.8.146:80)
remote file exists ## 访问成功
5.3.4、创建默认policy
创建默认拒绝所有入站流量的networkpolicy,测试访问
[root@k8s-master-01 networkpolicy]# vim default-deny-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
[root@k8s-master-01 networkpolicy]# kubectl apply -f default-deny-ingress.yaml
networkpolicy.networking.k8s.io/default-deny created
[root@k8s-master-01 ~]# kubectl run busy1 --rm -it --image=busybox /bin/sh
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.1.8.146:80)
wget: download timed out ## 访问失败
5.3.5、创建一个允许带有access=true的Pod访问nginx的网络策略
[root@k8s-master-01 networkpolicy]# vim nginx-policy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
run: nginx
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
[root@k8s-master-01 networkpolicy]# kubectl apply -f nginx-policy.yaml
networkpolicy.networking.k8s.io/access-nginx created
使用不带access=true标签的pod访问服务
[root@k8s-master-01 ~]# kubectl run busy1 --rm -it --image=busybox /bin/sh
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.1.8.146:80)
wget: download timed out ## 访问失败
使用带access=true标签的pod访问服务
[root@k8s-master-01 ~]# kubectl run busy2 --rm -it --labels="access=true" --image=busybox /bin/sh
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
/ # wget --spider --timeout=1 nginx
Connecting to nginx (10.1.8.146:80)
remote file exists ## 访问成功
5.4、生产使用场景
5.4.1、禁止访问指定服务
kubectl run web --image=nginx --labels app=web,env=prod --expose --port 80
网络策略
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-deny-all
spec:
podSelector:
matchLabels:
app: web
env: prod
5.4.2、只允许指定pod访问服务
kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
网络策略
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: api-allow
spec:
podSelector:
matchLabels:
app: bookstore
role: api
ingress:
- from:
- podSelector:
matchLabels:
app: bookstore
5.4.3、禁止 namespace 中所有 Pod 之间的相互访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: default
spec:
podSelector: {}
5.4.4、禁止其他 namespace 访问服务
kubectl create namespace secondary
kubectl run web --namespace secondary --image=nginx \
--labels=app=web --expose --port 80
网络策略
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: secondary
name: web-deny-other-namespaces
spec:
podSelector:
matchLabels:
ingress:
- from:
- podSelector: {}
5.4.5、只允许指定namespace访问服务
kubectl run web --image=nginx \
--labels=app=web --expose --port 80
网络策略
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-prod
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: production
5.4.6、允许外网访问服务
kubectl run web --image=nginx --labels=app=web --port 80
kubectl expose deployment/web --type=LoadBalancer
网络策略
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-external
spec:
podSelector:
matchLabels:
app: web
ingress:
- ports:
- port: 80
from: []
参考来源:
https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/flannel
https://github.com/ahmetb/kubernetes-network-policy-recipes
使用flannel+canal实现k8s的NetworkPolicy的更多相关文章
- 容器编排系统K8s之NetworkPolicy资源
前文我们了解了k8s的网络插件flannel的基础工作逻辑,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14225657.html:今天我们来聊一下k8s上 ...
- etcd,flannel,docker relationship---and k8s
journalctl -xe voidcn.com/article/p-qufvdmpq-bqn.html etcd more etcd.confETCD_NAME=default ETCD_DATA ...
- K8s二进制部署单节点 etcd集群,flannel网络配置 ——锥刺股
K8s 二进制部署单节点 master --锥刺股 k8s集群搭建: etcd集群 flannel网络插件 搭建master组件 搭建node组件 1.部署etcd集群 2.Flannel 网络 ...
- Kubernetes(k8s)底层网络原理刨析
目录 1 典型的数据传输流程图 2 3种ip说明 3 Docker0网桥和flannel网络方案 4 Service和DNS 4.1 service 4.2 DNS 5 外部访问集群 5.1 外部访问 ...
- flannel vxlan 实现原理【转】
flannel是coreos为kubernets提供的网络解决方案,主要为打通跨节点的容器通信,其中vxlan模式为flannel实现的一种后端模式,其他模式还包括udp, host-gw等,可以通过 ...
- kubernetes 配置网络插件 flannel
概述 在学习docker时知道docker有四种常用的网络模型 bridge:桥接式网络 joined:联盟式网络,共享使用另外一个容器的网络名称空间 opened:容器直接共享使用宿主机的网络名称空 ...
- Kubernetes 学习18配置网络插件flannel
一.概述 1.我们在学习docker时知道docker有四种常用的网络模型 a.bridge:桥接式网络 b.joined:联盟式网络,共享使用另外一个容器的网络名称空间 b.opened:容器直接共 ...
- k8s 网络模型解析之原理
今天研究了一下k8s的网络模型,该解析基于flannel vxlan+ kubeproxy iptables 模式. 一.Docker 首先分析一下Docker层面的网络模型,我们知道容器是基于内核的 ...
- K8s 实践 | 如何解决多租户集群的安全隔离问题?
作者 | 匡大虎 阿里巴巴技术专家 导读:如何解决多租户集群的安全隔离问题是企业上云的一个关键问题,本文主要介绍 Kubernetes 多租户集群的基本概念和常见应用形态,以及在企业内部共享集群的业 ...
随机推荐
- (转载)理解Spatial Transformer Networks
理解Spatial Transformer Networks 转载于:知乎-SIGAI 书的购买链接 书的勘误,优化,源代码资源 获取全文PDF请查看:理解Spatial Transformer Ne ...
- xcode简单教程
1.使用Xcode软件.Xcode是一个苹果系统上的集成开发环境(IDE),就是说用Xcode就能编写C语言程序,并编译运行.也能开发ios程序等,是一种软件.在windows上类似这种能编c语言的还 ...
- Java调用动态链接库so文件(传参以及处理返回值问题)
刚来到公司,屁股还没坐稳,老板把我叫到办公室,就让我做一个小程序.我瞬间懵逼了.对小程序一窍不通,还好通过学习小程序视频,两天的时间就做了一个云开发的小程序,但是领导不想核心的代码被别人看到,给了我一 ...
- pat 1100
1100 Mars Numbers (20 分) People on Mars count their numbers with base 13: Zero on Earth is called ...
- sql语句修改数据库字段的长度
修改字段的长度 alter table [OtpimizeRoute_Test].[dbo].[T_QueueFile] alter column ListFileName nvarchar()
- Django-06-模板(Template)
一.模板组成 HTML代码+逻辑控制代码 二.逻辑控制代码 1. 变量 语法格式: {{var_name}} Template和Context对象 D:\python\Project\django_t ...
- 【LEETCODE】60、数组分类,适中级别,题目:75、560、105
package y2019.Algorithm.array.medium; /** * @ProjectName: cutter-point * @Package: y2019.Algorithm.a ...
- 开启Telnet服务
在Win7系统中安装和启动Telnet服务非常简单:依次点击“开始”→“控制面板”→“程序”,“在程序和功能”找到并点击“打开或关闭Windows功能”进入Windows 功能设置对话框.找到并勾选“ ...
- Golang_小程序学golang
1 前置条件 Golang基本情况自行baidu/google 1.1 环境与工具 IDE:liteide (windows ).mingw-w64 (gcc) DB:SQL Server 2008 ...
- spring boot 分布式锁组件 spring-boot-klock-starter
基于redis的分布式锁spring-boot starter组件,使得项目拥有分布式锁能力变得异常简单,支持spring boot,和spirng mvc等spring相关项目 快速开始 sprin ...