GKEと仲良くなるまで
@tkow39
About Me
Leverages 新卒1年目(27)
内定者インターン時から
teratail 開発チーム
大学在学時に
暗号理論・機械学習
言語処理の研究に従事
アルバイトで
フロントエンドを中心に
開発経験を積む
Teratailで使われている技術
Web
インフラ
GKE上のマイクロサービス事例
https://teratail.com/sakura-quest/
同じホストに上のページに見えますが、teratail本体と別々のコンテナで動作しています。
※特殊な事情を除いて、UrlMap使うよりサブドメイン使った方がいいです。
クラウドクエストの構成図
ingress
teratail db
cloud quest db
GKE
/sakura-quest/
/
teratail.com
port:80
port:8080
port:8080
port:80
GKEと仲良くするにはまず
デプロイできるようになること
Tips[参考文献]
- 公式Doc: https://kubernetes.io/docs/home/?path=users&persona=app-developer&level=foundational
- 公式Tutorial: https://kubernetes.io/docs/tutorials/
- GKE Tutorials: https://cloud.google.com/kubernetes-engine/docs/tutorials?hl=ja
- cheatSheet: https://kubernetes.io/docs/reference/kubectl/cheatsheet/
- KubeObjectのパラメータ一覧: https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html
- Kubernetes Running & Up: https://www.amazon.co.jp/dp/B075G373MJ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1(日本語訳でますね)
-
Mastering Kubernetes(略): https://www.amazon.co.jp/dp/B01MXVUXDY
Kubernetesの概念を理解することが最重要なので、
公式DocとTutorialを最初に読むことをおすすめします
Deployment
- Pods(単数・複数のコンテナからなるアプリケーションの単位となるグループ)を指定する
- Podsのスケーリングのパラメータやヘルスチェックの条件を指定する
(ReplicaSet[旧Replication Controller]の設定)。ヘルスチェックは必ず指定したほうが良い。
Service
- クラスタの内部のPodsや外部のネットワークからのつなぎ方を指定する。デプロイするクラウドや、環境によって、仕様が変わるものがあるので、各環境での注意は目を通しましょう。
- GKEの場合Type=LoadBalancerで外部に公開可能(L4LB),L7はIngressというオブジェクトで行う
Deployに最低限必要なyaml
ConfigMap/Secret
- 環境変数などにAPIキーやDB接続情報を設定します。
- ConfigMapとSecretの使い分けは、機密情報かどうか。
- Secretのパラメータはbase64エンコードが必要。
Persistent Volume
- コンテナ起動中に生成するファイルで永続化しておきたいものを保存しておく方法を指定する
- GCEStorageが使えるため、VolumeMountしたStorageをgutilsを使って、バックアップ したりすることも可能
環境毎に使うであろうkubeオブジェクト
- クラウド環境毎の独自の実装はMetadataで吸収できるため、
Multi Cloudへの移行が容易になる。
(GCPではGCEインスタンス上にL7LBが起動)
- TCPロードバランサ単体では、同じport番号のリクエストを別々に振り分けることができない(ただし、TCPロードバランサの接続先をWebサーバにするなどは別)
- SSL/TLSの窓口を一個にすることによって、関連サービスごとに証明書を増やさなくて良いため、設定が楽になる(これが困るパターンもあるので要使い分け)。
Ingress(L7ロードバランサ)
teratailの構成ファイル
production
├── nginx-deployment.yml
├── nginx-ingress.yml
├── nginx-service.yml
├── sakura-deployment.yml
├── sakura-secret.yml
├── sakura-service.yml
├── service-account-secret.yml
├── teratail-deployment.yml
├── teratail-secret.yml
├── teratail-service.yml
└── tls-secret.yml
> kubectl apply -f production
※ teratailのDBはGCE上に立ててるのでPersistent Volumeは用意していません。(v1.9からなので、もっと早く出て入れば...)
ボリューム・データ以外の環境は、GKE上でteratailが再構成された状態でデプロイできる
時間が無い人のための単純なGKE Deploy Frow例
イメージビルド
初回デプロイ
次回以降のデプロイ
docker build . -t gcr.io/$project/hoge:v1
レジストリプッシュ
gcloud docker -- push gcr.io/$project/hoge:v1
kubectl apply -f production/
kubectl set image deploy/hoge-deployment \ $container_id= hoge:$next_version 等
クラスタ作成
認証
cloud container clusters create $cluster --zone $region --project $project
or ブラウザで GCP Consoleからポチポチ(こっちの方が設定楽)
gcloud container clusters get-credentials $cluster --zone $region --project $project
CI・CDツールで自動化も出来ます
リピート
デプロイ完了これで仲良くなれたと思いきや。。。
設定どおりにデプロイできてるのに上手く動かない!なんてことはザラです
GKEの罠
・Does not have minimum availability
このエラーは、設定ミスであり、minimum availabilityとは必ずしもリソースサイズに限らない。
エラーログやイベントを見て、デプロイのどこでこけてるかを追跡し、原因を特定しましょう。
(多いのはConfigMap/Secretの設定忘れとか、selectorやportの設定ミスとか)
GKEの罠(Ingress)
・Some backend services are in UNKOWN state
このエラーは、Ingress
のヘルスチェックが失敗していると起こる。
/でのアクセスで200を返すように設定するか、Serviceで接続するpodsまたはdeploymentのreadinessProbeの位置を変更する。(defaultのヘルスチェックpathは/に設定されている)
GKEの罠(Ingress)
・ingressは、GCEインスタンスに建てられるので、
ingress削除->クラスタ削除
の順番を守らないとingressがゾンビ化する
gcloud compute addresses list でip確認してもIN_USEのまま
ネットワーク->負荷分散で確認しても削除されていない
GKEはシャイなのでエラーの原因を直接教えてくれない。
readinessProbe
ServiceはreadinessProbeが設定されているpodに接続している際、Unhealthy状態のPodにユーザーが接続できないように異常が発生したpodを隔離できる。この設定は、間違って存在しないエンドポイントなどを設定してしまうと、Running状態のPodでも接続から切り離されることがあるため、要注意。基本的には設定すべき。
設定例 )
readinessProbe:
httpGet:
path: /healthz
port: 80
periodSeconds: 1
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 10
※Basic Authを入れるためにnginxの設定を変更してデプロイを行った際、先程のingressの仕様で / 200が返らない状態になり、podとの接続が切り離されるという事故に見舞われたため、ingressを使用する場合は、必ず設定しておいたほうが良いです。(設定すると、設定済みのpathでヘルスチェックしてくれます。)
livenessProbe
設定例 )
...略
livenessProbe:
httpGet:
path: /healthz
port: 80
periodSeconds: 1
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 10
設定すると、ServiceがエンドポイントからUnhealthyステートやデッドロックで応答を返さなくなると強制的にpodを再起動させることができる。設定を間違えると、生きては死ぬことを繰り返すpodが生まれるため注意。
Stack Driverで死活監視
Uptime Checkの成否判定によって、アラートを追加する。
( コンテナがダウンしたらアラートが来るように設定できる。)
一括・大量に死活監視入れたい時はPromethousにしましょう。
ここまで設定出来たら
仲良くなってきたのではない
でしょうか
teratailの構成ファイル(再掲)
production
├── nginx-deployment.yml
├── nginx-ingress.yml
├── nginx-service.yml
├── sakura-deployment.yml
├── sakura-secret.yml
├── sakura-service.yml
├── service-account-secret.yml
├── teratail-deployment.yml
├── teratail-secret.yml
├── teratail-service.yml
└── tls-secret.yml
> kubectl apply -f production
※ teratailのDBはGCE上に立ててるのでPersistent Volumeは用意していません。(v1.9からなので、もっと早く出て入れば...)
ボリューム・データ以外の環境は、GKE上でteratailが再構成された状態でデプロイできる
サービス増えるほどファイル多くならない?
構成ファイル削減の工夫
---
apiVersion: v1
kind: Service
metadata:
name: hoge
...
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
...
yamlを---で区切ってまとめる
-依存関係が分離できなくなるため、細かく設定変更したい際は不便になる。(そもそもIasCの考え方だと構成はガッチリ固め、インフラは家畜のように扱えなので、バージョン管理すればいいという考え方もあるかも)
-secretなど最初にデプロイしないと動かないアプリケーション等もあるため、secretなどは別デプロイにしたいなどの要求はある
Kubernetes構成をパッケージ化する
・Helm - kubernetesのパッケージマネージャー
テンプレートを作成しておくと、誰でも、そのテンプレートを使ってクラスタを構築できるようにする。
(ユーザーの環境設定はvalues.ymlに記述)
さまざまなチャート(kubernetesのパッケージ)が公開されているので、ディレクトリ階層とかはここを参考にするとよいです。
https://github.com/kubernetes/charts/tree/master/stable
https://hub.kubeapps.com/
GCPとも仲良くしましょう
・Google Container Builder - GCSのdocker imageのレジストリにVCSの更新からビルドを自動化できる
・Google Cloud Storage - 言わずもがな。backupや、CDNに。保存ファイル数や期間で、古いファイルを消してくれる機能があるため、backup設定が楽。
・ Cloud SQL - マネージドかつ対障害性設定されたマネージドのMySQLがあります。(postgreSQLはBeta)使うと、リードレプリカの設定だけで済むので、楽ができる。
・ Stack Driver - モニタリング・ロギング・アラート・豊富なメトリクス、プラグインでメトリクス追加などができて、機能が行き届いている。もちろんGKEの監視も対応。
GKEと仲良くなるまで
By tkow
GKEと仲良くなるまで
2018/03/2 酔いどれGCPUG
- 1,906