DirectorySecurity AdvisoriesPricing
Sign in
Directory
coredns logoHELM

coredns

Helm chart
Last changed
Request a free trial

Contact our team to test out this Helm chart and related images for free. Please also indicate any other images you would like to evaluate.

Overview
Chart tags
Default values
Chart metadata
Images

CoreDNS

Chainguard's redistribution of the CoreDNS Helm chart, pre-configured with hardened Chainguard Images.

Prerequisites

Authentication is required to access this chart and its images. First, authenticate with Chainguard and configure your environment:

chainctl auth login
chainctl auth configure-docker --pull-token --save
helm registry login cgr.dev

Create an image pull secret for the cluster:

kubectl create secret docker-registry cgr-pull-secret -n kube-system \
  --docker-server=cgr.dev \
  --docker-username="$(echo cgr.dev | docker-credential-cgr get | jq -r '.Username')" \
  --docker-password="$(echo cgr.dev | docker-credential-cgr get | jq -r '.Secret')"

Installation

Depending on your Kubernetes distro the kube-dns service will need to be set to an appropriate ClusterIP. For EKS, the default will be 172.20.0.10 or 10.100.0.10 depending on your cluster's service CIDR.

helm install coredns oci://cgr.dev/ORGANIZATION/charts/coredns -n kube-system \
  --set image.pullSecrets[0].name=cgr-pull-secret
  --set service.clusterIP="10.0.100.10"

About This Chart

This is a redistribution of the upstream CoreDNS Helm chart. All upstream configuration options and documentation apply.

For full documentation, see: https://coredns.io

Chainguard Customizations

The Service is named kube-dns, the name Kubernetes clusters use for cluster DNS.

EKS Add-on Compatibility Settings

This chart adds the setting shapes of AWS's own CoreDNS EKS add-on that the upstream chart lacks, so values written for AWS's add-on work here too, as EKS add-on configuration values or as Helm values. Each one does nothing unless it is set, and it wins over the chart setting it maps onto.

SettingEffect

corefile

The whole Corefile. Replaces the Corefile that the chart builds from servers and extraConfig. Keep the health plugin on :8080 and the ready plugin on :8181, which the liveness and readiness probes call, and serve DNS on :53, which the Service targets. The Service and container ports come from servers, not from corefile.

podDisruptionBudget.enabled

false removes the PodDisruptionBudget. true creates one, with maxUnavailable: 1 unless minAvailable or maxUnavailable is set.

autoScaling.enabled, minReplicas, maxReplicas, nodesPerReplica, cpuCoresPerReplica

Set autoscaler.enabled, min, max, nodesPerReplica, and coresPerReplica, which run the cluster-proportional-autoscaler.

trafficDistribution

Sets service.trafficDistribution on the kube-dns Service: PreferClose, PreferSameZone, or PreferSameNode. The last two need Kubernetes 1.34 or later, so the EKS add-on schema accepts only PreferClose.

annotationTopologyMode

Sets the service.kubernetes.io/topology-mode annotation on the kube-dns Service, and on the metrics Service when prometheus.service.enabled is set: Auto or Disabled.

autoScaling approximates EKS's own CoreDNS autoscaling. Both size CoreDNS to the larger of the node count divided by nodesPerReplica (16 when unset) and the CPU core count divided by cpuCoresPerReplica (256 when unset). But EKS's controller looks at 10-minute peaks and scales down gradually, while the cluster-proportional-autoscaler checks every 10 seconds. It runs as a separate Deployment, with its own ServiceAccount and cluster RBAC. Without minReplicas, it keeps 2 replicas on a cluster with more than one node and 1 on a single node; AWS's add-on keeps 2.

EKS Add-on Configuration Schema

EKS validates the configuration values of the Chainguard CoreDNS EKS add-on against aws_mp_configuration_schema.json at the chart root, which aws eks describe-addon-configuration returns. The schema starts from the schema of AWS's own coredns add-on v1.14.7-eksbuild.11 (CoreDNS 1.14.7), so a customer moving from AWS's add-on can pass the same settings in the same shape, except those in the table and list below. It also accepts the compatibility settings above and the adoption settings below. It does not accept service.clusterIP, which EKS sets to the cluster's DNS address.

