Container Engine for Kubernetes (OKE) で NetworkPolicy を設定する

# はじめに
OKEで [NetworkPolicy](https://kubernetes.io/ja/docs/concepts/services-networking/network-policies/) の設定方法を確認したいと思います。
NetworkPolicyを利用するには、NetworkPolicyに対応しているCNIネットワークプロバイダーでKubernetesクラスタを構築する必要があります。OKEはネットワークプロバイダーとして flannel が使われていますが、flannel はNetworkPolicyに対応していないので、対応しているネットワークプロバイダーをデプロイする必要があります。

```
$ kubectl get pod -A
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE
kube-system   coredns-54478696d-fvct7                1/1     Running   0          6d11h
kube-system   coredns-54478696d-h4g6v                1/1     Running   0          4d9h
kube-system   coredns-54478696d-j6kpx                1/1     Running   0          6d11h
kube-system   csi-oci-node-2zwqk                     1/1     Running   0          6d11h
kube-system   csi-oci-node-l9dvq                     1/1     Running   1          6d11h
kube-system   csi-oci-node-qh4n8                     1/1     Running   0          6d11h
kube-system   kube-dns-autoscaler-65f7579cb4-976kd   1/1     Running   0          6d11h
kube-system   kube-flannel-ds-g8lwr                  1/1     Running   1          6d11h
kube-system   kube-flannel-ds-rp59l                  1/1     Running   0          6d11h
kube-system   kube-flannel-ds-srztk                  1/1     Running   1          6d11h
kube-system   kube-proxy-56v4j                       1/1     Running   0          6d11h
kube-system   kube-proxy-t2tf5                       1/1     Running   0          6d11h
kube-system   kube-proxy-vbn96                       1/1     Running   0          6d11h
kube-system   proxymux-client-66l6q                  1/1     Running   0          6d11h
kube-system   proxymux-client-c8975                  1/1     Running   0          6d11h
kube-system   proxymux-client-sv9tg                  1/1     Running   0          6d11h
```

# Calicoのデプロイ
NetworkPolicyに対応しているCNIネットワークプロバイダーとして、マニュアルを参考にCalicoをデプロイします。

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengsettingupcalico.htm

## マニフェストのダウンロード、編集
ここでは、現時点（2022/1/6）で最新の3.21を使用します。

```
$ curl https://docs.projectcalico.org/v3.21/manifests/calico-policy-only.yaml -o calico-321.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  213k  100  213k    0     0  1095k      0 --:--:-- --:--:-- --:--:-- 1095k
```

Calico のマニフェストにはPod CIDRブロックが記載されています。デフォルトは「192.168.0.0/16」になっていますので、KubernetesクラスタのPod CIDRブロックに合わせて編集します。

OCIコンソールの「クラスタ詳細」から「ポッドCIDR」の設定値を確認します。

![oke.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/7bd8970b-0c4e-5ec4-f38f-7e2fbd6934dd.png)

確認した値に置き換えます。

```
$ export POD_CIDR="10.244.0.0/16"
$ sed -i -e "s?192.168.0.0/16?$POD_CIDR?g" calico-321.yaml
$ grep $POD_CIDR calico-321.yaml 
            #   value: "10.244.0.0/16"
```

## Calico のデプロイ

置き換えたマニフェストを apply します。

```
$ kubectl apply -f calico-321.yaml 
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.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/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.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-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
service/calico-typha created
deployment.apps/calico-typha created
Warning: policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
poddisruptionbudget.policy/calico-typha created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
poddisruptionbudget.policy/calico-kube-controllers created

$ kubectl get pod -A |grep calico
kube-system   calico-kube-controllers-6b9fbfff44-v2vkt   1/1     Running   1          58s
kube-system   calico-node-5kqtd                          1/1     Running   0          58s
kube-system   calico-node-fcnwg                          1/1     Running   0          58s
kube-system   calico-node-xsnj4                          1/1     Running   0          58s
kube-system   calico-typha-6ff8665955-z6699              1/1     Running   0          58s
```

# NetworkPolicy の設定と動作確認

Calico の Tutorial を参考にNetworkPolicyを設定して、動作を確認します。

https://projectcalico.docs.tigera.io/security/tutorials/kubernetes-policy-basic

## demo環境の作成

Namespaceを作成します。

```
$ kubectl create ns policy-demo
namespace/policy-demo created
```
demo用のPodをデプロイして、Serviceを設定します。

```
$ kubectl create deployment --namespace=policy-demo nginx --image=nginx
deployment.apps/nginx created
$ kubectl get pod -n policy-demo
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-j62km   1/1     Running   0          19s
$ kubectl expose --namespace=policy-demo deployment nginx --port=80
service/nginx exposed
$ kubectl get svc -n policy-demo
NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.96.244.66   <none>        80/TCP    21s
```

### demo環境にアクセスできることを確認

NetworkPolicyを設定する前に、アクセスできることを確認します。

```
$ kubectl run --namespace=policy-demo access --rm -ti --image busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -q nginx -O -
<!DOCTYPE html>
<html>
・・省略・・
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
・・省略・・
</html>
/ # exit
Session ended, resume using 'kubectl attach access -c access -i -t' command when the pod is running
pod "access" deleted
```

## NetworkPolicy の設定

NetworkPolicy のマニフェストを作成します。
Namespace「policy-demo」内のPodに対する通信をすべて拒否します。

```
$ cat <<EOF >np.yaml
> kind: NetworkPolicy
> apiVersion: networking.k8s.io/v1
> metadata:
>   name: default-deny
>   namespace: policy-demo
> spec:
>   podSelector:
>     matchLabels: {}
> EOF
```

マニフェストをapplyして、確認します。

```
$ kubectl apply -f np.yaml 
networkpolicy.networking.k8s.io/default-deny created
$ kubectl describe networkpolicy default-deny -n policy-demo
Name:         default-deny
Namespace:    policy-demo
Created on:   2022-01-06 02:15:14 +0000 UTC
Labels:       <none>
Annotations:  <none>
Spec:
  PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
  Allowing ingress traffic:
    <none> (Selected pods are isolated for ingress connectivity)
  Not affecting egress traffic
  Policy Types: Ingress
```

## 動作確認
Podをデプロイして通信が拒否されることを確認します。

```
$ kubectl run --namespace=policy-demo access --rm -ti --image busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -q --timeout=5 nginx -O -
wget: download timed out
/ # exit
Session ended, resume using 'kubectl attach access -c access -i -t' command when the pod is running
pod "access" deleted
```

NetworkPolicy 設定前に許可されていた通信が拒否されていることが確認できます。