使用 Antrea 集群网络策略(2021 版)

“Antrea是什么”

Antrea是一个开源的Kubernetes CNI,为Kubernetes集群提供L3/4网络功能和安全性。它使用经过验证的Open vSwitch作为数据平面的开放式虚拟交换机。

 

在Antrea中,我们试图实现一些在标准的Kubernetes集群网络中不支持的功能,但从网络安全的角度来看,Antrea Cluster Network Policy (ACNP)非常有趣。

Antrea不仅支持标准的NetworkPolicy,还通过ACNP提供以下功能,以更好地满足集群管理员的要求。

    • ポリシーの階層化と優先度設定

 

    • Namespace に限定されない、クラスターレベルのセキュリティ設定

 

    アクションルールのサポート: Allow, Drop, Reject のアクションを指定可能

我們將關注Antrea叢集網路策略,以確認其功能。

顺便提一句,2021年4月10日,在本文撰写时,Antrea已经达到了1.0.0版本。下面的内容是基于Antrea 1.0.0进行撰写的。
另外,除了上述的Project Antrea页面外,我还参考了以下文章:
https://blog.shin.do/2020/01/antrea-yet-another-cni-plugin-for-kubernetes/

Antrea 集群的准备

准备一个新的 K8s 集群

这次我使用 kubeadm 来准备一个新的 Kubernetes 集群,用于 Antrea。我参考了以下链接的内容:
https://thinkit.co.jp/article/18188

我配置了1台Master和2台Worker,但在应用CNI之前,它们将处于NotReady状态。

$ kubectl get node
NAME          STATUS     ROLES                  AGE     VERSION
k8s-master    NotReady   control-plane,master   1d      v1.20.5
k8s-worker1   NotReady   <none>                 44m     v1.20.5
k8s-worker2   NotReady   <none>                 2m41s   v1.20.5

将 Antrea 应用到集群中

作为CNI,我们将应用Antrea而不是Calico。有关Antrea的初始设置,请参考以下链接:
https://github.com/vmware-tanzu/antrea/blob/main/docs/getting-started.md

由于本次使用 Antrea v1.0.0,将按照以下方式指定并应用。

$ kubectl apply -f https://github.com/vmware-tanzu/antrea/releases/download/v1.0.0/antrea.yml

如果想应用最新的版本,也可以使用下面的方式。

$ kubectl apply -f https://raw.githubusercontent.com/vmware-tanzu/antrea/main/build/yamls/antrea.yml

应用 Antrea CNI 后,节点已准备就绪。

$ kubectl get node
NAME          STATUS   ROLES                  AGE   VERSION
k8s-master    Ready    control-plane,master   1d    v1.20.5
k8s-worker1   Ready    <none>                 57m   v1.20.5
k8s-worker2   Ready    <none>                 15m   v1.20.5

antctl的安装

antctl 是一个通过控制器来检查 Antrea 配置和状态的命令行工具。为了未来的可能需要,建议安装最新版本。以下是适用于 1.0.0 版本的 Linux。

$ curl -Lo ./antctl "https://github.com/vmware-tanzu/antrea/releases/download/v1.0.0/antctl-linux-x86_64"
$ chmod +x ./antctl
$ mv ./antctl /usr/local/bin
$ antctl version
antctlVersion: v1.0.0
controllerVersion: v1.0.0

确认设置

在部署Antrea时,将会创建Antrea的configmap。您可以确认当前的配置情况。查看已创建的antrea-config-xxxxxxxxx。

$ kubectl get configmap antrea-config-5ct9ktdt77 -n kube-system -o yaml

这里我们将确认AntreaPolicy的设置。在antrea-agent.conf和antrea-controller.conf的设置中,AntreaPolicy被设置为True,但被注释掉。由于从Antrea 1.0版本开始,默认情况下Antrea Network Policy已启用,所以已经被激活了。

