指定IPのみからアクセスできるようKubernetesの設定を弄ってみた

#はじめに
　　Kubernetesを利用する際に、指定のIPアドレス以外からのアクセスを防ぎたい時があると思います。今回はIBM Cloud Kubernets Service(IKS)を利用して開発環境の構築を行うことになりましたが、外部からのアクセスを防ぎたいと思っていろいろ設定して見ました。

#やったこと
- NodeのすべてのPortを閉じる。
- すべてのアクセスを禁止と設定する。
- 自分指定のIPからのアクセスを許可する。

#前提作業ーCalicoの設定
　　ネットワークポリシーの設定を行うにはまずCalicoというものが必要でした。

##### Calicoの導入
１．calicoのモジュールをダウンロードする。
calicoctlのモジュールをダウンロード：https://github.com/projectcalico/calicoctl/releases/tag/v3.1.1
Terminalを開き以下のコマンドを打ちます。
２．ダウンロードしたモジュールを「/usr/local/bin/calicoctl」に移動する。

```shell
$ mv ~/Downloads/calicoctl-darwin-amd64 /usr/local/bin/calicoctl
```
３．実行権限を付与する。

```shell
$ chmod +x /usr/local/bin/calicoctl
```
４．実行確認

```shell
$ calicoctl version
Client Version:    v3.1.1
Build date:        2018-04-19T23:47:00+0000 
apiVersion: projectcalico.org/v3
Git commit:        86318310
no etcd endpoints specified
```
##### Calicoの設定のための環境情報の取得
以下の操作はIBM Cloudにすでにログインしたことを前提としています。

１．Adminでkubernetes環境へアクセスするためのConfigファイルをダウンロードします。

```shell
$   ibmcloud ks cluster-config iks-env --admin
export KUBECONFIG=/Users/Kadoiri/.bluemix/plugins/c…
```
２．↑の操作で取得したexport文をterminalにコピペする。

```shell
$   export KUBECONFIG=/Users/Kadoiri/.bluemix/plugins/c…
```
３．EndPointを取得する。

```shell
$   kubectl get cm -n kube-system calico-config -o yaml | grep "etcd_endpoints:" | awk '{ print $2 }'
https://161.xxx.xxx.xxx:xxxxx   ←後で使用
```
４．IKSへ接続用ファイルの場所確認

```shell
$ dirname $KUBECONFIG
/Users/Kadoiri/.bluemix/plugins/container-service/clusters/iks-jump-admin
$ ls /Users/Kadoiri/.bluemix/plugins/container-service/clusters/iks-jump-admin
total 32
drwx------  6 Kadoiri  staff   192  9 19 10:51 .
drwxr-xr-x  7 Kadoiri  staff   224  9 19 10:51 ..
-rw-r--r--  1 Kadoiri  staff  3243  9 19 10:51 admin-key.pem   ←後で使用
-rw-r--r--  1 Kadoiri  staff  1822  9 19 10:51 admin.pem   ←後で使用
-rw-r--r--  1 Kadoiri  staff  1769  9 19 10:51 ca-xxxxx-iks-env.pem   ←後で使用
-rw-r--r--  1 Kadoiri  staff   375  9 19 10:51 kube-config-xxxxx-iks-env.yml
```
##### Calicoの設定ファイルの作成

１．Calico設定ファイル配置用ディレクトリの作成

```shell
$   sudo mkdir -p /etc/calico/
```
2．Calico設定ファイルの作成

```shell
$ sudo vi /etc/calico/calicoctl.cfg
```

```cfg
apiVersion: projectcalico.org/v3
 kind: CalicoAPIConfig
 metadata:
 spec:
     datastoreType: etcdv3
     etcdEndpoints: https://161.xxx.xxx.xxx:xxxxx  （Calicoの設定のための環境情報の取得の手順3参照）
     etcdKeyFile: /Users/Kadoiri/.bluemix/plugins/container-service/clusters/iks-env-admin/admin-key.pem  （Calicoの設定のための環境情報の取得の手順4参照）
     etcdCertFile: /Users/Kadoiri/.bluemix/plugins/container-service/clusters/iks-env-admin/admin.pem  （Calicoの設定のための環境情報の取得の手順4参照）
     etcdCACertFile: /Users/Kadoiri/.bluemix/plugins/container-service/clusters/iks-env-admin/ca-xxxxx-iks-env.pem  （Calicoの設定のための環境情報の取得の手順4参照）

```
3．Calicoの動作確認

