Rancherの「Network Policy Manager」機能を試す

# Network Policy Managerとは
[公式] (http://rancher.com/docs/rancher/v1.4/en/rancher-services/network-policy/)に詳しい解説がありますが、ざっくり説明するとRancherにおける環境（Environment）内においては、デフォルト状態では全てのコンテナ同士の相互通信が可能で、これはCattle、Kubernetes、Mesosといった各オーケストレーションツールでの共通事項です。

KubernetesはNamespaceで分離が可能でしたがCattleはそういった機能がありませんでした。（k8s詳しくないので間違えてたらツッコんでください）

それを可能にしたのがNetwork Policy Managerです。

# 試してみよう
## 環境
ノードは3つでやりました。バージョンは下記の通りです。

| 役割  | OS | Rancher/Server | Rancher/Agent| Docker |
|:-:|:-:|:-:|:-:|:-:|:-:|
| Rancher/Server  | RancherOS 1.0.2  | 1.6.4  | -  | 17.03.1-ce |
| Rancher/Agent  | RancherOS 1.0.2  | -  | 1.2.5  | 17.03.1-ce |
| Rancher/Agent  | RancherOS 1.0.2  | -  | 1.2.5  | 17.03.1-ce |

##確認
Network Policy Managerを導入する前に、とりあえず

 * dokuwiki
 * wordpress
 
の2つのstackを作成しました。

![2017-07-20_11h34_01.jpg](https://qiita-image-store.s3.amazonaws.com/0/151399/b431e642-d3fa-44cd-99b3-22a41f08312c.jpeg)

コンテナは4つ出来てます。dokuwikiとwordpressでHOSTが分かれてるようです。

![2017-07-20_11h40_22.jpg](https://qiita-image-store.s3.amazonaws.com/0/151399/932d3308-bb61-048a-7cb6-0f7b35e1df0b.jpeg)

| 名前 | IPアドレス |
|:--|:-:|
|dokuwiki01-dokuwiki-server-1    | 10.42.255.137 |
|wordpress01-db-1  | 10.42.231.102  |
|wordpress01-wordpress-1  | 10.42.173.168  |

この段階でコンテナ間通信は可能なのか？

dokuwiki01-dokuwiki-server-1から、他のコンテナにPINGしてみましょう。

```shell-session:dokuwiki01-dokuwiki-server-1からwordpress01-db-1
root@dw:/var/www/html# ping wordpress01-db-1
PING wordpress01-db-1.rancher.internal (10.42.231.102): 56 data bytes
64 bytes from 10.42.231.102: icmp_seq=0 ttl=62 time=0.550 ms
64 bytes from 10.42.231.102: icmp_seq=1 ttl=62 time=0.557 ms
64 bytes from 10.42.231.102: icmp_seq=2 ttl=62 time=0.445 ms
^C--- wordpress01-db-1.rancher.internal ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.445/0.517/0.557/0.051 ms
```

```shell-session:dokuwiki01-dokuwiki-server-1からwordpress01-wordpress-1
root@dw:/var/www/html# ping wordpress01-wordpress-1
PING wordpress01-wordpress-1.rancher.internal (10.42.173.168): 56 data bytes
64 bytes from 10.42.173.168: icmp_seq=0 ttl=62 time=1.019 ms
64 bytes from 10.42.173.168: icmp_seq=1 ttl=62 time=0.517 ms
64 bytes from 10.42.173.168: icmp_seq=2 ttl=62 time=0.528 ms
64 bytes from 10.42.173.168: icmp_seq=3 ttl=62 time=0.519 ms
^C--- wordpress01-wordpress-1.rancher.internal ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.517/0.646/1.019/0.216 ms
```

名前解決もコンテナ間通信も可能ですね！

## Network Policy Managerの導入

導入は凄ーく簡単で、この「Network Policy Manager」というカタログをデプロイするだけ。

![2017-07-20_13h36_33.jpg](https://qiita-image-store.s3.amazonaws.com/0/151399/b9717e23-5364-2910-5d2b-73a202b36f1a.jpeg)

環境の管理画面にこんな項目が増えてます。

![2017-07-20_13h43_30.jpg](https://qiita-image-store.s3.amazonaws.com/0/151399/c2f30f29-9c99-9925-d994-152dfb4bae0b.jpeg)


環境の編集画面に行くと、ポリシーを変更できるようです。

![2017-07-20_13h46_35.jpg](https://qiita-image-store.s3.amazonaws.com/0/151399/5e677b8c-4b8f-816a-ca48-6dea59207740.jpeg)

では、試しに「その他すべて」を拒否にしてみます。これでスタック間の通信は拒否されるようになったハズです。

![2017-07-20_13h53_28.jpg](https://qiita-image-store.s3.amazonaws.com/0/151399/8e3ba77a-9190-c0ed-b0cf-a0203063e469.jpeg)

では、さっきと同じようにPINGしてみましょう

```shell-session:dokuwiki01-dokuwiki-server-1からwordpress01-db-1
root@dw:/var/www/html# ping wordpress01-db-1
PING wordpress01-db-1.rancher.internal (10.42.231.102): 56 data bytes
^C--- wordpress01-db-1.rancher.internal ping statistics ---
7 packets transmitted, 0 packets received, 100% packet loss
```

```shell-session:dokuwiki01-dokuwiki-server-1からwordpress01-wordpress-1
root@dw:/var/www/html# ping wordpress01-wordpress-1
PING wordpress01-wordpress-1.rancher.internal (10.42.173.168): 56 data bytes
^C--- wordpress01-wordpress-1.rancher.internal ping statistics ---
10 packets transmitted, 0 packets received, 100% packet loss
root@dw:/var/www/html#
```
名前解決はできるけど、通信ができなくなってるね！ブラボー！

環境の管理画面でも、スタックとサービス内はOKでそれ以外は拒否になってるのが確認できます。

![2017-07-20_14h01_27.jpg](https://qiita-image-store.s3.amazonaws.com/0/151399/c0e3e569-cf5f-b9c2-2e1e-c5d83853117b.jpeg)

# 仕組み

仕組みはiptablesを使ってるようです。

導入前、導入直後、設定後のそれぞれのiptablesのエントリをご覧ください。

### 導入前

```shell-session
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
CATTLE_FORWARD  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain CATTLE_FORWARD (1 references)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            mark match 0x1068
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            mark match 0x4000

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
```


### 導入後

```shell-session
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
CATTLE_NETWORK_POLICY  all  --  10.42.0.0/16         10.42.0.0/16
CATTLE_FORWARD  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain CATTLE_FORWARD (1 references)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            mark match 0x1068
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            mark match 0x4000

Chain CATTLE_NETWORK_POLICY (1 references)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
```


### 設定後

```shell-session
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
CATTLE_NETWORK_POLICY  all  --  10.42.0.0/16         10.42.0.0/16
CATTLE_FORWARD  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain CATTLE_FORWARD (1 references)
target     prot opt source               destination
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            mark match 0x1068
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            mark match 0x4000

Chain CATTLE_NETWORK_POLICY (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-S-9363986724208910864 src
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-S-3308273598065079164 src
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-S-15242666270991449833 src
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-S-13647065898704439585 src
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-S-17252670097841251797 src
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-16499342654355883421 dst match-set RNCH-U-6570623208036296680 src ctstate NEW,RELATED,ESTABLISHED
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-6570623208036296680 dst match-set RNCH-U-16499342654355883421 src ctstate RELATED,ESTABLISHED
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-779566293458752651 dst match-set RNCH-U-4408526256349682844 src ctstate NEW,RELATED,ESTABLISHED
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-4408526256349682844 dst match-set RNCH-U-779566293458752651 src ctstate RELATED,ESTABLISHED
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-2522123324233178460 dst match-set RNCH-U-7387156407552891691 src
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-13545600463768368355 dst match-set RNCH-U-10203268415531602422 src
RETURN     all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-9270456092601784113 dst match-set RNCH-U-16496023848717693940 src
DROP       all  --  0.0.0.0/0            0.0.0.0/0            match-set RNCH-U-10594850245288165044 dst

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
```

まず、「CATTLE_NETWORK_POLICY」というターゲットが追加され、設定していくことでエントリが追加されていくようです。

# まとめ

コンテナ、スタック、サービスといった様々な単位で制御が可能なので、同一環境で複数アプリケーションを運用する場合は便利なのではないでしょうか。

Network Policy Manager自体もコンテナなので、HOSTに与える影響はありません。

カタログを追加するだけでセキュリティを強化できる。

そう、Rancherならね