导航:首页 > 网络设置 > pod网络策略怎么设置

pod网络策略怎么设置

发布时间:2023-03-18 03:52:35

A. 二十五 网络策略

网络策略(NetworkPolicy)是一种关于pod间及pod与其他网络端点间所允许的通信规则的规范。NetworkPolicy 资源使用标如知签选择pod,并定义选定pod所允许的通信规则。

前提
网络策略通过网络插件来实现,所以用户必须使用支持 NetworkPolicy 的网络解决方案 - 简单地创建资源对象,而没有控制器来使它生效的话,是没有任何作用的。

网络插件:

https://kubernetes.io/docs/concepts/services-networking/network-policies/
默认情况下,Pod是非隔离的,它们接受任何来源的流量。Pod可以通过相关的网络策略进行隔离。一旦命名空间中 NetworkPolicy 配置选择了特定的Pod,该Pod会拒绝网络策略所不允许的连接。 (命名空间下其他未被网络策略所选择的Pod会继续接收所有的流量)

必填字段: 与所有其他的Kubernetes配置一样,NetworkPolicy 需要 apiVersion、 kind和 metadata 。

spec: NetworkPolicy spec 中包含了在一个命名空间中定义特定网络策略所需的所有信息.

podSelector: 每个 NetworkPolicy 都包括一个 podSelector ,它对该策略所应用的一组Pod进行选择。因为 NetworkPolicy 目前只支持定义 ingress 规则,这里的 podSelector 本质上是为该策略定义 "目标pod" 。示例中的策略选择带有 "role=db" 标签的pod。空的 podSelector 选择命名空间下的所有pod。

policyTypes: 每个 NetworkPolicy 都包含一个 policyTypes 列表,其中包含 Ingress 或 Egress 或两者兼具。policyTypes 字段表示给定的策略是应用于 进入所选 Pod 的入站流量还是来自所选 Pod 的出站流量,或两者兼有。 如果 NetworkPolicy 未指定 policyTypes 则默认情况下始终设置 Ingress; 如果 NetworkPolicy 有任何出口规则的话则设置 Egress。

ingress: 每个 NetworkPolicy 包含一个 ingress 规则的白名单列表。(其中的)规则允许同时匹配 from 和 ports 部分的流派碰量。示例策略中包含一条简单的规则: 它匹配一个单一的端口,来自两个来源中的一个, 第一个通过 namespaceSelector 指定,第二个通过 podSelector 指定。

egress: 每个 NetworkPolicy 包含一个 egress 规则的白名单列表。每个规则都允许匹配 to 和 port 部分的流量。该示例策略包含一条规则,该规则将单个端口上的流量匹配到 10.0.0.0/24 中的任何目的地。

所以,示例网络策略:
1.隔离 "default" 命名空间下标签是 "role=db" 的pod (如果它们不是已经被隔离的话)。
2.(Ingress 规则)允许以下 Pod 连接到 "default" 名字空间下的带有 "role=db" 标签的所有 Pod 的 6379 TCP 端口:

注意作用域
“-”是同级,或的关系

注意ipBlock中目的地址或者源地址的NAT转换

选择器 to 和 from 的行为

可以在 ingress from 部分或 egress to 部分中指定四种选择器:

podSelector: 这将在与 NetworkPolicy 相同的命名空尘橡谈间中选择特定的 Pod,应将其允许作为入口源或出口目的地。

namespaceSelector: 这将选择特定的命名空间,应将所有 Pod 用作其输入源或输出目的地。

namespaceSelector 和 podSelector: 一个指定 namespaceSelector 和 podSelector 的 to/from 条目选择特定命名空间中的特定 Pod。注意使用正确的YAML语法;

下面的策略,在 from 数组中仅包含一个元素,只允许来自标有 role = client 的 Pod 且该 Pod 所在的命名空间中标有user=alice的连接。

这项策略,在 from 数组中包含两个元素,允许来自本地命名空间中标有 role = client 的 Pod 的连接,或来自任何命名空间中标有user = alice的任何Pod的连接。

ipBlock: 这将选择特定的 IP CIDR 范围以用作入口源或出口目的地。 这些应该是群集外部 IP,因为 Pod IP 存在时间短暂的且随机产生。

群集的入口和出口机制通常需要重写数据包的源 IP 或目标 IP。在发生这种情况的情况下,不确定在 NetworkPolicy 处理之前还是之后发生,并且对于网络插件,云提供商,Service 实现等的不同组合,其行为可能会有所不同。

在进入的情况下,这意味着在某些情况下,您可以根据实际的原始源 IP 过滤传入的数据包,而在其他情况下,NetworkPolicy 所作用的 源IP 则可能是 LoadBalancer 或 Pod的节点等。

