How To

Allow Insecure Registries in OpenShift / OKD 4.x

OpenShift and OKD 4.x enforce TLS verification on all container image pulls by default. In production, this is exactly what you want – every registry should serve images over HTTPS with valid certificates. But in development, lab, and air-gapped environments, you often run internal registries with self-signed certificates or no TLS at all. Configuring insecure registries lets your cluster pull images from these sources without certificate errors.

Original content from computingforgeeks.com - post 50710

This guide covers multiple methods to allow insecure registries in OpenShift 4.x and OKD 4.x clusters – from quick oc patch commands to the production-recommended approach of adding CA certificates. We also cover mirror registry configuration and troubleshooting common image pull failures. All commands are tested on OpenShift 4.14+ and apply to any OpenShift Container Platform 4.x release.

Prerequisites

  • A running OpenShift 4.x or OKD 4.x cluster
  • The oc CLI installed and authenticated as a cluster-admin user
  • Access to the internal registry you want to configure (know the hostname/IP and port)
  • If adding CA certificates – the registry’s CA certificate file in PEM format

Step 1: Check Current Image Configuration

Before making changes, review the current cluster-wide image configuration. OpenShift stores registry settings in the image.config.openshift.io/cluster resource.

oc get image.config.openshift.io/cluster -o yaml

On a default cluster with no custom registry configuration, the output shows an empty spec:

apiVersion: config.openshift.io/v1
kind: Image
metadata:
  name: cluster
spec: {}
status:
  internalRegistryHostname: image-registry.openshift-image-registry.svc:5000

The spec section is where you define insecure registries, allowed/blocked registries, and additional CA certificates. The status.internalRegistryHostname shows the cluster’s built-in registry address.

Step 2: Add Insecure Registry with oc patch

The fastest way to allow an insecure registry is using oc patch. This method works well when you need to add one or two registries quickly. Replace registry.lab.example.com:5000 with your actual registry address.

oc patch image.config.openshift.io/cluster --type=merge -p '{"spec":{"registrySources":{"insecureRegistries":["registry.lab.example.com:5000"]}}}'

The command returns a confirmation that the resource was patched:

image.config.openshift.io/cluster patched

To add multiple insecure registries in a single patch, list them all in the array:

oc patch image.config.openshift.io/cluster --type=merge -p '{"spec":{"registrySources":{"insecureRegistries":["registry.lab.example.com:5000","192.168.1.50:8443","harbor.dev.local"]}}}'

After patching, the Machine Config Operator (MCO) rolls out the change to all nodes. This triggers a rolling reboot of worker and master nodes, so plan accordingly in shared environments.

Step 3: Add Insecure Registry via YAML Edit

For more control over the configuration, edit the image config resource directly. This approach is better when you need to set multiple options at once – insecure registries, allowed registries, and blocked registries all in one edit.

oc edit image.config.openshift.io/cluster

Add or update the spec section with your insecure registries. Here is an example configuration with multiple registry settings:

apiVersion: config.openshift.io/v1
kind: Image
metadata:
  name: cluster
spec:
  registrySources:
    insecureRegistries:
      - registry.lab.example.com:5000
      - 192.168.1.50:8443
    allowedRegistries:
      - registry.lab.example.com:5000
      - 192.168.1.50:8443
      - docker.io
      - registry.redhat.io
      - quay.io
      - registry.access.redhat.com
      - ghcr.io

A few important points about this configuration:

  • insecureRegistries – registries where TLS verification is skipped. OpenShift will connect over HTTP or accept invalid/self-signed certificates
  • allowedRegistries – when set, only these registries can be used for image pulls. All others are blocked. Always include the Red Hat registries (registry.redhat.io, quay.io, registry.access.redhat.com) or cluster updates and operator installs will break
  • blockedRegistries – the inverse of allowedRegistries. Cannot be used together with allowedRegistries. Blocks only the listed registries

Save and exit the editor. The MCO picks up the change and starts rolling it out to all nodes.

Step 4: Verify Machine Config Operator Rollout

