Docker for Mac [Edge] で Kubernetes を試してみる

# Docker for Mac [Edge] で Kubernetes を試してみる

# インストール

- macOS Sierra(10.12.6)
- [Docker for Mac[Edge]](https://docs.docker.com/docker-for-mac/install/#download-docker-for-mac)をインストールします。
- <img width="255" alt="docker_for_mac_edge.png" src="https://qiita-image-store.s3.amazonaws.com/0/140713/eefd4c6d-43e7-4b6c-b1b7-922134b98773.png">

- Docker for Mac の設定から、Kubernetes を有効化します。
- <img width="495" alt="docker_for_mac_k8s.png" src="https://qiita-image-store.s3.amazonaws.com/0/140713/d26d4fd6-8d99-6ddb-a59a-c921b2065217.png">

- Kubernetes パッケージマネージャーの [helm](https://github.com/kubernetes/helm) をインストールします。

```shell
$ brew install kubernetes-helm
```


- バージョンは下記の通りです。

```shell
$ docker -v
Docker version 18.03.0-ce-rc4, build fbedb97

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.2", GitCommit:"5fa2db2bd46ac79e5e00a4e6ed24191080aa463b", GitTreeState:"clean", BuildDate:"2018-01-18T10:09:24Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.2", GitCommit:"5fa2db2bd46ac79e5e00a4e6ed24191080aa463b", GitTreeState:"clean", BuildDate:"2018-01-18T09:42:01Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}

$ helm version
Client: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.1", GitCommit:"6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2", GitTreeState:"clean"}
```

# Kubernetes とは

- コンテナオーケストレーションツールです。
- 自動デプロイ、スケーリング、コンテナアプリケーションの管理のためのオープンソースソフトウェアです。

# アプリケーション

## 今回は Nginx + PHP-FPM 7.1 のWebアプリケーションを構築します。

### Dockerfile

- nginx

```yaml:Dockerfile
FROM nginx:1.13.8-alpine

ADD conf/nginx.conf /etc/nginx/nginx.conf
```

```conf:nginx.conf
user  nginx;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  text/html;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       8080;
        server_name  localhost;
        root   /docker/app/;

        location / {
            index  index.php;
        }

        location ~ \.php {
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index index.php;
            include       fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }

}
```

- php-fpm

```yaml:Dockerfile
FROM php:7.1-fpm-alpine
```

### Dockerコンテナビルド

```bash
$ docker build -t sample/nginx:1.0 docker/nginx
$ docker build -t sample/php:1.0 docker/php-fpm
```

# Pods

- 1つ以上のコンテナから構成されます。
- Kubernetes でデプロイ可能な最小単位です。

# Deployment

- ReplicaSet と Pods から構成されます。

```yaml:deployment.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: sample-k8s
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: sample-k8s
    spec:
      containers:
        - name: sample-nginx
          image: "sample/nginx:1.0"
          imagePullPolicy: IfNotPresent
          ports:
          - containerPort: 8080
          volumeMounts:
          - name: web-root
            mountPath: /docker
        - name: sample-php
          image: "sample/php:1.0"
          imagePullPolicy: IfNotPresent
          ports:
          - containerPort: 9000
          volumeMounts:
          - name: web-root
            mountPath: /docker
      volumes:
      - name: web-root
        hostPath:
          path: /Users/moritake/go/src/github.com/mediba-moritake/sample-kubernetes
```

# Service

- Pods へのアクセスを提供します。

```yaml:service.yml
apiVersion: v1
kind: Service
metadata:
  name: sample-k8s
spec:
  type: NodePort
#  type: LoadBalancer
  selector:
    name: sample-k8s
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
```

# Ingress

- HTTP(S)ロードバランサを設定します。

```yaml:ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: sample-k8s
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  backend:
    serviceName: sample-k8s
    servicePort: 8080
```

# Ingress Controller

- Ingress ロードバランサの実態である Nginx Ingress Controller をインストールします。

```shell
$ helm install stable/nginx-ingress
```

# Deployment, Service, Ingress の作成

```shell
$ kubectl create -f deployment.yml -f service.yml -f ingress.yml
```

# PHP アプリケーション

```php:index.php
<?php

echo 'Hello k8s!';
```

# 動作確認

```
$ curl localhost
Hello k8s!
```

# まとめ

- [Docker for Mac[Edge]](https://docs.docker.com/docker-for-mac/install/#download-docker-for-mac) にて Kubernetes を試してみました。
- より高い環境一致を目指して Ingress を導入しましたが、開発環境であれば必須ではありません。その時はService を `type: LoadBalancer` のように設定しましょう。
- Docker Compose でも同様なことが出来ると思いますが、Kubernetes を使用することでより高い環境一致になるのではないでしょうか。
- [Amazon EKS](https://aws.amazon.com/jp/eks/) (現在はプレビュー)を早く使ってみたいです。

# ソースコード

- https://github.com/mediba-moritake/sample-kubernetes

# メモ(よく使うコマンド)

- pods/service/ingress の状態を確認します。

```
$ kubectl get pods
$ kubectl get service
$ kubectl get ingress
```

- pods/service/ingress の詳細な説明を確認します。

```
$ kubectl describe pods
$ kubectl describe service
$ kubectl describe ingress
```

- コンテナのログを確認します。

```
$ kubectl log #{pod名} -c #{コンテナ名}
$ kubectl log sample-k8s-xxxxxxxxxx-yyyyy -c sample-nginx
```

- コンテナに入ります。

```
$ kubectl exec -it #{pod名} -c #{コンテナ名} ash
$ kubectl exec -it sample-k8s-xxxxxxxxxx-yyyyy -c sample-nginx ash
$ kubectl exec -it sample-k8s-xxxxxxxxxx-yyyyy -c sample-php ash
```

- コンテナにコマンドを実行します。

```
$ kubectl exec #{pod名} -c #{コンテナ名} -- #{コマンド}
$ kubectl exec sample-k8s-xxxxxxxxxx-yyyyy -c sample-nginx -- nginx -v
$ kubectl exec sample-k8s-77596b46b5-ggvg4 -c sample-php -- php -v
```