Kubernetes2 Advent Calendar 2017 16日目です(10日遅れました..)
https://qiita.com/advent-calendar/2017/kubernetes2
GKE を触る機会があったので GKE を使って kubenetes クラスタを使ってサンプルアプリが動くまでのコマンドなどを(ほぼ自分用に)忘備録としてまとめてみました
初めて GCP+Kubenetes を使ってどっちもよくわからんて状態だったのでとりあえず最終的にココらへんのコマンドを使ったら動く所まで行ったというメモ程度な感じです
結構やることが多かったので結構コマンドをそのまま列挙する感じになってしまっています
やりたいこと
- Kubenetes(GKE)
- MySQL(Cloud SQL)
を使ったWEBアプリケーション環境の構築
プロジェクト作成 ~ gcloud コマンドに設定
GCP にはプロジェクト単位で課金をするアカウントを設定する必要があるようなので、あらかじめ以下のコマンドで課金を行うアカウントのIDの取得しておきます
gcloud beta billing accounts list
取得したらプロジェクトの作成と gcloud コマンドの設定を行う
gcloud projects create sample-app # プロジェクト作成
gcloud beta billing projects link sample-app --billing-account=XXXXXX-XXXXXX-XXXXXX # 決済アカウントと紐付け(XXXXXX-XXXXXX-XXXXXX の部分は先ほど取得したアカウントIDに置き換える)
gcloud config set project sample-app # gcloud コマンドで操作するデフォルトのプロジェクトを設定
gcloud config set compute/zone asia-northeast1-b # gcloud コマンドで利用するデフォルトのリージョンを設定
Cloud SQL
サンプルで作成するアプリケーションでは Cloud SQL の MySQL を利用してみようと思うので gcloud コマンドから Cloud SQL API の有効化します
GCP ではプロジェクト単位で各 API を利用する際に予め有効化しておく必要があるようです
gcloud service-management enable sqladmin.googleapis.com
有効化したので Cloud SQL インスタンスを起動
gcloud beta sql instances create sample-app \
--tier db-f1-micro \
--backup \
--backup-start-time '19:00' \
--database-version MYSQL_5_7 \
--activation-policy ALWAYS \
--enable-bin-log \
--region asia-northeast1 \
--gce-zone asia-northeast1-b \
--maintenance-release-channel production \
--maintenance-window-day MON \
--maintenance-window-hour 18 \
--storage-auto-increase \
--storage-type SSD \
--database-flags character_set_server=utf8
起動後に MySQL の root アカウントのパスワード設定やアプリケーション用ユーザーの作成を行います
root_password=$(pwgen -sy 16 1)
app_user_password=$(pwgen -sy 16 1)
gcloud sql instances set-root-password sample-app --password $root_password
gcloud beta sql users create app_user cloudsqlproxy~% --instance=sample-app --password=$app_user_password
サービスアカウント
Cloud SQL への接続にはいくつかの方法があるようだが GKE を利用する場合に Cloud SQL Proxy を使った方法が紹介されていたのでこの方法を使って接続できるようにしてみます
https://cloud.google.com/sql/docs/mysql/connect-container-engine
GKE のコンテナ上で Cloud SQL Proxy を利用するにはサービスアカウントが必要なようなので作成を行います
https://cloud.google.com/iam/docs/service-accounts
個人的な雑な理解としてはサービスアカウント=AWSでいう所のIAMロールぽく使えるものみたいな認識です
gcloud iam service-accounts create cloud-sql
作成したサービスアカウントの email を取得
gcloud iam service-accounts list
更にこのサービスアカウントを利用して Cloud SQL Proxy で接続できるようにするために Cloud SQL クライアント権限を付与
gcloud projects add-iam-policy-binding sample-app \
--member='serviceAccount:cloud-sql@sample-app.iam.gserviceaccount.com' \
--role='roles/cloudsql.client'
cloud-sql@sample-app.iam.gserviceaccount.com
の部分を取得した email に差し替えて実行する
権限を付与したらこのサービスアカウントを利用するための秘密鍵を生成
gcloud iam service-accounts keys create ~/cloud-sql-key.json --iam-account cloud-sql@sample-app.iam.gserviceaccount.com
https://cloud.google.com/sql/docs/mysql/connect-admin-proxy#install
を参考に環境にあわせた Cloud SQL Proxy をインストールして Cloud SQL Proxy を起動する
cloud_sql_proxy \
-instances=sample-app:asia-northeast1:sample-app=tcp:3306 \
-credential_file="~/cloud-sql-key.json"
-credential_file="~/cloud-sql-key.json"
で渡した json ファイルのサービスアカウントで Cloud SQL Proxy が立ち上がるようです
実際に接続できるかを確認してみる
mysql -h 127.0.0.1 -u sample-app -p$app_user_password
GKE
Cloud SQL 周りの設定ができたので次は GKE 関連の設定などをおこなっていきます
GKE を利用するために compute API を有効化します
gcloud service-management enable compute.googleapis.com
Kubenetes のクラスタを作成
gcloud container clusters create sample-app \
--cluster-version=1.7.8 \
--image-type=COS \
--machine-type=g1-small \
--num-nodes=3 \
--node-labels=role=sample-app-node \
--enable-cloud-logging \
--enable-cloud-monitoring
更に kubectl コマンド用に以下で credentials を取得しておく
gcloud container clusters get-credentials sample-app --zone asia-northeast1-b --project sample-app
kubectl config use-context gke_sample-app_asia-northeast1-b_sample-app
Cloud SQL Proxy 向けの credentials を設定
kubectl create secret generic
コマンドを使ってパスワードなど暗号化したいデータをコンテナに渡すことができるようなので設定しておく
kubectl create secret generic cloudsql-oauth-credentials --from-file=credentials.json='~/cloud-sql-key.json'
kubenates 関連情報の設定
ドメインを当てる場合に IP が切り替わると困るので static ip を取得して利用するようにする
gcloud compute addresses create sample-app-static-ip --global
deployment 生成
kubenetes では自作した docker イメージを利用するようにしてみたいので Container Registory API を有効化する
gcloud service-management enable containerregistry.googleapis.com
有効にしたらデプロイしたいコンテナアプリケーションを
gcloud docker -- push asia.gcr.io/sample-app
のようにして Container Registory に push する
push したイメージを利用して以下のような deployment の mainifest ファイルを作成
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: app
spec:
minReadySeconds: 15
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 100%
maxUnavailable: 0
replicas: 2 # 作成する pod の数
template:
metadata:
labels:
app: app
spec:
containers:
- image: asia.gcr.io/sample-app:latest # リリースするコンテナを設定
name: app
ports:
- containerPort: 3000 # 起動するアプリケーションポートの番号
name: app
readinessProbe: # リクエスト送信可能かをチェックするヘルスチェックのパス情報を記載
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 60
periodSeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 10
livenessProbe: # コンテナが行きているかをチェックするヘルスチェックのパス情報を記載
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 60
periodSeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 10
- image: b.gcr.io/cloudsql-docker/gce-proxy:1.09 # Cloud SQL Proxy コンテナ
name: cloudsql-proxy
command: ["/cloud_sql_proxy",
"--dir=/cloudsql",
"-instances=sample-app:asia-northeast1:sample-app=tcp:3306", # 接続先情報 gcloud sql instances describe sample-app | grep connectionName のようにして取得できる
"-credential_file=/secrets/cloudsql-proxy/credentials.json"] # サービスアカウントの認証 json ファイル
volumeMounts:
- name: cloudsql-oauth-credentials
mountPath: /secrets/cloudsql
readOnly: true
- name: ssl-certs
mountPath: /etc/ssl/certs
- name: cloudsql
mountPath: /cloudsql
volumes:
- name: cloudsql-oauth-credentials
secret:
secretName: cloudsql-oauth-credentials # kubectl create secret generic で設定した秘密情報データを設定
- name: ssl-certs
hostPath:
path: /etc/ssl/certs
- name: cloudsql
emptyDir:
作成したら
kubectl apply -f deployment.yml
のようにして kubenetes に設定を適用する
適用したら
kubectl get pods
のようにして manifest ファイルから起動した pod の情報を取得できる
NodePort Service を作成
次に NodePort の作成を行う
kubectl expose deployment app --target-port=3000 --type=NodePort
Ingress 作成
次に Ingress の作成を行う
deployment の時のように manifest ファイルを作成して適用する
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: sample-app-static-ip # gcloud compute addresses create の時の名前を指定する
spec:
backend:
serviceName: app
servicePort: 3000
kubectl apply -f ingress.yaml
実行したら
watch kubectl get ingress
を実行して最終的に
NAME HOSTS ADDRESS PORTS AGE
app-ingress * 11.111.111.111 80 1m
のように ADDRESS のIPアドレスが表示されるまで1~2分待つ
(何分も待っても表示されない場合何らかでうまく行ってない可能性が高い)
この時点で↑で表示されるIPアドレスにアクセスするとアプリケーションが表示されるはずです
うまく行っていれば対象IPにドメインを割り当てたりすれば良いかと思います
(ややこしかったのでSSL対応についてはスキップしてます)
感想
いきなり GCP も Kubenetes も慣れていない状態で GKE 触ろうとすると両方を覚えながらやらなきゃいけないので覚えることが多くてはじめに動かすところまで行くのが結構大変でした