apiVersion: v1
data:
  antrea-agent.conf: |
    # FeatureGates is a map of feature names to bools that enable or disable experimental features.
    featureGates:
    # Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent.
    # It should be enabled on Windows, otherwise NetworkPolicy will not take effect on
    # Service traffic.
    #  AntreaProxy: true

    # Enable EndpointSlice support in AntreaProxy. Don't enable this feature unless that EndpointSlice
    # API version v1beta1 is supported and set as enabled in Kubernetes. If AntreaProxy is not enabled,
    # this flag will not take effect.
    #  EndpointSlice: false

    # Enable traceflow which provides packet tracing feature to diagnose network issue.
    #  Traceflow: true

    # Enable NodePortLocal feature to make the pods reachable externally through NodePort
    #  NodePortLocal: false

    # Enable Antrea ClusterNetworkPolicy feature to complement K8s NetworkPolicy for cluster admins
    # to define security policies which apply to the entire cluster, and Antrea NetworkPolicy
    # feature that supports priorities, rule actions and externalEntities in the future.
    #  AntreaPolicy: true

(snip...)

  antrea-controller.conf: |
    # FeatureGates is a map of feature names to bools that enable or disable experimental features.
    featureGates:
    # Enable traceflow which provides packet tracing feature to diagnose network issue.
    #  Traceflow: true

    # Enable Antrea ClusterNetworkPolicy feature to complement K8s NetworkPolicy for cluster admins
    # to define security policies which apply to the entire cluster, and Antrea NetworkPolicy
    # feature that supports priorities, rule actions and externalEntities in the future.
    #  AntreaPolicy: true

(snip...)

尝试使用Antrea集群网络策略

我們現在來實際使用 Antrea Cluster Network Policy,並且比較一下它與 K8s 標準的 NetworkPolicy 的差異。

部署示例应用程式

首先,我们将部署一个用于进行操作确认的应用程序。将Guestbook应用程序部署到默认的命名空间中。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-master-controller.json
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-master-service.json
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-slave-controller.json
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/redis-slave-service.json
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/guestbook-controller.json
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/guestbook-service.json

创建了三种类型的服务和容器:guestbook、redis-master、redis-slave。

$ kubectl get all -n default
NAME                     READY   STATUS    RESTARTS   AGE
pod/guestbook-hmsrw      1/1     Running   0          23h
pod/guestbook-nl7xv      1/1     Running   0          23h
pod/guestbook-s9spp      1/1     Running   0          23h
pod/redis-master-z2vjh   1/1     Running   0          23h
pod/redis-slave-cplgv    1/1     Running   0          23h
pod/redis-slave-r2tmz    1/1     Running   0          23h

NAME                                 DESIRED   CURRENT   READY   AGE
replicationcontroller/guestbook      3         3         3       23h
replicationcontroller/redis-master   1         1         1       23h
replicationcontroller/redis-slave    2         2         2       23h

NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/guestbook      LoadBalancer   10.109.117.193   <pending>     3000:30731/TCP   23h
service/kubernetes     ClusterIP      10.96.0.1        <none>        443/TCP          2d
service/redis-master   ClusterIP      10.98.195.90     <none>        6379/TCP         23h
service/redis-slave    ClusterIP      10.109.248.115   <none>        6379/TCP         23h

访客留言板服务是负载均衡的类型,但由于此环境中尚未存在提供者负载均衡器,因此EXTERNAL-IP仍处于待定状态。暂时,请使用NodePort通过以下URL访问,即可显示访客留言板的用户界面。192.168.110.91是工作节点的IP地址。

http://192.168.110.91:30731/
image.png

在这里,我们将确认每个 Pod 的标签设置。前端容器 guestbook 具有 app: guestbook 的标签,后端的 redis-master 和 redis-slave 具有 app: redis 的标签。这些标签将在接下来的 NetworkPolicy 和 Antrea Network Policy 的 PodSelector 设置中使用。

$ kubectl get pod -L app
NAME                 READY   STATUS    RESTARTS   AGE     APP
guestbook-hmsrw      1/1     Running   0          23h   guestbook
guestbook-nl7xv      1/1     Running   0          23h   guestbook
guestbook-s9spp      1/1     Running   0          23h   guestbook
redis-master-z2vjh   1/1     Running   0          23h     redis
redis-slave-cplgv    1/1     Running   0          23h     redis
redis-slave-r2tmz    1/1     Running   0          23h     redis

