
Google Cloud Anthos DayでGKEのセキュリティ対策と運用について話してきました
Posted on
こんにちは、エンジニアの @komukomo です。2020/01/30 に行われた Google Cloud Anthos Day に 「GKEにおけるセキュリティ対策と運用」というタイトルで登壇させていただいので、こちらのブログでもその内容を簡単にまとめておきます。(他の登壇者の方の資料も公式サイトにて公開されています)
我々が開発している KARTE ではユーザの行動データを扱っており、その中にはセンシティブなデータも含まれているので KARTE を開発する上ではセキュリティというのは重要なトピックです。ということで今回お話したのはセキュリティに関する内容で、直接プロダクトの KARTE とは関係ないのですが、
- GKE でのセキュリティに関する考え方
と、個別機能の紹介とユーザ目線での注意点や感想ということで
について発表してきました。内容としては、これからGoogle Kubernetes Engine (GKE) を導入しようとしている方や運用しはじめの方、機能の概要を知りたい方向けのお話となっています。
こちらにスライドとざっくりお話した内容を載せておきます。
GKEにおけるセキュリティ対策
最初のトピックは GKE でのセキュリティ対策の話で、中身を省いて結論のみ書いてしまうと、
- ユーザの管理範囲と Google の管理範囲を意識しましょう
- まずは GKE 公式のドキュメントにそって運用していきましょう
ということで基本的すぎる感じになってしまいましたが、それでも重要なことだとは思うので、ここにも当日紹介したドキュメントのリンクを貼っておきます。
GKE の記事:
こちらは GKE に限らず、Kuberentes の記事:
- 9 Kubernetes Security Best Practices Everyone Must Follow
- Security Best Practices for Kubernetes Deployment
以降は個別の GKE の機能のお話です。
GKE Sandbox
GKE Sandbox は、信頼できないワークロードをクラスタで動かすようなケースで有用な機能です。
内部では gVisor が使われていますが、この仕組みは使う前にざっくりとでも中身を知っておくとといろいろと判断する上で役に立ちます。
gVisor では kernel の System Call をインターセプトして、kernel の機能を emulation するようなレイヤを実装しています。(さらっと書きましたが、なかなか凄まじい実装です。コードはこちら。)
このようなレイヤを実装することで、コンテナは System Call を直接実行できなくなり、Host はセキュリティを考慮して制限された System Call のみ処理するようになるので、kernel の脆弱性を悪用するような攻撃から Host を守ることができます。
この gVisor をGKE上で使えるようになっているのが、 GKE Sandbox です。
注意点
使用する上で気をつけておくとよさそうと感じたのは、互換性、パフォーマンス、gVisor の責任範囲についてです。
互換性
kernel の機能を emulation している部分があるので、そもそも使いたい機能が使えるかはまず確認しておくとよいかと思います。GKE Sandbox にも gVisor にも互換性に関するドキュメントがあるので両方読んでおくと確実かと思います。
自分は GKE Sandbox を最初試したとき Port Forward が使えないということを知らずにデバッグしようとしていて、無駄に調査に時間をかけてしまいました😅
パフォーマンス
こちらもgVisorがSystem Callをemulationしているため gVisor を使うとそのワークロードのパフォーマンスが劣化する可能性があります。逆にいうと、System Call を激しく使わない数値計算のようなワークロードはそれほど影響はないと考えられます。
実際に GKE Sandbox を使う場合にはもちろんその時に計測するかと思いますが gVisor のPerformance Guide もあるのでこちらも参考になるかと思います。
gVisorの責任範囲
仕組みをしっていれば当たり前の話かもしれませんが、gVisor を使えばサンドボックス化は完璧、というものではありません。例えば Pod 間通信の制御をするなら別途設定が必要です。自社でサンドボックスのような基盤が必要なサービスを運用する場合は、gVisor の挙動を把握した上で適宜必要なレイヤーの制限をかけていく必要があります。
gVisor がどのような目的で作られ、どのような脅威を軽減するのかについては Security Model に詳しく書かれています。
Binary Authorization
次の話はBinary Authorization。こちらは信頼できるイメージのみがデプロイされることを保証できる機能です。クラスタでBinary Authorization を有効にすると、Pod 作成の前に Policy のチェックが入ります。
Policy の設定としては image の Path のホワイトリストの他、 attestation という概念があるので、信頼できる検証者によって検証されたイメージのみ許可、といった設定が可能です。(※発表スライド内では"署名"と書いてしまっていますが、英語では attest なので多分"証明"、"検証"という訳の方が正しいですね。)
設定可能な Policyの仕様 はとてもシンプルなので、ざっと設定例 と合わせて読めばすぐに把握できるかと思います。
運用時は、いろいろと例外的な状況も発生するかと思いますが、Dry Run(Policyチェックしてログは出すが制限しない)や、Break Glass( Policy を無視してデプロイできるようにするannotation)という機能もあり、こういった運用時の考慮もされています。
注意点・感想
Binary Authorization の注意点としては、PolicyはGCPのプロジェクトごとで、クラスタごとの設定はある程度できるのですが Namespaceごとの細かい設定はできません。そのため、大きなクラスタで複数チームを Namespace で管理している場合は Policy 設定が難しいかもしれません。
ちなみに Mercari さんではGKEのBinary Authorizationではなく、その内部で使われているkritis を自社でフォークして使用しているとのことです。
また、「何かを強制する」機能全般に言えることですが、Dry Run や Break Glass の機能があるとはいえ、管理するProjectが大きくなればなるほど導入が大変になるものです。(有効化したものの全対応が難しくいつまでたっても dryrun 状態...のように)
導入するつもりなら早めに、迷っているなら修正が難しくなる前に判断するのがよいかと思います。
Anthos Config Management
最後にAnthos Config Management (以下、ACM)。こちらは、セキュリティというよりは運用の話ですが、Namespace や RoleBinding など様々な設定を管理するための機能です。
ACMはいわゆる GitOps で クラスタの設定管理をするツールで、クラスタに ACM のオペレータを入れておくと、そのオペレータが指定した Git Repository と同期し設定をクラスタに反映してくれます。(ちなみに、とくに管理可能なオブジェクトの制限は今の所ないようで Namespace や RoleBinding だけでなく、Deployment や Service でも同期してくれます。そのため ACM でアプリケーションのようなものもデプロイ可能ですが、反映の順序は考慮されないそうなのであくまでも設定系のオブジェクトのみにしておいた方が良さそうです。)
単一クラスタ、単一 Namespace しか扱っていない場合はさほどありがたみはないかもしれませんが、複数クラスタ、Namespace を運用していて、似たようなポリシーを全体に適用したいケースなどに有用かと思います。
Git Repository との同期だけであればその他の flux や argo などでも可能かとは思いますが、ディレクトリの階層構造でNamespace に階層構造のようなものを持たせられる、という点は特徴的です。
例えば ACM で管理するポリシーの Repository を上の図のようなディレクトリ構成(緑は何らかのk8sオブジェクトのyaml、オレンジは Namespace の yaml とします)にした場合、Namespace が3つ (audit, service-a, service-b) 作成され、all-policy
は全てのNamespace に反映、app-policy
は service-a
とservice-b
の Namespace にのみ反映、といった挙動になります。
ちなみに ACM の他にも、こういった階層構造を使うというアイデアはあるようです。
https://github.com/kubernetes-sigs/multi-tenancy
感想
ACM は仕組みも動作もシンプルなので、Anthos を使っていてクラスタ、Namespace が複数あるような環境ならば入れておいて特に損はなさそうかなと感じました。ACM の導入についても、既に多くのクラスタにいろいろな設定をいれて管理していたとしても、ACM 管理用の repository に対象のyamlを入れてそのオブジェクトが管理対象になる( configmanagement.gke.io/managed: enabled
という annotation がつきます)のを待つだけなのでそこまで大変ではなさそうです。
Policy Controller
ACM の基本的な機能は以上なのですが、追加オプションとして、 Policy Controller という機能もついており、こちらは Gatekeeper を使ったポリシーの Enforcer です。(ACM の機能とは全く別機能のような気がしますが、現状 ACM の中の機能として提供されていたのでおまけとして紹介しています。)
例えば PodSecurityPolicy の場合は、「特権コンテナ禁止」といった特定の条件の制限ができるかと思いますが、こちらは任意の Kind の field をチェックできるため柔軟に設定をすることが可能です。公式の例では、Ingress の domain に重複がないか、Namespace に特定の prefix がついているか、などをチェックするサンプルがありました。
何をどう制限するか、というのは Rego という言語で書くことになるのですが、よく使うテンプレートは予め用意されているので Rego を知らなくてもある程度使うことができます。
最後に
Google Cloud Anthos Dayで話したGKEのセキュリティとその周りの機能の紹介でした。Kuberentes も GKE でも次々と新機能がでてくるので追っていくのは大変ですが、全てのユースケースで必要なものではないものも多いので、しっかりそれぞれの機能を把握した上で適切に運用していきたいですね。
おまけ
@amsy810 さんに撮っていただいた写真。ありがとうございます👍
こちらは Google Cloud Anthos Day 後の懇親会。Googler、登壇者、スポンサー、様々なAnthos/k8sな人たちと話しました。これからのさらなる盛り上がりを感じたとともに、我々もどんどんアップデートしていかないとと感じました!...ということで、スピード感を持って一緒に開発していく仲間は常に募集しているので、興味のある方は弊社採用ページまたは Wantedly からお気軽にご連絡ください!