diff --git a/chart/templates/coredns-configmap.yaml b/chart/templates/coredns-configmap.yaml index ee5575b0b..b39d546ab 100644 --- a/chart/templates/coredns-configmap.yaml +++ b/chart/templates/coredns-configmap.yaml @@ -159,6 +159,14 @@ data: {{- if .Values.controlPlane.coredns.deployment.nodeSelector }} {{ toYaml .Values.controlPlane.coredns.deployment.nodeSelector | indent 12 }} {{- end }} + {{- if .Values.controlPlane.coredns.deployment.affinity }} + affinity: +{{ toYaml .Values.controlPlane.coredns.deployment.affinity | indent 12 }} + {{- end }} + {{- if .Values.controlPlane.coredns.deployment.tolerations }} + tolerations: +{{ toYaml .Values.controlPlane.coredns.deployment.tolerations | indent 12 }} + {{- end }} {{- if .Values.controlPlane.coredns.deployment.topologySpreadConstraints }} topologySpreadConstraints: {{ toYaml .Values.controlPlane.coredns.deployment.topologySpreadConstraints | indent 12 }} diff --git a/chart/tests/coredns-configmap_test.yaml b/chart/tests/coredns-configmap_test.yaml index a15108758..263ce2b8d 100644 --- a/chart/tests/coredns-configmap_test.yaml +++ b/chart/tests/coredns-configmap_test.yaml @@ -333,3 +333,245 @@ tests: - name: metrics port: 9153 protocol: TCP + - it: should correctly apply affinity and tolerations + set: + controlPlane: + coredns: + deployment: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - coredns + topologyKey: kubernetes.io/hostname + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + asserts: + - equal: + path: data["coredns.yaml"] + value: |- + apiVersion: v1 + kind: ServiceAccount + metadata: + name: coredns + namespace: kube-system + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:coredns + rules: + - apiGroups: + - "" + resources: + - endpoints + - services + - pods + - namespaces + verbs: + - list + - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:coredns + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:coredns + subjects: + - kind: ServiceAccount + name: coredns + namespace: kube-system + --- + apiVersion: v1 + kind: ConfigMap + metadata: + name: coredns + namespace: kube-system + data: + Corefile: |- + .:1053 { + errors + health + ready + rewrite name regex .*\.nodes\.vcluster\.com kubernetes.default.svc.cluster.local + kubernetes cluster.local in-addr.arpa ip6.arpa { + pods insecure + fallthrough in-addr.arpa ip6.arpa + } + hosts /etc/NodeHosts { + ttl 60 + reload 15s + fallthrough + } + prometheus :9153 + forward . /etc/resolv.conf + cache 30 + loop + loadbalance + } + + import /etc/coredns/custom/*.server + NodeHosts: "" + --- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: coredns + namespace: kube-system + labels: + k8s-app: kube-dns + kubernetes.io/name: "CoreDNS" + spec: + replicas: 1 + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + selector: + matchLabels: + k8s-app: kube-dns + template: + metadata: + labels: + k8s-app: kube-dns + spec: + priorityClassName: "" + serviceAccountName: coredns + nodeSelector: + kubernetes.io/os: linux + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - coredns + topologyKey: kubernetes.io/hostname + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + topologySpreadConstraints: + - labelSelector: + matchLabels: + k8s-app: kube-dns + maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + containers: + - name: coredns + image: {{.IMAGE}} + imagePullPolicy: IfNotPresent + resources: + limits: + cpu: 1000m + memory: 170Mi + requests: + cpu: 20m + memory: 64Mi + args: [ "-conf", "/etc/coredns/Corefile" ] + volumeMounts: + - name: config-volume + mountPath: /etc/coredns + readOnly: true + - name: custom-config-volume + mountPath: /etc/coredns/custom + readOnly: true + securityContext: + runAsNonRoot: true + runAsUser: {{.RUN_AS_USER}} + runAsGroup: {{.RUN_AS_GROUP}} + allowPrivilegeEscalation: false + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + readOnlyRootFilesystem: true + livenessProbe: + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /ready + port: 8181 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 2 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + dnsPolicy: Default + volumes: + - name: config-volume + configMap: + name: coredns + items: + - key: Corefile + path: Corefile + - key: NodeHosts + path: NodeHosts + - name: custom-config-volume + configMap: + name: coredns-custom + optional: true + --- + apiVersion: v1 + kind: Service + metadata: + name: kube-dns + namespace: kube-system + annotations: + prometheus.io/port: "9153" + prometheus.io/scrape: "true" + labels: + k8s-app: kube-dns + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" + spec: + type: ClusterIP + selector: + k8s-app: kube-dns + ports: + - name: dns + port: 53 + targetPort: 1053 + protocol: UDP + - name: dns-tcp + port: 53 + targetPort: 1053 + protocol: TCP + - name: metrics + port: 9153 + protocol: TCP diff --git a/chart/values.schema.json b/chart/values.schema.json index 22f01d2c9..6aad9717c 100755 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -617,6 +617,17 @@ "type": "object", "description": "NodeSelector is the node selector to use for coredns." }, + "affinity": { + "type": "object", + "description": "Affinity is the affinity to apply to the pod." + }, + "tolerations": { + "items": { + "type": "object" + }, + "type": "array", + "description": "Tolerations are the tolerations to apply to the pod." + }, "resources": { "$ref": "#/$defs/Resources", "description": "Resources are the desired resources for coredns." diff --git a/chart/values.yaml b/chart/values.yaml index 536044458..085e685bc 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -430,6 +430,10 @@ controlPlane: annotations: {} # NodeSelector is the node selector to use for coredns. nodeSelector: {} + # Affinity is the affinity to apply to the pod. + affinity: {} + # Tolerations are the tolerations to apply to the pod. + tolerations: [] # Resources are the desired resources for coredns. resources: # Limits are resource limits for the container diff --git a/config/config.go b/config/config.go index b5de05066..f0fb096be 100644 --- a/config/config.go +++ b/config/config.go @@ -1193,6 +1193,12 @@ type CoreDNSDeployment struct { // NodeSelector is the node selector to use for coredns. NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // Affinity is the affinity to apply to the pod. + Affinity map[string]interface{} `json:"affinity,omitempty"` + + // Tolerations are the tolerations to apply to the pod. + Tolerations []map[string]interface{} `json:"tolerations,omitempty"` + // Resources are the desired resources for coredns. Resources Resources `json:"resources,omitempty"` diff --git a/config/values.yaml b/config/values.yaml index 1d6161cb3..9fd96940b 100644 --- a/config/values.yaml +++ b/config/values.yaml @@ -240,6 +240,8 @@ controlPlane: labels: {} annotations: {} nodeSelector: {} + affinity: {} + tolerations: [] resources: limits: cpu: 1000m