kubestronautへの道 ~CKS編 その14 killer coda「ImagePolicyWebhook Setup」~

tech article

今日覚えて帰ること

ImagePolicyWebhook

  • Admission controller プラグインの一つ
  • Admission controller プラグインの MutatingAdmissionWebhook/ValidatingAdmissionWebhookに近い
  • pod作成時にリモートポリシーサービスにリクエストを送り、コンテナイメージが検査に通った時のみ pod を立ち上げることを許可する。

ImagePolicyWebhook Setup

Complete the ImagePolicyWebhook setup

An ImagePolicyWebhook setup has been half finished, complete it:

  • Make sure admission_config.json points to correct kubeconfig
  • Set the allowTTL to 100
  • All Pod creation should be prevented if the external service is not reachable
  • The external service will be reachable under https://localhost:1234 in the future. It doesn’t exist yet so it shouldn’t be able to create any Pods till then
  • Register the correct admission plugin in the apiserver

ImagePolicyWebhookが何なのかあまりわかっていないので調査から始めます。

Admission Controllers Reference
This page provides an overview of Admission Controllers. What are they? An admission controller is a piece of code that intercepts requests to the Kubernetes AP...

どうやら Validating タイプの admission policy みたいです。

事前にコンテナイメージを管理・制御するリモートポリシーサービスを別途立ち上げておいて、クラスター内でpodを立ち上げる直前にそのサービスへkube-apiserverからリクエストを送り、バリデーションチェックをするような機能っぽいです。

デフォルトでは無効になっています。

admission policy については admission controller について書いた記事に詳しく書いているのでそちらをご参照ください。

より詳しく知りたい方は以下の記事が参考になると思います。

Admission Webhookを作って遊んで、その仕組みを理解しよう(説明編) · Goldstine研究所
Kubernetesの運用には欠かせなくなってくる拡張。そのひとつであるAdmission Webhookを作って遊んでみるというものです。本記事は説明編で、動作編にも続きます。

それでは問題を解いていきましょう。

まず、admission_config.jsonがどこにあるかわからないのでサーバー内のどこに位置するのか探索します。

sudo find / -name "*.yaml" 

find / で / 配下のディレクトリ全て調べます。
-name “<file name>” でファイルがどこにあるのか調べることができます。

controlplane $ sudo find / -name "admission_config.json"            
/etc/kubernetes/policywebhook/admission_config.json

/etc/kubernetes/policywebhook/admission_config.json で設定するのは以下の3つです。

  • Make sure admission_config.json points to correct kubeconfig
  • Set the allowTTL to 100
  • All Pod creation should be prevented if the external service is not reachable

こいつらを仕留めていきます。

まず、”kubeConfigFile”を確認すると指定されている値が/todo/kubecofigとなっているので正しい値を設定しましょう。
先ほどのfindと同じ要領で検索すると/etc/kubernetes/policywebhook/kubeconfに配置されていることが分かります。

次に、”allowTTL”が50に設定されているので100に修正します。

最後に、”defaultAllow”を修正します。少しわかりづらいですが、こちらはexternal service(リモートポリシーサービス)が応答を返さなかった場合の挙動についての設定です。
問題文にはexternal serviceに到達しなかった場合はPod作成を禁止せよ、と書いているので、defaultAllowをfalseに設定します。

controlplane $ cp /etc/kubernetes/policywebhook/admission_config.json /etc/kubernetes/policywebhook/admission_config.json.org 
controlplane $ cat /etc/kubernetes/policywebhook/admission_config.json
{
   "apiVersion": "apiserver.config.k8s.io/v1",
   "kind": "AdmissionConfiguration",
   "plugins": [
      {
         "name": "ImagePolicyWebhook",
         "configuration": {
            "imagePolicy": {
               "kubeConfigFile": "/todo/kubeconf",
               "allowTTL": 50,
               "denyTTL": 50,
               "retryBackoff": 500,
               "defaultAllow": true
            }
         }
      }
   ]
}
controlplane $ vi /etc/kubernetes/policywebhook/admission_config.json
controlplane $ diff /etc/kubernetes/policywebhook/admission_config.json /etc/kubernetes/policywebhook/admission_config.json.org
9,10c9,10
<                "kubeConfigFile": "/etc/kubernetes/policywebhook/kubeconf",
<                "allowTTL": 100,
---
>                "kubeConfigFile": "/todo/kubeconf",
>                "allowTTL": 50,
13c13
<                "defaultAllow": false
---
>                "defaultAllow": true
controlplane $ 

続いて

  • The external service will be reachable under https://localhost:1234 in the future. It doesn’t exist yet so it shouldn’t be able to create any Pods till then

です。こちらについては kubeconfig で設定します。
admission_config.jsonで “kubeConfigFile”: “/etc/kubernetes/policywebhook/kubeconf” と設定しました。
ここでは、kube-apiserverがexternal serviceに接続するための設定を行います。

serverにThe external serviceのURL(今回でいうとhttps://localhost:1234)を設定します。

controlplane $ cp /etc/kubernetes/policywebhook/kubeconf /etc/kubernetes/policywebhook/kubeconf.org
controlplane $ cat /etc/kubernetes/policywebhook/kubeconf
apiVersion: v1
kind: Config

# clusters refers to the remote service.
clusters:
- cluster:
    certificate-authority: /etc/kubernetes/policywebhook/external-cert.pem  # CA for verifying the remote service.
    server: TODO                   # URL of remote service to query. Must use 'https'.
  name: image-checker

contexts:
- context:
    cluster: image-checker
    user: api-server
  name: image-checker
current-context: image-checker
preferences: {}

# users refers to the API server's webhook configuration.
users:
- name: api-server
  user:
    client-certificate: /etc/kubernetes/policywebhook/apiserver-client-cert.pem     # cert for the webhook admission controller to use
    client-key:  /etc/kubernetes/policywebhook/apiserver-client-key.pem             # key matching the cert
controlplane $ 
controlplane $ 
controlplane $ 
controlplane $ vi /etc/kubernetes/policywebhook/kubeconf
controlplane $ diff /etc/kubernetes/policywebhook/kubeconf /etc/kubernetes/policywebhook/kubeconf.org
8c8
<     server: https://localhost:1234                  # URL of remote service to query. Must use 'https'.
---
>     server: TODO                   # URL of remote service to query. Must use 'https'.

最後に /etc/kubernetes/manifest/kube-apiserver の設定を変えます。
enable-admission-plugins の値に ImagePolicyWebhook を追加します。

controlplane $ cp /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.org

controlplane $ cat /etc/kubernetes/manifests/kube-apiserver.yaml 
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 172.30.1.2:6443
  creationTimestamp: null
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=172.30.1.2
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --enable-admission-plugins=NodeRestriction



///


controlplane $ vi /etc/kubernetes/manifests/kube-apiserver.yaml 
controlplane $ diff /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.org
20c20
<     - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
---
>     - --enable-admission-plugins=NodeRestriction
controlplane $ 

上手くいっているかどうがのテストは、

watch crictl ps

で kube-apiserver が再起動されたのを確認してから、podを立てて以下のような画面になれば成功です!

controlplane $ k run pod --image=nginx
Error from server (Forbidden): pods "pod" is forbidden: Post "https://localhost:1234/?timeout=30s": dial tcp 127.0.0.1:1234: connect: connection refused
controlplane $ 

タイトルとURLをコピーしました