```shell
$ calicoctl get nodes
NAME
kube-xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-w1.cloud.ibm
kube-xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-w2.cloud.ibm
kube-xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-w3.cloud.ibm
```
#NodeのすべてのPortを閉じる。

１．ネットワークポリシーファイルの作成。
ここではファイル名を「policy.yaml」にする。

```yaml
  apiVersion: projectcalico.org/v3
  kind: GlobalNetworkPolicy
  metadata:
    name: deny-kube-node-port-services
  spec:
    applyOnForward: true
    ingress:
    - action: Deny
      destination:
        ports:
        - 30000:32767
      protocol: TCP
      source: {}
    - action: Deny
      destination:
        ports:
        - 30000:32767
      protocol: UDP
      source: {}
    preDNAT: true
    selector: ibm.role in { 'worker_public' }
    order: 1100
    types:
    - Ingress
```
２．ネットワークポリシーの設定

```shell
$　calicoctl apply -f policy.yaml
```
#すべてのアクセスを禁止と設定する。

１．subnetの確認

```shell
$ ibmcloud ks subnets
OKID        Network             Gateway          VLAN ID   Type      Bound Cluster 
17xxxxx   10.xx.xx.xxx/29     10.xx.xxx.xxx     2454213   private      
18xxxxx   10.xxx.xx.xxx/29    10.xx.xxx.xxx    2468601   private   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   
18xxxxx   130.xxx.xx.xxx/29   130.xx.xxx.xxx   2454211   public       
18xxxxx   161.xxx.xx.xxx/29   161.xx.xxx.xxx   2468599   public    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 　ここの「161.xxx.xx.xxx/29」を後で使用
```
２．接続禁止用のyamlファイルの作成
ここではファイル名を「deny-exposed.yaml」にする。

```yaml
apiVersion: projectcalico.org/v3
 kind: GlobalNetworkPolicy
 metadata:
   name: deny-exposed
 spec:
   applyOnForward: true
   ingress:
   - action: Deny
     destination:
       nets:
       - <subnet>
       ports:
       - 80
     protocol: TCP
     source: {}
   - action: Deny
     destination:
       nets:
       - 161.xxx.xx.xxx/29 ここは↑にて取得したsubnet
       ports:
       - 80
     protocol: UDP
     source: {}
   - action: Deny
     destination:
       nets:
       - <subnet>
       ports:
       - 443
     protocol: TCP
     source: {}
   - action: Deny
     destination:
       nets:
       - <subnet>
       ports:
       - 443
     protocol: UDP
     source: {}
   preDNAT: true
   selector: ibm.role=='worker_public'
   order: 1100
   types:
   - Ingress
```
３．設定を反映する。

```shell
$ calicoctl apply -f deny-exposed.yaml
```

#自分指定のIPアドレスからのアクセスを許可する。

１．指定のIPからのアクセス許可用yamlファイルの作成
ここではファイル名を「allow-IP.yaml」にする。

```yaml
- apiVersion: projectcalico.org/v3
  kind: GlobalNetworkPolicy
  metadata:
    name: ibm-public-allow
  spec:
    applyOnForward: true
    ingress:
    - action: Allow
      destination:
        nets:
        - 161.xxx.xx.xxx/29 ここは↑にて取得したsubnet
      source:
        nets:
        - xxx.xxx.xxx.x/xx ここに指定したいIPを記入
        - xxx.xxx.xx.x/xx
        - xxx.xxx.xx.x/xx
    order: 500
    selector: ibm.role in { 'worker_public', 'master_public' }
    preDNAT: true
    types:
    - Ingress
```
３．設定を反映する。

```shell
$ calicoctl apply -f allow-IP.yaml
```

以上の設定で自分指定のIPのみからのアクセスになります。