Kubernetesの1.4で追加されそうなImage Policy Webhookというイメージの制御ができる機能が面白そうだったので概要をまとめてみました。
Image Policy (Image Provenance)とは
Image PolicyとはKubernetesクラスタ上で動かすコンテナイメージを独自に制御したい場合に使える仕組みです。Proposalのドキュメントによると下記のようなユースケースを想定しているようです。
- 既知の脆弱性を含まないことを確認されたイメージだけを動かしたい
- 特定のベースイメージを使ったイメージだけを動かしたい
- レビュー済みのコードでビルドされたイメージだけを動かしたい
- 署名されたイメージだけを動かしたい
Image Policy Webhookは、ユーザが定義するWebAPIに対してそのPodに含まれるコンテナイメージの情報を渡し、実行可否をチェックする仕組みです。コンテナイメージ制御自体は自前のWebAPIで行う必要があります。Admission ControllerプラグインImagePolicyWebhookとして実装されています。参考: Kubernetes: Admission Controlとは何か
WebhookへのRequest/Response
webhookへのリクエスト、レスポンスにはImageReview構造体のJSON形式が使われます。参考: pkg/apis/imagepolicy/types.go
type ImageReview struct {
	unversioned.TypeMeta
	api.ObjectMeta
	Spec ImageReviewSpec       // チェックするイメージの情報
	Status ImageReviewStatus   // チェック結果
}
type ImageReviewSpec struct {
	Containers []ImageReviewContainerSpec // Podに含まれるコンテナ(複数)
	Annotations map[string]string         // Podに定義できるアノテーション `*.image-policy.k8s.io/*`
	Namespace string
}
type ImageReviewContainerSpec struct {
	Image string // image:tag or image@SHA:012345679abcde のような形式
}
type ImageReviewStatus struct {
	Allowed bool  // 許可するかどうか
	Reason string // 否認の場合の理由
}
Request
リクエストのJSONは以下のようなイメージなります。spec.containers[].imageにはPodのコンテナのイメージタグ(image:tag形式)またはイメージID(image@SHA:012345679abcde形式)が入ります。
{
  "kind": "ImageReview",
  "apiVersion": "imagepolicy.k8s.io/v1alpha1",
  "metadata": {
    "creationTimestamp": null
  },
  "spec": {
    "containers": [
      {
        "image": "nginx:latest" # チェック対象のコンテナ
      }
    ],
    "namespace": "namespace"
  }
}
ProposalのImage tags and IDsで説明されていますが、初期の実装では複雑さを避けるため、PodTemplateのイメージ情報をそのままWebhookへ渡す形になっています。そのため、イメージタグで指定された場合はWebhookでチェックしたときのイメージと、クラスタがイメージをPullしたときのイメージの同一性を厳密に保証することは現状は難しいようです。ProposalではPodTemplateでイメージIDだけを許可するような形にするなどの対策などが提案されていました。
Response
許可する場合のレスポンスは以下のようなイメージになります。
{
  "apiVersion": "imagepolicy.k8s.io/v1alpha1",
  "kind": "ImageReview",
  "status": {
    "allowed": true, # 許可する
    "reason": ""     # 否認する場合は理由が入る
  }
}
キャッシュ
Image Policy Webhookにはレスポンスは一定時間キャッシュをする仕組みがあります。ImageReviewSpec構造体のJSON表記をキャシュのキーにしているようです。現時点のデフォルトはAllowが5分、Denyが30秒になっていました。参考: plugin/pkg/admission/imagepolicy/config.go#L32-L33
ソース
- pkg/apis/imagepolicy 型定義
- plugin/pkg/admission/imagepolicy Admission Controllerの実装