网络策略

在尝试 Antrea Cluster Network Policy 之前,先确认标准 NetworkPolicy 的运作情况。

在命名空间中对容器之间的控制

应用以下策略,确认在命名空间内,前端guestbook与后端redis的通信受到阻碍。

$ cat np1.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: drop-access-to-redis
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: redis
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: other
$
$ kubectl apply -f np1.yaml
networkpolicy.networking.k8s.io/drop-access-to-redis created

当再次访问Guestbook的URL时,会显示以下内容,表明无法连接到后端。

image.png

删除此 NetworkPolicy 后,您将能够重新连接。

$ kubectl delete -f np1.yaml
networkpolicy.networking.k8s.io "drop-access-to-redis" deleted

命名空间用于控制外部访问。

这次我们将创建并应用一个禁止访问前端guestbook的策略。

$ cat np2.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: drop-access-to-guestbook
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: guestbook
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: other
$
$ kubectl apply -f np2.yaml
networkpolicy.networking.k8s.io/drop-access-to-guestbook created

在这种情况下,仍然可以通过NodePort从外部访问。

image.png

然而,不允许通过前端容器访问ClusterIP。

$ kubectl exec guestbook-hmsrw -it -- sh


BusyBox v1.21.1 (Ubuntu 1:1.21.0-1ubuntu1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

/app # wget -O - http://guestbook.default.svc.cluster.local:3000
Connecting to guestbook.default.svc.cluster.local:3000 (10.109.117.193:3000)
^C
/app # 

删除策略后,前端也可以再次访问。

$ kubectl delete -f np2.yaml
networkpolicy.networking.k8s.io "drop-access-to-guestbook" deleted
/app # wget -O - http://guestbook.default.svc.cluster.local:3000
Connecting to guestbook.default.svc.cluster.local:3000 (10.109.117.193:3000)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta charset="utf-8">
    <meta content="width=device-width" name="viewport">
    <link href="style.css" rel="stylesheet">
    <title>Guestbook</title>
  </head>
  <body>
    <div id="header">
      <h1>Guestbook</h1>
    </div>

(snip...)

用NodePort进行外部控制时,无法使用NetworkPolicy。

命名空间的控制

这次,我们将创建以下策略,允许其他命名空间的访问。

$ cat np3.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-access-from-other-ns
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: guestbook
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: test
    - podSelector:
        matchLabels:
          app: other
$
$ kubectl apply -f np3.yaml
networkpolicy.networking.k8s.io/allow-access-from-other-ns created

为了进行这个测试,暂时创建一个名为test的命名空间,并给其添加项目:test的标签。

$ kubectl create namespace test
namespace/test created
$ kubectl label namespace test project=test
namespace/test labeled

接下来,我们将在testnamespace中创建一个用于测试的容器。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook-go/guestbook-controller.json -n test
$ kubectl get pod -n test
NAME              READY   STATUS    RESTARTS   AGE
guestbook-5w6ft   1/1     Running   0          79m
guestbook-cfzfd   1/1     Running   0          79m
guestbook-jlfpw   1/1     Running   0          79m

确保可以从该容器访问最初部署在 defaultnamespace 中的 Guestbook 应用程序。

$ kubectl exec guestbook-5w6ft -n test  -it -- sh


BusyBox v1.21.1 (Ubuntu 1:1.21.0-1ubuntu1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

/app # wget -O - http://guestbook.default.svc.cluster.local:3000
Connecting to guestbook.default.svc.cluster.local:3000 (10.109.117.193:3000)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta charset="utf-8">
    <meta content="width=device-width" name="viewport">
    <link href="style.css" rel="stylesheet">
    <title>Guestbook</title>
  </head>
  <body>
    <div id="header">
      <h1>Guestbook</h1>
    </div>

(snip...)

就如上所述,NetworkPolicy 允许在集群内对每个命名空间进行访问控制,但无法应用于跨命名空间或跨集群。此外,策略仅包括允许规则,同时也会自动添加隐式的拒绝规则。因此,似乎不适合编写详细的拒绝规则以进行更精细的安全控制。

Antrea 集群网络策略旨在解决这些问题。

Antrea 集群网络策略 (ACNP)

Antrea Cluster Network Policy 的設定現在正式開始。由於 Antrea 1.0 版本已經預設啟用 Antrea Cluster Network Policy,所以您可以立即開始進行設定,但首先我們需要了解一下 Antrea Cluster Network Policy 專屬的 Tier。

阶层

层次结构对于管理策略来说是一个概念,在希望为策略设定优先级的情况下非常有用。在初始设置中,层次结构通常被设定如下。

$ kubectl get tier --sort-by=.spec.priority
NAME          PRIORITY   AGE
emergency     50         37m
securityops   100        37m
networkops    150        37m
platform      200        37m
application   250        37m
baseline      253        37m

各级别的PRIORITY表示实际处理的优先级。数值越小,优先级越高。例如,如果有希望首先处理的最高优先级策略,可以将其设置为emergency,这样将首先进行处理。通过标准的NetworkPolicy设置的策略将在application Tier之后处理。

Tier可以通过自己创建来实现。在这里,让我们尝试使用以下的mytier.yaml清单文件创建一个新的Tier。

apiVersion: security.antrea.tanzu.vmware.com/v1alpha1
kind: Tier
metadata:
  name: mytier
spec:
  priority: 10
  description: "my custom tier"
$ kubectl apply -f mytier.yaml
tier.security.antrea.tanzu.vmware.com/mytier created
$
$ kubectl get tiers --sort-by=.spec.priority
NAME          PRIORITY   AGE
mytier        10         42s
emergency     50         45m
securityops   100        45m
networkops    150        45m
platform      200        45m
application   250        45m
baseline      253        45m

应用 Antrea 集群网络策略

我们现在要开始创建Antrea集群网络策略。首先,创建以下的acnp1.yaml文件。

apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-drop-access-to-redis
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - podSelector:
        matchLabels:
          app: redis
  ingress:
    - action: Allow
      from:
        - podSelector:
            matchLabels:
              app: other
      name: AllowFromOther
      enableLogging: false

这与我最初在 NetworkPolicy 中创建的 np1.yaml 非常相似,但实际操作有所不同。您可以使用以下命令来应用此清单。

$ kubectl apply -f acnp1.yaml
clusternetworkpolicy.crd.antrea.io/acnp-drop-access-to-redis created
$ 
$ kubectl get acnp
NAME                        TIER          PRIORITY   DESIRED NODES   CURRENT NODES   AGE
acnp-drop-access-to-redis   securityops   5          1               1               24s

以这种状态访问Guestbook应用程序时,不会阻止对后端的访问,因此可以正常显示。

image.png

当使用 NetworkPolicy 时,一旦策略生效,隐性的的拒绝规则将会激活,被拒绝的流量将会被丢弃。然而,ACNP 中,除非显性地写明 Drop 规则,流量将会被允许通过。
需要注意的是,ACNP 的类型为 ClusterNetworkPolicy,但是可以像上面的 kubectl get acnp 命令一样,也可以使用缩写 acnp 来进行操作。

这次,我们将修改acnp1.yaml并创建并应用以下的acp11.yaml。我们将通过podSelector明确指定源Pod,并将action更改为Drop。

apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-drop-access-to-redis
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - podSelector:
        matchLabels:
          app: redis
  ingress:
    - action: Drop
      from:
        - podSelector:
            matchLabels:
              app: guestbook
      name: DropFromGuestbook
      enableLogging: false

将此同样适用。

$ kubectl apply -f acnp11.yaml
clusternetworkpolicy.crd.antrea.io/acnp-drop-access-to-redis configured

然后,由于无法访问后端,显示变成了以下内容。

image.png

在这个ACNP中,tier被指定为securityops,priority被指定为5。priority表示在tier内部的处理优先级。
与上述情况相同,指定给securityops tier的策略将比标准的网络策略具有更高的优先级。例如,我们首先应用np1.yaml以创建阻止对后端的访问,然后应用acnp12.yaml,这样ACNP的处理将优先进行,从而允许访问后端。

apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-allow-access-to-redis
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - podSelector:
        matchLabels:
          app: redis
  ingress:
    - action: Allow
      from:
        - podSelector:
            matchLabels:
              app: guestbook
      name: AllowFromGuestbook
      enableLogging: false

我认为您现在理解了使用Antrea集群网络策略可以比标准的NetworkPolicy更清晰地指定源和目标的安全策略定义。

ACNP 对于命名空间之间的控制

我想在这里看看隔离命名空间的ACNP控制。在此之前,让我们再次确认一下K8s NetworkPolicy的行为。复制之前使用的np2.yaml,并创建一个名为np22.yaml的副本,以允许Guestbook应用程序之间的流量,并应用该副本。

$ cat np22.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-access-from-to-guestbook
spec:
  policyTypes:
  - Ingress
  podSelector:
    matchLabels:
      app: guestbook
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: guestbook
$
$ kubectl apply -f np22.yaml
networkpolicy.networking.k8s.io/allow-access-from-to-guestbook created
$ 

目前,已部署在 default 和 test 命名空间中的 Pod 的状态如下。

$ kubectl get pod -L app -n default
NAME                 READY   STATUS    RESTARTS   AGE   APP
guestbook-hmsrw      1/1     Running   0          28d   guestbook
guestbook-nl7xv      1/1     Running   0          28d   guestbook
guestbook-s9spp      1/1     Running   0          28d   guestbook
redis-master-blz4w   1/1     Running   0          21d   redis
redis-slave-fbsz6    1/1     Running   0          21d   redis
redis-slave-rpvqt    1/1     Running   0          21d   redis
$ 
$ kubectl get pod -L app -n test
NAME              READY   STATUS    RESTARTS   AGE   APP
guestbook-5w6ft   1/1     Running   0          27d   guestbook
guestbook-cfzfd   1/1     Running   0          27d   guestbook
guestbook-jlfpw   1/1     Running   0          27d   guestbook
$ 

在这种情况下,不允许来自test namespace中的Guestbook pod访问default namespace。因为K8s NetworkPolicy不允许跨越命名空间使用podSelector。实际上,不允许test namespace中的Guestbook Pod访问default namespace中的Guestbook pod,如下所示。

$ kubectl exec guestbook-5w6ft -n test  -it -- sh


BusyBox v1.21.1 (Ubuntu 1:1.21.0-1ubuntu1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

/app # wget -O - http://guestbook.default.svc.cluster.local:3000
Connecting to guestbook.default.svc.cluster.local:3000 (10.109.117.193:3000)
wget: can't connect to remote host (10.109.117.193): Connection timed out
/app #

让我们在中国文化产业协会尝试制定类似的政策并进行实践。

$ cat acnp2.yaml
apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-allow-access-from-to-guestbook
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - podSelector:
        matchLabels:
          app: guestbook
  ingress:
    - action: Allow
      from:
        - podSelector:
            matchLabels:
              app: guestbook
      name: AllowFromGuestbook
      enableLogging: false
$
$ kubectl apply -f acnp2.yaml
clusternetworkpolicy.crd.antrea.io/acnp-allow-access-from-to-guestbook created
$ 

与 np22.yaml 相同,我们在 appliedTo 和 from 的 podSelector 中都指定了标签 app: guestbook,但没有特别指定命名空间。另外,之前创建的 K8s NetworkPolicy 也保持不变。

$ kubectl get networkpolicy
NAMESPACE   NAME                             POD-SELECTOR    AGE
default     allow-access-from-to-guestbook   app=guestbook   32m
$ 
$ kubectl get acnp
NAME                                  TIER          PRIORITY   DESIRED NODES   CURRENT NODES   AGE
acnp-allow-access-from-to-guestbook   securityops   5          2               2               10m

当使用测试端的Pod再次访问默认端时,在这种情况下,将被授权如下。

/app # wget -O - http://guestbook.default.svc.cluster.local:3000
Connecting to guestbook.default.svc.cluster.local:3000 (10.109.117.193:3000)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta charset="utf-8">
    <meta content="width=device-width" name="viewport">
    <link href="style.css" rel="stylesheet">
    <title>Guestbook</title>
  </head>
  <body>
    <div id="header">
      <h1>Guestbook</h1>
    </div>

(snip...)

  </body>
</html>
-                    100% |*******************************|   922   0:00:00 ETA
/app #

另外,在 ACNP 中,我们可以同时使用 podSelector 和 namespaceSelector 来明确指定适用于每个命名空间的目标和源 pod。我们可以编辑 acnp2.yaml,在其中添加 namespaceSelector 条件,从而创建 acnp22.yaml。

$ cat acnp22.yaml
apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-allow-access-from-to-guestbook
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - podSelector:
        matchLabels:
          app: guestbook
      namespaceSelector:
        matchLabels:
          project: prod
  ingress:
    - action: Allow
      from:
        - podSelector:
            matchLabels:
              app: guestbook
          namespaceSelector:
            matchLabels:
              project: test
      name: AllowFromGuestbook
      enableLogging: false
$
$ kubectl apply -f acnp22.yaml
clusternetworkpolicy.crd.antrea.io/acnp-allow-access-from-to-guestbook configured
$ 

通过这个修订,接收方命名空间的标签条件添加了 project: prod,发送方命名空间的标签条件添加了 project: test。然而,接收方的 Guestbook pod 存在于默认的命名空间中,但由于还未添加标签到命名空间中,所以通信将失败。

/app # wget -O - http://guestbook.default.svc.cluster.local:3000
Connecting to guestbook.default.svc.cluster.local:3000 (10.109.117.193:3000)
wget: can't connect to remote host (10.109.117.193): Connection timed out
/app #

在此,我們將在默認命名空間中添加標籤。

$ kubectl label ns default project=prod
namespace/default labeled
$ 
$ kubectl get ns --show-labels
NAME              STATUS   AGE   LABELS
default           Active   29d   project=prod
kube-node-lease   Active   29d   <none>
kube-public       Active   29d   <none>
kube-system       Active   29d   <none>
test              Active   27d   project=test

すると test namespace 内の Guestbook pod から default namespace 内の Guestbook pod にアクセスできるようになりました。

/app # wget -O - http://guestbook.default.svc.cluster.local:3000
Connecting to guestbook.default.svc.cluster.local:3000 (10.109.117.193:3000)
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <meta charset="utf-8">
    <meta content="width=device-width" name="viewport">
    <link href="style.css" rel="stylesheet">
    <title>Guestbook</title>
  </head>
  <body>
    <div id="header">
      <h1>Guestbook</h1>
    </div>

(snip...)

  </body>
</html>
-                    100% |*******************************|   922   0:00:00 ETA
/app #

このように、Antrea Cluster Network Policy では、namespace に限定されないクラスターレベルのネットワークポリシーを設定することが可能です。クラスター管理者は namespace に依存しないクラスターレベルのセキュリティポリシーを設定することができるようになります。

ClusterGroup

ClusterGroup は ACNP の特徴的な機能の一つで、エンドポイントをグルーピングするルールを NetworkPolicy の外で作成し再利用することができます。これまでに紹介した podSelector や namespaceSelector、おなじみの ipBlock 以外に、K8s Service を利用する serviceReference やグルーピングのネスト構造を定義できる childGroups といった定義を使うことが可能です。

在使用ClusterGroup创建规则之前,需要先将以前创建的所有策略全部删除。

$ kubectl get networkpolicy --no-headers | awk '{print $1}'| xargs kubectl delete networkpolicy
networkpolicy.networking.k8s.io "allow-access-from-to-guestbook" deleted
$ 
$ kubectl get acnp --no-headers | awk '{print $1}'| xargs kubectl delete acnp
clusternetworkpolicy.crd.antrea.io "acnp-allow-access-from-to-guestbook" deleted

そして default namespace 内の Pod へのすべてのトラフィックを暗黙的に不許可にするために以下の acnp-dropany.yaml を作成し適用します。適用先の Tier として baseline を指定しています。この場合、このルールは K8s NetworkPolicy を含むすべてのポリシールールが評価された後に適用されるようになります。

$ cat acnp-dropany.yaml

apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-drop-any-in-production
spec:
  priority: 100
  tier: baseline
  appliedTo:
    - podSelector: {}
      namespaceSelector:
        matchLabels:
          project: prod
  ingress:
    - action: Drop
      from:
        - podSelector: {}
      name: DropFromAny
      enableLogging: false
$
$ kubectl apply -f acnp-dropany.yaml
clusternetworkpolicy.crd.antrea.io/acnp-drop-any-in-production created
$
image.png

そこで、 フロントエンドとバックエンド間の通信を許可するポリシーを記載していきますが、そこで ClusterGroup を使用してみます。ここでは、Redis バックエンドサービスのグルーピングに serviceReference と childGroups を使ってみます。

$ cat cg1.yaml
apiVersion: crd.antrea.io/v1alpha2
kind: ClusterGroup
metadata:
  name: cg-guestbook
spec:
  podSelector:
    matchLabels:
      app: guestbook
---
apiVersion: crd.antrea.io/v1alpha2
kind: ClusterGroup
metadata:
  name: cg-redis-master
spec:
  serviceReference:
    name: redis-master
    namespace: default
---
apiVersion: crd.antrea.io/v1alpha2
kind: ClusterGroup
metadata:
  name: cg-redis-slave
spec:
  serviceReference:
    name: redis-slave
    namespace: default
---
apiVersion: crd.antrea.io/v1alpha2
kind: ClusterGroup
metadata:
  name: cg-redis-nested
spec:
  childGroups: [cg-redis-master, cg-redis-slave]
$
$ kubectl apply -f cg1.yaml
clustergroup.crd.antrea.io/cg-guestbook created
clustergroup.crd.antrea.io/cg-redis-master created
clustergroup.crd.antrea.io/cg-redis-slave created
clustergroup.crd.antrea.io/cg-redis-nested created
$ 

次にこれらの ClusterGroup を利用した ACNP を acnp3.yaml として作成していきます。

$ cat acnp3.yaml
apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-allow-access-to-guestbook
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - group: "cg-guestbook"
  ingress:
    - action: Allow
      from:
        - group: "cg-guestbook"
      name: AllowToGuestbook
      enableLogging: false
---
apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-allow-access-to-redis
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - group: "cg-redis-nested"
  ingress:
    - action: Allow
      from:
        - group: "cg-guestbook"
      name: AllowFromGuestbookToRedis
      enableLogging: false
---
apiVersion: crd.antrea.io/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: acnp-allow-access-to-redis-slave
spec:
  priority: 5
  tier: securityops
  appliedTo:
    - group: "cg-redis-slave"
  ingress:
    - action: Allow
      from:
        - group: "cg-redis-master"
      name: AllowToRedisSlave
      enableLogging: false
$
$ kubectl apply -f acnp3.yaml
clusternetworkpolicy.crd.antrea.io/acnp-allow-access-to-guestbook created
clusternetworkpolicy.crd.antrea.io/acnp-allow-access-to-redis created
clusternetworkpolicy.crd.antrea.io/acnp-allow-access-to-redis-slave created
$ 

在这种状态下通过浏览器访问,允许访问 Redis 后端并成功返回正常响应。

image.png

いかがでしたでしょうか。Antrea Cluster Network Policy では、クラスターレベルで柔軟なエンドポイントのグルーピングが可能になっていることを理解いただけたかと思います。

我希望在接下来的时间里,能够为大家介绍更详细的Antrea集群网络策略操作方法等内容。

广告
将在 10 秒后关闭
bannerAds