Edited at
Z LabDay 10

SPIREのk8s pluginについて

More than 1 year has passed since last update.

昨日はSPIFFEとその参照実装であるSPIREについてのエントリを書きましたが、本日はSPIREのワークロードとしてKubernetesのPodを対象とする場合に利用するKubernetesのworkload attestor pluginの動きを説明します。


Kubernetes workload attestor plugin とは

SPIRE-Agentのworkload attestorのプラグインとして動作します。

Worload AttestorとはWorkload APIの呼び出し元の情報からSelector情報を生成するコンポーネントでした。

Kubernetes pluginの場合には呼び出し元Workloadのpidからそのpidで動作するPodのNamespaceとServiceAccountの情報を収集します。つまり、呼び出し元のワークロードが動作するPodに紐づくNamespaceとServiceAccount情報を収集します。


How to work this plugin?

/proc/${PID}/cgroup

KubernetesのPodを動しているpidの場合、上記ファイルを開くとこのような情報が確認できます。このプラグインはkubepodsのエントリのContainerID(一番後ろの要素)を抜き出します。(ContainerIDは全部同じ)

11:memory:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778

10:freezer:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
9:perf_event:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
8:devices:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
7:pids:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
6:cpu,cpuacct:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
5:net_cls,net_prio:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
4:hugetlb:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
3:blkio:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
2:cpuset:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778
1:name=systemd:/kubepods/besteffort/pod2ece296c-c5ec-11e7-858e-fa163e451acc/bc1eb339399eae78dd1115c765fda84b71ac6a954291b223820cfe775d8af778

また、kubeletのReadOnlyポートにアクセスし、自身の上で動作するPod情報の一覧をPod情報を取得します。

http://localhost:${KUBELET_READONLY_PORT}/pods

https://kubernetes.io/docs/api-reference/v1.8/#podlist-v1-core

アクセスすると上記URLにて定義されている情報が返ってきます。

Kuberentes Pluginにおいて必要な情報は各レコードの3つの情報です。


  • .metadata.namespace

  • .spec.serviceaccount

  • .status.containerStatuses[*].containerID (e.g., docker://')

プラグインはcgroupの情報から取得したContainerIDと上記Kubeletから取得したContainer情報が一致するPod情報を探します。ちなみに、Podの情報に含まれるContainerIDは docker://... のような文字列になっているのでURL構造と見立てた場合のホスト部とcgroupのContainerIDを比較します。

そうして、一致したPod情報に含まれるServiceAccountとNamespaceの情報をSelectorとして返却するわけです。

[]*Selector{

&Selector{
Type: "k8s",
Value: "k8s:ns:${Namespace}"
},
&Selector{
Type: "k8s",
Value: "k8s:sa:${ServiceAccount}"
},
...
}

最後にこれを受け取ったWorkload AttestorはSPIRE-Server側にこのワークロードが対象として登録済みかどうかを確かめるために、Serverから取得した自身の上で動作可能なSelector情報と、Workload Atterstorによって生成されたSelector情報を比較します。

一致するものがあれば許可されたWorkloadであると判断しSVIDを渡します。


おわりに

このようにKubernetesのPodもSPIREのワークロードとして動作させることが可能であり、PodとKubernetesクラスタ外のアプリケーションを相互認証させることができます。

自分は今後も継続してSPIFFE/SPIREの動向をウォッチしていこうと思っています。また何かあれば何らかの形でフィードバックしたいと思います。