SlideShare a Scribd company logo
1 of 65
Download to read offline
GKEで半年運用してみた
Katsutoshi Nagaoka



gcp ja night #31 (2016/01/21) #gcpja
永岡 克利 (Katsutoshi Nagaoka)
• 2011年 CyberAgent 中途入社
• 社内向け基盤システムの開発・運用
• 現在、ライブ配信サービス「takusuta」を立ち上げ、運用中
• エンジニア
• #java #cassandra …
• #golang #node.js #mongodb #aws #gcp …
@na_ga
About me
Outline
• takusuta 紹介
• GKE ざっくり説明
• takusuta における GKE の活用例
• まとめ
takusuta 紹介
ライブ配信サービス takusuta
iOS & Android App

2015/07 ~
ライブ配信サービス takusuta
https://takusuta.com/ on GKE

2015/08 ~
iOS & Android App

2015/07 ~
• API
• EC2
• S3
• Web
• GKE
• S3
構成
AWS
Route53
CloudFront S3
EC2 MongoDBELB
BigQuery
GCP
GKEGCE-LB
Aerospike
GKE 採用に至るまで
• 2015/07
• iOS, Android アプリ公開
• S3 の Static Content でペライチな Web ページ
• nodejs + riot による SEO 対策した Web ページを作ることに
• ちょうど kubernetes v1.0.0 がリリースされた
• 近いうちに GKE も GA になりそうな
• どうせ作るなら… 一旦 Web だけワンチャン使ってみたい
• 2015/08
• GKE is Generally Available
• Web ページリニューアル
GKE について
GKE とは
• Kubernetes のフルマネージドサービス
• Docker コンテナの管理ツール
• GCE 上に Kubernetes Cluster を構築
• クラスタのリサイズ
• コンテナのグルーピング
• コンテナの自動配置
• コンテナのリサイズ
• コンテナの負荷分散
出典: http://kubernetes.io/
GKE の料金
• すごい安い
• Cluster の各 Node 料金は GCE 料金が適用
• Cluster の料金は Node 数によって異なる
• 5 Node までは無料
• 6 Node 以上で $0.15 hour / cluster
• $108 month / cluster
GKE の用語
• Pod
• コンテナのグループ
• 1コンテナ以上で作成
• Replication Controller (RC)
• Pod のレプリカ管理
• 管理下の Pod のリサイズを担当
Pod
GKE Node
Pod Pod
GKE Node
Pod Pod Pod
RC
Management Pod Replica
GKE の用語
• Pod
• コンテナのグループ
• 1コンテナ以上で作成
• Replication Controller (RC)
• Pod のレプリカ管理
• 管理下の Pod のリサイズを担当
• Service
• Pod に対する LB みたいなやつ
• iptables で DNAT → kube-proxy
Pod
GKE Node
Pod Pod
GKE Node
Pod Pod Pod
Service RC
Layer4 Load Balancer
GKE における構成
単体構成
• GKE
• tkst-service (type: LoadBalancer)

設定された Global IP で公開される

現状では Layer4 のみサポート
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User
Admin
https://takusuta.com
単体構成
• GKE
• tkst-service (type: LoadBalancer)

設定された Global IP で公開される

現状では Layer4 のみサポート

• Service に証明書を設定できない
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User
Admin
https://takusuta.com
単体構成
• GKE
• tkst-service (type: LoadBalancer)

設定された Global IP で公開される

現状では Layer4 のみサポート

• Service に証明書を設定できない
• 各 Pod に証明書を持たせる
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User
Admin
https://takusuta.com
単体構成
• GKE
• tkst-service (type: LoadBalancer)

設定された Global IP で公開される

現状では Layer4 のみサポート

• Service に証明書を設定できない
• 各 Pod に証明書を持たせる
• 非効率的なので避けたい
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User
Admin
https://takusuta.com
GCE-LB と組み合わせた構成
• GKE
• tkst-service (type: NodePort)

各 Node が Service に設定した

ポートでリクエストを受け付ける
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User
tkst-backend
tkst-url-map
GCE-HTTPS-LB
https://takusuta.com
Admin
GCE-LB と組み合わせた構成
• GKE
• tkst-service (type: NodePort)

各 Node が Service に設定した

ポートでリクエストを受け付ける

• GCE-LB に証明書を設定する
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User
tkst-backend
tkst-url-map
GCE-HTTPS-LB
https://takusuta.com
Admin
GCE-LB と組み合わせた構成
• GKE
• tkst-service (type: NodePort)

各 Node が Service に設定した

ポートでリクエストを受け付ける

• GCE-LB に証明書を設定する
• GKE の Instance Group と

ポートを Backend として指定する
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User
tkst-backend
tkst-url-map
GCE-HTTPS-LB
https://takusuta.com
Admin
Cross Region LB 構成
• 米国からは US Region
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User from US
tkst-backend-us
tkst-url-map
Cross-Region HTTPS-LB
https://takusuta.com
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
tkst-backend-asia
Cross Region LB 構成
• 日本からは Asia Region
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User from Japan
tkst-backend-us
https://takusuta.com
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
tkst-backend-asia
tkst-url-map
Cross-Region HTTPS-LB
Cross Region LB 構成
• 利用率や Rate で自動切り替え
• ex: CPU 80%
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
User from Japan
tkst-backend-us
https://takusuta.com
tkst-pod
GKE NODE GKE NODE
tkst-service tkst-rc
tkst-pod
tkst-backend-asia
tkst-url-map
Cross-Region HTTPS-LB
Region/zone の選択
• Zone によって差異がある
• Haswell [2013 ]
• Ivy Bridge [2012 ]
• Sandy Bridge [2011 ]
• Asia Region は同じなので

気にしなくて ok
出典: https://cloud.google.com/compute/docs/zones
GKE の構築
Google Cloud SDK
• Google 社製の GCP 管理ツール群
• gcloud
• Cluster の作成/管理
• kubectl
• RC の作成/管理
• Service の作成/管理
Cluster の作成
# create cluster

$ gcloud container clusters create "tkst-asia-001" 

--num-nodes 3 
--zone "asia-east1-b" 
--machine-type "n1-highcpu-4" 

--scope "compute-rw","storage-ro","bigquery","logging-write","monitoring"



• cluster 作成時しか設定できない項目がある
• num-nodes は cluster 作成後もオンラインで変更できる
• 現時点では num-nodes 以外の項目は cluster 作成後に変更できない

• 特に scope は後々面倒になるので注意が必要
• GKE から Fluentd などで BigQuery に流し込む為には bigquery scope が必須
• 直近使う予定がなくても、とりあえず付けといた方が良い

Cluster の取得
# describe cluster

$ gcloud container clusters describe tkst-asia-001



currentNodeCount: 3
currentMasterVersion: 1.1.4
currentNodeVersion: 1.1.4
initialClusterVersion: 1.1.4
nodeConfig:
diskSizeGb: 100
machineType: n1-highcpu-4
oauthScopes:
- https://www.googleapis.com/auth/bigquery
- https://www.googleapis.com/auth/compute
- https://www.googleapis.com/auth/devstorage.read_only
- https://www.googleapis.com/auth/logging.write
- https://www.googleapis.com/auth/monitoring
nodeIpv4CidrSize: 24
status: RUNNING
zone: asia-east1-b
Image のアップロード
# build docker image

$ docker build .



# upload docker image to Google Container Registry (GCR)

$ docker tag -f tkst/tkst asia.gcr.io/xxxxx/tkst:1.9.3

$ gcloud docker push asia.gcr.io/xxxxx/tkst:1.9.3



• GCR はホスト名でアップロード先リージョンを指定できる
• asia.gcr.io: asia リージョン
• us.gcr.io: us リージョン
• eu.gcr.io: european リージョン
RC の作成
# create replication controller