AWS's own add-on accepts one setting that the schema leaves out:

SettingWhy the schema leaves it out

computeType

The schema accepts only settings that the chart honors, and AWS's schema gives computeType no description or allowed values. Guides use computeType: Fargate to run AWS's CoreDNS on Fargate, where older EKS CoreDNS Deployments pinned it to EC2 with the eks.amazonaws.com/compute-type: ec2 annotation. This chart never sets that annotation, so its pods run on Fargate when a Fargate profile selects them. AWS's documented profile selects k8s-app=kube-dns, and this chart labels its pods k8s-app: coredns by default, so set k8sAppLabelOverride to kube-dns (as the adoption settings below do) or select k8s-app=coredns in the profile. With autoScaling.enabled, the cluster-proportional-autoscaler runs in its own pod, labeled k8s-app: kube-dns-autoscaler (coredns-autoscaler without k8sAppLabelOverride), so the profile must select that pod too; otherwise, on a cluster with no EC2 nodes, it stays Pending and CoreDNS does not scale. Remove computeType from the values you migrate.

Some settings accept less than AWS's own schema does. Except where noted below, they still accept every valid Kubernetes value that has no null fields:

  • affinity, tolerations, and topologySpreadConstraints accept only the fields of their Kubernetes types, where AWS's schema accepts any object. Fields inside them may not be null, so leave out a field that you do not set. affinity itself may be null.
  • Pod affinity and anti-affinity terms under affinity do not accept matchLabelKeys or mismatchLabelKeys, which Kubernetes accepts from 1.31 on. The schema's shared Kubernetes types also serve add-ons that support Kubernetes 1.29 and 1.30, where the MatchLabelKeysInPodAffinity feature gate is off by default. A later version of this add-on may accept them.
  • affinity, tolerations, topologySpreadConstraints, and deployment.selector need the fields that Kubernetes requires, and take only the operators, effects, policies, and bounds that Kubernetes allows. For example, a spread constraint needs maxSkew of at least 1, topologyKey, and whenUnsatisfiable, and a weight must be from 1 to 100. The schema still accepts some values that Kubernetes rejects, so they fail at install instead:
    • values that break a rule relating two fields, such as minDomains without whenUnsatisfiable: DoNotSchedule, a toleration with no key and an operator other than Exists, or a deployment.selector that the pod labels do not match
    • a required node affinity without nodeSelectorTerms, which the schema does not require because other charts' defaults fill it and Helm merges the customer's value into the default
  • Values and keys under affinity and topologySpreadConstraints may not contain { or }, because the chart renders them as Helm templates, where a template could change any other chart value.
  • tolerations fields may not contain { or }, which Kubernetes rejects there too.
  • Label and annotation keys must be valid Kubernetes keys, and label values valid Kubernetes label values. An annotation key prefix, such as example.com in example.com/owner, must be lowercase, which is stricter than Kubernetes. A later version of this add-on may widen the rule if customers need it.
  • resources takes only cpu and memory, each a Kubernetes quantity given as a string, such as 100m or 128Mi.
  • nodeSelector, podAnnotations, and podLabels accept only string values, as Kubernetes does.
  • podAnnotations keys may not start with container.apparmor.security.beta.kubernetes.io/ or the seccomp prefixes seccomp.security.alpha.kubernetes.io/ and container.seccomp.security.alpha.kubernetes.io/. Kubernetes, from 1.30 through at least 1.37, still copies the AppArmor annotation into the container's security context when that field is unset (applyAppArmorVersionSkew in kubernetes/kubernetes), so the annotation could set the profile to unconfined. The seccomp annotations have done nothing since Kubernetes 1.27 and are refused too.
  • Strings may not contain control characters or the NEL, LS, and PS separators, which YAML reads as line breaks. corefile and podAnnotations values may contain tabs and line feeds.
  • podDisruptionBudget accepts only enabled, maxUnavailable, and minAvailable, where AWS's schema accepts any key, because the chart copies the whole setting into the PodDisruptionBudget's spec. It may not set both maxUnavailable and minAvailable, which Kubernetes rejects.
  • podLabels may not set k8s-app, app.kubernetes.io/name, or app.kubernetes.io/instance. The chart sets these labels on the CoreDNS pods, and its Deployment selects the pods by them, so a different value would stop the pods from matching their own selector. Use k8sAppLabelOverride to change k8s-app.
  • replicaCount must be from 0 to 999999. Kubernetes rejects a negative count, and the chart renders the count unquoted, where Helm writes 1000000 and above in exponent form (1e+06).
  • trafficDistribution accepts only PreferClose, where AWS's schema also accepts PreferSameZone and PreferSameNode. Those two need the PreferSameTrafficDistribution feature gate, which is off by default in Kubernetes 1.33, the oldest version this add-on supports. A later version of this add-on may accept them.
