N^2周回遅れでKubernetesに入門してみた(デプロイ編)

N^2周回遅れでKubernetesにblue-greenデプロイぽいことをしてみました。
(デプロイというよりは、切り替えているだけですが。。。)

# 概要
1. blue-greenデプロイぽいもの
2. nginxのkeepaliveを有効(デフォルト)のままにした時の挙動の確認

# 環境
- GKE
- nginxのコンテナイメージをちょっといじったもの

# 1. blue-greenデプロイぽいもの
　　　![k8s-bg.png](https://qiita-image-store.s3.amazonaws.com/0/192584/b1859e44-e4c8-0435-29de-c63072e22a59.png)

※Redがいますが、気にしないで下さい。

### 1. バージョンの異なる3個のpodをデプロイする。
```
$ kubectl apply -f deployment-v1b.yaml
$ kubectl apply -f deployment-v2b.yaml
$ kubectl apply -f deployment-v3b.yaml
$ kubectl get pods
NAME                             READY     STATUS    RESTARTS   AGE
deploytest-v1-5747f44698-8pllm   1/1       Running   0         33m
deploytest-v2-6f9c565dc4-xv4b2   1/1       Running   0         27m
deploytest-v3-5ddd95675d-4fpdd   1/1       Running   0         14m
```

### 2. ServiceをBlue(V1)に向ける

```
$ kubectl apply -f service-v1.yaml
```

ブラウザからアクセスすると、Blue(V1)のログに出力されます。

```Blue(V1)のログ
$ kubectl logs -f deploytest-v1-5747f44698-8pllm
10.138.0.2 - - [30/Sep/2018:09:08:16 +0000] "GET / HTTP/1.1" 200 110 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
```

### 3. ServiceをGreen(V2)に向ける

```
$ kubectl apply -f service-v2.yaml
```

ブラウザからアクセスすると、Green(V2)のログに出力されます。

```Green(V2)のログ
$ kubectl logs -f deploytest-v2-6f9c565dc4-xv4b2
10.138.0.4 - - [30/Sep/2018:09:08:45 +0000] "GET / HTTP/1.1" 200 110 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
```

### 3. ServiceをRed(V3)に向ける

```
$ kubectl apply -f service-v3.yaml
```

ブラウザからアクセスすると、Red(V3)のログに出力されます。

```Red(V3)のログ
$ kubectl logs -f deploytest-v3-5ddd95675d-4fpdd
10.138.0.4 - - [30/Sep/2018:09:09:05 +0000] "GET / HTTP/1.1" 200 110 "-" "Mozilla/5.0 (Macintosh; Intel MacOS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
```

### 4. Serviceの向き先をGreen(V2)に戻す

```
$ kubectl apply -f service-v2.yaml
```

ブラウザからアクセスすると、Green(V2)のログに出力されます。

```Green(V2)のログ
$ kubectl logs -f deploytest-v2-6f9c565dc4-xv4b2
10.138.0.2 - - [30/Sep/2018:09:12:23 +0000] "GET / HTTP/1.1" 200 110 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
```

# 2. nginxのkeepaliveを有効(デフォルト)のままにした時の挙動

上の例では、nginxのkeepaliveをOFF(keepalive_timeout  0)にしましたが
nginxのkeepaliveが有効の場合、serviceの向き先を変える前にブラウザからアクセスすると
serviceの向き先を変えてもしばらくは元のpodに流れてしまうようです。

　[*参考：kube-proxy: add option to forcibly disconnect existing TCP clients on service updates #46753*](https://github.com/kubernetes/kubernetes/issues/46753)

### 1. バージョンの異なる2個のpodをデプロイする。
```
$ kubectl apply -f deployment-v1.yaml
$ kubectl apply -f deployment-v2.yaml
```

### 2. ServiceをBlue(V1)に向ける

```
$ kubectl apply -f ../deploy-tutorial/deploy/service-v1.yaml
```

Blue(V1)のログ

```
10.28.0.1 - - [30/Sep/2018:05:56:56 +0000] "GET / HTTP/1.1" 200 108 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X10.14; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
```

### 3. ServiceをGreen(V2)に向ける

```
$ kubectl apply -f ../deploy-tutorial/deploy/service-v2.yaml
```

#### Blue(V1)のログ
同じブラウザからアクセスすると、切り替え直後はBlue(V1)に流れる！！

```
10.28.0.1 - - [30/Sep/2018:05:57:11 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
```

#### Green(V2)のログ
しばらくすると、Green(V2)に流れる。

```
10.138.0.4 - - [30/Sep/2018:05:59:15 +0000] "GET / HTTP/1.1" 200 108 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
```

# X.利用したyaml

```deployment-v1b.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploytest-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploytest
      ver: "1"
  template:
    metadata:
      labels:
        app: deploytest
        ver: "1"
    spec:
      containers:
      - image: sirotosiko/docker-deploytest:v1.0b
        name: deploytest
        ports:
          - containerPort: 80
```

```deployment-v2b.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploytest-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploytest
      ver: "2"
  template:
    metadata:
      labels:
        app: deploytest
        ver: "2"
    spec:
      containers:
      - image: sirotosiko/docker-deploytest:v2.0b
        name: deploytest
        ports:
          - containerPort: 80
```

```deployment-v3b.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploytest-v3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploytest
      ver: "3"
  template:
    metadata:
      labels:
        app: deploytest
        ver: "3"
    spec:
      containers:
      - image: sirotosiko/docker-deploytest:v3.0b
        name: deploytest
        ports:
          - containerPort: 80
```

```deployment-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploytest-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploytest
      ver: "1"
  template:
    metadata:
      labels:
        app: deploytest
        ver: "1"
    spec:
      containers:
      - image: sirotosiko/docker-deploytest:v1.0
        name: deploytest
        ports:
          - containerPort: 80
```

```deployment-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploytest-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deploytest
      ver: "2"
  template:
    metadata:
      labels:
        app: deploytest
        ver: "2"
    spec:
      containers:
      - image: sirotosiko/docker-deploytest:v2.0
        name: deploytest
        ports:
          - containerPort: 80
```

```service-v1.yaml
apiVersion: v1
kind: Service
metadata:
  name: deploytest
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 80
  selector:
    app: deploytest
    ver: "1"
  sessionAffinity: None
  type: LoadBalancer
```

```service-v2.yaml
apiVersion: v1
kind: Service
metadata:
  name: deploytest
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 80
  selector:
    app: deploytest
    ver: "2"
  sessionAffinity: None
  type: LoadBalancer
```

```service-v3.yaml
apiVersion: v1
kind: Service
metadata:
  name: deploytest
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 80
  selector:
    app: deploytest
    ver: "3"
  sessionAffinity: None
  type: LoadBalancer
```