今日覚えて帰ること
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が何なのかあまりわかっていないので調査から始めます。
どうやら Validating タイプの admission policy みたいです。
事前にコンテナイメージを管理・制御するリモートポリシーサービスを別途立ち上げておいて、クラスター内でpodを立ち上げる直前にそのサービスへkube-apiserverからリクエストを送り、バリデーションチェックをするような機能っぽいです。
デフォルトでは無効になっています。
admission policy については admission controller について書いた記事に詳しく書いているのでそちらをご参照ください。
より詳しく知りたい方は以下の記事が参考になると思います。
それでは問題を解いていきましょう。
まず、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 $