このページは 5/18(土) 14:00 - 18:00 開催予定のGCPUG Shimane #04 のハンズオンセッションの資料となります。
https://gcpug-shimane.connpass.com/event/128517/
目的
今回のハンスおんはGKEにRedmineをデプロイする作業を通して、FileStore(nfs), CloudSQL(mysql)との連携を体験していただくことがメインとなります。
アジェンダ
- 資料の説明(ハンズオンの内容説明)
- GCPの構成の説明(コンテナ、kubernetesの説明)
- RedmineをGKEをベースに動かしてみる(ハンズオン)
- 事前準備
- Cluster 作成
- FileStore 作成
- CloudSQL 作成
- Redmine デプロイ
- 運用管理について
- 削除方法
構成の説明
RedmineをGKEをベースに動かしてみる(ハンズオン)
kubectl (よく使うコマンド)
kubectl get xxx
# (pod, svc, deploy, pv, pvc, secrets, etc)
kubectl describe xxx [xxx_name]
# (pod, svc, deploy, pv, pvc, secrets, etc)
kubectl logs [pod_name]
# ssh(pod)
kubectl get pod
kubectl exec -it [pod_name] /bin/bash
# ssh(node)
kubectl get nodes
gcloud compute ssh [node_name]
# 削除系のコマンド
kubectl delete svc [service_name]
kubectl delete deployment [deployment_name]
kubectl delete pv [pv_name]
kubectl delete pvc [pvc_name]
1. 事前準備
- プロジェクトの作成
- 課金の有効化
- APIの有効化
- Kubernetes Engine API
- Cloud SQL
- Cloud SQL Admin API
- Cloud Filestore API
注)以降の手順(コマンド)はCloud Shellにアクセスして行う
# componentsのインストール
gcloud components install kubectl
# プロジェクトの選択
gcloud config set project [project-id]
# リージョンの選択(東京リージョンを選択)
gcloud config set compute/zone asia-northeast1-a
# 設定情報の確認 上記設定が反映されているか確認してみてください。(任意で実行)
$ gcloud config list
[compute]
region = asia-northeast1
zone = asia-northeast1-a
[core]
account = xxxxxxx@gmail.com
disable_usage_reporting = False
pass_credentials_to_gsutil = true
project = [project-id]
2. Cluster 作成
クラスター名は [ redmine-cloudsql-filestore ] で作成する。
gcloud container clusters create redmine-cloudsql-filestore --num-nodes=3
preemptibleを利用する場合(参考)
# g1-smallタイプのnode(GCEインスタンス)をpreemptible(強制停止あり)で2つ立ち上げる
gcloud container clusters create redmine-cloudsql-filestore --preemptible --machine-type=g1-small --num-nodes=2
# 一台はpreemptibleでないnodeを使用することによって無停止で運用
gcloud container node-pools create default-pool --cluster redmine-cloudsql-filestore --machine-type=g1-small --num-nodes=1
作成済みのclusterを利用する場合(クラスターの選択)
# クラスターのリストを取得
gcloud container clusters list
---
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
persistent-disk-redmine asia-northeast1-a 1.11.8-gke.6 (55 days left) 35.221.66.68 n1-standard-1 1.11.8-gke.6 3 ERROR
---
# kubectlで操作するクラスターを選択する
gcloud config set container/cluster redmine-cloudsql-filestore
作成完了後、コンソールから確認してみてください。
- 「コンピューティング > Kubernetes Engine」
3. Docker Image 作成
GKEで動かすアプリケーションのDocker imagesを作成します。
今回は事前にRedmineを GKE 向けにDocker image化したリポジトリーを準備しましたので、それを使用します。
https://github.com/yoshiokaCB/redmine/tree/gcp/master
以下の手順で CloudShell 上でDocker image をbuildし、GCPのレジストリーサービス(Container Registry)にpushする。
# リポジトリーをダウンロード
git clone -b gcp/master https://github.com/yoshiokaCB/redmine.git ./redmine_gke && cd $_
# Docker imagesをbuild
docker-compose build
# ビルドされたか確認
docker images
# アップロードようにtag付け
docker tag redmine_gke_app asia.gcr.io/[project-id]/redmine_app:v1
# Buildしたイメージをpush
docker push asia.gcr.io/[project-id]/redmine_app
作成完了後、コンソールから確認してみてください。
*「ツール > Container Registry」
4. FileStore 作成 (ストレージサービス)
データの永続化をするために、FileStore(nfs)を作成し、kubernetesのからアクセスできるよに PersistentVolume で volume を定義し, Pod でま mount できるように PersistentVolumeClaim を作成します。
gcloud filestore instances create redmine-nfs-server \
--project=[project-id] \
--zone=asia-northeast1-a \
--tier=STANDARD \
--file-share=name="vol01",capacity=1TB \
--network=name="default"
FileStoreのIPアドレスを確認し、メモしておく
gcloud filestore instances list
INSTANCE_NAME ZONE TIER CAPACITY_GB FILE_SHARE_NAME IP_ADDRESS STATE CREATE_TIME
redmine-nfs-server asia-northeast1-a STANDARD 1024 vol01 10.171.14.xx READY 2019-05-xxT03:24:36
先ほどメモしたIPアドレスを追記する
vi redmine-pv.yaml
# x.x.x.x を先ほどメモしたIPに変更する
# ...
# nfs:
# path: /vol01
# server: x.x.x.x
kubernetesで接続できるようにvolumeを作成
# PersistentVolume の作成(volumeを定義)
kubectl apply -f redmine-pv.yaml
# PersistentVolumeClaim(volumeとpodを紐付け)
kubectl apply -f redmine-volumeclaim.yaml
参考
https://cloud.google.com/kubernetes-engine/docs/concepts/persistent-volumes?hl=ja
作成完了後、コンソールからそれぞれのストレージを確認してみてください。
- 「コンピューティング > Kubernetes Engine > ストレージ」
- 「ストレージ > FileStore」
注) FireStoreとFileStoreは別物です。
5. CloudSQL 作成
データベースの作成し、パスワードをkubernetesに暗号化して登録します。(今回はMySQLを使用)
また今回はDBへのアクセスにSQLProxyを使用しますので、DB作成後、アクセス用に権限(iam)の設定も行います。
権限を作成後をcredentialファイルを一度ダウンロードし、パスワードと同じくkubernetesに暗号化して登録します。
注意) [password]は任意の文字列に変更してください。
# cloudsql instance 作成
gcloud sql instances create redmine-mysql \
--region=asia-northeast1 \
--database-version=MYSQL_5_6 \
--root-password=[password] \
--cpu=1 \
--memory=3840MiB \
--storage-type=SSD \
--storage-size=10GB \
--storage-auto-increase
# k8sへファイルを暗号化して保存しておく
# mysqlというnameの中にpasswordというkeyで値を保存します。
# 後ほどredmineをデプロイするときに環境変数の呼び出しで利用します。
kubectl create secret generic mysql --from-literal=password=[password]
# sqlproxyのコンテナからcloudsql へのアクセスための iam を作成
gcloud iam service-accounts create cloudsql --display-name="cloudsql"
# cloudsql(iam) へ権限追加
gcloud projects add-iam-policy-binding [project-id] \
--member="serviceAccount:cloudsql@[project-id].iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
# credential ファイルのダウンロード(アクセスkeyとpasswordが記入されたjsonファイル)
gcloud iam service-accounts keys create $HOME/cloudsql-credentials.json \
--iam-account cloudsql@[project-id].iam.gserviceaccount.com
# kubernetes へ credential ファイルを登録
# 後ほどredmineのデプロイするときにファイルを参照できるように登録します
kubectl create secret generic cloudsql-instance-credentials \
--from-file=credentials.json=$HOME/cloudsql-credentials.json
作成完了後、コンソールから確認してみてください。
- 「ストレージ > SQL」
6. Redmine デプロイ
いよいよRedmineのデプロイです。
redmine.yaml(deployment)でPodを起動し、redmine-service.yaml(service)で外部へのエンドポイントを作成します。
secret_key_baseを設定する
# secrete_key_baseを編集する
docker-compose run --rm app bundle exec rake secret
vi redmine.yaml
- name: SECRET_KEY_BASE
value: [secret_key_base]
Redmineのデプロイをする
# redmine+sqlproxy のpod作成
kubectl create -f redmine.yaml
# サービスの作成
kubectl create -f redmine-service.yaml
サービス作成後、サイトの確認をする。
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.47.xxx.xx <none> 443/TCP 1d
mysql ClusterIP 10.47.xxx.xx <none> 3306/TCP 1d
redmine LoadBalancer 10.47.xxx.xx 35.221.90.xx 80:30667/TCP 1d
# 35.221.90.xx にブラウザでアクセスする。
EXTERNL-IP(35.221.90.xx)にブラウザからアクセスする。
(ログインID,PASS共にadmin
でアクセス可能)
修正変更等を反省させる時は下記のように apply -f
を使用する
kubectl apply -f redmine.yaml
更新
- Redmineのコードに変更を加える。
- ビルドの再実行
- tagをv2に変更してpush
- redmine.yamlのimageのtagをv2に変更して更新
ロールバック
$ kubectl get deployment
--
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
redmine 1 1 1 1 8d
--
$ kubectl rollout history deployment redmine
deployments "redmine"
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
# バージョンの詳細確認(yaml表示)
$ kubectl rollout history deployment redmine --revision=1
# ロールバック
$ kubectl rollout undo deployment redmine --to-revision=1
スケール・オートスケール
コンソールで設定してアクセス負荷をかけてみる
無停止でnodeを更新する
# 新規 node-pool 作成
gcloud container node-pools create n1-pool --cluster redmine-cloudsql-filestore --machine-type=n1-standard-1 --num-nodes=2 --enable-autoscaling --min-nodes=2 --max-nodes=10 --zone asia-northeast1-a
# nodeのスケジューリングを停止する
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do kubectl cordon "$node"; done
# nodeをdrainする
for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=180 "$node";
done
# 古い node-pools 削除
gcloud container node-pools delete default-pool --cluster redmine-cloudsql-filestore --zone asia-northeast1-a
参考サイト
gcloud リファレンス
kubectl リファレンス
kubernetes : kubectlコマンド一覧
GKE
チュートリアル
Using Persistent Disks with WordPress and MySQL
Github(サンプルコード)
GKE + FileStore
https://cloud.google.com/filestore/docs/accessing-fileshares
https://cloud.google.com/kubernetes-engine/docs/concepts/persistent-volumes?hl=ja
GKE + CloudSQL
EC2 インスタンスで運用している GitLab を、 GKE に移行してみた。(Kubernetes Engine + Cloud SQL + Cloud Filestore)
Kubernetes: Deployment の仕組み
GKEのインスタンスタイプを無停止で変更する
https://cloud.google.com/kubernetes-engine/docs/concepts/node-pools?hl=ja
https://cloud.google.com/kubernetes-engine/docs/resize-cluster?hl=ja
KubernetesにおけるLoadBalancerとIngressの違いについて