今年一年Kubernetes on AWSをやってきて、kube-awsメンテナ目線で、「今日から、できるだけ楽に、安定して本番運用」するための個人的ベスト・プラクティスをまとめておきます。

TL;DR

  • EKSはまだプレビュー申込の段階。実際に動くものがあるかもわからない。
  • EKSとkops、kube-aws、kubesprayなどは組み合わせて使うもの。代替えにはならない。
  • SaaSありなら分散ログ、分散トレース、リソースモニタリングはDatadogに寄せると運用が楽
  • istioは安心して本番運用できるフェーズではない(Service Meshが必要なら、まだLinkerdのほうがよい)
  • アプリケーションにPrometheusエンドポイントを生やしてメトリクスを取れるようにすべき
  • アプリケーションはOpenTracingやZipkin、Jaegerなどのトレーサを組み込み、Zipkin v1スパンを送るべき

前置き

kube-awsはパーツの一つでしかありませんので、kube-aws成分は少なめです。

また、長くなりすぎないよう、詳細についてはできるだけこの記事内に書くのではなく各参考記事におまかせする方向性にしておきます(とはいえついつい書いてしまったところもありますが・・・)。

最後になりますが、あくまで「今日から、できるだけ楽に、安定して本番運用をする」という観点でまとめますので、あまりエッジのきいたものは紹介しません(し、実際、してないと思います。たぶん)。

Dos

Pod、EC2インスタンスの入れ替えによりダウンタイムが発生しないようにする

  • ステートレスなPodは最低2個以上セットにする
    • Podがノードの入れ替え等で一時的に増減するのは当たり前に起こることなので、それに対処しておく
    • できるだけそれぞれ別のEC2インスタンスにスケジュールされるようにする
      • podAntiAffinity
      • クラスタ自体がMulti-AZの場合のみ。
    • できるだけそれぞれ別のAZにスケジュールされるようにする
      • podAntiAffinity
      • クラスタ自体がMulti-AZの場合のみ。
  • Podにreadiness/health probesを設定する
    • 起動中のPod、障害発生中のPodを自動的にロードバランス対象から外すために必要
  • SIGTERMを受けたらGraceful Stopすること。N秒後にSIGKILLで強制停止させられるから。
    • NはterminationGracePeriodSecondsで変更可能
  • ノードが
    • PodDisruptionBudget

合わせて読みたい:

EKSでK8Sクラスタ自体の運用を楽にしていく

AWS re:Invent 2017でKubernetesのマネージドサービスがついに発表されましたね!