$ cat << EOS > ./tkst-rc.json; kubectl create -f ./tkst-rc.json
{
"kind": "ReplicationController",
"apiVersion": "v1",
"metadata": { "name": "tkst-rc", "labels": { "name": "tkst-rc" } },
"spec": {
"replicas": 3,
"selector": { "name": "tkst-rc-pods" },
"template": {
"metadata": { "labels": { "name": "tkst-rc-pods" } },
"spec": {
"containers": [ {
"name": "tkst-container",
"image": "asia.gcr.io/xxxxx/tkst:1.9.3",
"ports": [ { "containerPort":3000, "protocol":"TCP" } ]
} ]
}
}
}
}
EOS
RC の取得
# get replication controller

$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
tkst-rc tkst asia.gcr.io/xxxxx/tkst:1.9.3 name=tkst-rc-pods 3 



# describe replication controller

$ kubectl describe rc tkst-rc
Name: tkst-rc
Namespace: default

Image(s): asia.gcr.io/xxxxx/tkst:1.9.3
Selector: name=tkst-rc-pods
Labels: name=tkst-rc
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
No volumes.

Events:
FirstSeen LastSeen Count Reason Message
───────── ──────── ───── ────── ───────
25m 25m 1 SuccessfulCreate Created pod: tkst-rc-5gghw
25m 25m 1 SuccessfulCreate Created pod: tkst-rc-b59cv

25m 25m 1 SuccessfulCreate Created pod: tkst-rc-qw4da
Pod の取得
# get pod

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
tkst-rc-1tjlf 1/1 Running 0 25m
tkst-rc-5zogh 1/1 Running 0 25m
tkst-rc-kpujg 1/1 Running 0 25m



# describe pod

$ kubectl describe pod tkst-rc-1tjlf
Name: tkst-rc-1tjlf
Namespace: default
Image(s): asia.gcr.io/xxxxx/tkst:1.9.3
Node: gke-tkst-asia-001-a48fb14f-node-crjc/10.240.0.18
Start Time: Thu, 21 Jan 2016 06:03:50 +0900
Labels: name=tkst-rc-pods
Status: Running
IP: 10.184.2.3
Replication Controllers: tkst-rc (3/3 replicas created)
Pod への接続
# attach pod

$ kubectl attach pod tkst-rc-1tjlf


# get pod log

