LoginSignup
32
20

More than 5 years have passed since last update.

Kubernetes: Admission Controlとは何か

Posted at

KubernetesのAdmission Controlについて理解のためメモをまとめてみました。Kubernetes 1.2時点での情報です。

Admission Controlとは

Admission ControlとはKubernetesのAPI Serverのリクエスト制御の機能です。APIリクエストに対して認証、認可を行ったあとのフェーズで、別途そのリクエストを受け入れるか制御を行います。また場合によって、リクエストの変更や別の操作を行います。

プラグイン形式で複数の制御の方法が用意されており、APIの起動オプション--admission-controlで有効にしたいものをカンマ区切りで指定します。

プラグイン

APIサーバーのデフォルトではAlwaysAdmitのみが有効になっています。(参考: cmd/kube-apiserver/app/options/options.go

マニュアルでは下記の指定が推奨されています。

--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota

プラグインはチェーン式にいずれかのプラグインがdenyするまで呼ばれていくため、順序に意味があるので注意が必要です。(変更を伴うプラグインもあるため)

プラグイン一覧

deprecatedなプラグインは省略しています。推奨設定に入っているものは :thumbsup: を付けています。

AlwaysAdmit

すべてのリクエストを許可します。APIサーバーの--admission-controlに何も指定しない場合、これが設定されています。

AlwaysPullImages

PodのimagePullPolicyAlwaysに強制的に変更します。マルチテナントでKubernetesを利用する際これを使わないと、クレデンシャルが必要なPrivateのイメージであっても、Nodeがpull済みのものはクレデンシャル無しで別のPodが使用することができてしまいます。

AlwaysDeny

テスト用途ですべてのリクエストを禁止します。

DenyEscalatingExec

privilegeやHostIPC, HostPIDを要求するPodに対してexecattachを禁止します。クラスタがprivilegeをサポートサポートする場合、この設定が強く推奨されます。

ServiceAccount :thumbsup:

ServiceAccountというPodのためのアカウント(デフォルトではdefaultが使われる)を制御するための仕組みです。PodはAPIにアクセスするためのServiceAccountのトークンが/var/run/secrets/kubernetes.io/serviceaccountに自動でマウントされますが、このプラグインがそのマウントをPodに追加することで実現しているようです。

SecurityContextDeny :thumbsup:

SecurityContextの設定のうち、SELinuxOptionsRunAsUserなどの設定をしているものを禁止します。(セキュリティ上の理由?)

ResourceQuota :thumbsup:

リクエストがnamespace内のリソース制限(ResourceQuota)を超えていないかチェックします。ResourceQuotaを使う場合、このプラグインを有効にしなければなりません。

このプラグインは内部的にResourceQuotaの使用量をアップデートする処理があるため、プラグインの最後尾に指定することが強く推奨されます。(前に指定すると、後のプラグインでdenyされた場合に使用量がおかしくなってしまう)

LimitRanger :thumbsup:

namespaceのLimitRangeで指定されたPodの制限を行います。ResourceQuotaと違い、LimitRangeではPod単体の制限を行うもので、resourcesで指定するCPU, Memoryの範囲を制限することができます。

InitialResources (experimental)

コンテナのリソース(resources)を指定しなかった場合に、過去の実績に基づき初期のリソースを自動で設定するものです。

NamespaceLifecycle :thumbsup:

存在しないnamespaceや削除中のnamespaceへの指定を禁止します。また、デフォルトのnamespaceを削除できないようにします。

Admissionのプラグインの仕組み

admissionの仕組みはpkg/admissionで定義されています。InterfaceにはAdmit, Handlesの2メソッドだけが用意されており、プラグインはこれを実装します。

pkg/admission/interfaces.go
type Interface interface {
    // リクエストの属性(Attributees)を見て、許可の場合nil, 禁止の場合errorを返す
    Admit(a Attributes) (err error)

    // リクエストのオペレーション(CREATE, UPDATE, DELETE, CONNECT)対象とするか
    Handles(operation Operation) bool
}

プラグインの登録は各プラグインでadmission.RegisterPluginを呼び出すだけです。

plugin/pkg/admission/admit/admission.go
func init() {
    admission.RegisterPlugin("AlwaysAdmit", func(client clientset.Interface, config io.Reader) (admission.Interface, error) {
        return NewAlwaysAdmit(), nil
    })
}

最終的に各プラグインはチェーン式に呼ばれ、一つでもdenyを返すとそこで終了します。呼び出し元はpkg/apiserver/resthandler.goです。

pkg/admission/chain.go
func (admissionHandler chainAdmissionHandler) Admit(a Attributes) error {
    for _, handler := range admissionHandler {
        if !handler.Handles(a.GetOperation()) {
            continue
        }
        err := handler.Admit(a)
        if err != nil {
            return err
        }
    }
    return nil
}

参考

32
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
20