k8sにAPIサーバをデプロイ

# では早速
Dockerを使っていた方は入りやすいと思います．
Kubernetesは複数コンテナからなる一つのサービスを**Podという単位**で管理します．
> Docker-Compose ≒ Podと解釈して頂いていいと思います．

# 題材
https://github.com/tozastation/gRPC-Training-Golang
を使って説明していきます．

## Docker-Compose
DBとAPIサーバのサービスを立ち上げるとする．
いつもならこんな感じだと思います．

```yaml
version: '3'
services:
    db:
      build: ./mssql_container
      ports:
        - 1433:1433
      environment:
        - ACCEPT_EULA=Y
        - SA_PASSWORD=Test@1234
        - MSSQL_PID=Express
        - MSSQL_LCID=1041
        - MSSQL_COLLATION=Japanese_CI_AS
      volumes:
        - ./mssql_container/sql:/init-data
        - ./mssql_container/start-up.sh:/start-up.sh
      command: "sh -c '/start-up.sh & /opt/mssql/bin/sqlservr;'"
    api:
      build: .
      stdin_open: true
      tty: true
      ports:
        - 3001:3001
```

## Pod(Kubernetes)
一方Kubernetesですとこう書きます．

### Deployment(deployment.yaml)
Deploymentの責務は，Podを維持すること及びデプロイの管理です．

```yaml
apiVersion: extensions/v1beta1
kind: Deployment # KubernetesのどのAPIを使用するか指定
metadata: 
  name: tozastation-grpc
  namespace: tozastation # tozastationという名前空間にデプロイを指定(詳細はあとに記載)
spec:
　 # ReplicaSetという，設定したPod数を維持する(負荷分散)
  replicas: 1　
  template:
    metadata:
      labels: # 検索が容易になるようにラベル付け
        app: tozastation-grpc　# kubectl get pods -l tozastation-grpc みたいに使う
    # Podの中身を設定していく
    spec:
      containers:
        - name: grpc-server　# Podの名前
          image: tozastation/grpc_training_golang:latest　# Podのイメージパス
          ports: # Exposeするポート
            - containerPort: 3001
        - name: mssql
          image: microsoft/mssql-server-linux:latest
          ports:
            - containerPort: 1433
          env: # 環境変数
            - name: ACCEPT_EULA
              value: Y
            - name: SA_PASSWORD
              value: Test@1234
            - name: MSSQL_PID
              value: Express
            - name: MSSQL_LCID
              value: 1041
            - name: MSSQL_COLLATION
              value: Japanese_CI_AS
         command: ["sh"]　# コンテナ起動時に呼び出されるShellコマンド
         args: ["-c", "'/start-up.sh & /opt/mssql/bin/sqlservr;'"]
```

### Service(service.yaml)
Serviceの責務は，Deployment(Pod)をサービスとして公開することです．

```yaml
apiVersion: v1
kind: Service
metadata:
  labels: 
    name: tozastation-grpc
  name: tozastation-service
spec:
  clusterIP: None # Serviceの種類を指定します．(詳細はあとに記載)
  ports:
    - name: tozastation-grpc # Portの名前
      port: 3001 # 外に見せる場合のPort番号
      protocol: TCP # プロトコル
      targetPort: 3001 # バインドするPodのポート番号
  selector:
    app: tozastation-grpc # バインドするPodの名前
```

#### Namespace(名前空間について)
Kubernetesは，クラスタ内で隔離された環境を再現するために，名前空間というAPIを持っています．
これができると，このサービスのStaging環境はあそこにデプロイという感じで定義できます．

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: tozastation-stag
```
#### Serviceの種類
##### ClusterIP
内部のクラスタ向けに公開します．
`clusterIP: 10.0.100.80`
###### HeadLess Service
通常，Podをデプロイした際の負荷分散は，VIPが割り振られ行われます．
しかし，gRPC通信などは，これだとうまく分散されないなどの現状があります．
PodのIPは全てこちらで知っておきたいなどの場合にこれを用います．
`clusterIP: None`
##### NodePort
全てのKubernetes NodeのIP:Portで受けたトラフィックをコンテナに転送する形で、外部疎通性を確立します
[KubernetesのDiscovery＆LBリソース（その1）](https://thinkit.co.jp/article/13738?page=0%2C1)

```yaml
type: NodePort
ports:
  - name: "http-port"
    protocol: "TCP"
    port: 8080
    targetPort: 80
    nodePort: 30080
```
##### LoadBalancer
グローバルIPを発行してくれる(クラウドベンダーで主に利用可能)
`type: LoadBalancer`

# 最後に
作成したファイルを以下で実行すればおしまいです！
`kubectl apply -f [設定ファイルのパス]`

# まとめ
ちょっとしたAPIサーバをKubernetesでデプロイする手順を書かせていただいきました．
少しでも興味を持ってもらい知識共有ができたらなと思います！