Kyverno and private registry
Clusters that pull images from a private registry must provide access credentials to each workload. In an environment with many components — such as TDP Kubernetes — repeating that configuration manually in each chart is inefficient and error-prone.
Kyverno solves this problem as a cluster policy engine: it intercepts Pod creation and automatically injects the required imagePullSecrets, based on a centralized ClusterPolicy. This way, all components gain access to the private registry without each manifest declaring the credentials individually.
This adjustment is conditional: it only applies when the environment requires authentication to pull images from a private registry. Environments using public registries or that configure imagePullSecrets directly in each chart do not need this step.
When to consider this adjustment
Consider this configuration when:
- images are distributed through a private registry
- the cluster must reuse the same credentials across multiple components
- the platform policy requires standardized use of
imagePullSecrets - credential maintenance should be centralized
Role of Kyverno in this context
The Secret remains the object that stores registry credentials. Kyverno standardizes and enforces the use of that Secret in the cluster through a ClusterPolicy. As a result, new Pods can automatically receive the imagePullSecrets reference without repeating the same configuration in each component manifest.
Configuration overview
The flow has three steps:
- Install Kyverno in the cluster
- Create a Kubernetes Secret with the registry credentials
- Create a
ClusterPolicythat automatically injectsimagePullSecretsinto all Pods
1. Install Kyverno
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno --namespace kyverno --create-namespace
2. Create the registry Secret
Create a file named tdp-registry.yaml with the content below:
apiVersion: v1
kind: Secret
metadata:
name: tdp-registry
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths": {
"registry.tecnisys.com.br": {
"username": "user@tecnisys.com.br",
"password": "xxxxxxxxxxx"
}
}
}
Then apply the Secret to the cluster:
kubectl apply -f tdp-registry.yaml
3. Create the policy to inject imagePullSecrets
Create a file named policy-kyverno.yaml:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: inject-tecnisys-registry-secret
annotations:
policies.kyverno.io/title: Inject Image Pull Secrets
policies.kyverno.io/description: Automatically adds the Tecnisys secret to all pods.
spec:
background: false
rules:
- name: inject-secret
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
spec:
imagePullSecrets:
- name: tdp-registry
Apply the policy:
kubectl apply -f policy-kyverno.yaml
Expected result
After the ClusterPolicy is applied, new Pods created in the cluster automatically receive the imagePullSecrets entry named tdp-registry, allowing private images from the Tecnisys registry to be pulled without repeating the configuration in every chart.
Where to store in the GitOps repository
Version the tdp-registry.yaml and policy-kyverno.yaml files in the GitOps repository under a policies/ folder:
tdp-gitops/
├── app-of-apps.yaml
├── apps/
├── values/
└── policies/
├── tdp-registry.yaml
└── kyverno-registry.yaml
These files are applied with kubectl apply -f, not by Argo CD. Keeping them in the repository ensures that private image credentials and policies are versioned alongside the rest of the configuration.