Image Policy Admission Controller & Admission Controllers
Image Policy Admission Controller
* ImagePolicyWebhook admission controller
* adds new field to Pod, e.g. pod.spec.container[i].imageID (or an annotation). and kubelet will enforce that both the imageID and image match the image pulled.
* It does not cover Post Pod creation audit (out of scope)
** images allowed due to backend not reachable
** images that kept running after policy change (e.g. CVE discovered)
** images started via local files or http option of kubelet
** checking SHA of images allowed by a tag which was remapped
* Alternatives
1 Admission Control on Controller Objects
2 Enforcement at Docker level: twistlock/authz Docker plugin
3 Policy Stored in API (PSP) depends on
*** Dockerfile,
*** the source code,
*** the source repo,
*** the source review tools,
*** vulnerability databases
4 Registry whitelist/blacklist by prefix match on image strings
5 Send every Request to a Generic Admission Control Backend
How to implement?
Three relevant files
1 . Configuration of admission control. Let's say it A.yaml. It is specified using --admission-control-config-file flag at API-server pod's YAML
--admission-control-config-file=/etc/kubernetes/A.yaml
Content of /etc/kubernetes/A.yaml
plugins:
- name: ImagePolicyWebhook
path: /etc/kuberenets/B.yaml
2. Configuration of Image Policy. Let's say it is B.yaml OR B.json. It is specified in A.yaml as above
imagePolicy:
kubeConfigFile: /etc/kubernetes/admission/C
allowTTL: 50
denyTTL: 50
retryBackoff: 500
defaultAllow: false # DENY ALL PODS IF SERVICE NOT AVAILABLE
3. kubeconfig file. Ler's tell it as file C. It is specified in file B, as above
Here is partial C file
clusters:
- name: name-of-remote-imagepolicy-service
cluster:
certificate-authority: /path/to/ca.pem # CA for verifying the remote service.
server: https://images.example.com/policy # URL of remote service to query. Must use 'https'.
# users refers to the API server's webhook configuration.
users:
- name: name-of-api-server
user:
client-certificate: /path/to/cert.pem # cert for the webhook admission controller to use
client-key: /path/to/key.pem # key matching the cert
Note: We can remove B.yaml 2 and put its content to A.yaml. Now A.yaml will point to kubeConfigFile C, as below
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
configuration:
imagePolicy:
kubeConfigFile: /etc/kubernetes/admission/C
allowTTL: 50
denyTTL: 50
retryBackoff: 500
defaultAllow: true
Admission Controllers
List of admission controllers are enabled by default
- NamespaceLifecycle,
- LimitRanger,
- ServiceAccount,
- TaintNodesByCondition,
- Priority,
- DefaultTolerationSeconds,
- DefaultStorageClass,
- StorageObjectInUseProtection,
- PersistentVolumeClaimResize,
- RuntimeClass,
- CertificateApproval,
- CertificateSigning,
- CertificateSubjectRestriction,
- DefaultIngressClass,
- MutatingAdmissionWebhook,
- ValidatingAdmissionWebhook,
- ResourceQuota
As per CSI following plugins shall be enabled
- EventRateLimit,
- AlwaysPullImages,
- PodSecurityPolicy OR SecurityContextDeny
- NodeRestriction
As per CSI following plugins shall be disabled
- ServiceAccount
- NamespaceLifecycle
- AlwaysAdmit