C-0075 - Image pull policy on latest tag
Framework
AllControls, DevOpsBest
Severity
Low
Description of the the issue
While usage of the latest tag is not generally recommended, in some cases this is necessary. If it is, the ImagePullPolicy must be set to Always, otherwise Kubernetes may run an older image with the same name that happens to be present in the node cache. Note that using Always will not cause additional image downloads because Kubernetes will check the image hash of the local local against the registry and only pull the image if this hash has changed, which is exactly what users want when use the latest tag. This control will identify all pods with latest tag that have ImagePullSecret not set to Always. Note as well that some vendors don't use the word latest in the tag. Some other word may also behave like the latest. For example, Redis uses redis:alpine to signify the latest. Therefore, this control treats any word that does not contain digits as the latest. If no tag is specified, the image is treated as latests too.
Related resources
CronJob, DaemonSet, Deployment, Job, Pod, ReplicaSet, StatefulSet
What does this control test
If imagePullPolicy = always pass, else fail.
Remediation
Set ImagePullPolicy to Always in all pods found by this control.
Example
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "8"
meta.helm.sh/release-name: redis-aggregated
meta.helm.sh/release-namespace: ca-production
creationTimestamp: "2020-05-21T12:19:30Z"
generation: 14
labels:
app: ca-redis-aggregared
app-display-label: ca-redis-aggregared
app.kubernetes.io/component: ca-redis-aggregared
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/part-of: visibilityAndReporting
app.kubernetes.io/version: 1.0.0
environment: producation
region: aws-eu-north-1
name: deployment-with-image-pull-not-always
resourceVersion: "244972372"
selfLink: /apis/apps/v1/namespaces/ca-production/deployments/ca-redis-aggregared
uid: 3658319c-f69b-4e04-87b7-72992a721f22
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/instance: redis-aggregated
app.kubernetes.io/name: ca-redis-aggregared
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: ca-redis-aggregared
app-display-label: ca-redis-aggregared
app.kubernetes.io/component: ca-redis-aggregared
app.kubernetes.io/instance: redis-aggregated
app.kubernetes.io/managed-by: helm
app.kubernetes.io/name: ca-redis-aggregared
app.kubernetes.io/part-of: visibilityAndReporting
app.kubernetes.io/version: 1.0.0
environment: producation
region: aws-eu-north-1
spec:
containers:
- command:
- redis-server
- /redis.conf
image: redis:latest
imagePullPolicy: IfNotPresent
name: ca-redis-aggregared
ports:
- containerPort: 6379
name: redis-port
protocol: TCP
resources:
limits:
cpu: "2"
memory: 14848Mi
requests:
cpu: 500m
memory: 10Gi
stdin: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
tty: true
volumeMounts:
- mountPath: /redis.conf
name: ca-redis-aggregared-config-volume
subPath: redis.conf
- mountPath: /data
name: ca-redis-aggregared-persistent-storage
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: caregcred
nodeSelector:
env: prod
subgroup: prod-redis
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 420
name: ca-redis-aggregared-configmap
name: ca-redis-aggregared-config-volume
- name: ca-redis-aggregared-persistent-storage
persistentVolumeClaim:
claimName: ca-redis-aggregared-pv-claim
Updated 4 months ago