After modifying the image configuration, the Machine Config Operator updates the /etc/containers/registries.conf file on every node. This requires a node reboot, which the MCO handles automatically. Monitor the rollout progress with these commands.

Check the MachineConfigPool status for worker nodes:

oc get machineconfigpool

During the rollout, you see nodes updating one at a time. The UPDATED column shows False until all nodes finish:

NAME     CONFIG                                             UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT   UPDATEDMACHINECOUNT   UNAVAILABLEMACHINECOUNT   AGE
master   rendered-master-a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6   True      False      False      3               3                   3                     0                         45d
worker   rendered-worker-f6e5d4c3b2a1f6e5d4c3b2a1f6e5d4c3   False     True       False      3               2                   2                     1                         45d

Wait for all pools to show UPDATED=True and UPDATING=False. You can watch the progress in real time:

oc wait machineconfigpool/worker --for=condition=Updated --timeout=600s

Once complete, the command returns:

machineconfigpool.machineconfiguration.openshift.io/worker condition met

To confirm the registry configuration reached the nodes, open a debug shell on any worker node and check the container registry config:

oc debug node/worker-0.example.com -- chroot /host cat /etc/containers/registries.conf

You should see your insecure registry listed with insecure = true in the output:

[[registry]]
  prefix = ""
  location = "registry.lab.example.com:5000"
  insecure = true

Step 5: Test Pulling from Insecure Registry

With the configuration applied and all nodes updated, verify that your cluster can pull images from the insecure registry. Create a test pod that pulls an image from your registry.

oc run test-pull --image=registry.lab.example.com:5000/myapp:latest --restart=Never

Check the pod status to confirm the image was pulled successfully:

oc get pod test-pull

A successful pull shows the pod in Running or Completed state:

NAME        READY   STATUS      RESTARTS   AGE
test-pull   1/1     Running     0          15s

If the pod is stuck in ImagePullBackOff, check the events for details:

oc describe pod test-pull | grep -A 5 Events

Clean up the test pod when done:

oc delete pod test-pull

You can also test image pulls in a Harbor registry deployment or any private registry running in your lab. If you need to add pull secrets for authenticated registries, see Step 8 for troubleshooting authentication issues.

Step 6: Add Registry CA Certificate (Production Approach)

For production environments, the correct approach is to add your registry’s CA certificate to the cluster trust store instead of marking the registry as insecure. This keeps TLS verification active while trusting your internal certificate authority.

First, create a ConfigMap in the openshift-config namespace containing your registry’s CA certificate. The key in the ConfigMap must be the registry hostname and port:

oc create configmap registry-ca \
  --from-file=registry.lab.example.com:5000=/path/to/ca-certificate.crt \
  -n openshift-config

If your CA certificate covers multiple registries, add them all to the same ConfigMap:

oc create configmap registry-ca \
  --from-file=registry.lab.example.com:5000=/path/to/ca-certificate.crt \
  --from-file=harbor.internal.local=/path/to/harbor-ca.crt \
  -n openshift-config

Next, patch the cluster image config to reference this ConfigMap:

oc patch image.config.openshift.io/cluster --type=merge -p '{"spec":{"additionalTrustedCA":{"name":"registry-ca"}}}'

The MCO distributes the CA certificate to all nodes and updates the trust store. Monitor the rollout the same way as Step 4:

oc get machineconfigpool -w

This approach is strongly recommended over insecure registries because it maintains certificate validation while trusting your internal CA. If you ever need to update the certificate, edit the ConfigMap and the MCO re-rolls the nodes automatically. For troubleshooting x509 certificate errors with container registries, the CA trust method resolves these permanently.

Step 7: Configure Mirror Registries

Mirror registries are common in air-gapped or disconnected OpenShift clusters where nodes cannot reach the internet. Instead of pulling from docker.io or quay.io, the cluster pulls from a local mirror. OpenShift 4.x uses ImageDigestMirrorSet (IDMS) and ImageTagMirrorSet (ITMS) resources for this purpose.

Create an ImageDigestMirrorSet to mirror images from a public registry to your local one:

apiVersion: config.openshift.io/v1
kind: ImageDigestMirrorSet
metadata:
  name: local-mirror
spec:
  imageDigestMirrors:
    - mirrors:
        - registry.lab.example.com:5000/docker-io
      source: docker.io
    - mirrors:
        - registry.lab.example.com:5000/quay-io
      source: quay.io

Apply the mirror configuration:

oc apply -f image-digest-mirror-set.yaml

If your mirror registry uses self-signed certificates, combine the mirror configuration with Step 6 (add the CA certificate) or Step 2 (mark it as insecure for lab environments).

For environments using Project Quay as the mirror registry, the Quay operator can handle mirror synchronization automatically.

To verify the mirror configuration is active on nodes, check the registries config:

oc debug node/worker-0.example.com -- chroot /host cat /etc/containers/registries.conf.d/99-master-generated-registries.conf

Step 8: Troubleshoot Insecure Registry Issues

When pods fail to pull images from insecure registries, the symptoms are usually ImagePullBackOff or ErrImagePull. Here are the most common causes and fixes.

ImagePullBackOff with x509 Certificate Error

This happens when the registry uses a self-signed certificate but is not listed in insecureRegistries and its CA is not trusted. Check pod events for the exact error:

oc describe pod failing-pod -n your-namespace

Look for messages like this in the Events section:

Failed to pull image "registry.lab.example.com:5000/myapp:latest": rpc error: code = Unknown desc = pinging container registry registry.lab.example.com:5000: Get "https://registry.lab.example.com:5000/v2/": x509: certificate signed by unknown authority

Fix: either add the registry to insecureRegistries (Step 2) or add its CA certificate (Step 6).

MCO Rollout Stuck or Degraded

If the MachineConfigPool shows DEGRADED=True after changing image config, a node failed to apply the new configuration. Check which node is degraded:

oc get nodes -o wide

Then inspect the machine config daemon logs on the affected OpenShift node:

oc logs -n openshift-machine-config-operator -l k8s-app=machine-config-daemon --tail=50

Registry Not Reachable from Nodes

Even with insecure registry configured, pods fail if nodes cannot reach the registry on the network. Open a debug shell and test connectivity:

oc debug node/worker-0.example.com -- chroot /host curl -k https://registry.lab.example.com:5000/v2/

If this times out, check firewall rules between your cluster nodes and the registry server. Port 5000 (or your registry’s configured port) must be open TCP.

Authentication Failures (401 Unauthorized)

Insecure registry configuration handles TLS, not authentication. If your registry requires login credentials, you need a pull secret. Create one and link it to the service account:

oc create secret docker-registry my-registry-secret \
  --docker-server=registry.lab.example.com:5000 \
  --docker-username=admin \
  --docker-password=secretpassword \
  -n your-namespace

Link the secret to the default service account in your namespace:

oc secrets link default my-registry-secret --for=pull -n your-namespace

For cluster-wide pull secrets that apply to all namespaces, update the global pull secret. See the Harbor pull secret guide for a detailed walkthrough on managing registry authentication in OpenShift and Kubernetes.

Conclusion

You now have multiple methods to allow insecure registries in your OpenShift or OKD 4.x cluster – from quick oc patch commands for dev/lab environments to the production-grade approach of adding CA certificates. The insecure registry option works for testing but should not be used in production. For production clusters, always add your registry’s CA certificate to the cluster trust store and use allowedRegistries to restrict which registries your cluster can pull from.

For air-gapped deployments, combine mirror registries with CA certificates to keep your cluster secure while running fully disconnected. Monitor MCO rollouts after every image config change and verify the configuration reached all nodes before deploying workloads.

Related Articles

Kubernetes How To Run VSCode Code Server on Kubernetes using Helm Containers Deploy HashiCorp Vault for Secrets Management in Kubernetes Openshift Run Local OpenShift (OKD) with CRC on RHEL 10 / Fedora Cloud Managing Containerd Containers using ctr and crictl

Leave a Comment

Press ESC to close