$ kubectl logs -f tkst-rc-1tjlf
# get pod log (with content name)
$ kubectl logs -f tkst-rc-1tjlf -c tkst-node-container
{"level":"info","message":"use memcached store [options={"hosts":["10.240.0.4:11211
{"level":"debug","message":"try to update site-maps cache.","label":"dev","timestamp":
{"level":"debug","message":"cache update scheduler started. key=sitemap","label":"dev"
{"level":"info","message":"[middleware_access_logger] setup with options {"tag":"ta
{"level":"info","message":"[WEB] Append route. path={"twitter":"/explore/auth/twitt
{"level":"info","message":"[WEB] Append route. path="/explore/logout"","label":"web_
{"level":"info","message":"[WEB] Append route. path="/ping"","label":"web_dev","time
{"level":"info","message":"[WEB] Append route. path="/"","label":"web_dev","timestam
...
Service の作成
# create service

$ cat << EOS > ./tkst-srv.json; kubectl create -f ./tkst-srv.json
{
"kind": "Service",
"apiVersion": "v1",
"metadata": { "name": "tkst-srv", "labels": { "name": "tkst-srv" } },
"spec": {
"type": "NodePort",
"ports": [ {
"port": 3000,
"targetPort": 3000,
"nodePort": 30000
} ],
"selector": {
"name": "tkst-rc-pods"
}
}
}
EOS
Service の取得
# get service

$ kubectl get service
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR
tkst-srv 10.119.246.120 nodes 3000/TCP name=tkst-rc-pods
kubernetes 10.119.240.1 <none> 443/TCP <none> 



# describe service

$ kubectl describe service tkst-srv
Name: tkst-srv
Namespace: default
Labels: name=tkst-srv
Selector: name=tkst-rc-pods
Type: NodePort
IP: 10.119.246.120
Port: 3000/TCP
NodePort: 30000/TCP
Endpoints: 10.116.0.3:3000,10.116.2.3:3000
Session Affinity: None
No events.
HTTPS-LB の作成
# create backend

$ gcloud beta compute backend-services create "tkst-backend" 

—-protocol HTTP --port-name "tkst-port" --http-health-check "tkst-check"



# add backend resource 

$ gcloud beta compute backend-services add-backend "tkst-backend" 
--instance-group "${GKE_INSTANCE_GROUP}"


# create url maps
$ gcloud beta compute url-maps create "tkst-https-lb" 

--default-service "tkst-backend"
# create target https proxy
$ gcloud beta compute target-https-proxies create "tkst-https-lb-proxy" 

--url-map "tkst-https-lb" 

--ssl-certificate "${SSL_CERTIFICATE}"



# create forwarding rule
$ gcloud beta compute forwarding-rules create "tkst-https-lb-forward" 

--global --address "${LB_GLOBAL_IP}" --port-range "443" 

--target-https-proxy "tkst-https-lb-proxy"
takusuta における GKE 活用例
用途によって Cluster を別ける
• 大きなクラスターは作らない
• 5 ノード以下は無料
• 最大ノード数は 250 まで(少し前は 100 までだった)
• 同じ Pod でまとめた方がキャパシティ制御しやすい
用途によって Cluster を別ける
• ennis-asia-app-001 cluster
• num-nodes: 5, machine-type: n1-highcpu-4
• service: ennis-asia-app-srv (type=NodeType, 30000),
• rc: ennis-asia-app-rc (replica=10 )

• ennis-asia-nginx-001 cluster
• num-nodes: 3, machine-type: n1-highcpu-2
• service: ennis-asia-nginx-srv (type=NodeType, 30080, 30443)
• rc: ennis-asia-nginx-rc (replica=3 )
Cluster の命名規則ぽい奴
• ennis-asia-app-001
• ennis: プロジェクトの chord name
• asia: 配置する region
• app: 稼働させる container の名称
• 001: ユニークにするための連番(なんでも良い)

• Cluster の machine-type をオンラインで変更はサポートされていない
• 現状だと新しく Cluster を作成して GCE-LB を切り替える
• 高い頻度で Cluster を再構築 (使い捨て) している
Cluster の命名規則ぽい奴
• ennis-asia-app-001
• ennis: プロジェクトの chord name
• asia: 配置する region
• app: 稼働させる container の名称
• 001: ユニークにするための連番(なんでも良い)

• Cluster の machine-type をオンラインで変更はサポートされていない
• 現状だと新しく Cluster を作成して GCE-LB を切り替える
• 高い頻度で Cluster を再構築 (使い捨て) している
• Instance Templates の更新 API が無い … (́・ω・`)
Multi Container Pod
• ennis-app pod
• 用途
• Web アプリケーションコンテナ
• 全てのログは 127.0.0.1:24224 を経由して BigQuery に投げている
• コンテナ
• API (ennis-node-con, TCP:3000, 3001)
• Fluentd (ennis-fluentd-con, TCP:24224)

Multi Container Pod
# get service list
$ kubectl get service
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR
ennis-app-srv 10.187.254.39 nodes 3000/TCP,3001/TCP name=ennis-app-rc-pods
kubernetes 10.187.240.1 <none> 443/TCP <none>
# get replication controller list

$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S)
ennis-app-rc-1453323827 ennis-node-con asia.gcr.io/xxxxx/ennis-node:1.9.5
ennis-fluentd-con asia.gcr.io/xxxxx/fluentd-aggregator:1.0.1
# get pod list
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
ennis-app-rc-1453323827-0ampm 2/2 Running 0 2h
ennis-app-rc-1453323827-5xvfk 2/2 Running 0 2h
ennis-app-rc-1453323827-gvr4z 2/2 Running 0 2h
Single Container Pod
• ennis-nginx pod 
• 用途
• GCE-LB の Default Backend として設定する
• url-maps に該当しないリクエストは nginx 経由で転送させる
• ex: http(s)://107.178.243.152/ → https://takusuta.com/
• コンテナ
• Nginx (ennis-nginx-proxy-con, TCP:80)

Single Container Pod
# get service list
$ kubectl get service
NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR
ennis-nginx-srv 10.107.251.130 nodes 80/TCP name=ennis-nginx-rc-pods
kubernetes 10.107.240.1 <none> 443/TCP <none>
# get replication controller list

$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S)
ennis-nginx-rc ennis-nginx-proxy-con asia.gcr.io/xxxxx/nginx-proxy:1.0.2
# get pod list
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
ennis-nginx-rc-3byoj 1/1 Running 0 7h
ennis-nginx-rc-i6dbs 1/1 Running 0 7h
ennis-nginx-rc-sefai 1/1 Running 0 7h
Sample : Dockerfile
# nginx-proxy Dockerfile
$ cat ./nginx-proxy/Dockerfile
FROM takusuta/nginx-1.8.0
MAINTAINER Katsutoshi Nagaoka <katsutoshi.nagaoka@gmail.com>
USER root
ENV HOME /root
WORKDIR /root
# Define default command.
CMD ["bash"]
# Generate script.
ADD generate-nginx-proxy-conf.sh /usr/local/sbin/generate-nginx-proxy-conf.sh
# Staring nginx.
EXPOSE 80
CMD /usr/local/sbin/generate-nginx-proxy-conf.sh && nginx -g "daemon off;"
Sample : Dockerfile
# generate nginx-proxy config script
$ cat ./nginx-proxy/generate-nginx-proxy-conf.sh
#!/bin/sh
if [ "x${ENNIS_WEB_DOMAIN}" = "x" ] ; then
echo "Invalid parameter, ENNIS_WEB_DOMAIN is empty”; exit 1
fi
cat << EOS > /etc/nginx/conf.d/nginx-proxy.conf
server {
listen 80;
server_name _;
location ~^/ping$ {
access_log off;
return 200;
}
location / {
return 301 https://${ENNIS_WEB_DOMAIN}$request_uri;
}
}
EOS
Sample : RC
# create ennis-nginx replication controller

$ cat << EOS > ./${NGINX_RC_NAME}.json && kubectl create -f ./${NGINX_RC_NAME}.json
{
"kind": "ReplicationController",

"apiVersion": "v1",
"metadata": { "name": "${NGINX_RC_NAME}", "labels": { "name": "${NGINX_RC_NAME}" } },
"spec": {
"replicas": 3,
"selector": { "name": "${NGINX_POD_NAME}" },
"template": {
"metadata": { "labels": { "name": "${NGINX_POD_NAME}" } },
"spec": {
"containers": [
{
"name": “ennis-nginx-proxy-con",
"image": "${GCR_DOMAIN}/${PROJECT_ID}/nginx-proxy:${TAG}",
"env": [ { "name": "ENNIS_WEB_DOMAIN", "value": "${DOMAIN}" } ],
"ports": [ { "containerPort":80, "protocol":"TCP" } ]
}
...
EOS
Sample : Service
# create ennis-nginx service

$ cat << EOS > ./${NGINX_SRV_NAME}.json && kubectl create -f ./${NGINX_RC_NAME}.json
{
"kind": "Service",
"apiVersion": "v1",
"metadata": { "name": "${NGINX_SRV_NAME}", "labels": { "name": "${NGINX_SRV_NAME}" } },
"spec": {
"type": "NodePort",
"ports": [
{
"port": 80,
"targetPort": 80,
"nodePort": 30080,
"protocol": "TCP"
}
],
"selector": { "name": "${NGINX_POD_NAME}" }
}
}
EOS
GCR への最速アップロード
• GCE 上の Jenkins でイメージのビルド & アップロードをしている
• 同じ Google ネットワーク内のため最速で GCR にアップロード可能
• タグ切り → CI → Jenkins (build & upload & release) ← hubot
• GCR が落ちたなどの障害は今の所、経験なし
GCR への最速アップロード
• GCE 上の Jenkins でイメージのビルド & アップロードをしている
• 同じ Google ネットワーク内のため最速で GCR にアップロード可能
• タグ切り → CI → Jenkins (build & upload & release) ← hubot
• GCR が落ちたなどの障害は今の所、経験なし
• GCR 上にアップロードした古いイメージの削除に若干難あり
• そのうち改善されるはず…
RC の無停止アップデート
• kubectl rolling-update コマンドでリリース作業をしている
• 新旧 RC の各 Pod を一台ずつ inc/dec してくれる
• single container Pod は非常に簡単

kubectl rolling-update [old-rc-name] [new-image-url]

• multi container Pod は分かり難い
• kubectl rolling-update [old-rc-name] -f [new-rc-json]
• rc name に "-unixtime" などを追記し、

selector と metadata も同様に version: "unixtime" などを入れる
• ex: ennis-asia-app-rc → ennis-asia-app-rc-1453323016
RC の無停止アップデート
# create multi container pod schema JSON for rolling update

$ RC_NAME=tkst-rc
$ RC_CREATED=$(Date +'%s') 

$ RC_UNIQUE_NAME=${RC_NAME}-${RC_CREATED}


$ cat << EOS | kubectl rolling-update ${RC_CURRENT_NAME} -f -
{
"kind": "ReplicationController",
"metadata": { "name": "${RC_UNIQUE_NAME}", "labels": { "name": "${RC_UNIQUE_NAME}" }
},
"spec": {
"selector": { "name": "${RC_NAME}-pods", "version": "${RC_CREATED}" },
"template": {
"metadata": {
"labels": { "name": "${RC_NAME}-pods", "version": "${RC_CREATED}" }
},
"spec": {
"containers": [ { ... }, { ... }, ... ],
...
EOS
Cluster / RC のスケール
• gcloudコマンドで node を制御できる
• gcloud compute instance-groups managed 

resize [gke-cluster-instance-group] --size [num]
• kubectl scale コマンドで replica を制御できる
• kubectl scale rc [rc-name] --replicas=[num]
• RC のオートスケールも実装されたが、まだ使い道が浮かんでこない
Cloud Logging によるログ管理
• GKE は各 Pod の標準出力を Cloud Logging に投げている 
• ログの集約及び閲覧をリアルタイムに実現できる
• 最近 GKE フィルターが付いて益々便利になった
Cloud Logging によるログ管理
• GKE は各 Pod の標準出力を Cloud Logging に投げている 
• ログの集約及び閲覧をリアルタイムに実現できる
• 最近 GKE フィルターが付いて益々便利になった
• 標準機能だとノイズが多く若干不便
• app container から CL の REST API を直接叩いている (winston-gcl)
• ログ名、レベルによるフィルターも効くのでもっと便利に
• 負荷急騰時は、一旦 CL を見る体勢
Cloud Monitoring による死活監視
• イマなら StackDriver を無料で使える
• 元々AWS の死活監視に使用していたので違和感なし
• Alert 時は Slack とメールでの通知を行っている
Cloud Monitoring による死活監視
• イマなら StackDriver を無料で使える
• 元々AWS の死活監視に使用していたので違和感なし
• Alert 時は Slack とメールでの通知を行っている
• GKE Container リソースで取得可能な metrics が少ない
• 古い GKE Cluster の場合 StackDriver agent から取得できない
• GKE Cluster をアップデート (or 作り直し) で正常に取得できる
• 足りない箇所は各 container から custom metrics を送信している
Kubernetes dashboard
• 標準機能の簡易ダッシュボード
• そんなに信用してないし、あまり見ていない
• 使いにくい
https://xxx.xxx.xxx.xxx/api/v1/proxy/namespaces/kube-system/services/kube-ui
• 結構使える子
• https://github.com/kubernetes/kubedash
• Cloud Monitoring は重い…
• パッと確認するのに便利
• インストールも簡単
kubedash
https://xxx.xxx.xxx.xxx/api/v1/proxy/namespaces/kube-system/services/kubedash
まとめ
GKEで半年運用してみて…
• 簡単 & 安い & 期待
• 細かいところは幾つかあるが、本番環境で問題なく利用できてる
• ここ数ヶ月で Cloud Logging の GKE 連携改善など色々キテル
• GKE のドキュメントは少ないが、kubernetes docs で事足りる

• GKE によるコンテナ管理は非常に魅力的で、積極的に使っていきたい
• 出来るだけシンプルに使う・複雑な構成はしない
チートシート
# pod

$ kubectl get pod
$ kubectl describe pod [pod-name]
$ kubectl attach [pod-name]
$ kubectl logs [-f] [pod-name] [-c container-name]
# replication controller

$ kubectl get rc
$ kubectl describe rc [rc-name]
$ kubectl rolling-update [rc-name] [new-image-url]
$ kubectl rolling-update [rc-name] -f [new-rc-schema-json-file-path]
$ kubectl scale rc [rc-name] --replicas=[num]
# service

$ kubectl service service
$ kubectl describe service [service-name]
# cluster

$ kubectl cluster-info
$ gcloud compute instance-groups managed resize [gke-cluster-instance-group] --size [num]
ご静聴ありがとうございました

More Related Content

What's hot

Kubernetesを触ってみた
Kubernetesを触ってみたKubernetesを触ってみた
Kubernetesを触ってみたKazuto Kusama
 
AWSとGCPを使用したインフラ環境
AWSとGCPを使用したインフラ環境AWSとGCPを使用したインフラ環境
AWSとGCPを使用したインフラ環境Katsutoshi Nagaoka
 
机上の Kubernetes - 形式手法で見るコンテナオーケストレーション #NGK2016B
机上の Kubernetes -  形式手法で見るコンテナオーケストレーション #NGK2016B机上の Kubernetes -  形式手法で見るコンテナオーケストレーション #NGK2016B
机上の Kubernetes - 形式手法で見るコンテナオーケストレーション #NGK2016By_taka_23
 
Kubernetes超入門 with java
Kubernetes超入門 with javaKubernetes超入門 with java
Kubernetes超入門 with javaYasunari Tanaka
 
Fission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyoFission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyoy_taka_23
 
新しいOpenShiftのしくみを調べてみた
新しいOpenShiftのしくみを調べてみた新しいOpenShiftのしくみを調べてみた
新しいOpenShiftのしくみを調べてみたKazuto Kusama
 
Kubernetesにまつわるエトセトラ(主に苦労話)
Kubernetesにまつわるエトセトラ(主に苦労話)Kubernetesにまつわるエトセトラ(主に苦労話)
Kubernetesにまつわるエトセトラ(主に苦労話)Works Applications
 
Docker, Kubernetes and OpenShift v3
Docker, Kubernetes and OpenShift v3Docker, Kubernetes and OpenShift v3
Docker, Kubernetes and OpenShift v3Emma Haruka Iwao
 
Dockerでらくらく開発・運用を体感しよう
Dockerでらくらく開発・運用を体感しようDockerでらくらく開発・運用を体感しよう
Dockerでらくらく開発・運用を体感しようTakashi Makino
 
Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~
Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~
Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~Masahito Zembutsu
 
VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門Masashi Shinbara
 
Weaveを試してみた
Weaveを試してみたWeaveを試してみた
Weaveを試してみたKazuto Kusama
 
IBM Log Analysis with LogDNAを評価した話
 IBM Log Analysis with LogDNAを評価した話 IBM Log Analysis with LogDNAを評価した話
IBM Log Analysis with LogDNAを評価した話Daisuke Hiraoka
 
TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-
TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-
TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-Masahito Zembutsu
 
【dots. IT勉強会】開発環境のDocker化
【dots. IT勉強会】開発環境のDocker化【dots. IT勉強会】開発環境のDocker化
【dots. IT勉強会】開発環境のDocker化Yuki Kanazawa
 
”30分”ぐらいでわかる「Kubernetes」について
”30分”ぐらいでわかる「Kubernetes」について”30分”ぐらいでわかる「Kubernetes」について
”30分”ぐらいでわかる「Kubernetes」についてYuya Ohara
 
Kubernetes introduction
Kubernetes introductionKubernetes introduction
Kubernetes introductionDAEBUM LEE
 

What's hot (20)

Kubernetesを触ってみた
Kubernetesを触ってみたKubernetesを触ってみた
Kubernetesを触ってみた
 
AWSとGCPを使用したインフラ環境
AWSとGCPを使用したインフラ環境AWSとGCPを使用したインフラ環境
AWSとGCPを使用したインフラ環境
 
机上の Kubernetes - 形式手法で見るコンテナオーケストレーション #NGK2016B
机上の Kubernetes -  形式手法で見るコンテナオーケストレーション #NGK2016B机上の Kubernetes -  形式手法で見るコンテナオーケストレーション #NGK2016B
机上の Kubernetes - 形式手法で見るコンテナオーケストレーション #NGK2016B
 
Kubernetes超入門 with java
Kubernetes超入門 with javaKubernetes超入門 with java
Kubernetes超入門 with java
 
Fission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyoFission で 始める Containerless Kubernetes #serverlesstokyo
Fission で 始める Containerless Kubernetes #serverlesstokyo
 
新しいOpenShiftのしくみを調べてみた
新しいOpenShiftのしくみを調べてみた新しいOpenShiftのしくみを調べてみた
新しいOpenShiftのしくみを調べてみた
 
Kubernetesにまつわるエトセトラ(主に苦労話)
Kubernetesにまつわるエトセトラ(主に苦労話)Kubernetesにまつわるエトセトラ(主に苦労話)
Kubernetesにまつわるエトセトラ(主に苦労話)
 
Docker, Kubernetes and OpenShift v3
Docker, Kubernetes and OpenShift v3Docker, Kubernetes and OpenShift v3
Docker, Kubernetes and OpenShift v3
 
Dockerでらくらく開発・運用を体感しよう
Dockerでらくらく開発・運用を体感しようDockerでらくらく開発・運用を体感しよう
Dockerでらくらく開発・運用を体感しよう
 
Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~
Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~
Dockerは2016年の秋現在どのような状況なのか~忙しい人の5分で分かるDocker~
 
VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門VagrantユーザのためのDocker入門
VagrantユーザのためのDocker入門
 
Weaveを試してみた
Weaveを試してみたWeaveを試してみた
Weaveを試してみた
 
Lattice深掘り話
Lattice深掘り話Lattice深掘り話
Lattice深掘り話
 
IBM Log Analysis with LogDNAを評価した話
 IBM Log Analysis with LogDNAを評価した話 IBM Log Analysis with LogDNAを評価した話
IBM Log Analysis with LogDNAを評価した話
 
俺とKubernetes
俺とKubernetes俺とKubernetes
俺とKubernetes
 
TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-
TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-
TectonicはKubernetesの構築・管理基盤である -概要の章-/-構築の章-
 
【dots. IT勉強会】開発環境のDocker化
【dots. IT勉強会】開発環境のDocker化【dots. IT勉強会】開発環境のDocker化
【dots. IT勉強会】開発環境のDocker化
 
”30分”ぐらいでわかる「Kubernetes」について
”30分”ぐらいでわかる「Kubernetes」について”30分”ぐらいでわかる「Kubernetes」について
”30分”ぐらいでわかる「Kubernetes」について
 
Dockerを社内で使うために
Dockerを社内で使うためにDockerを社内で使うために
Dockerを社内で使うために
 
Kubernetes introduction
Kubernetes introductionKubernetes introduction
Kubernetes introduction
 

Similar to GKEで半年運用してみた

kube-system落としてみました
kube-system落としてみましたkube-system落としてみました
kube-system落としてみましたShuntaro Saiba
 
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...NTT DATA Technology & Innovation
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Masahiro Nagano
 
Apache cloudstack4.0インストール
Apache cloudstack4.0インストールApache cloudstack4.0インストール
Apache cloudstack4.0インストールYasuhiro Arai
 
Rancher2.3とwindows Containerで作るkubernetesクラスタ
Rancher2.3とwindows Containerで作るkubernetesクラスタRancher2.3とwindows Containerで作るkubernetesクラスタ
Rancher2.3とwindows Containerで作るkubernetesクラスタTakashi Kanai
 
Apache CloudStack 4.0 インストール(ver0.5)
Apache CloudStack 4.0 インストール(ver0.5)Apache CloudStack 4.0 インストール(ver0.5)
Apache CloudStack 4.0 インストール(ver0.5)Yasuhiro Arai
 
CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...
CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...
CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...VirtualTech Japan Inc.
 
[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送
[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送
[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送Google Cloud Platform - Japan
 
Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-cluster
Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-clusterKubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-cluster
Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-clusterPreferred Networks
 
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜Masaya Aoyama
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略Hiroshi SHIBATA
 
Jenkins x Kubernetesが簡単だと思ったら大変だった話
Jenkins x Kubernetesが簡単だと思ったら大変だった話Jenkins x Kubernetesが簡単だと思ったら大変だった話
Jenkins x Kubernetesが簡単だと思ったら大変だった話Masaki Yamamoto
 
On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"
On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"
On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"Masaya Aoyama
 
Rookの基礎・バージョンアップ
Rookの基礎・バージョンアップRookの基礎・バージョンアップ
Rookの基礎・バージョンアップTakashi Sogabe
 
Architecting on Alibaba Cloud - Fundamentals - 2018
Architecting on Alibaba Cloud - Fundamentals - 2018Architecting on Alibaba Cloud - Fundamentals - 2018
Architecting on Alibaba Cloud - Fundamentals - 2018真吾 吉田
 
今だからこそ知りたい Docker Compose/Swarm 入門
今だからこそ知りたい Docker Compose/Swarm 入門今だからこそ知りたい Docker Compose/Swarm 入門
今だからこそ知りたい Docker Compose/Swarm 入門Masahito Zembutsu
 
20150101勉強会 dokku alt
20150101勉強会 dokku alt20150101勉強会 dokku alt
20150101勉強会 dokku altShugo Numano
 
AKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたAKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたHideaki Aoyagi
 
Kubernetes、Flannel、CNIでWindows Container Clusterオーケストレーション
Kubernetes、Flannel、CNIでWindows Container ClusterオーケストレーションKubernetes、Flannel、CNIでWindows Container Clusterオーケストレーション
Kubernetes、Flannel、CNIでWindows Container ClusterオーケストレーションTakashi Kanai
 
はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入Yu Nobuoka
 

Similar to GKEで半年運用してみた (20)

kube-system落としてみました
kube-system落としてみましたkube-system落としてみました
kube-system落としてみました
 
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
CloudNativePGを動かしてみた! ~PostgreSQL on Kubernetes~(第34回PostgreSQLアンカンファレンス@オンライ...
 
Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14
 
Apache cloudstack4.0インストール
Apache cloudstack4.0インストールApache cloudstack4.0インストール
Apache cloudstack4.0インストール
 
Rancher2.3とwindows Containerで作るkubernetesクラスタ
Rancher2.3とwindows Containerで作るkubernetesクラスタRancher2.3とwindows Containerで作るkubernetesクラスタ
Rancher2.3とwindows Containerで作るkubernetesクラスタ
 
Apache CloudStack 4.0 インストール(ver0.5)
Apache CloudStack 4.0 インストール(ver0.5)Apache CloudStack 4.0 インストール(ver0.5)
Apache CloudStack 4.0 インストール(ver0.5)
 
CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...
CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...
CyberAgent: How We Deployed Production Kubernetes Clusters on OpenStack witho...
 
[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送
[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送
[Cloud OnAir] Dive to Google Kubernetes Engine 2018年8月2日 放送
 
Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-cluster
Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-clusterKubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-cluster
Kubernetes meetup-tokyo-13-customizing-kubernetes-for-ml-cluster
 
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜
CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜
 
成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略成長を加速する minne の技術基盤戦略
成長を加速する minne の技術基盤戦略
 
Jenkins x Kubernetesが簡単だと思ったら大変だった話
Jenkins x Kubernetesが簡単だと思ったら大変だった話Jenkins x Kubernetesが簡単だと思ったら大変だった話
Jenkins x Kubernetesが簡単だと思ったら大変だった話
 
On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"
On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"
On-premise コンテナ基盤と Hardware LB を使った "type LoadBalancer"
 
Rookの基礎・バージョンアップ
Rookの基礎・バージョンアップRookの基礎・バージョンアップ
Rookの基礎・バージョンアップ
 
Architecting on Alibaba Cloud - Fundamentals - 2018
Architecting on Alibaba Cloud - Fundamentals - 2018Architecting on Alibaba Cloud - Fundamentals - 2018
Architecting on Alibaba Cloud - Fundamentals - 2018
 
今だからこそ知りたい Docker Compose/Swarm 入門
今だからこそ知りたい Docker Compose/Swarm 入門今だからこそ知りたい Docker Compose/Swarm 入門
今だからこそ知りたい Docker Compose/Swarm 入門
 
20150101勉強会 dokku alt
20150101勉強会 dokku alt20150101勉強会 dokku alt
20150101勉強会 dokku alt
 
AKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたAKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみた
 
Kubernetes、Flannel、CNIでWindows Container Clusterオーケストレーション
Kubernetes、Flannel、CNIでWindows Container ClusterオーケストレーションKubernetes、Flannel、CNIでWindows Container Clusterオーケストレーション
Kubernetes、Flannel、CNIでWindows Container Clusterオーケストレーション
 
はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入はてなにおける継続的デプロイメントの現状と Docker の導入
はてなにおける継続的デプロイメントの現状と Docker の導入
 

GKEで半年運用してみた

  • 2. 永岡 克利 (Katsutoshi Nagaoka) • 2011年 CyberAgent 中途入社 • 社内向け基盤システムの開発・運用 • 現在、ライブ配信サービス「takusuta」を立ち上げ、運用中 • エンジニア • #java #cassandra … • #golang #node.js #mongodb #aws #gcp … @na_ga About me
  • 3. Outline • takusuta 紹介 • GKE ざっくり説明 • takusuta における GKE の活用例 • まとめ
  • 6. ライブ配信サービス takusuta https://takusuta.com/ on GKE
 2015/08 ~ iOS & Android App
 2015/07 ~
  • 7. • API • EC2 • S3 • Web • GKE • S3 構成 AWS Route53 CloudFront S3 EC2 MongoDBELB BigQuery GCP GKEGCE-LB Aerospike
  • 8. GKE 採用に至るまで • 2015/07 • iOS, Android アプリ公開 • S3 の Static Content でペライチな Web ページ • nodejs + riot による SEO 対策した Web ページを作ることに • ちょうど kubernetes v1.0.0 がリリースされた • 近いうちに GKE も GA になりそうな • どうせ作るなら… 一旦 Web だけワンチャン使ってみたい • 2015/08 • GKE is Generally Available • Web ページリニューアル
  • 10. GKE とは • Kubernetes のフルマネージドサービス • Docker コンテナの管理ツール • GCE 上に Kubernetes Cluster を構築 • クラスタのリサイズ • コンテナのグルーピング • コンテナの自動配置 • コンテナのリサイズ • コンテナの負荷分散 出典: http://kubernetes.io/
  • 11. GKE の料金 • すごい安い • Cluster の各 Node 料金は GCE 料金が適用 • Cluster の料金は Node 数によって異なる • 5 Node までは無料 • 6 Node 以上で $0.15 hour / cluster • $108 month / cluster
  • 12. GKE の用語 • Pod • コンテナのグループ • 1コンテナ以上で作成 • Replication Controller (RC) • Pod のレプリカ管理 • 管理下の Pod のリサイズを担当 Pod GKE Node Pod Pod GKE Node Pod Pod Pod RC Management Pod Replica
  • 13. GKE の用語 • Pod • コンテナのグループ • 1コンテナ以上で作成 • Replication Controller (RC) • Pod のレプリカ管理 • 管理下の Pod のリサイズを担当 • Service • Pod に対する LB みたいなやつ • iptables で DNAT → kube-proxy Pod GKE Node Pod Pod GKE Node Pod Pod Pod Service RC Layer4 Load Balancer
  • 15. 単体構成 • GKE • tkst-service (type: LoadBalancer)
 設定された Global IP で公開される
 現状では Layer4 のみサポート tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User Admin https://takusuta.com
  • 16. 単体構成 • GKE • tkst-service (type: LoadBalancer)
 設定された Global IP で公開される
 現状では Layer4 のみサポート
 • Service に証明書を設定できない tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User Admin https://takusuta.com
  • 17. 単体構成 • GKE • tkst-service (type: LoadBalancer)
 設定された Global IP で公開される
 現状では Layer4 のみサポート
 • Service に証明書を設定できない • 各 Pod に証明書を持たせる tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User Admin https://takusuta.com
  • 18. 単体構成 • GKE • tkst-service (type: LoadBalancer)
 設定された Global IP で公開される
 現状では Layer4 のみサポート
 • Service に証明書を設定できない • 各 Pod に証明書を持たせる • 非効率的なので避けたい tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User Admin https://takusuta.com
  • 19. GCE-LB と組み合わせた構成 • GKE • tkst-service (type: NodePort)
 各 Node が Service に設定した
 ポートでリクエストを受け付ける tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User tkst-backend tkst-url-map GCE-HTTPS-LB https://takusuta.com Admin
  • 20. GCE-LB と組み合わせた構成 • GKE • tkst-service (type: NodePort)
 各 Node が Service に設定した
 ポートでリクエストを受け付ける
 • GCE-LB に証明書を設定する tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User tkst-backend tkst-url-map GCE-HTTPS-LB https://takusuta.com Admin
  • 21. GCE-LB と組み合わせた構成 • GKE • tkst-service (type: NodePort)
 各 Node が Service に設定した
 ポートでリクエストを受け付ける
 • GCE-LB に証明書を設定する • GKE の Instance Group と
 ポートを Backend として指定する tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User tkst-backend tkst-url-map GCE-HTTPS-LB https://takusuta.com Admin
  • 22. Cross Region LB 構成 • 米国からは US Region tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User from US tkst-backend-us tkst-url-map Cross-Region HTTPS-LB https://takusuta.com tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod tkst-backend-asia
  • 23. Cross Region LB 構成 • 日本からは Asia Region tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User from Japan tkst-backend-us https://takusuta.com tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod tkst-backend-asia tkst-url-map Cross-Region HTTPS-LB
  • 24. Cross Region LB 構成 • 利用率や Rate で自動切り替え • ex: CPU 80% tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod User from Japan tkst-backend-us https://takusuta.com tkst-pod GKE NODE GKE NODE tkst-service tkst-rc tkst-pod tkst-backend-asia tkst-url-map Cross-Region HTTPS-LB
  • 25. Region/zone の選択 • Zone によって差異がある • Haswell [2013 ] • Ivy Bridge [2012 ] • Sandy Bridge [2011 ] • Asia Region は同じなので
 気にしなくて ok 出典: https://cloud.google.com/compute/docs/zones
  • 27. Google Cloud SDK • Google 社製の GCP 管理ツール群 • gcloud • Cluster の作成/管理 • kubectl • RC の作成/管理 • Service の作成/管理
  • 28. Cluster の作成 # create cluster
 $ gcloud container clusters create "tkst-asia-001" 
 --num-nodes 3 --zone "asia-east1-b" --machine-type "n1-highcpu-4" 
 --scope "compute-rw","storage-ro","bigquery","logging-write","monitoring"
 
 • cluster 作成時しか設定できない項目がある • num-nodes は cluster 作成後もオンラインで変更できる • 現時点では num-nodes 以外の項目は cluster 作成後に変更できない
 • 特に scope は後々面倒になるので注意が必要 • GKE から Fluentd などで BigQuery に流し込む為には bigquery scope が必須 • 直近使う予定がなくても、とりあえず付けといた方が良い

  • 29. Cluster の取得 # describe cluster
 $ gcloud container clusters describe tkst-asia-001
 
 currentNodeCount: 3 currentMasterVersion: 1.1.4 currentNodeVersion: 1.1.4 initialClusterVersion: 1.1.4 nodeConfig: diskSizeGb: 100 machineType: n1-highcpu-4 oauthScopes: - https://www.googleapis.com/auth/bigquery - https://www.googleapis.com/auth/compute - https://www.googleapis.com/auth/devstorage.read_only - https://www.googleapis.com/auth/logging.write - https://www.googleapis.com/auth/monitoring nodeIpv4CidrSize: 24 status: RUNNING zone: asia-east1-b
  • 30. Image のアップロード # build docker image
 $ docker build .
 
 # upload docker image to Google Container Registry (GCR)
 $ docker tag -f tkst/tkst asia.gcr.io/xxxxx/tkst:1.9.3
 $ gcloud docker push asia.gcr.io/xxxxx/tkst:1.9.3
 
 • GCR はホスト名でアップロード先リージョンを指定できる • asia.gcr.io: asia リージョン • us.gcr.io: us リージョン • eu.gcr.io: european リージョン
  • 31. RC の作成 # create replication controller
 $ cat << EOS > ./tkst-rc.json; kubectl create -f ./tkst-rc.json { "kind": "ReplicationController", "apiVersion": "v1", "metadata": { "name": "tkst-rc", "labels": { "name": "tkst-rc" } }, "spec": { "replicas": 3, "selector": { "name": "tkst-rc-pods" }, "template": { "metadata": { "labels": { "name": "tkst-rc-pods" } }, "spec": { "containers": [ { "name": "tkst-container", "image": "asia.gcr.io/xxxxx/tkst:1.9.3", "ports": [ { "containerPort":3000, "protocol":"TCP" } ] } ] } } } } EOS
  • 32. RC の取得 # get replication controller
 $ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS tkst-rc tkst asia.gcr.io/xxxxx/tkst:1.9.3 name=tkst-rc-pods 3 
 
 # describe replication controller
 $ kubectl describe rc tkst-rc Name: tkst-rc Namespace: default
 Image(s): asia.gcr.io/xxxxx/tkst:1.9.3 Selector: name=tkst-rc-pods Labels: name=tkst-rc Replicas: 3 current / 3 desired Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed No volumes.
 Events: FirstSeen LastSeen Count Reason Message ───────── ──────── ───── ────── ─────── 25m 25m 1 SuccessfulCreate Created pod: tkst-rc-5gghw 25m 25m 1 SuccessfulCreate Created pod: tkst-rc-b59cv
 25m 25m 1 SuccessfulCreate Created pod: tkst-rc-qw4da
  • 33. Pod の取得 # get pod
 $ kubectl get pod NAME READY STATUS RESTARTS AGE tkst-rc-1tjlf 1/1 Running 0 25m tkst-rc-5zogh 1/1 Running 0 25m tkst-rc-kpujg 1/1 Running 0 25m
 
 # describe pod
 $ kubectl describe pod tkst-rc-1tjlf Name: tkst-rc-1tjlf Namespace: default Image(s): asia.gcr.io/xxxxx/tkst:1.9.3 Node: gke-tkst-asia-001-a48fb14f-node-crjc/10.240.0.18 Start Time: Thu, 21 Jan 2016 06:03:50 +0900 Labels: name=tkst-rc-pods Status: Running IP: 10.184.2.3 Replication Controllers: tkst-rc (3/3 replicas created)
  • 34. Pod への接続 # attach pod
 $ kubectl attach pod tkst-rc-1tjlf 
 # get pod log
 $ kubectl logs -f tkst-rc-1tjlf # get pod log (with content name) $ kubectl logs -f tkst-rc-1tjlf -c tkst-node-container {"level":"info","message":"use memcached store [options={"hosts":["10.240.0.4:11211 {"level":"debug","message":"try to update site-maps cache.","label":"dev","timestamp": {"level":"debug","message":"cache update scheduler started. key=sitemap","label":"dev" {"level":"info","message":"[middleware_access_logger] setup with options {"tag":"ta {"level":"info","message":"[WEB] Append route. path={"twitter":"/explore/auth/twitt {"level":"info","message":"[WEB] Append route. path="/explore/logout"","label":"web_ {"level":"info","message":"[WEB] Append route. path="/ping"","label":"web_dev","time {"level":"info","message":"[WEB] Append route. path="/"","label":"web_dev","timestam ...
  • 35. Service の作成 # create service
 $ cat << EOS > ./tkst-srv.json; kubectl create -f ./tkst-srv.json { "kind": "Service", "apiVersion": "v1", "metadata": { "name": "tkst-srv", "labels": { "name": "tkst-srv" } }, "spec": { "type": "NodePort", "ports": [ { "port": 3000, "targetPort": 3000, "nodePort": 30000 } ], "selector": { "name": "tkst-rc-pods" } } } EOS
  • 36. Service の取得 # get service
 $ kubectl get service NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR tkst-srv 10.119.246.120 nodes 3000/TCP name=tkst-rc-pods kubernetes 10.119.240.1 <none> 443/TCP <none> 
 
 # describe service
 $ kubectl describe service tkst-srv Name: tkst-srv Namespace: default Labels: name=tkst-srv Selector: name=tkst-rc-pods Type: NodePort IP: 10.119.246.120 Port: 3000/TCP NodePort: 30000/TCP Endpoints: 10.116.0.3:3000,10.116.2.3:3000 Session Affinity: None No events.
  • 37. HTTPS-LB の作成 # create backend
 $ gcloud beta compute backend-services create "tkst-backend" 
 —-protocol HTTP --port-name "tkst-port" --http-health-check "tkst-check"
 
 # add backend resource 
 $ gcloud beta compute backend-services add-backend "tkst-backend" --instance-group "${GKE_INSTANCE_GROUP}" 
 # create url maps $ gcloud beta compute url-maps create "tkst-https-lb" 
 --default-service "tkst-backend" # create target https proxy $ gcloud beta compute target-https-proxies create "tkst-https-lb-proxy" 
 --url-map "tkst-https-lb" 
 --ssl-certificate "${SSL_CERTIFICATE}"
 
 # create forwarding rule $ gcloud beta compute forwarding-rules create "tkst-https-lb-forward" 
 --global --address "${LB_GLOBAL_IP}" --port-range "443" 
 --target-https-proxy "tkst-https-lb-proxy"
  • 39. 用途によって Cluster を別ける • 大きなクラスターは作らない • 5 ノード以下は無料 • 最大ノード数は 250 まで(少し前は 100 までだった) • 同じ Pod でまとめた方がキャパシティ制御しやすい
  • 40. 用途によって Cluster を別ける • ennis-asia-app-001 cluster • num-nodes: 5, machine-type: n1-highcpu-4 • service: ennis-asia-app-srv (type=NodeType, 30000), • rc: ennis-asia-app-rc (replica=10 )
 • ennis-asia-nginx-001 cluster • num-nodes: 3, machine-type: n1-highcpu-2 • service: ennis-asia-nginx-srv (type=NodeType, 30080, 30443) • rc: ennis-asia-nginx-rc (replica=3 )
  • 41. Cluster の命名規則ぽい奴 • ennis-asia-app-001 • ennis: プロジェクトの chord name • asia: 配置する region • app: 稼働させる container の名称 • 001: ユニークにするための連番(なんでも良い)
 • Cluster の machine-type をオンラインで変更はサポートされていない • 現状だと新しく Cluster を作成して GCE-LB を切り替える • 高い頻度で Cluster を再構築 (使い捨て) している
  • 42. Cluster の命名規則ぽい奴 • ennis-asia-app-001 • ennis: プロジェクトの chord name • asia: 配置する region • app: 稼働させる container の名称 • 001: ユニークにするための連番(なんでも良い)
 • Cluster の machine-type をオンラインで変更はサポートされていない • 現状だと新しく Cluster を作成して GCE-LB を切り替える • 高い頻度で Cluster を再構築 (使い捨て) している • Instance Templates の更新 API が無い … (́・ω・`)
  • 43. Multi Container Pod • ennis-app pod • 用途 • Web アプリケーションコンテナ • 全てのログは 127.0.0.1:24224 を経由して BigQuery に投げている • コンテナ • API (ennis-node-con, TCP:3000, 3001) • Fluentd (ennis-fluentd-con, TCP:24224)

  • 44. Multi Container Pod # get service list $ kubectl get service NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR ennis-app-srv 10.187.254.39 nodes 3000/TCP,3001/TCP name=ennis-app-rc-pods kubernetes 10.187.240.1 <none> 443/TCP <none> # get replication controller list
 $ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) ennis-app-rc-1453323827 ennis-node-con asia.gcr.io/xxxxx/ennis-node:1.9.5 ennis-fluentd-con asia.gcr.io/xxxxx/fluentd-aggregator:1.0.1 # get pod list $ kubectl get pod NAME READY STATUS RESTARTS AGE ennis-app-rc-1453323827-0ampm 2/2 Running 0 2h ennis-app-rc-1453323827-5xvfk 2/2 Running 0 2h ennis-app-rc-1453323827-gvr4z 2/2 Running 0 2h
  • 45. Single Container Pod • ennis-nginx pod  • 用途 • GCE-LB の Default Backend として設定する • url-maps に該当しないリクエストは nginx 経由で転送させる • ex: http(s)://107.178.243.152/ → https://takusuta.com/ • コンテナ • Nginx (ennis-nginx-proxy-con, TCP:80)

  • 46. Single Container Pod # get service list $ kubectl get service NAME CLUSTER_IP EXTERNAL_IP PORT(S) SELECTOR ennis-nginx-srv 10.107.251.130 nodes 80/TCP name=ennis-nginx-rc-pods kubernetes 10.107.240.1 <none> 443/TCP <none> # get replication controller list
 $ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) ennis-nginx-rc ennis-nginx-proxy-con asia.gcr.io/xxxxx/nginx-proxy:1.0.2 # get pod list $ kubectl get pod NAME READY STATUS RESTARTS AGE ennis-nginx-rc-3byoj 1/1 Running 0 7h ennis-nginx-rc-i6dbs 1/1 Running 0 7h ennis-nginx-rc-sefai 1/1 Running 0 7h
  • 47. Sample : Dockerfile # nginx-proxy Dockerfile $ cat ./nginx-proxy/Dockerfile FROM takusuta/nginx-1.8.0 MAINTAINER Katsutoshi Nagaoka <katsutoshi.nagaoka@gmail.com> USER root ENV HOME /root WORKDIR /root # Define default command. CMD ["bash"] # Generate script. ADD generate-nginx-proxy-conf.sh /usr/local/sbin/generate-nginx-proxy-conf.sh # Staring nginx. EXPOSE 80 CMD /usr/local/sbin/generate-nginx-proxy-conf.sh && nginx -g "daemon off;"
  • 48. Sample : Dockerfile # generate nginx-proxy config script $ cat ./nginx-proxy/generate-nginx-proxy-conf.sh #!/bin/sh if [ "x${ENNIS_WEB_DOMAIN}" = "x" ] ; then echo "Invalid parameter, ENNIS_WEB_DOMAIN is empty”; exit 1 fi cat << EOS > /etc/nginx/conf.d/nginx-proxy.conf server { listen 80; server_name _; location ~^/ping$ { access_log off; return 200; } location / { return 301 https://${ENNIS_WEB_DOMAIN}$request_uri; } } EOS
  • 49. Sample : RC # create ennis-nginx replication controller
 $ cat << EOS > ./${NGINX_RC_NAME}.json && kubectl create -f ./${NGINX_RC_NAME}.json { "kind": "ReplicationController",
 "apiVersion": "v1", "metadata": { "name": "${NGINX_RC_NAME}", "labels": { "name": "${NGINX_RC_NAME}" } }, "spec": { "replicas": 3, "selector": { "name": "${NGINX_POD_NAME}" }, "template": { "metadata": { "labels": { "name": "${NGINX_POD_NAME}" } }, "spec": { "containers": [ { "name": “ennis-nginx-proxy-con", "image": "${GCR_DOMAIN}/${PROJECT_ID}/nginx-proxy:${TAG}", "env": [ { "name": "ENNIS_WEB_DOMAIN", "value": "${DOMAIN}" } ], "ports": [ { "containerPort":80, "protocol":"TCP" } ] } ... EOS
  • 50. Sample : Service # create ennis-nginx service
 $ cat << EOS > ./${NGINX_SRV_NAME}.json && kubectl create -f ./${NGINX_RC_NAME}.json { "kind": "Service", "apiVersion": "v1", "metadata": { "name": "${NGINX_SRV_NAME}", "labels": { "name": "${NGINX_SRV_NAME}" } }, "spec": { "type": "NodePort", "ports": [ { "port": 80, "targetPort": 80, "nodePort": 30080, "protocol": "TCP" } ], "selector": { "name": "${NGINX_POD_NAME}" } } } EOS
  • 51. GCR への最速アップロード • GCE 上の Jenkins でイメージのビルド & アップロードをしている • 同じ Google ネットワーク内のため最速で GCR にアップロード可能 • タグ切り → CI → Jenkins (build & upload & release) ← hubot • GCR が落ちたなどの障害は今の所、経験なし
  • 52. GCR への最速アップロード • GCE 上の Jenkins でイメージのビルド & アップロードをしている • 同じ Google ネットワーク内のため最速で GCR にアップロード可能 • タグ切り → CI → Jenkins (build & upload & release) ← hubot • GCR が落ちたなどの障害は今の所、経験なし • GCR 上にアップロードした古いイメージの削除に若干難あり • そのうち改善されるはず…
  • 53. RC の無停止アップデート • kubectl rolling-update コマンドでリリース作業をしている • 新旧 RC の各 Pod を一台ずつ inc/dec してくれる • single container Pod は非常に簡単
 kubectl rolling-update [old-rc-name] [new-image-url]
 • multi container Pod は分かり難い • kubectl rolling-update [old-rc-name] -f [new-rc-json] • rc name に "-unixtime" などを追記し、
 selector と metadata も同様に version: "unixtime" などを入れる • ex: ennis-asia-app-rc → ennis-asia-app-rc-1453323016
  • 54. RC の無停止アップデート # create multi container pod schema JSON for rolling update
 $ RC_NAME=tkst-rc $ RC_CREATED=$(Date +'%s') 
 $ RC_UNIQUE_NAME=${RC_NAME}-${RC_CREATED} 
 $ cat << EOS | kubectl rolling-update ${RC_CURRENT_NAME} -f - { "kind": "ReplicationController", "metadata": { "name": "${RC_UNIQUE_NAME}", "labels": { "name": "${RC_UNIQUE_NAME}" } }, "spec": { "selector": { "name": "${RC_NAME}-pods", "version": "${RC_CREATED}" }, "template": { "metadata": { "labels": { "name": "${RC_NAME}-pods", "version": "${RC_CREATED}" } }, "spec": { "containers": [ { ... }, { ... }, ... ], ... EOS
  • 55. Cluster / RC のスケール • gcloudコマンドで node を制御できる • gcloud compute instance-groups managed 
 resize [gke-cluster-instance-group] --size [num] • kubectl scale コマンドで replica を制御できる • kubectl scale rc [rc-name] --replicas=[num] • RC のオートスケールも実装されたが、まだ使い道が浮かんでこない
  • 56. Cloud Logging によるログ管理 • GKE は各 Pod の標準出力を Cloud Logging に投げている  • ログの集約及び閲覧をリアルタイムに実現できる • 最近 GKE フィルターが付いて益々便利になった
  • 57. Cloud Logging によるログ管理 • GKE は各 Pod の標準出力を Cloud Logging に投げている  • ログの集約及び閲覧をリアルタイムに実現できる • 最近 GKE フィルターが付いて益々便利になった • 標準機能だとノイズが多く若干不便 • app container から CL の REST API を直接叩いている (winston-gcl) • ログ名、レベルによるフィルターも効くのでもっと便利に • 負荷急騰時は、一旦 CL を見る体勢
  • 58. Cloud Monitoring による死活監視 • イマなら StackDriver を無料で使える • 元々AWS の死活監視に使用していたので違和感なし • Alert 時は Slack とメールでの通知を行っている
  • 59. Cloud Monitoring による死活監視 • イマなら StackDriver を無料で使える • 元々AWS の死活監視に使用していたので違和感なし • Alert 時は Slack とメールでの通知を行っている • GKE Container リソースで取得可能な metrics が少ない • 古い GKE Cluster の場合 StackDriver agent から取得できない • GKE Cluster をアップデート (or 作り直し) で正常に取得できる • 足りない箇所は各 container から custom metrics を送信している
  • 60. Kubernetes dashboard • 標準機能の簡易ダッシュボード • そんなに信用してないし、あまり見ていない • 使いにくい https://xxx.xxx.xxx.xxx/api/v1/proxy/namespaces/kube-system/services/kube-ui
  • 61. • 結構使える子 • https://github.com/kubernetes/kubedash • Cloud Monitoring は重い… • パッと確認するのに便利 • インストールも簡単 kubedash https://xxx.xxx.xxx.xxx/api/v1/proxy/namespaces/kube-system/services/kubedash
  • 63. GKEで半年運用してみて… • 簡単 & 安い & 期待 • 細かいところは幾つかあるが、本番環境で問題なく利用できてる • ここ数ヶ月で Cloud Logging の GKE 連携改善など色々キテル • GKE のドキュメントは少ないが、kubernetes docs で事足りる
 • GKE によるコンテナ管理は非常に魅力的で、積極的に使っていきたい • 出来るだけシンプルに使う・複雑な構成はしない
  • 64. チートシート # pod
 $ kubectl get pod $ kubectl describe pod [pod-name] $ kubectl attach [pod-name] $ kubectl logs [-f] [pod-name] [-c container-name] # replication controller
 $ kubectl get rc $ kubectl describe rc [rc-name] $ kubectl rolling-update [rc-name] [new-image-url] $ kubectl rolling-update [rc-name] -f [new-rc-schema-json-file-path] $ kubectl scale rc [rc-name] --replicas=[num] # service
 $ kubectl service service $ kubectl describe service [service-name] # cluster
 $ kubectl cluster-info $ gcloud compute instance-groups managed resize [gke-cluster-instance-group] --size [num]