GKEにGoのアプリケーションをデプロイする

# 概要
GoLang製のアプリケーションをGKE（Google Kubernetes Engine）にデプロイするまでの流れを解説した記事です。

# 環境
macOS Mojave バージョン10.14.6

# 筆者のスペック
AWSは分かるがGCPは本格的に扱ったことがないという状況です。

# 作成したアプリケーション

こちらになります。

https://github.com/nekochans/portfolio-backend

Goとnginxで単純なJSONを返すだけの簡単なAPIになります。

# GCPプロジェクトの作成

https://cloud.google.com にアクセスを行い「無料トライアル」からアカウントを発行します。（Google アカウントは事前に作成しておく必要があります、普段使っているGoogleアカウントを使ってもOK）

以下の情報の入力が必要です。クレジットカードを準備しておきましょう。

- 国と通貨
- 口座の種類（ビジネス／個人）
- 名前と住所
- お支払い方法（クレジットカード／デビットカード）
- 使用言語

現在は年間300$まで無料で利用出来るようです。

デフォルトだと「My First Project」というProjectが既に作成されていますが、それは利用しないで目的別にProjectを作成したほうが良いと思います。

[こちら](https://cloud.google.com/resource-manager/docs/creating-project?hl=ja) を参考に任意の名前で作成します。

# gcloudのインストール

GCP上の様々なリソースを操作出来るツールです。

[公式ドキュメント](https://cloud.google.com/sdk/downloads?hl=JA) を参考にインストールしても良いのですがMacの場合、 `brew cask` を利用してインストールが可能です。

`brew cask install google-cloud-sdk` を実行します。

`gcloud init` を実行します。

利用するGoogleアカウント、利用するGCPProject等を聞かれるので対話形式のインターフェースに従い入力します。

初期化が終わったら念の為 `gcloud components update` を実行して各Componentを最新状態にしておきましょう。

# kubectlのインストール

最初 `gcloud components install kubectl` を実行してインストールを行ったのですが私の環境だと以下のような警告メッセージが出力されました。

```
WARNING:   There are older versions of Google Cloud Platform tools on your system PATH.
  Please remove the following to avoid accidentally invoking these old tools:

  /Applications/Docker.app/Contents/Resources/bin/kubectl
```

Docker for Macに内蔵されている `kubectl` と競合している為だと思われます。

その為、以下の記事を参考に `gcloud` から `kubectl` を消して brewでインストールするように修正を行いました。

```
gcloud components remove kubectl

brew install kubernetes-cli

brew link --overwrite kubernetes-cli
```

はじめから `brew install kubernetes-cli` でインストールを行ったほうが良いかもしれません。

# GCPのデフォルトリージョンを指定

デフォルトで利用するリージョンを指定します。

`gcloud config set compute/zone asia-northeast1-a`

# GCP Container Registry（gcr） に Docker ImageをPushする

まず初めに [公式ドキュメント](https://cloud.google.com/container-registry/docs/advanced-authentication?hl=ja) を参考に認証を行います。

`gcloud auth configure-docker` を実行すればOKです。

その後、DockerイメージをBuildしてプッシュを行います。

こちらはシェルスクリプトのサンプルコードがあるのでリンクを置いておきます。

下記の例だとGoLangアプリケーションとnginxの2つのイメージをプッシュしています。

https://github.com/nekochans/portfolio-backend/blob/master/docker-push-to-gcr.sh

Repository名ですが `${GCRのドメイン名}/${GCPのProjectID}/{任意の名前}` という形になればOKです。

```
// 例
gcr.io/your-project-id/your-app
```

詳しくは [公式ドキュメント](https://cloud.google.com/container-registry/docs/quickstart?hl=ja) を参考にして下さい。

正常に登録が終了すれば以下のようにイメージが登録されていることが確認出来ます。

![gcr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71899/f8a07e3e-4c75-5d77-d071-e60acc6ba5ad.png)

# kubernetesクラスタを作成

[クイックスタート](https://cloud.google.com/kubernetes-engine/docs/quickstart?hl=ja) に書いてある通りにGoogle Kubernetes Engine API を有効にします。

次に以下のコマンドを実行しクラスタを作成します。

`portfolio-backend` という部分はクラスタの名前なので任意の名前に置き換えて下さい。

```
gcloud container clusters create portfolio-backend \
  --machine-type=n1-standard-1 \
  --num-nodes=1
```

クラスタ作成時に指定出来る引数は今回最低限にしていますが、利用出来る引数はたくさんあります。

詳しくは [公式ドキュメント](https://cloud.google.com/sdk/gcloud/reference/container/clusters/create) を参考にすると良いでしょう。

Kubernetes Engine → クラスタ を確認するとクラスタが作成されていることを確認出来ます。

![clustersCreate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71899/70e1c4e8-8fa4-d654-71d4-af73fe516c66.png)

# kubernetesクラスタに接続

Kubernetes Engine → クラスタに表示されている「接続」をクリックすると以下のように接続用のコマンドが確認出来ます。

![container-clusters-get-credentials.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71899/080c05dd-d109-2b8b-a83a-33628074d5bc.png)

これを実行すると `kubectl` で対象のKubernetesクラスタに接続可能になります。

```
gcloud container clusters get-credentials portfolio-backend --zone asia-northeast1-a --project yourprojectid
```

上記のコマンド実行後に `kubectl config get-contexts` を実行すると対象のクラスタと接続していることが確認出来るかと思います。

```
$ kubectl config get-contexts
CURRENT   NAME                                                CLUSTER                                             AUTHINFO                                            NAMESPACE
          docker-desktop                                      docker-desktop                                      docker-desktop
          docker-for-desktop                                  docker-desktop                                      docker-desktop
*         gke_nekochans_asia-northeast1-a_portfolio-backend   gke_yourprojectid_asia-northeast1-a_portfolio-backend   gke_yourprojectid_asia-northeast1-a_portfolio-backend
```

# kubernetesのマニフェストファイルを作成

[こちらで作成したサンプル](https://github.com/nekochans/portfolio-backend/tree/master/k8s) を参考にマニフェストファイルを作成して下さい。

詳しい説明は省略しますが、ざっくり説明すると nginxのコンテナがバックエンドのGoのアプリケーションコンテナに通信するように設定を行っています。

さらに `ingress` の設定を行いインターネット上からアクセス可能にしています。

# デプロイを行う

クラスタ上にデプロイを行います。

[サンプルアプリケーション](https://github.com/nekochans/portfolio-backend) の場合は `k8s` ディレクトリにマニフェストファイルをまとめてあるので以下のコマンドでデプロイを行います。

`kubectl apply -f k8s/`

しばらくすると `Kubernetes Engine → ServiceとIngress` よりマニフェストファイルに書かれたServiceとIngressの設定が作成されていることが確認出来るかと思います。

<img width="1019" alt="ServiceIngress.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71899/ac7bee73-3978-4023-4d90-3c2d55cbe566.png">

※ Ingressの作成には少し時間がかかるようです。

Ingressの詳細ページからロードバランサのIPを確認出来るので、 `http://確認したIP` にアクセスを行います。

アプリケーションが正常動作していることが確認出来るかと思います。

# 後片付け（クラスタの削除）

このままだとクレジットを消費してしまうので、クラスタの削除を行います。

`portfolio-backend` の部分は作成したクラスタ名に合わせて下さい。

```
gcloud container clusters delete portfolio-backend
```

上記のコマンドでクラスタを削除すると関連して作成されたロードバランサ等も一緒に削除してくれるので便利です。

# おわりに

GKEだとかなり簡単にKubernetesを試す事が出来ます。

これから本格運用に向けて色々と調べていこうと思います。

この記事は以上になります。

最後まで読んで頂きありがとうございました。