ブログに GKE を使う
このブログはHexoを使って VPS 上に構築していましたが、
今回、 VPS をやめて GKS を使うようにしました。
目標
- リポジトリに push したら自動でブログの内容が更新される
- https で通信できる
- そんなに費用がかからない
手順概要
- GKE の使い方を勉強する
- Kubernetes クラスタを作る
- Hexo 用の Docker イメージを作る
- Cloud Build の設定をする
- https で通信できるように設定する
手順詳細
1. GKE の使い方を勉強する
Cloud Build を利用すると GCP で CI/CD の環境を構築できます。次のドキュメントがわかりやすいです。
https://cloud.google.com/kubernetes-engine/docs/tutorials/gitops-cloud-build?hl=ja
途中、リポジトリに Push できない箇所がありましたが、hello-cloudbuild-env/.git/config
ファイルの[credential]
部分をコピーすれば Push できるようになります。
また、最後までいったら忘れずにクラスをを削除して余計な課金がされないようにしましょう。
2. Kubernetes クラスタを作る
ブログ用のクラスタを作成します。
クラスタを作る前にリージョンを設定しておきます。日本を指定すると若干費用が高いです。
1 2
| gcloud config set compute/zone asia-northeast1-c gcloud config set compute/region asia-northeast1
|
現在の設定値は以下のコマンドで確認できます。
クラスタを作成します。f1-micro
ではメモリ不足でクラスタを作成できないので、今回はe2-micro
を指定しました。
1
| gcloud container clusters create k8s-cluster --preemptible --machine-type=e2-micro --num-nodes=3 --disk-size=10
|
asia-northeast1
でプリエンプティブルのe2-micro
が 3 台だと 1 ヶ月あたりUSD 7.06
らしいです。
費用はこちらで計算できます。
https://cloud.google.com/products/calculator?hl=ja
3. Hexo 用の Docker イメージを作る
hello-cloudbuild-app と同じように app と env の 2 つのリポジトリを用意します。
app にDockerfile
を用意します。
1 2 3 4 5 6 7 8 9 10
| FROM node:slim as builder WORKDIR /app ADD . . RUN npm install RUN npm install -g hexo-cli RUN hexo clean RUN hexo generate
FROM nginx COPY --from=builder /app/public /usr/share/nginx/html
|
Docker イメージで作成した場合、何故か hexo generate したときに出力されるファイルのサイズが 0 になりました。
この問題は npm のライブラリ のバージョンを最新にすると解消しました。
4. Cloud Build の設定をする
hello-cloudbuild-app と同じように設定します。
まずはcloudbuild.yaml
ファイルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| steps: - name: "gcr.io/cloud-builders/docker" id: Build args: - "build" - "-t" - "gcr.io/$PROJECT_ID/kujilabo-blog-app:$SHORT_SHA" - "."
- name: "gcr.io/cloud-builders/docker" id: Push args: - "push" - "gcr.io/$PROJECT_ID/kujilabo-blog-app:$SHORT_SHA"
- name: "gcr.io/cloud-builders/gcloud" id: Clone env repository entrypoint: /bin/sh args: - "-c" - | gcloud source repos clone kujilabo-blog-env && \ cd kujilabo-blog-env && \ git checkout candidate && \ git config user.email $(gcloud auth list --filter=status:ACTIVE --format='value(account)')
- name: "gcr.io/cloud-builders/gcloud" id: Generate manifest entrypoint: /bin/sh args: - "-c" - | sed "s/GOOGLE_CLOUD_PROJECT/${PROJECT_ID}/g" k8s/kubernetes.yaml.tpl | \ sed "s/COMMIT_SHA/${SHORT_SHA}/g" > kujilabo-blog-env/kubernetes.yaml
- name: "gcr.io/cloud-builders/gcloud" id: Push manifest entrypoint: /bin/sh args: - "-c" - | set -x && \ cd kujilabo-blog-env && \ git add kubernetes.yaml && \ git commit -m "Deploying image gcr.io/${PROJECT_ID}/kujilabo-blog:${SHORT_SHA} Built from commit ${COMMIT_SHA} of repository kujilabo-blog-app Author: $(git log --format='%an <%ae>' -n 1 HEAD)" && \ git push origin candidate
|
続いてk8s/kubernetes.yaml.tpl
にファイルを用意します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| apiVersion: apps/v1 kind: Deployment metadata: name: kujilabo-blog namespace: default spec: selector: matchLabels: run: kujilabo-blog template: metadata: labels: run: kujilabo-blog spec: containers: - image: gcr.io/cocotola/kujilabo-blog-app:COMMIT_SHA imagePullPolicy: IfNotPresent name: kujilabo-blog ports: - containerPort: 80 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: kujilabo-blog namespace: default spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: kujilabo-blog type: NodePort
|
Service はLoadBalancer
ではなくNodePort
を指定しています。
1
| gcloud compute addresses create kujilabo --global
|
IP アドレスの確認コマンドはこちら。
1
| gcloud compute addresses list
|
トリガーも GCP のコンソールから作成しておきます。
ここまでで、app に Push したらビルドが実行されるところまで動作します。
5. https で通信できるように設定する
ドメインは Google Domains で取得済みです。
SSL の設定については以下のドキュメントがわかりやすいです。
https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs?hl=ja
このドキュメントに書かれていることの一部は、すでに Kubernetes で構築した部分もあるので適宜置き換えて読んでください。
k8s/ingress.yaml
にファイルを用意します。
1 2 3 4 5 6 7 8 9 10 11
| apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: kujilabo-blog annotations: kubernetes.io/ingress.global-static-ip-name: kujilabo networking.gke.io/managed-certificates: kujilabo-certificate spec: backend: serviceName: kujilabo-blog servicePort: 80
|
以下のコマンドで適用します。
1
| kubectl apply -f k8s/ingress.yaml
|
k8s/cert.yaml
にファイルを用意します。
1 2 3 4 5 6 7
| apiVersion: networking.gke.io/v1beta1 kind: ManagedCertificate metadata: name: kujilabo-certificate spec: domains: - kujilabo.com
|
以下のコマンドで適用します。
1
| kubectl apply -f k8s/cert.yaml
|
SSL の進捗状況は以下のコマンドで確認できます。
1
| kubectl describe managedcertificate
|