跳转至

Kubernetes 网络策略


2020-04-15 by dongnan

开始之前

在前面的三篇文章中,至此我们已经准备好了K8S集群环境。

接下来我们将以在K8S集群运行一个真实的项目为目标,依次介绍项目所使用的K8S资源对象。

这个项目是一个典型的Web系统,使用 Java Spring Boot框架开发,需要使用 MySqlRedis数据库、NFS共享存储(多个Pod容器间共享文件)。

由于K8S环境部署在阿里云上,所以这里使用了阿里云提供的 RDS-MysqlRDS-Redis 数据库服务、NAS(NFS) 网络附加存储等中间件产品,对于K8S集群来说,我们需要将这些服务映射为K8S的资源对象。

项目使用的K8S的资源对象包括:

环境

测试的k8s集群由一个Master管理节点、两个Worker计算节点组成,详细请参考这里

目标

  • 使用 NetworkPolicy 隔离命名空间,例如隔离生产环境测试环境的网络。
  • 使用 NetworkPolicy 网络策略保护 Pod 的网络服务 (白名单)。

举个栗子

Yaml文档

定义名称为 yyi-server-np 的网络策略:

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  namespace: yyi-prod
  name: yyi-server-np
spec:
  podSelector:
    matchLabels:
      app: yyi-server
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          app.kubernetes.io/name: ingress-nginx
    ports:
    - protocol: TCP
      port: 8080

这个NetworkPolicy对象的作用如下:

  • 使用这个 NetworkPolicy 对象,需要在 yyi-prod命名空间中,并且必须带有 app: yyi-server 标签的 Pod容器组。
  • 进入方向,允许来自 ingress-nginx 命名空间的 Pod(Ingress控制器),访问yyi-server(Pod)容器的TCP协议8080端口。
  • 进入方向,拒绝其它不符合规则的请求。
  • 出方向,没有规则限制。

创建网络策略

kubectl apply -f yii-np.yaml

验证网络策略

查看 NetworkPolicy详细信息:

kubectl -n yyi-prod describe networkpolicies yyi-server-np 
Name:         yyi-server-np
Namespace:    yyi-prod
Labels:       <none>
              #...省略
Spec:
  PodSelector:     app=yyi-server
  Allowing ingress traffic:
    To Port: 8080/TCP
    From:
      NamespaceSelector: app.kubernetes.io/name=ingress-nginx
  Not affecting egress traffic
  Policy Types: Ingress

尝试使用 default 命名空间中的Pod 访问 yyi-server 容器的 8080 端口:

# 获得 Pod IP 地址
kubectl -n yyi-prod get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE    IP              NODE   #...省略  
yyi-server-78df87c94d-gxt6r     1/1     Running   0          164d   172.18.xx.120   host2

# 登录 Pod 控制台
kubectl exec -ti demo-secret-cf58d4f99-8n6wj /bin/bash

# 尝试访问 yyi-server 的端口
root@demo-secret-cf58d4f99-8n6wj:/var/www/html# telnet 172.18.xx.120 8080
Trying 172.18.xx.120...
telnet: Unable to connect to remote host: Connection timed out

由于 yyi-server-np 网络策略的规则,拒绝了访问请求。

NetworkPolicy

NetworkPolicy 定义了一组Pod是否允许相互通信,或者Pod与网络中的其它端点通信的规则。 NetworkPolicy 对象使用标签选择Pod,并规定选中的Pod可以执行什么样的网络通信。

NetworkPolicy网络插件实现,因此使用的网络插件必须能够支持 NetworkPolicy 才可以使用此特性。

参数含义

重点看下spec段包,含了定义网络策略的主要信息:

podSelector:

  • 名称空间中,符合此标签选择器.spec.podSelectorrPod都将应用这个 NetworkPolicy
  • 如果该字段为空,则将对名称空间中所有的Pod应用这个NetworkPolicy

policyTypes:

  • 是一个数组类型的字段,该数组中可以包含 IngressEgress 中的一个,也可能两个都包含。
  • 该字段默认将始终包含 Ingress,当 NetworkPolicy 中包含出方向的规则时,Egress 也将被添加到默认值。

ingress:

  • ingress代表入方向的白名单规则,每一条规则都将允许与fromports匹配的入方向的网络流量发生关联。

egress:

  • egress代表出方向的白名单规则,每一条规则都将允许与toports匹配的出方向的网络流量发生。

.spec.ingress.from.spec.egress.to 字段可以指定4种类型的标签选择器:

  • podSelector: 选择与 NetworkPolicy 相同名称空间中的 Pod 作为入方向访问控制规则的源或者出方向访问控制规则的目标。
  • namespaceSelector: 选择某个名称空间所有的Pod 作为入方向访问控制规则的源或者出方向访问控制规则的目标。
  • namespaceSelector && podSelector: 在一个 to / from 条目中同时包含这两个选择器,将选中指定名称空间中的指定 Pod
  • ipBlock 可选择IP地址CIDR范围作为入方向访问控制规则的源或者出方向访问控制规则的目标。这里应该指定的是集群外部的IP,因为集群内部 Pod 的 IP 地址是临时分配的,且不可预测。

小结

  • NetworkPolicy 由网络插件实现,因此使用的网络插件必须能够支持 NetworkPolicy 才可以使用。
  • 默认情况下 Pod 都是非隔离的,可以接受来自任何请求方的网络请求。
  • 如果一个 NetworkPolicy 的标签选择器选中了某个 Pod,则该 Pod 将变成隔离的,并将拒绝任何不被 NetworkPolicy 许可的网络连接。
  • NetworkPolicy 不会相互冲突,而是相互叠加的。
  • 如果多个 NetworkPolicy 选中了同一个 Pod,则该 Pod 可以接受这些 NetworkPolicy 当中任何一个 NetworkPolicy 定义的规则。
  • 因此,NetworkPolicy顺序并不重要,因为不会影响到最终的结果。

参考

回到页面顶部