对于出口,这意味着从 Pod 到被重写为集群外部 IP 的 Service IP 的连接可能会或可能不会受到基于 ipBlock 的策略的约束。

默认策略
默认情况下,如果命名空间中不存在任何策略,则所有进出该命名空间中的Pod的流量都被允许。以下示例使您可以更改该命名空间中的默认行为。

默认拒绝所有入口流量
创建选择所有容器但不允许任何进入这些容器的入口流量的 NetworkPolicy 来为命名空间创建 "default" 隔离策略。

这样可以确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离。此策略不会更改默认的出口隔离行为。

默认允许所有入口流量
如果要允许所有流量进入某个命名空间中的所有 Pod(即使添加了导致某些 Pod 被视为“隔离”的策略),则可以创建一个策略来明确允许该命名空间中的所有流量。

默认拒绝所有出口流量
您可以通过创建选择所有容器但不允许来自这些容器的任何出口流量的 NetworkPolicy 来为命名空间创建 "default" egress 隔离策略。

这样可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许流出流量。此策略不会更改默认的 ingress 隔离行为。

默认允许所有出口流量
如果要允许来自命名空间中所有 Pod 的所有流量(即使添加了导致某些 Pod 被视为“隔离”的策`略),则可以创建一个策略,该策略明确允许该命名空间中的所有出口流量。

默认拒绝所有入口和所有出口流量
可以为命名空间创建 "default" 策略,以通过在该命名空间中创建以下 NetworkPolicy 来阻止所有入站和出站流量.

这样可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许进入或流出流量。

SCTP支持
Kubernetes 支持 SCTP 作为 NetworkPolicy 定义中的协议值作为 alpha 功能提供。要启用此功能,集群管理员需要在 apiserver 上启用 SCTPSupport 功能门,例如 “--feature-gates=SCTPSupport=true,...”。启用功能门后,用户可以将 NetworkPolicy 的 protocol 字段设置为 SCTP。 Kubernetes 相应地为 SCTP 关联设置网络,就像为 TCP 连接一样。

CNI插件必须在 NetworkPolicy 中将 SCTP 作为 protocol 值支持。

首先需要有一个支持网络策略的 Kubernetes 集群。已经有许多支持 NetworkPolicy 的网络提供商,包括:
Calico
Romana
Weave 网络

注意:以上列表是根据产品名称按字母顺序排序,而不是按推荐或偏好排序。下面示例对于使用了上面任何提供商的 Kubernetes 集群都是有效的

创建一个nginx deployment并且通过服务将其暴露
为了查看 Kubernetes 网络策略是怎样工作的,可以从创建一个nginx deployment 并且通过服务将其暴露开始

在 default 命名空间下运行了两个 nginx pod,而且通过一个名字为 nginx 的服务进行了暴露

测试服务能够被其它的pod访问
从其它的 pod 访问这个新的 nginx 服务。为了验证它,从 default 命名空间下的其它 pod 来访问该服务。请您确保在该命名空间下没有执行孤立动作。

启动一个 busybox 容器,然后在容器中使用 wget 命令去访问 nginx 服务:

限制访问nginx服务
想限制 nginx 服务,只让那些拥有标签 access: true 的 pod 访问它,那么您可以创建一个只允许从那些 pod 连接的 NetworkPolicy:

为服务指定策略
使用 kubectl 工具根据上面的 nginx-policy.yaml 文件创建一个 NetworkPolicy:

当访问标签没有定义时测试访问服务
如果您尝试从没有设定正确标签的 pod 中去访问 nginx 服务,请求将会超时:

定义访问标签后再次测试
创建一个拥有正确标签的 pod,您将看到请求是被允许的:

B. K8s创建Pod的不同姿势,常用策略讲解Demo

钱比你想象的重要得多,超过20岁了就别整天活在梦里了,对于平凡的你来讲,钱就是你的尊严。

Pod 环境:Ansible+K8s集群

Ansible 环境准备

容器集群环境准备

kubectl explain --help

查看pod的语法结构

新建一个命名空间用于创建

kubectl config set-context context1 --namespace=liruilong-pod-create

查看当前集群信息乎皮

查看命名空间

设置刚才新建的命名空间为当前命名空间

kubectl run podcommon --image=nginx --image-pull-policy=IfNotPresent --labels="name=liruilong" --env="name=liruilong"

kubectl get pods -o wide

kubectl delete pod pod-demo --force

每个Pod都有一个pause镜像

kubectl run pod-demo --image=nginx --image-pull-policy=IfNotPresent --dry-run=client -o yaml >pod-demo.yaml

yaml文件的获取方法:-o yaml

yaml文件创建pod

pod-demo.yaml

yaml文件创建pod

删除pod:delete pod

创建pod时指定伏慧运行命令。替换镜像中CMD的命令缺顷答

kubectl delete -f comm-pod.yaml 删除pod

批量创建pod

通过 sed 更改 pod名字的方式:sed ‘s/demo/demo1/’ demo.yaml | kubectl apply -f -

容器共享pod的网络空间的。即使用同一个IP地址:pod IP

一个pod内创建多个容器

comm-pod.yaml 文件编写

创建 多容器pod

--image-pull-policy

restartPolicy –单个容器正常退出

k8s中每个资源对象都有标签

查看标签

指定标签过滤

C. k8s 网络三

k8s网络包括网络模型、CNI、Service、Ingress、DNS。
k8s的容器网络关注两点:IP地址分配,路由。

k8s的网络依赖于docker,docker的网络需要linux内核特性的支持。

1 每个Pod除了创建时指定的容器外,都有一个kubelet启动时指定的基础容器。
2 kubelet创建基础容器,庆兆生成network namespace。
3 kubelet调用网络CNI driver,由它根据配置调用具体的CNI 插件。
4 CNI 插件给基础容器配置网络。
5 Pod 中其他的容器共享使用基础容器的网络。

Ingress是HTTP方式的路由转发机制,即是7层负载均衡器,由Ingress Controller和HTTP代理服务器组成。Ingress Controller实时监控k8s API,实时更新HTTP代理服务器的转发规则。HTTP代理服务器有GCE Load-Balancer、HaProxy、Nginx等方案。ingress controller在转发客户端请求到后端服务时,将跳过kube-proxy提供的4层负载均衡器的功能,直接转发到service的后端pod(endpoint)。

对于需要为k8s集群外的客户端提供服务的service,可以通过ingress将服务暴露出去。

网络策略是基于pod源ip(因此k8s网络不能随便做SNAT)的访问控制列表,限制pod之间的访问。
网络策略作为pod网络隔离的一层抽象,用白名单实现了访问控制列表,从label selector、namespace selector、端握烂口、CIDR这4个维度限制pod的流量进出。

ingress限制进入的流量,egress限制外出的流量。

完成从服务名到clusterIP的解析。
DNS服务经历从skyDNS到kubeDNS再到coreDNS的过程。k8s通过Add-On增值包的方式引入DNS系统,把服务名作为dns域名。程序就可以直接使用服务名来建立通信连接。

从容器发出的数据包先到达br0,然后交给host机器的协议栈,由于目的IP是外网,且host主机开启了IP forward功能,数据包会通过eth0发出。因容器分配的网段都不在物理网络网段内,所以一般发出去之前先做NAT转换。(可誉皮租以用iptables进行转换)
当涉及转发的目的IP地址是其他机器时,需要确保启用ip forward功能,即把linux当作交换机。

D. Kubernetes Pod 安全策略(PSP)配置

Kubernetes Pod 安全策略(PSP)配置
默认情况下,Kubernetes 允许创建一个有特权并带州容器的 Pod,这些容器很可能会危机系统安全,而 Pod 安全策略(PSP)则通过确保请求者有权限按配置来创建 Pod,从而来保护集群免受特权 Pod 的影响。

其他插件来自 Kubernetes 文档中推荐的一些插件列表。

然后直接创建上面的 Deployment:

deployment.apps/nginx-deploy created
我们可以看到 Deployment 已经创建成功了,现在检查下 default 命名空间下面的 pod、replicaset、deployment:

NAME READY STATUS RESTARTS AGE
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-deploy-77f7d4c6b4 1 0 0 40s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-deploy 0/1 0 0 40s
可行凳以看到 replicaset 和 deployment 都创建成功了,但是 replicaset 控制器却并没有创建 Pod,这个时候就需要使用 ServiceAccount 了。

attachdetach-controller
calico-kube-controller
certificate-controller
clusterrole-aggregation-controller
cronjob-controller
daemon-set-controller
deployment-controller
disruption-controller
endpoint-controller
expand-controller
job-controller
namespace-controller
node-controller
pv-protection-controller
pvc-protection-controller
replicaset-controller
replication-controller
resourcequota-controller
service-account-controller
service-controller
statefulset-controller
ttl-controller
这些 ServiceAccount 指定了哪个控制器可以解析哪些策略的配置。

podsecuritypolicy.policy/restrictive configured
虽然限制性的访问对于大多数 Pod 创建是足够的了,但是对于需要提升访问权绝蔽限的 Pod 来说,就需要一些允许策略了,例如,kube-proxy 就需要启用 hostNetwork:

NAME READY STATUS RESTARTS AGE
kube-proxy-4z4vf 1/1 Running 0 18d
$ kubectl get pods -n kube-system kube-proxy-4z4vf -o yaml |grep hostNetwork
hostNetwork: true
这就需要创建一个用于提升创建权限的许可策略了:(psp-permissive.yaml)

podsecuritypolicy.policy/permissive configured
$ kubectl get psp
NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES
permissive true RunAsAny RunAsAny RunAsAny RunAsAny false *
restrictive false * RunAsAny RunAsAny RunAsAny RunAsAny false configMap,downwardAPI,emptyDir,persistentVolumeClaim,secret,projected
现在配置都已经就绪了,但是我们需要引入到 Kubernetes 授权,这样才可以确定请求 Pod 创建的用户或者 ServiceAccount 是否解决了限制性或许可性策略,这就需要用到 RBAC 了。

clusterrole.rbac.authorization.k8s.io/psp-restrictive created
clusterrolebinding.rbac.authorization.k8s.io/psp-default created
然后现在我们再重新创建上面我们的定义的 Deployment:

deployment.apps "nginx-deploy" deleted
$ kubectl apply -f nginx.yaml
deployment.apps/nginx-deploy created
创建完成后同样查看下 default 命名空间下面我们创建的一些资源对象:

NAME READY STATUS RESTARTS AGE
pod/nginx-deploy-77f7d4c6b4-njfdl 1/1 Running 0 13s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-deploy-77f7d4c6b4 1 1 1 13s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-deploy 1/1 1 1 13s
我们可以看到 Pods 被成功创建了,但是,如果我们尝试做一些策略不允许的事情,正常来说就应该被拒绝了。首先删除上面的这个 Deployment:

deployment.apps "nginx-deploy" deleted
现在我们在 nginx-deploy 基础上添加hostNetwork: true来使用 hostNetwork 这个特权:(nginx-hostnetwork.yaml)

deployment.apps/nginx-hostnetwork-deploy created
创建完成后同样查看 default 这个命名空间下面的一些资源对象:

NAME READY STATUS RESTARTS AGE
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 1 0 0 44s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 0/1 0 0 44s
现在我们发现 ReplicaSet 又没有创建 Pod 了,可以使用kubectl describe命令去查看这里我们创建的 ReplicaSet 资源对象来了解更多的信息:

Name: nginx-hostnetwork-deploy-74c8fbd687
......
Events:
Type Reason Age From Message
-
Warning FailedCreate 80s (x15 over 2m42s) replicaset-controller Error creating: pods "nginx-hostnetwork-deploy-74c8fbd687-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used]
我们可以看到很明显 Hostnetwork 不被允许使用,但是在某些情况下,我们的确有在某个命名空间(比如 kube-system)下面创建使用 hostNetwork 的 Pod,这里就需要我们创建一个允许执行的 ClusterRole,然后为特定的命名空间创建一个 RoleBinding,将这里的 ClusterRole 和相关的控制器 ServiceAccount 进行绑定:(psp-permissive-rbac.yaml)

clusterrole.rbac.authorization.k8s.io/psp-permissive created
rolebinding.rbac.authorization.k8s.io/psp-permissive created
现在,我们就可以在 kube-system 这个命名空间下面使用 hostNetwork 来创建 Pod 了,将上面的 nginx 资源清单更改成 kube-system 命名空间下面:

重新创建这个 Deployment:

deployment.apps/nginx-hostnetwork-deploy created
创建完成后同样查看下对应的资源对象创建情况:

NAME READY STATUS RESTARTS AGE
pod/nginx-hostnetwork-deploy-74c8fbd687-7x8px 1/1 Running 0 2m1s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 1 1 1 2m1s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 1/1 1 1 2m1s
现在我们可以看到 Pod 在 kube-system 这个命名空间下面创建成功了。

serviceaccount/specialsa created
然后创建一个 RoleBinding 将 specialsa 绑定到上面的 psp-permissive 这个 CluterRole 上:(specialsa-psp.yaml)

创建上面的 RoleBinding 对象:

rolebinding.rbac.authorization.k8s.io/specialsa-psp-permissive created
然后为我们上面的 Deployment 添加上 serviceAccount 属性:(nginx-hostnetwork-sa.yaml)

然后直接创建即可:

deployment.apps/nginx-hostnetwork-deploy configured
这个时候我们查看 default 这个命名空间下面带有 hostNetwork 的 Pod 也创建成功了:

NAME READY STATUS RESTARTS AGE
pod/nginx-hostnetwork-deploy-6c85dfbf95-hqt8j 1/1 Running 0 65s
NAME DESIRED CURRENT READY AGE
replicaset.extensions/nginx-hostnetwork-deploy-6c85dfbf95 1 1 1 65s
replicaset.extensions/nginx-hostnetwork-deploy-74c8fbd687 0 0 0 31m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.extensions/nginx-hostnetwork-deploy 1/1 1 1 31m

上面我们描述了 Pod 安全策略是一种通过使用 PSP 授权策略来保护 k8s 集群中的 Pod 的创建过程的方法。

https://kubernetes.io/docs/concepts/policy/pod-security-policy/#policy-reference

https://octetz.com/posts/setting-up-psps

https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#is-there-a-recommended-set-of-admission-controllers-to-use

E. Kubernetes之NetworkPolicy,Flannel和Calico

Pod是Kubernetes调度的最小单元。一个Pod可以包含一个或多个容器,因此它可以被看作是内部容器的逻辑宿主机。Pod的设计理念是为了支持多个容器在一个Pod中共享网络和文件系统。那么为什么Pod内的容器能够共享网络,IPC和PID命名空间?

原因:Kubernetes在每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause:version的容器,所有处于该Pod中的容器在启动时都会添加诸如--net=container:pause --ipc=contianer:pause --pid=container:pause的启动参数,因此Pod内所有容器共用pause容器的network,IPC和PID命名空间。所有容器共享pause容器的IP地址,也被称为Pod IP。因此处于同一个Pod内的容器,可以通过localhost进行相互访问。

在讲K8s Pod间通信前,我们先复习一下Docker容器间的网络通信。默认情况下,Docker使用一种名为bridge的网络模型。如下图所示:

Docker引擎在启动时,会在宿主机上创建一个名为docker0的虚拟网桥,这个虚拟网桥负责给所有容器分配不重复的ip地址以及容器间的网络通信。首先,Docker在创建一个容器时,会执行以下操作:

通过这个docker0网桥,同一宿主机上的容器可以互相通信。然而由于宿主机的IP地址与容器veth pair的 IP地址均不在同一个网段,故仅仅依靠veth pair和namespace的技术,还不足以使宿主机以外的网络主动发现容器的存在。为了使外界可以访问容器中的进程,docker采用了端口绑定的方式,也就是通过iptables的NAT,将宿主机上的端口端口流量转发到容器内的端口上。

K8s 默认不提供网络功能,所有Pod的网络功能,都依赖于宿主机上的Docker。因此,Pod IP即是依靠docker0网桥分配给pause容器的虚拟IP。

同一个Node内,不同的Pod都有一个docker0网桥分配的IP,可以直接通过这个IP进行通信。Pod IP和docker0在同一个网段。因此,当同节点上的Pod-A发包给Pod-B时,包传送路线如下:

不同的Node之间,Node的IP相当于外网IP,可以直接访问,而Node内的docker0和Pod的IP则是内网IP,无法直接跨Node访问。因此,不同Node上的Pod间需要通信,需要满足以下两个条件:

因此,为了实现以上两个需求,K8s提供了CNI(Container Network Interface)供第三方实现从而进行网络管理。由此出现了一系列开源渣陵的Kubernetes中的网络插件与方案,包括:flannel,calico,cilium等等。这些网络插件集中解决了以下需求:

CNI的介绍请参考这篇文章: https://jimmysong.io/kubernetes-handbook/concepts/cni.html

在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外冲梁高IP地址。

Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使散尺得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

Flannel实质上是一种“覆盖网络(overlay network)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式,默认的节点间数据通信方式是UDP转发。下图展示了数据包在flannel中的流转:

Flannel是一种典型的Overlay网络,它将已有的物理网络(Underlay网络)作为基础,在其上建立叠加的逻辑网络,实现网络资源的虚拟化。Overlay网络有一定额外的封包和解包等网络开销,对网络通信的性能有一定损耗。

Calico是纯三层的SDN 实现,它基于BPG 协议和Linux自身的路由转发机制,不依赖特殊硬件,容器通信也不依赖iptables NAT或Tunnel 等技术。能够方便的部署在物理服务器、虚拟机(如 OpenStack)或者容器环境下。同时calico自带的基于iptables的ACL管理组件非常灵活,能够满足比较复杂的安全隔离需求。

Calico 还基于 iptables 还提供了丰富而灵活的网络 policy, 保证通过各个节点上的 ACLs 来提供 workload 的多租户隔离、安全组以及其他可达性限制等功能。

核心问题是,nodeA怎样得知下一跳的地址?答案是node之间通过BGP协议交换路由信息。

每个node上运行一个软路由软件bird,并且被设置成BGP Speaker,与其它node通过BGP协议交换路由信息。

可以简单理解为,每一个node都会向其它node通知这样的信息:

我是X.X.X.X,某个IP或者网段在我这里,它们的下一跳地址是我。

通过这种方式每个node知晓了每个workload-endpoint的下一跳地址。

K8s NetworkPoclicy 用于实现Pod间的网络隔离。在使用Network Policy前,必须先安装支持K8s NetworkPoclicy的网络插件,包括:Calico,Romana,Weave Net,Trireme,OpenContrail等。

在未使用NetworkPolicy前,K8s中所有的Pod并不存在网络隔离,他们能够接收任何网络流量。一旦使用NetworkPolicy选中某个namespace下的某些Pod,那么这些Pod只能接收特定来源的流量(由Ingress属性定义),并且只能向特定出口发送网络请求(由Egress属性定义)。其他未被这个NetworkPolicy选中的Pod,依然不具备网络隔离。

下面是一个NetworkPolicy的例子:

下面的例子表示默认禁止所有Pod间的Ingress流量:

默认拒绝所有 Pod 之间 Egress 通信的策略为:

而默认允许所有 Pod 之间 Ingress 通信的策略为:

默认允许所有 Pod 之间 Egress 通信的策略为:

以 calico 为例看一下 Network Policy 的具体用法。首先配置 kubelet 使用 CNI 网络插件:

安装 calio 网络插件:

首先部署一个 nginx 服务,此时,通过其他 Pod 是可以访问 nginx 服务的:

开启 default namespace 的 DefaultDeny Network Policy 后,其他 Pod(包括 namespace 外部)不能访问 nginx 了:

最后再创建一个运行带有 access=true label的 Pod 访问的网络策略:

F. 如何指定pod的运行节点

一般情况下kubernets可以通过kube-scheler默认的调度策略合理的将pod分配到可用的节点上, 但是随着pod数量的增加以及不同pod对资源的使用情况不同我们需要更加合理的分配集群中的资源, 所以对一些pod运行节点的控制是由必要的。

源于硬件和软件层多样性,我们需要将某个 pod 调度到某些特定的节点上,例如指定机房,存储类型,网络类型等等:

有两种方法 nodeSelector 以及 affinity 可以实现对应的需求

K8S中pod的调度都是通过节点label实现的 , 所以对于除必要的节点label外对于其它用途也要做一些规划

设置参数

为 node 设置 taint 与 label:

or

删除taint:

删除扒燃node的label

查看 node上的 taint:

查看node1的label

kubernetes中是通过label-selector机制进行节点选择,由scheler调度策略 MatchNodeSelector 进行label匹配,调度pod到目标节点,该匹配规则是强制约束。

类型包括:

限制方式:

匹配逻辑label

如果nodeAffinity中nodeSelector有多个选项,节点满足任何一个条件即可;如果matchExpressions有多个选项,则节点必须同时满足这些选项才能运行pod 。需要说明的是,node并没有anti-affinity这种东西,因为NotIn和DoesNotExist能提供类似的功能。

这个 pod 同时定义了 和 两种nodeAffinity。第一个要求 pod 运行在特定 devops 的节点上,第二个希望节点最好有对应的department:model和dedicated:app标签, 根据权重决定了顺序 NodeSelectorTerms 可以有多个,之间是或的关系,满足任意一个既满足, MatchExpressions 也可以有多个,他们之间是且的关系 必须都满足
值为列表,根据权重决定顺序 MatchExpressions 值为列表 关系为且,必须都满足

PodAffinit是根据通过已运行在节点上的pod的标签而不是node的标签来决定被调度pod的运行节点,因为pod运行在指定的namespace所以需要自己指定运行pod的namesapce

上面这个例子中的 POD 需要调度到某个指定的主机上,至少有一个节点上运行了这样的 POD:这个 POD 有一个app=busybox-pod的 label。podAntiAffinity则是希望最好不要调度到这样的节点:这个节点上运行了某个 POD,而这个 POD 有app=node-affinity-pod的 label。根据前面两个 POD 的定义,我们可以预见上面这个 POD 应该会被调度到一个busybox-pod被调度的节点上,而node-affinity-pod被调度到了该节点以外的节点

对于nodeAffinity无论是硬策略还是软策略方式,都是调度 POD 到预期节点上,而Taints恰好与之相反,如春段虚果一个节点标记为 Taints ,除非 POD 也被标识为可以容忍污点节点,否则该 Taints 节点不会被调度pod。

比如用户希望把 Master 节点保留给 Kubernetes 系统组件使用,或者把一组具有特殊资源预留给某些 POD,则污点就很有用了,POD 不会再被调度到 taint 标记过的节点。taint 标记节点举例如下:

如果仍然希望某个 POD 调度到 taint 节点上,则必须在 Spec 中做出Toleration定义,才能调度到该节点,举例如下:

effect 共有三个燃辩可选项,可按实际需求进行设置:

设置label 和 taint, edgenode为特殊属性的节点所以需要设置taint

资源文件

运维服务部署在固定的几台主机上, 每个主机设置 department 的label, 部署服务时指定该label

设置label

资源文件

G. 11.4 跨pod网络

现在,你知道每个pod有自己唯一的IP地址,可以通过一个扁平的、非 NAT网络和其他pod通信。Kubernetes是如何做到这一点的?简单来说,Kubernetes不负责这块。网络是由系统管理员或者Container Network Interface(CNI)插件建立的,而非Kubernetes本身。

Kubernetes并不会要求你使用特定的网络技术,但是授权pod(或者更准确地说,其容器)不论是否运行在同一个工作节点上,可以互相通信。pod用于通信的网络必须是:pod自己认为的IP地址一定和所有其他节谈握点认为该pod拥有的IP地址一致。

查看图 11.14。当pod A连接(发送网络包)到pod B时,pod B获取到的源IP地址必须和pod A自己认为的IP地址一致。其间应该没有网络地址转换(NAT)操作——pod A发送到pod B的包必须保持源和目的地址不变。

这很重要,保证运行在pod内部的应用网络的简猜清洁性,就像运行在同一个网关机上一样。pod没有NAT使得运行在其中的应用可以自己注册在其他pod中。

image

图11.14 Kubernetes规定pod必须通过非NAT网络进行连接

例如,有客户端pod X和pod Y,为所有通过它们注册的pod提供通知服务。pod X连接到pod Y并且告诉pod Y,“你好,我是pod X,IP地址为1.2.3.4,请把更新发送到这个IP地址”。提供服务的pod可以通过收到的IP地址连接第一个pod。

pod到节点及节点到pod通信也应用了无NAT通信。但是当pod和internet上的服务通信时,pod发送包的源IP不需要改变,因为pod的IP是私有的。向外发送包的源IP地址会被改成主机工作节点的IP地址。

构建一个像样的Kubernetes集群包含按照这些要求建立网络。有不同的方法和技术来建立,在给定场景中它们都有其优点和缺点。因此,我们不会深入探究特定的技术,会阐述跨pod网络通用的工作原理。

在 11.3 节,我们看到创建了pod的IP地址以及网络命名空间,由基础设施容器(暂停容器)来保存这些信息,然后pod容器就可以使用网络命名空间了。pod网络接口就是生成在基础设施容器的一些东西。让我们看一下接口是如何被创建的,以及如何连接到其他pod的接口,如图 11.15 所示。

[图片上传失败...(image-d2fcf3-1627950575030)]

图11.15 同一节点上pod通过虚拟Ethernet接口对连接到同一个桥接

同节点pod通信

基础设施容器启动之前,会为容器创建一个虚拟Ethernet接口对(一个veth pair),其中一个对的接口保留在主机的命名空间中(在节点上运行ifconfig命令时可以看到vethXXX的条目),而其他的对被移入容器网络命名空间,并重命名为eth0。两个虚拟接口就像管道的两端(或者说像Ethernet电缆连接的两个网络设备)——从一端进入,另一端出来,等等。

主机网络命名空间的接口会绑定到容器运行时配置使用的网络桥接上。从网桥的地址段中取IP地址赋值给容器内的eth0 接口。应用的任何运行在容器内部的程序都会发送数据到eth0 网络接口(在容器命名空间中的那一个),数据从主机命名穗侍前空间的另一个veth接口出来,然后发送给网桥。这意味着任何连接到网桥的网络接口都可以接收该数据。

如果pod A发送网络包到pod B,报文首先会经过pod A的veth对到网桥然后经过pod B的veth对。所有节点上的容器都会连接到同一个网桥,意味着它们都能够互相通信。但是要让运行在不同节点上的容器之间能够通信,这些节点的网桥需要以某种方式连接起来。

不同节点上的pod通信

有多种连接不同节点上的网桥的方式。可以通过overlay或underlay网络,或者常规的三层路由,我们会在后面看到。

跨整个集群的pod的IP地址必须是唯一的,所以跨节点的网桥必须使用非重叠地址段,防止不同节点上的pod拿到同一个IP。如图 11.16 所示的例子,节点A上的网桥使用 10.1.1.0/24 IP段,节点B上的网桥使用 10.1.2.0/24 IP段,确保没有IP地址冲突的可能性。

图 11.16 显示了通过三层网络支持跨两个节点pod通信,节点的物理网络接口也需要连接到网桥。节点 A的路由表需要被配置成图中所示,这样所有目的地为 10.1.2.0/24 的报文会被路由到节点B,同时节点B的路由表需要被配置成图中所示,这样发送到 10.1.1.0/24 的包会被发送到节点A。

图11.16 为了让不同节点上的pod能够通信,网桥需要以某种方式连接

按照该配置,当报文从一个节点上容器发送到其他节点上的容器,报文先通过veth pair,通过网桥到节点物理适配器,然后通过网线传到其他节点的物理适配器,再通过其他节点的网桥,最终经过veth pair到达目标容器。

仅当节点连接到相同网关、之间没有任何路由时上述方案有效。否则,路由器会扔包因为它们所涉及的pod IP是私有的。当然,也可以配置路由使其在节点间能够路由报文,但是随着节点数量增加,配置会变得更困难,也更容易出错。因此,使用SDN(软件定义网络)技术可以简化问题,SDN可以让节点忽略底层网络拓扑,无论多复杂,结果就像连接到同一个网关上。从pod发出的报文会被封装,通过网络发送给运行其他pod的网络,然后被解封装、以原始格式传递给pod。

为了让连接容器到网络更加方便,启动一个项目容器网络接口(CNI)。CNI允许Kubernetes可配置使用任何CNI插件。这些插件包含

我们不会去深入探究这些插件的细节,如果想要了解更多,可以参考 https://kubernetes.io/docs/concepts/cluster-administration/addons/ 。

安装一个网络插件并不难,只需要部署一个包含DaemonSet以及其他支持资源的YAML。每个插件项目首页都会提供这样一个YAML文件。如你所想,DaemonSet用于往所有集群节点部署一个网络代理,然后会绑定CNI接口到节点。但是,注意Kubetlet需要用 --network-plugin=cni 命令启动才能使用CNI。

H. k8s网络配置DNS

Kubernetes支持Pod维度DNS策略设置,通过pod规约中dnsPolicy字段设置,最终配置落到 /etc/resolv.conf 文件中,也就说k8s最终还是通过设置Pod容器中/etc/resolv.conf 文件来做设置解析配置,跟普通的虚拟机或者实体机是一样,因为Pod容器本身就一个小的主机。

采用集群DNS,与配置的集群域后缀不匹配的任何 DNS 查询 都将转发到从节点继承的上游名称服务器。简单来说,就是使用 Kubernetes 中 kubedns 或 coredns 服务码液进行域名解析,如果解析不成功,才会使用宿主机的 DNS 配置进行解析。

example容器/etc/resolv.conf

options ndots:5 代表当待解析域名包含.大于等于5时就会先解析域名,只有域名解析不成功时才会继续匹配serach域或domain域

访问test名字空间下example-svc服务,可以直接通过 example-svc 访问,会与search域组合,最终组合成 example-svc.test.svc.cluster.local ,访问test1名字空间下example-svc1,通过 example-svc.test1 ,会与search域组合,最终组合成 example-svc.test1.svc.cluster.local

自定义DNS策略,设置允许 Pod 忽略 Kubernetes 环境中的 DNS 设置,Pod 会使用其 dnsConfig 字段 所提供的 DNS 设置。

用户可以在 dnsConfig 字段中指定以下属性:

创建上面的 Pod 后,容器 test 会在其 /etc/resolv.conf 文件中获取以下内容:

Pod 从运行所在的节点继承名称解析配置,即跟所在节点主机一致

对于以 hostNetwork 方式运行的 Pod,应显式设置其 DNS 策略 为"ClusterFirstWithHostNet"

k8s新版本集群DNS服务是默认采用CoreDNS组件实现,1.13版本之前是采用Kube-dns

当 DNS 配置以及其它选项不合理陵庆的时候,通过向 Pod 的 /etc/hosts 文件中添加条目, 可以在 Pod 级别覆盖对主机名的解析。你可以通过迟汪物 PodSpec 的 HostAliases 字段来添加这些自定义条目.

pod打印/etc/hosts文件,多了以下内容

I. 简述Kubernetes网络策略

为实现细粒度的容器间网络访问隔离策略,Kubernetes引入Network Policy。
Network Policy的主要功能是对Pod间的网络通信进行限制和准入控制,设置允许访问或禁止访问的客户端Pod列表。Network Policy定义网络策略,配合策略控制器(Policy Controller)进行策略的实现。我推荐你去看看时速云,他们是一家全栈云原生技术服务提供商,提供云原生应用及数据平台产品,其中涵盖容器云PaaS、DevOps、微服务治理、服务网格、API网关等。大家可以去体验一下。 如果我的回答能够对您有帮助的话,求给大大的赞。

阅读全文

与pod网络策略怎么设置相关的资料

热点内容
欧洲成年人网络安全 浏览:998
网络信号源怎么选择 浏览:532
如何防范网络暴力的危害 浏览:835
网络盒子连接wifi网不好 浏览:498
钣金产品网络推广平台有哪些 浏览:766
usb共享网络访问 浏览:87
为什么我家wifi无法连接网络 浏览:982
火腿网络营销 浏览:664
学习网络如何创业 浏览:231
网络上哪里能借到钱 浏览:703
网络安全运维巡检 浏览:103
公共网络系统设置 浏览:552
电脑关掉网络通信 浏览:561
催乳师网络培训哪里不错 浏览:598
网络彩票500公司在哪里 浏览:761
路由器哪个网络都可以用吗 浏览:900
网络设置权限在哪里找 浏览:520
香信找回密码网络异常 浏览:756
索尼系统usb共享网络 浏览:89
计算机网络毕设ppt 浏览:852

友情链接