Taking Over AWS's Own Add-on

AWS's own add-on labels its CoreDNS pods k8s-app: kube-dns and eks.amazonaws.com/component: coredns. Its coredns Deployment selects pods by both labels, and its kube-dns Service by k8s-app: kube-dns. This chart's labels and selector differ by default, and Kubernetes does not let a Deployment's selector change. To take over the objects that AWS's own add-on created, pass these adoption settings:

{
  "k8sAppLabelOverride": "kube-dns",
  "podLabels": { "eks.amazonaws.com/component": "coredns" },
  "deployment": { "selector": { "matchLabels": { "k8s-app": "kube-dns", "eks.amazonaws.com/component": "coredns" } } },
  "service": { "selector": { "k8s-app": "kube-dns" } }
}

Keep k8sAppLabelOverride, the podLabels entry, and deployment.selector on every later update: removing one changes the Deployment's selector or its pod labels, and Kubernetes rejects that.

CoreDNS runs as the chart's own ServiceAccount, which has the same name as the chart's Deployment and ConfigMap, and the chart binds its ClusterRole to it. When those objects are named coredns, as AWS's are, the chart takes over AWS's coredns ServiceAccount along with them. The chart does not create AWS's system:coredns ClusterRole and ClusterRoleBinding, so if they remain from AWS's add-on, they still grant their permissions to that ServiceAccount.

Defaults That Differ From AWS's Own Add-on

The chart has the same defaults for the EKS add-on and for Helm. To get AWS's value, set it in the configuration values, except for resources (see below the table):

SettingThis chartAWS's own add-on

replicaCount

1

2

podDisruptionBudget

none

enabled: true, maxUnavailable: 1

affinity

none

Linux nodes on amd64 or arm64 required; one CoreDNS pod per node preferred, by a pod anti-affinity on k8s-app: kube-dns that matches this chart's pods only with k8sAppLabelOverride: kube-dns

tolerations

none

CriticalAddonsOnly, and NoSchedule for node-role.kubernetes.io/control-plane

autoScaling.minReplicas

2 on a cluster with more than one node, else 1

2

resources

limits: cpu: 100m, memory: 128Mi; requests: cpu: 100m, memory: 128Mi

limits: memory: 170Mi; requests: cpu: 100m, memory: 70Mi; no CPU limit

The schema's first root example sets AWS's values for the first four, with the anti-affinity on app.kubernetes.io/name: coredns, which this chart's pods always carry.

AWS's resources cannot be set exactly. Helm merges the value into the chart's default, so the chart's 100m CPU limit stays, and the schema does not accept the null that would remove it. To come close to AWS's add-on, set AWS's memory limit and requests, and set limits.cpu above what CoreDNS uses.

Chart versions
  • 1.50.0-fips

    Latest
  • 1.50-fips

  • 1.50.0

  • 1.50

View all chart versions

Images

Helm charts contain references to Chainguard Container images. The following images are referenced in the chart:

cluster-proportional-autoscaler-fips logoFIPS

cluster-proportional-autoscaler-fips


The trusted source for open source

Talk to an expert
PrivacyTerms

Product

Chainguard ContainersChainguard LibrariesChainguard VMsChainguard OS PackagesChainguard ActionsChainguard Agent SkillsIntegrationsPricing
© 2026 Chainguard, Inc. All Rights Reserved.
Chainguard® and the Chainguard logo are registered trademarks of Chainguard, Inc. in the United States and/or other countries.
The other respective trademarks mentioned on this page are owned by the respective companies and use of them does not imply any affiliation or endorsement.