OpenStack on Kubernetesを、GKEで試してみる

Dockerコンテナのオーケストレーションとして、巷で話題となっている"Kubernetes"の基本動作を試してみました。
目標感としては、マイクロサービス的な、複数のDockerコンテナが協調しあって、全体動作の振る舞いが決定されるような機能確認を試してみたかったので、OpenStack内部モジュールを、をKubernetesで動作させることにしました。なお、OpenStackのコアコンポーネント（Nova, Neutron, Keystone, Glanceモジュール）と、MYSQLの５つのDockerコンテナを題材にしてみました。
いま時点では、libvirt経由でVMインスタンスをデプロイする部分は、省略しています。

# ■ 事前準備
(1) 事前に、Cloud SDKを有効にしておく
gcloudコマンドで作業できるように、[Cloud SDK](https://cloud.google.com/sdk/)をセットアップしておく


(2) Webコンソールから、新たにプロジェクトを作成する
今回、gke-sampleというプロジェクトを作成し、プロジェクトID"gke-sample-211005"をメモっておく。
![gke-sample.png](https://qiita-image-store.s3.amazonaws.com/0/103595/12225171-0916-7551-875c-fb043c299648.png)



(3) プロジェクトでのAPIを有効にしておく
- Google Compute Engine API
- Kubernetes Engine API


(4) 以下、gloudコマンドを使用して、zone設定を行う

```
$ export PROJECT_ID="gke-sample-211005"
$ gcloud config set project $PROJECT_ID
$ gcloud config set compute/zone asia-northeast1-a
$ gcloud config set container/new_scopes_behavior true
$ gcloud config list
[compute]
zone = asia-northeast1-a
[container]
new_scopes_behavior = true
[core]
disable_usage_reporting = False
project = gke-sample-211005

Your active configuration is: [default]
```
(5) Cloud Datastore環境を準備する

```
$ gcloud auth login

 ... snip

$ gcloud app create --region=asia-northeast1
You are creating an app for project [gke-sample-211005].
WARNING: Creating an App Engine application for a project is irreversible and the region
cannot be changed. More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.

done.            
Success! The app is now created. Please use `gcloud app deploy` to deploy your first app.
```
こんな感じで環境準備できた！
![storage.png](https://qiita-image-store.s3.amazonaws.com/0/103595/f60db6fd-9cd7-102b-45a4-f7fdb5b806c7.png)


# ■ Kubernetes Cluster環境の各種セットアップ
(1) kubectlコマンドを有効にする

```
$ gcloud components install kubectl


Your current Cloud SDK version is: 209.0.0
Installing components from version: 209.0.0

┌──────────────────────────────────────────────────────────────────┐
│               These components will be installed.                │
├─────────────────────┬─────────────────────┬──────────────────────┤
│         Name        │       Version       │         Size         │
├─────────────────────┼─────────────────────┼──────────────────────┤
│ kubectl             │               1.9.7 │             14.8 MiB │
│ kubectl             │                     │                      │
└─────────────────────┴─────────────────────┴──────────────────────┘

For the latest full release notes, please visit:
  https://cloud.google.com/sdk/release_notes

Do you want to continue (Y/n)?  y

╔════════════════════════════════════════════════════════════╗
╠═ Creating update staging area                             ═╣
╠════════════════════════════════════════════════════════════╣
╠═ Installing: kubectl                                      ═╣
╠════════════════════════════════════════════════════════════╣
╠═ Installing: kubectl                                      ═╣
╠════════════════════════════════════════════════════════════╣
╠═ Creating backup and activating new installation          ═╣
╚════════════════════════════════════════════════════════════╝

Performing post processing steps...done.                                                                        

Update done!
```

(2) Kubernetesクラスタを作成する

```
$ gcloud container clusters create openstack-sample \
> --num-nodes 3 \
> --machine-type=n1-standard-1 \
> --no-enable-ip-alias
This will enable the autorepair feature for nodes. Please see
https://cloud.google.com/kubernetes-engine/docs/node-auto-repair for more
information on node autorepairs.

Creating cluster openstack-sample...done.                                                                                                 
Created [https://container.googleapis.com/v1/projects/gke-sample-211005/zones/asia-northeast1-a/clusters/openstack-sample].
To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/asia-northeast1-a/openstack-sample?project=gke-sample-211005
kubeconfig entry generated for openstack-sample.
NAME              LOCATION           MASTER_VERSION  MASTER_IP   MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
openstack-sample  asia-northeast1-a  1.9.7-gke.3     x.x.x.x     n1-standard-1  1.9.7-gke.3   3          RUNNING
```
ちなみに、現時点(2018年7月22日)で利用可能なk8sクラスタバージョンは、以下で確認できるようです

```
$ gcloud container get-server-config
Fetching server config for asia-northeast1-a
defaultClusterVersion: 1.9.7-gke.3
defaultImageType: COS
validImageTypes:
- COS
- UBUNTU
validMasterVersions:
- 1.10.5-gke.3
- 1.10.5-gke.0
- 1.10.4-gke.2
- 1.9.7-gke.4
- 1.9.7-gke.3
- 1.9.6-gke.1
- 1.8.12-gke.2
- 1.8.12-gke.1
- 1.8.10-gke.0
validNodeVersions:
- 1.10.5-gke.3
- 1.10.5-gke.2
- 1.10.5-gke.0
- 1.10.4-gke.2
- 1.10.4-gke.0
- 1.10.2-gke.3
- 1.10.2-gke.1
- 1.9.7-gke.4
- 1.9.7-gke.3
- 1.9.7-gke.1
- 1.9.7-gke.0
- 1.9.6-gke.1
- 1.9.3-gke.0
- 1.8.12-gke.2
- 1.8.12-gke.1
- 1.8.12-gke.0
- 1.8.10-gke.0
- 1.8.9-gke.1
- 1.8.8-gke.0
- 1.7.15-gke.0
- 1.7.12-gke.2
- 1.6.13-gke.1
```
(3) Kubernetesクラスタの認証情報をダウンロードする

```
$ gcloud container clusters get-credentials openstack-sample
Fetching cluster endpoint and auth data.
kubeconfig entry generated for openstack-sample.
```

(4) gcloudコンポーネントを最新化したのち、kubectlを用いて、k8sのバージョンを確認してみる

```
$ gcloud components update
... (snip)

$ kubectl version --short
Client Version: v1.9.7
Server Version: v1.9.7-gke.3
```
(5) ノード情報を確認する

```
$ kubectl get nodes
NAME                                              STATUS    ROLES     AGE       VERSION
gke-openstack-sample-default-pool-5954c0d1-1lww   Ready     <none>    4m        v1.9.7-gke.3
gke-openstack-sample-default-pool-5954c0d1-hzsj   Ready     <none>    4m        v1.9.7-gke.3
gke-openstack-sample-default-pool-5954c0d1-r4c3   Ready     <none>    4m        v1.9.7-gke.3
```
(6) Kubernetesクラスタ環境を確認する

```
$ kubectl cluster-info
Kubernetes master is running at https://x.x.x.x
GLBCDefaultBackend is running at https://x.x.x.x/api/v1/namespaces/kube-system/services/default-http-backend:http/proxy
Heapster is running at https://x.x.x.x/api/v1/namespaces/kube-system/services/heapster/proxy
KubeDNS is running at https://x.x.x.x/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
kubernetes-dashboard is running at https://x.x.x.x/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy
Metrics-server is running at https://x.x.x.x/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
```

# ■ Dockerコンテナのイメージ準備
OpenStackのKeystone, glanceサービスをDockerコンテナで動作させることを目的としたGitリポジトリ：[openstack-docker](https://github.com/ttsubo/openstack-docker) に配備しておきました。すでに、EOLになってしまったOpenStack Mitaka版で試していますが、あまり深い意図はありません。
あくまでも、サンプル版ということで。。。。



(1) Dockerイメージを作成しておく

```
$ docker images|grep -e "keystone" -e "glance" -e "nova" -e "neutron"
ttsubo/neutron                     1.0.1               a99cea7f23f7        13 seconds ago      716MB
ttsubo/nova                        1.0.1               fd6f51db4dbe        4 minutes ago       1.01GB
ttsubo/glance                      1.0.1               f0d960b8a0ac        11 minutes ago      666MB
ttsubo/keystone                    1.0.1               50ea8bf48dba        17 minutes ago      621MB
...
```
(2) DockerイメージをContainer Registryための準備として、タグ名を付与しておく

```
$ export PROJECT_ID=$(gcloud config list project --format "value(core.project)")
$ echo $PROJECT_ID
gke-sample-211005
```
```
$ docker tag ttsubo/keystone:1.0.1 gcr.io/$PROJECT_ID/keystone:1.0.1
$ docker tag ttsubo/glance:1.0.1 gcr.io/$PROJECT_ID/glance:1.0.1
$ docker tag ttsubo/nova:1.0.1 gcr.io/$PROJECT_ID/nova:1.0.1
$ docker tag ttsubo/neutron:1.0.1 gcr.io/$PROJECT_ID/neutron:1.0.1

$ docker images|grep -e "keystone" -e "glance" -e "nova" -e "neutron"
ttsubo/neutron                      1.0.1               a99cea7f23f7        About a minute ago   716MB
gcr.io/gke-sample-211005/neutron    1.0.1               a99cea7f23f7        About a minute ago   716MB
ttsubo/nova                         1.0.1               fd6f51db4dbe        6 minutes ago        1.01GB
gcr.io/gke-sample-211005/nova       1.0.1               fd6f51db4dbe        6 minutes ago        1.01GB
gcr.io/gke-sample-211005/glance     1.0.1               f0d960b8a0ac        12 minutes ago       666MB
ttsubo/glance                       1.0.1               f0d960b8a0ac        12 minutes ago       666MB
ttsubo/keystone                     1.0.1               50ea8bf48dba        18 minutes ago       621MB
gcr.io/gke-sample-211005/keystone   1.0.1               50ea8bf48dba        18 minutes ago       621MB
```
(3) Dockerイメージを、Container Registryにプッシュする

```
$ gcloud auth configure-docker
The following settings will be added to your Docker config file 
located at [/Users/ttsubo/.docker/config.json]:
 {
  "credHelpers": {
    "gcr.io": "gcloud", 
    "us.gcr.io": "gcloud", 
    "eu.gcr.io": "gcloud", 
    "asia.gcr.io": "gcloud", 
    "staging-k8s.gcr.io": "gcloud", 
    "marketplace.gcr.io": "gcloud"
  }
}

Do you want to continue (Y/n)?  y

Docker configuration file updated.
```
```
$ docker push gcr.io/$PROJECT_ID/keystone:1.0.1
... (snip)

$ docker push gcr.io/$PROJECT_ID/glance:1.0.1
... (snip)

$ docker push gcr.io/$PROJECT_ID/nova:1.0.1
... (snip)

$ docker push gcr.io/$PROJECT_ID/neutron:1.0.1
... (snip)
```

(4) Container RegistryにDockerイメージがアップロードできたことを確認する

```
$ gcloud container images list --repository=gcr.io/$PROJECT_ID
NAME
gcr.io/gke-sample-211005/glance
gcr.io/gke-sample-211005/keystone
gcr.io/gke-sample-211005/neutron
gcr.io/gke-sample-211005/nova
```
ちなみに、Webコンソールからも確認することができます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103595/e891e7f2-89ff-f0dd-1dc4-a7637bc3bd64.png)


# ■ Kubernetes用Configureファイルの準備
(0) これまでの、docker-compose環境では、、、
こちらが、これまで使用していた[docker-compose用yamlファイル](https://github.com/ttsubo/openstack-docker/blob/master/docker/docker-compose.yaml)になります。
以下の作業では、この定義を、Kubernetes環境に移行することを目指します。

(1) Kubernetes環境でのサービス定義ファイルを準備する

今回は、Kubernetesドキュメント"[Services, Load Balancing, and Networking / Services](https://kubernetes.io/docs/concepts/services-networking/service/)" あたりを参考にして、サービス定義ファイルを準備しました。
ちなみに、今回の環境は、あくまでも手元でKubernetes環境を動作させてみることが目的なので、外部に公開する設定は行っていません。

- mysqlサービス定義ファイル

```yaml:mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    name: mysql-openstack
  name: mysql-openstack
spec:
  ports:
  - port: 3306
  selector:
    name: mysql-pod
```
- keystoneサービス定義ファイル

```yaml:keystone-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    name: keystone-server
  name: keystone-server
spec:
  ports:
  - name: admin-port
    port: 35357
  - name: public-port
    port: 5000
  selector:
    name: keystone-pod
```
- glanceサービス定義ファイル

```yaml:glance-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    name: glance-server
  name: glance-server
spec:
  ports:
  - port: 9292
  selector:
    name: glance-pod
```
- novaサービス定義ファイル

```yaml:nova-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    name: nova-server
  name: nova-server
spec:
  ports:
  - name: port5999
    port: 5999
  - name: port8773
    port: 8773
  - name: port8774
    port: 8774
  - name: port8775
    port: 8775
  selector:
    name: nova-pod
```
- neutronサービス定義ファイル

```yaml:neutron-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    name: neutron-server
  name: neutron-server
spec:
  ports:
  - port: 9696
  selector:
    name: neutron-pod
```

(2) Kubernetes環境でのデプロイメント定義ファイルを準備する

今回は、Kubernetesドキュメント"[Workloads / Controllers / Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)" あたりを参考にして、デプロイメント定義ファイルを準備しました。

**Dockerイメージ名の指定個所は、各自のGCP環境に即したPROJECT_IDに修正する必要があります。**


- mysqlデプロイメント定義ファイル

```yaml:mysql-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-pod
  labels:
    name: mysql-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      name: mysql-pod
  template:
    metadata:
      labels:
        name: mysql-pod
    spec:
      containers:
      - name: mysql-pod
        image: mysql:5.5
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "mysql123"
```

- keystoneデプロイメント定義ファイル

```yaml:keystone-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keystone-pod
  labels:
    name: keystone-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      name: keystone-pod
  template:
    metadata:
      labels:
        name: keystone-pod
    spec:
      containers:
      - name: keystone-pod
        image: gcr.io/gke-sample-211005/keystone:1.0.1
        ports:
        - containerPort: 5000
        - containerPort: 35357
        env:
        - name: OS_TOKEN
          value: "ADMIN"
        - name: OS_URL
          value: "http://localhost:35357/v3"
        - name: OS_IDENTITY_API_VERSION
          value: "3"
        command: ["/bin/sh"]
        args: ["-c", "sleep 20; /root/init_mitaka.sh; /root/start_keystone.sh"]
```

- glanceデプロイメント定義ファイル

```yaml:glance-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: glance-pod
  labels:
    name: glance-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      name: glance-pod
  template:
    metadata:
      labels:
        name: glance-pod
    spec:
      containers:
      - name: glance-pod
        image: gcr.io/gke-sample-211005/glance:1.0.1
        ports:
        - containerPort: 9292
        env:
        - name: OS_PROJECT_DOMAIN_NAME
          value: "default"
        - name: OS_USER_DOMAIN_NAME
          value: "default"
        - name: OS_PROJECT_NAME
          value: "admin"
        - name: OS_USERNAME
          value: "admin"
        - name: OS_PASSWORD
          value: "passw0rd"
        - name: OS_AUTH_URL
          value: "http://keystone-server:35357/v3"
        - name: OS_IDENTITY_API_VERSION
          value: "3"
        - name: OS_IMAGE_API_VERSION
          value: "2"
        command: ["/bin/sh"]
        args: ["-c", "sleep 60; /root/init_mitaka.sh; /usr/bin/supervisord -n"]
```
- novaデプロイメント定義ファイル

```yaml:nova-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nova-pod
  labels:
    name: nova-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      name: nova-pod
  template:
    metadata:
      labels:
        name: nova-pod
    spec:
      containers:
      - name: nova-pod
        image: gcr.io/gke-sample-211005/nova:1.0.1
        ports:
        - containerPort: 5999
        - containerPort: 8773
        - containerPort: 8774
        - containerPort: 8775
        securityContext:
          privileged: true
        env:
        - name: OS_PROJECT_DOMAIN_NAME
          value: "default"
        - name: OS_USER_DOMAIN_NAME
          value: "default"
        - name: OS_PROJECT_NAME
          value: "admin"
        - name: OS_USERNAME
          value: "admin"
        - name: OS_PASSWORD
          value: "passw0rd"
        - name: OS_AUTH_URL
          value: "http://keystone-server:35357/v3"
        - name: OS_IDENTITY_API_VERSION
          value: "3"
        - name: OS_IMAGE_API_VERSION
          value: "2"
        command: ["/bin/sh"]
        args: ["-c", "sleep 80; /root/init_mitaka.sh; /usr/bin/supervisord -n"]
```
- neutronデプロイメント定義ファイル

```yaml:neutron-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: neutron-pod
  labels:
    name: neutron-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      name: neutron-pod
  template:
    metadata:
      labels:
        name: neutron-pod
    spec:
      containers:
      - name: neutron-pod
        image: gcr.io/gke-sample-211005/neutron:1.0.1
        ports:
        - containerPort: 9696
        securityContext:
          privileged: true
        env:
        - name: OS_PROJECT_DOMAIN_NAME
          value: "default"
        - name: OS_USER_DOMAIN_NAME
          value: "default"
        - name: OS_PROJECT_NAME
          value: "admin"
        - name: OS_USERNAME
          value: "admin"
        - name: OS_PASSWORD
          value: "passw0rd"
        - name: OS_AUTH_URL
          value: "http://keystone-server:35357/v3"
        - name: OS_IDENTITY_API_VERSION
          value: "3"
        - name: OS_IMAGE_API_VERSION
          value: "2"
        command: ["/bin/sh"]
        args: ["-c", "sleep 80; /root/init_mitaka.sh; /usr/bin/supervisord -n"]
```

# ■ Kubernetes環境へのDockerコンテナのデプロイ
(1) サービス定義ファイルを用いて、サービスを作成する

```
$ kubectl create -f mysql-service.yaml
service "mysql-openstack" created

$ kubectl create -f keystone-service.yaml
service "keystone-server" created

$ kubectl create -f glance-service.yaml 
service "glance-server" created

$ kubectl create -f nova-service.yaml 
service "nova-server" created

$ kubectl create -f neutron-service.yaml 
service "neutron-server" created
```
```
$ kubectl get service -o wide
NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE       SELECTOR
glance-server     ClusterIP   10.31.250.56    <none>        9292/TCP                              53s       name=glance-pod
keystone-server   ClusterIP   10.31.247.219   <none>        35357/TCP,5000/TCP                    59s       name=keystone-pod
kubernetes        ClusterIP   10.31.240.1     <none>        443/TCP                               1h        <none>
mysql-openstack   ClusterIP   10.31.251.93    <none>        3306/TCP                              1m        name=mysql-pod
neutron-server    ClusterIP   10.31.241.77    <none>        9696/TCP                              38s       name=neutron-pod
nova-server       ClusterIP   10.31.242.236   <none>        5999/TCP,8773/TCP,8774/TCP,8775/TCP   46s       name=nova-pod
```
(2) デプロイメント定義ファイルを用いて、Dockerコンテナ用Podを作成する(keystone用Pod作成したのち、約１分程度待ってから、glance用Podを作成する必要があります。)

```
$ kubectl create -f mysql-pod.yaml
deployment "mysql-pod" created

$ kubectl create -f keystone-pod.yaml 
deployment "keystone-pod" created

$ kubectl create -f glance-pod.yaml 
deployment "glance-pod" created

$ kubectl create -f nova-pod.yaml 
deployment "nova-pod" created

$ kubectl create -f neutron-pod.yaml 
deployment "neutron-pod" created
```
```
$ kubectl get pods -o wide
NAME                            READY     STATUS    RESTARTS   AGE       IP           NODE
glance-pod-74d57c9557-5gbpn     1/1       Running   0          1m        10.28.0.13   gke-openstack-sample-default-pool-5954c0d1-r4c3
keystone-pod-5f786f6cf5-7bh2d   1/1       Running   0          2m        10.28.0.12   gke-openstack-sample-default-pool-5954c0d1-r4c3
mysql-pod-9d78d5c7c-477vp       1/1       Running   0          2m        10.28.0.11   gke-openstack-sample-default-pool-5954c0d1-r4c3
neutron-pod-667cc7f886-pj8qg    1/1       Running   0          1m        10.28.0.15   gke-openstack-sample-default-pool-5954c0d1-r4c3
nova-pod-b4dd67b7f-gkxt6        1/1       Running   0          1m        10.28.0.14   gke-openstack-sample-default-pool-5954c0d1-r4c3
```

# ■ いよいよ、OpenStack基本動作を確認してみる


## 1. 仮想ネットワーク環境を作成する
neutron-server環境下で、neutronサービス基本動作を試してみたいと思います。


(1) neutronコンテナにログインする

```
$ kubectl get pods
NAME                            READY     STATUS    RESTARTS   AGE
glance-pod-74d57c9557-5gbpn     1/1       Running   0          1m
keystone-pod-5f786f6cf5-7bh2d   1/1       Running   0          3m
mysql-pod-9d78d5c7c-477vp       1/1       Running   0          3m
neutron-pod-667cc7f886-pj8qg    1/1       Running   0          1m
nova-pod-b4dd67b7f-gkxt6        1/1       Running   0          1m
```
```
$ kubectl exec -it neutron-pod-667cc7f886-pj8qg bash
root@neutron-pod-667cc7f886-pj8qg:~#
```
(2) neutronエージェント構成を確認しておく

```
root@neutron-pod-667cc7f886-pj8qg:~# neutron agent-list
+--------------------------------------+--------------------+------------------------------+-------------------+-------+----------------+---------------------------+
| id                                   | agent_type         | host                         | availability_zone | alive | admin_state_up | binary                    |
+--------------------------------------+--------------------+------------------------------+-------------------+-------+----------------+---------------------------+
| 061ba689-846a-4c73-bc86-6bbff80a96dc | DHCP agent         | neutron-pod-667cc7f886-pj8qg | nova              | :-)   | True           | neutron-dhcp-agent        |
| 44ca8fda-d872-4d91-abd0-432b05d291d1 | Linux bridge agent | neutron-pod-667cc7f886-pj8qg |                   | :-)   | True           | neutron-linuxbridge-agent |
| df02f54f-3ae8-4829-b6c4-32aefd2ecd65 | L3 agent           | neutron-pod-667cc7f886-pj8qg | nova              | :-)   | True           | neutron-l3-agent          |
+--------------------------------------+--------------------+------------------------------+-------------------+-------+----------------+---------------------------+
```

(3) 新たに、networkリソースを作成する

```
root@neutron-pod-667cc7f886-pj8qg:~# neutron net-create admin_net
Created a new network:
+---------------------------+--------------------------------------+
| Field                     | Value                                |
+---------------------------+--------------------------------------+
| admin_state_up            | True                                 |
| availability_zone_hints   |                                      |
| availability_zones        |                                      |
| created_at                | 2018-07-22T07:44:30                  |
| description               |                                      |
| id                        | c329a92c-c66a-4dbf-bc41-5d0cfbc7b7c9 |
| ipv4_address_scope        |                                      |
| ipv6_address_scope        |                                      |
| mtu                       | 1500                                 |
| name                      | admin_net                            |
| provider:network_type     | local                                |
| provider:physical_network |                                      |
| provider:segmentation_id  |                                      |
| router:external           | False                                |
| shared                    | False                                |
| status                    | ACTIVE                               |
| subnets                   |                                      |
| tags                      |                                      |
| tenant_id                 | e97dc78bf1294314be843a5698f19d3c     |
| updated_at                | 2018-07-22T07:44:30                  |
+---------------------------+--------------------------------------+
```
(4) Subnetリソースを作成する

```
root@neutron-pod-667cc7f886-pj8qg:~# neutron subnet-create admin_net 10.0.0.0/24 --name admin_subnet
Created a new subnet:
+-------------------+--------------------------------------------+
| Field             | Value                                      |
+-------------------+--------------------------------------------+
| allocation_pools  | {"start": "10.0.0.2", "end": "10.0.0.254"} |
| cidr              | 10.0.0.0/24                                |
| created_at        | 2018-07-22T07:45:23                        |
| description       |                                            |
| dns_nameservers   |                                            |
| enable_dhcp       | True                                       |
| gateway_ip        | 10.0.0.1                                   |
| host_routes       |                                            |
| id                | d85feb29-212c-4ff5-8363-63a0d18cc137       |
| ip_version        | 4                                          |
| ipv6_address_mode |                                            |
| ipv6_ra_mode      |                                            |
| name              | admin_subnet                               |
| network_id        | c329a92c-c66a-4dbf-bc41-5d0cfbc7b7c9       |
| subnetpool_id     |                                            |
| tenant_id         | e97dc78bf1294314be843a5698f19d3c           |
| updated_at        | 2018-07-22T07:45:23                        |
+-------------------+--------------------------------------------+
```
```
root@neutron-pod-667cc7f886-pj8qg:~# neutron net-list
+--------------------------------------+-----------+--------------------------------------------------+
| id                                   | name      | subnets                                          |
+--------------------------------------+-----------+--------------------------------------------------+
| c329a92c-c66a-4dbf-bc41-5d0cfbc7b7c9 | admin_net | d85feb29-212c-4ff5-8363-63a0d18cc137 10.0.0.0/24 |
+--------------------------------------+-----------+--------------------------------------------------+
```

(5) neutronコンテナからログアウトする

```
root@neutron-pod-667cc7f886-pj8qg:~# exit
exit
```
ここまでは、期待通り、Neutronコンポーネントが動作できているようです。

## 2. Novaインスタンスを作成する

(1) novaコンテナにログインする

```
$ kubectl exec -it nova-pod-b4dd67b7f-gkxt6 bash
root@nova-pod-b4dd67b7f-gkxt6:~#
```

(2) glanceイメージを確認しておく

```
root@nova-pod-b4dd67b7f-gkxt6:~# glance image-list
+--------------------------------------+--------+
| ID                                   | Name   |
+--------------------------------------+--------+
| 82bd9973-ff62-4ed3-9154-4aae5b98cd36 | cirros |
+--------------------------------------+--------+
```

(3) novaフレーバーを確認しておく

```
root@nova-pod-b4dd67b7f-gkxt6:~# nova flavor-list
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
| 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
| 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
| 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
| 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
```
(4) Novaインスタンスの管理ポート用に、新たにPortリソースを作成する

```
root@nova-pod-b4dd67b7f-gkxt6:~# neutron port-create admin_net
Created a new port:
+-----------------------+---------------------------------------------------------------------------------+
| Field                 | Value                                                                           |
+-----------------------+---------------------------------------------------------------------------------+
| admin_state_up        | True                                                                            |
| allowed_address_pairs |                                                                                 |
| binding:host_id       |                                                                                 |
| binding:profile       | {}                                                                              |
| binding:vif_details   | {}                                                                              |
| binding:vif_type      | unbound                                                                         |
| binding:vnic_type     | normal                                                                          |
| created_at            | 2018-07-22T08:17:20                                                             |
| description           |                                                                                 |
| device_id             |                                                                                 |
| device_owner          |                                                                                 |
| extra_dhcp_opts       |                                                                                 |
| fixed_ips             | {"subnet_id": "d85feb29-212c-4ff5-8363-63a0d18cc137", "ip_address": "10.0.0.2"} |
| id                    | 05853162-921c-4bef-ae08-8738ba7c2084                                            |
| mac_address           | fa:16:3e:6c:ff:c4                                                               |
| name                  |                                                                                 |
| network_id            | c329a92c-c66a-4dbf-bc41-5d0cfbc7b7c9                                            |
| security_groups       | b3088289-f015-4a71-a88b-2c2ac41df535                                            |
| status                | DOWN                                                                            |
| tenant_id             | e97dc78bf1294314be843a5698f19d3c                                                |
| updated_at            | 2018-07-22T08:17:20                                                             |
+-----------------------+---------------------------------------------------------------------------------+
```
```
root@nova-pod-b4dd67b7f-gkxt6:~# neutron port-list
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
| id                                   | name | mac_address       | fixed_ips                                                                       |
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+
...

| 05853162-921c-4bef-ae08-8738ba7c2084 |      | fa:16:3e:6c:ff:c4 | {"subnet_id": "d85feb29-212c-4ff5-8363-63a0d18cc137", "ip_address": "10.0.0.2"} |
+--------------------------------------+------+-------------------+---------------------------------------------------------------------------------+

```

(5) 新たに、Novaインスタンスを作成する

```
root@nova-pod-b4dd67b7f-gkxt6:~# nova boot --flavor 1 --image cirros --nic port-id=05853162-921c-4bef-ae08-8738ba7c2084 server1
+--------------------------------------+-----------------------------------------------+
| Property                             | Value                                         |
+--------------------------------------+-----------------------------------------------+
| OS-DCF:diskConfig                    | MANUAL                                        |
| OS-EXT-AZ:availability_zone          |                                               |
| OS-EXT-SRV-ATTR:host                 | -                                             |
| OS-EXT-SRV-ATTR:hypervisor_hostname  | -                                             |
| OS-EXT-SRV-ATTR:instance_name        | instance-00000001                             |
| OS-EXT-STS:power_state               | 0                                             |
| OS-EXT-STS:task_state                | scheduling                                    |
| OS-EXT-STS:vm_state                  | building                                      |
| OS-SRV-USG:launched_at               | -                                             |
| OS-SRV-USG:terminated_at             | -                                             |
| accessIPv4                           |                                               |
| accessIPv6                           |                                               |
| adminPass                            | DEFR2JEkbKbP                                  |
| config_drive                         |                                               |
| created                              | 2018-07-22T08:21:50Z                          |
| flavor                               | m1.tiny (1)                                   |
| hostId                               |                                               |
| id                                   | 13ab2ca4-303d-4e71-bf81-2ea82817f4a4          |
| image                                | cirros (82bd9973-ff62-4ed3-9154-4aae5b98cd36) |
| key_name                             | -                                             |
| metadata                             | {}                                            |
| name                                 | server1                                       |
| os-extended-volumes:volumes_attached | []                                            |
| progress                             | 0                                             |
| security_groups                      | default                                       |
| status                               | BUILD                                         |
| tenant_id                            | e97dc78bf1294314be843a5698f19d3c              |
| updated                              | 2018-07-22T08:21:51Z                          |
| user_id                              | bdf0a213fca94706adabc2cbc7c92dd5              |
+--------------------------------------+-----------------------------------------------+
```
```
root@nova-pod-b4dd67b7f-gkxt6:~# nova list
+--------------------------------------+---------+--------+------------+-------------+----------+
| ID                                   | Name    | Status | Task State | Power State | Networks |
+--------------------------------------+---------+--------+------------+-------------+----------+
| 13ab2ca4-303d-4e71-bf81-2ea82817f4a4 | server1 | ACTIVE | -          | Running     |          |
+--------------------------------------+---------+--------+------------+-------------+----------+
```
ちなみに、作成したNovaインスタンスは、Fakeドライバを作成したダミーインスタンスなので実態は、存在しません。

```
root@nova-pod-3143696547-7xbw7:~# cat /etc/nova/nova.conf

  ...

compute_driver = fake.FakeDriver

  ...
```
(6) neutronコンテナからログアウトする

```
root@nova-pod-b4dd67b7f-gkxt6:~# exit
exit
```
こちらも、期待通り、Novaコアコンポーネントが動作できているようです。


# ■ 補足；Pod間のDockeコンテナ通信を試してみる
せっかくなので、この環境で、Pod間通信を少し試しておきます。
(1) まず、PodsのIPアドレスを確認しておく

```
$ kubectl get pods -o wide
NAME                            READY     STATUS    RESTARTS   AGE       IP           NODE
glance-pod-74d57c9557-5gbpn     1/1       Running   0          45m       10.28.0.13   gke-openstack-sample-default-pool-5954c0d1-r4c3
keystone-pod-5f786f6cf5-7bh2d   1/1       Running   0          46m       10.28.0.12   gke-openstack-sample-default-pool-5954c0d1-r4c3
mysql-pod-9d78d5c7c-477vp       1/1       Running   0          47m       10.28.0.11   gke-openstack-sample-default-pool-5954c0d1-r4c3
neutron-pod-667cc7f886-wk9rd    1/1       Running   0          34m       10.28.2.7    gke-openstack-sample-default-pool-5954c0d1-hzsj
nova-pod-b4dd67b7f-gkxt6        1/1       Running   0          45m       10.28.0.14   gke-openstack-sample-default-pool-5954c0d1-r4c3
```
keystone-podのIPアドレスには、"10.28.0.12"、mysql-podのIPアドレスには、10.28.0.11が、各々割り当てられていることが確認できました。

(2) 続いて、Cluster-IPを確認しておく

```
$ kubectl get service -o wide
NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                               AGE       SELECTOR
glance-server     ClusterIP   10.31.250.56    <none>        9292/TCP                              55m       name=glance-pod
keystone-server   ClusterIP   10.31.247.219   <none>        35357/TCP,5000/TCP                    55m       name=keystone-pod
kubernetes        ClusterIP   10.31.240.1     <none>        443/TCP                               2h        <none>
mysql-openstack   ClusterIP   10.31.251.93    <none>        3306/TCP                              55m       name=mysql-pod
neutron-server    ClusterIP   10.31.241.77    <none>        9696/TCP                              55m       name=neutron-pod
nova-server       ClusterIP   10.31.242.236   <none>        5999/TCP,8773/TCP,8774/TCP,8775/TCP   55m       name=nova-pod
```
"mysql-openstack"には、"10.31.251.93"が割り振られたことが確認できました。

(3) keystone-podにログインして、IPアドレスを確認する

```
$ kubectl exec -it keystone-pod-5f786f6cf5-7bh2d bash
root@keystone-pod-5f786f6cf5-7bh2d:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
3: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc noqueue state UP group default 
    link/ether 0a:58:0a:1c:00:0c brd ff:ff:ff:ff:ff:ff
    inet 10.28.0.12/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::b4d2:57ff:fea2:b360/64 scope link 
       valid_lft forever preferred_lft forever
```
keystone-podには、"10.28.0.12"が割り当てられていました。

(4) keystone-podから、mysql-podに、直接、pingを打ってみる

```
root@keystone-pod-5f786f6cf5-7bh2d:~# ping 10.28.0.11
PING 10.28.0.11 (10.28.0.11) 56(84) bytes of data.
64 bytes from 10.28.0.11: icmp_seq=1 ttl=64 time=0.086 ms
64 bytes from 10.28.0.11: icmp_seq=2 ttl=64 time=0.076 ms
64 bytes from 10.28.0.11: icmp_seq=3 ttl=64 time=0.070 ms
64 bytes from 10.28.0.11: icmp_seq=4 ttl=64 time=0.073 ms
^C
--- 10.28.0.11 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 0.070/0.076/0.086/0.008 ms
```
問題なく、mysql-podに、ping通信できました。

(5) keystone-podから、mysql-podに、直接、MYSQLクライアント経由でアクセスしてみる

```
root@keystone-pod-5f786f6cf5-7bh2d:~# mysql -uroot -pmysql123 -h10.28.0.11
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 65
Server version: 5.5.60 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| glance             |
| keystone           |
| mysql              |
| neutron            |
| nova               |
| nova_api           |
| performance_schema |
+--------------------+
8 rows in set (0.06 sec)

mysql> 
```
mysql-podへの、MYSQLアクセスも可能になりました。

(6) keystone-podから、mysql-podに、Cluster-IPを介して、pingを打ってみる

```
root@keystone-pod-5f786f6cf5-7bh2d:~# env |grep MYSQL
MYSQL_OPENSTACK_PORT_3306_TCP=tcp://10.31.251.93:3306
MYSQL_OPENSTACK_PORT_3306_TCP_PORT=3306
MYSQL_OPENSTACK_PORT_3306_TCP_PROTO=tcp
MYSQL_OPENSTACK_PORT_3306_TCP_ADDR=10.31.251.93
MYSQL_OPENSTACK_PORT=tcp://10.31.251.93:3306
MYSQL_OPENSTACK_SERVICE_PORT=3306
MYSQL_OPENSTACK_SERVICE_HOST=10.31.251.93
```
```
root@keystone-pod-5f786f6cf5-7bh2d:~# ping 10.31.251.93
PING 10.31.251.93 (10.31.251.93) 56(84) bytes of data.
^C
--- 10.31.251.93 ping statistics ---
6 packets transmitted, 0 received, 100% packet loss, time 4999ms

```
Cluster-IPアドレスを直接指定して、pingを打った場合には、不達になりました。

(7) keystone-podから、mysql-podに、Cluster-IPを介して、MYSQLクライアント経由でアクセスしてみる

```
root@keystone-pod-5f786f6cf5-7bh2d:~# mysql -uroot -pmysql123 -h10.31.251.93
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 67
Server version: 5.5.60 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| glance             |
| keystone           |
| mysql              |
| neutron            |
| nova               |
| nova_api           |
| performance_schema |
+--------------------+
8 rows in set (0.00 sec)

mysql>
```
Cluster-IPアドレスを直接指定して、MYSQLアクセスは、可能になりました。

```
root@keystone-pod-5f786f6cf5-7bh2d:~# apt-get update
root@keystone-pod-5f786f6cf5-7bh2d:~# apt-get install -y dnsutils
```
```
root@keystone-pod-5f786f6cf5-7bh2d:~# nslookup mysql-openstack
Server:		10.31.240.10
Address:	10.31.240.10#53

Name:	mysql-openstack.default.svc.cluster.local
Address: 10.31.251.93
```
```
root@keystone-pod-5f786f6cf5-7bh2d:~# mysql -uroot -pmysql123 -hmysql-openstack
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 68
Server version: 5.5.60 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| glance             |
| keystone           |
| mysql              |
| neutron            |
| nova               |
| nova_api           |
| performance_schema |
+--------------------+
8 rows in set (0.00 sec)

mysql> 
```

今度は、Cluster-IPアドレスを直接指定せずに、DNSエントリされた"mysql-openstack"を指定しても、MYSQLアクセスが可能になりました。

以上のPod間通信に関わる動作確認から、二つの結論が導き出されるようです。

- PodまたがりのDockerコンテナ間の直接通信では、特にフィルタなしにアクセスが可能である。
- PodまたがりのDockerコンテナ間のCluster-IP経由した通信では、サービス定義ファイルで指定されたポート番号に限り通信が許容される。

# ■ 終わりに
OpenStackコアコンポーネントによるマイクロサービス的な基本動作は、想定通り動作することが確認できました。
ただし、Docker-composeを使用している際には、Dockerコンテナ間の通信は、単に、リンクを指定しておくだけだったですが、KubernetesのPod間通信については、もっと体系的に、Kubernetesクラスタにおけるネットワーク知識を、もっと会得する必要があることが判明しました。
これは、大きな収穫ですけど。

# ■ 参考情報
- [Lab: Deploy a Sample Game API Application on GKE](https://github.com/asashiho/gke-gobang-app-example/blob/master/README.md)
- WEB+DB-PRESS Vol99 「実践Kubernetes」
- プログラマのためのGoogle Cloud Platform入門