詳細は「Amazon Elastic Container Service for Kubernetes (EKS)の所感」にまとめました。まだ実際に利用できるわけではありませんが、今のところでている情報だと、

  • 「Masterノードのマネージドサービス」。WorkerノードはCloudFormationなどで自分で持ち寄る(これは個人的には圧倒的に良い判断だと思いますが、GKEのようなサービスを求めてた人からは評判悪そうですね
  • KubernetesのCluster NetworkingによりAWSネイティブなサポートを追加していく
  • Kubernetes on AWSを便利に使うためのOSSをバンドルしていく
    • kube2iam, heptio/authenticator

の点だけでも、かなりKubernetes on AWSの導入と運用と敷居が下がると考えられ、歓迎すべきサービスだと思います。

一方で、

  • Fargate対応

は実際どのようになるのか次第ですね。

  • LambdaのようにENIをアタッチするために数十秒待たされるような仕様になると「すぐスケールしてほしい」というユースケースには対応できなくなる(むしろSpot Fleetで安価なインスタンスをホットスタンバイでおいておくほうがよいのでは)
  • virtual-kubeletで検討されているような抽象化をするとしたら、Daemonsetはどうするのか(fluentdやdatadog agentでFargateに起動したK8S Podのログやメトリクスをとれるの?たぶんとれない実装になりそう)

などが既にKubernetes on AWSを本番運用している立場からすると気になります。

EKS + kube-aws

手前味噌ですみませんが、kube-awsはEKSと統合予定です。
kube-awsはetcdとcontrollerノードもCloudFormationで管理してくれるのですが、それをEKSに任せられるとkube-awsとしても、その利用者としてもメリットがあるためです。

※kube-awsは、AWS上にカスタマイズ可能なKubernetesクラスタをつくるためのCloudFormation + cloud-initのWrapperなので、EKSとはスコープが違います。kopsも同様です。なので、「EKSがくるから、kopsが不要になる」みたいな話はちょっと間違ってます。もちろん、「EKSで作れないところは手動か自前のスクリプトでやります」なら確かにkopsなどは不要になるのですが、それは自前でkops的なものをつくるのとどれくらい違うのでしょうか、という疑問は残ります!

利便性と運用性の高い分散ロギング

  • Google Stackdriver Logging
  • [New!] Datadog Logs

へfluentdからログを送って、ほぼリアルタイムにログをフィルタリングしたり追いかけたりできる環境をつくっておくと、デバッグが捗ります。特にマイクロサービスアーキテクチャをとっていて、Kubernetes on AWS上にデプロイされるサービスが複数ある場合は必須だと思います。

Kubernetes上のアプリケーションログを自動収集する」には、、kube-fluentdをクラスタにデプロイして、StackdriverかDatadog Logsにログを送る方法とその意図を書きました。

Kubernetesネイティブなリソースモニタリングサービス

  • Prometheus
  • Datadog
  • Stackdriver Monitoring

のような、Kubernetesの対応が充実したモニタリングサービスを利用します。外せないポイントは二つあって、一つはカスタムメトリクスのオートディスカバリ、もう一つは標準でKubernetesのノードからPod、Deployment等の汎用的なメトリクスの収集に対応しているかどうか、です。特にオートディスカバリに関しては、Podに所定のAnnotationをつけるだけで自動的にメトリクスをスクレープしてバックエンドサービスに送ってくれるようなソリューションが用意されているPrometheusやDatadogが一歩抜きん出ています。

Datadogのオートディスカバリに関しては、「Kubernetesにデプロイしたアプリケーションのメトリクスを自動収集する」に書きました。

どのマイクロサービスが原因で障害が発生しそうか・したのか知るための分散トレーシング

「分散トレーシングといえばOpenTracing」というような雰囲気もありますが、できるだけ手間をかけず、今後の移行パスも用意しつつ、プロダクション利用したいというようなモチベーションであれば、現状ではZipkin + Datadog APMをおすすめします。

詳細は「Kubernetes上のマイクロサービスを分散トレースする」に書きました。

もちろん、OpenTracingの発展に貢献したい、ぷるりを送ることも辞さない、ということであれば、OpenTracing一択です。

OpenTracingは以下の4パートから構成されますが、それぞれまだまだ改善の余地があるという状況です。

  • 各言語向けのクライアントライブラリであるTracer、
  • Tracerによる計測データを送る先となるバックエンド(Zipkin等)、
  • クライアントとバックエンドのプロトコルまたはspan format、
  • マイクロサービス間でトレースを関連付けするためのpropagation format

Kubernetes界隈で少し例を挙げると、2017/12現在は以下のコントリビュート先があります。

  • Envoy
    • OpenTracingトレーサに非対応
      • Zipkinサポートはビルド時に組み込まれている
      • OpenTracing Tracer(C++)をEnvoyに組み込んだり、OpenTracing Tracerの実装を動的にロードできるようにするようなコントリビューションが考えられます
  • nginx-ingress-controller

Kubernetesへデプロイしたサービスを最速で公開する

KubernetesのDeploymentやServiceのような形でアプリをデプロイしても、本番サービスに必要な

  • Route 53 RecordSet
  • ELB/ALB/NLB
  • TLS証明書

は別途用意する必要があります。そのために、

  • AWSへの一定のアクセス権をエンジニアに配布するのかしないのか、
  • CloudFormationやTerraformを使うのか、
  • どのRecordSet/*LB/証明書がどのサービスと対応するのか、
  • 証明書はどこに保存するのか
  • ...

など、運用を考えると、悩みはつきませんね。
インフラエンジニアが登場したり、そのためだけにKubernetes以外のツールを覚えたりしなくても、もっと気軽にサービスを公開できるようにしたいものです。

そこで、KubernetesのIngressを作成するだけで、ALB、証明書、Record Setを自動生成するようにしました。

をそれぞれ説明しました。

Kubernetesのユーザ管理を効率化

利用者の数だけ個別にKubernetesのService Accountをつくったり、OpenIDなどの設定をするより、AWS IAMの権限でKubernetesに認証してもらったほうが楽です。

EKSでも採用される予定のheptio/authenticatorを使うとできます。

authenticatorの使い方については「heptio-authenticator-awsの使い方」に書きました。

バージョン管理

secretはmozilla/sopsで暗号化

人・チーム

最低二人はKubernetesクラスタ自体の運用+利用手引ができるように

Certified Kubernetes Administrator試験(CKA)に合格するか、そのレベルの、Kubernetes利用者からすると低レイヤーの知識を持った人を一人、二人は育成したほうがいいです。

Kubernetesには、プラットフォームとしての汎用性と、それに応じた複雑性があります。

それをAWS上で動かすためにはAWSの知識も必要になります。本番運用するとなると、JekinsなどとのCI・CDとの統合や、モニタリング、開発者や運用者のワークフロー整備など、Kubernetesの応用に関する実践的な知識も必要になってきます。仮にEKSが利用できるようになっても、その本質は変わりません。(Kubernetes自体の運用に関して自分で責任を持たなければならない範囲は減るのは確かですが)。

CKA合格レベルの知識を身につける近道は、Heptioのブログで紹介されている内容を学ぶことです。

How Heptio Engineers Ace the Certified Kubernetes Administrator Exam

Don'ts

長期的に見ると将来性はありそうですが、OSSにコントリビュートしたい気持ちがない限り「今は」手を出さないほうが無難なものを挙げておきます。

ただし、OSSに貢献したい場合は、むしろ採用してどんどんフィードバックやPRを送るといいですね。

サービスメッシュ関連

istio

pilot/proxy(ingress, sidecar), mixer

istioはアーキテクチャ良し、(Service Meshとしての)将来性よし、golang(!)、メモリフットプリント小さい、Kubernetes Native(!)ということで、最高のサービスメッシュですね。

でも、プロダクション事例を全然聞かないので、K8S on AWSを「今日から、できるだけ楽に、安定して本番運用」するという趣旨には反しますね。

また、具体的な話をすると、以下の点が本番運用を「楽に」するためにはかけているパーツだと思います。

  • 専用のWeb UIがない
    • 公式にもGrafanaのダッシュボードで賄ってくださいと書いてあります
    • Grafanaがだめなのではなく、汎用のWeb UI(+メトリクスのストア)ならPrometheusやDatadog、Stackdriverなども色々候補にあがってきますし、そうすると「Service Meshのモニタリングと操作に特化したダッシュボード」ってしばらくはどこにもない状態になるんですよね。
    • そうすると、たぶんどこかのベンダーがistioのWebダッシュボードをつくって、それとコマーシャルサポートをセット販売することになると思うのですが、それだけで果たしてビジネスになるのか疑問。ビジネスにならなければその独自ダッシュボードの進化も遅くなる。また、Grafana等で賄ってしまう会社も多いと思うので、istioベンダーがとれるパイも少なくなる
    • そういう状況だと、エンジニアが100人くらいはいるそこそこの規模の組織でないとistioは採用できないのでは

アプリケーションカタログ・コンソール関連

Kubeapps/Monocular

Kubeapps
Monocular

helm installコマンドを打つより親しみやすいのは確か。

ただし、まだ認証機能が不完全なので、本番運用するのは恐ろしい(誰が何を本番クラスタにインストールできるのかを制御できない。ログはとれるのかな?)

細かな権限管理が不要な場合は使ってもいいかもしれません。また、コンソール的には、RancherやKubernetes Dashboardのようにアプリケーションのログやメトリクスも確認できるようになっていくと、より使うメリットが出てくると思います。

Sealed Secrets

Sealed Secrets

SealedSecretという独自リソースをKubernetesにつくって、それにKubernetesのSecretを管理させるというもの。KubernetesのSecretはkubectlがあれば平文で見えるので、それを問題視する場合には使える?

ただし、これを使う利点の一つと説明されている「Kubernetesに保存する機密情報=SecretをGitにコミットできる」という点に関しては、疑問が残る。

おそらくKubernetesを採用するような組織だとKubernetes Secret以外にもGitで管理したい機密情報があると思う。であれば、sopsのような特定のプラットフォームやプロビジョニングツールに依存しない、Gitとの組み合わせを前提としたツールを利用するほうがよさそう。