---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nodelocaldns
  namespace: kube-system
  labels:
    addonmanager.kubernetes.io/mode: Reconcile

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nodelocaldns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  selector:
    matchLabels:
      k8s-app: nodelocaldns
  template:
    metadata:
      labels:
        k8s-app: nodelocaldns
      annotations:
        prometheus.io/scrape: 'true'
        prometheus.io/port: '9253'
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      serviceAccountName: nodelocaldns
      hostNetwork: true
      dnsPolicy: Default  # Don't use cluster DNS.
      tolerations:
      - effect: NoSchedule
        operator: "Exists"
      - effect: NoExecute
        operator: "Exists"
      - key: "CriticalAddonsOnly"
        operator: "Exists"
      containers:
      - name: node-cache
        image: {{ .kubernetes.networking.dns_cache_image }}
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 70Mi
        args: [ "-localip", "169.254.25.10", "-conf", "/etc/coredns/Corefile", "-upstreamsvc", "coredns" ]
        securityContext:
          privileged: true
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9253
          name: metrics
          protocol: TCP
        livenessProbe:
          httpGet:
            host: 169.254.25.10
            path: /health
            port: 9254
            scheme: HTTP
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 10
        readinessProbe:
          httpGet:
            host: 169.254.25.10
            path: /health
            port: 9254
            scheme: HTTP
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 10
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
        - name: config-volume
          configMap:
            name: nodelocaldns
        - name: xtables-lock
          hostPath:
            path: /run/xtables.lock
            type: FileOrCreate
      # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force
      # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods.
      terminationGracePeriodSeconds: 0
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 20%
    type: RollingUpdate

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nodelocaldns
  namespace: kube-system
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
data:
  Corefile: |
  {{- range .kubernetes.coredns.external_zones }}
    {{ .zones | join " " }}{
      log
      errors
      loadbalance
      cache {{ .cache }}
      reload
      loop
      bind 169.254.25.10
      prometheus :9253

    {{- range .rewrite }}
      rewrite {{ .rule }} {
        {{ .field }} {{ .type }} {{ .value }}
        {{ .options }}
      }
    {{- end }}

    {{- range .forward }}
      forward {{ .from }} {{ .to | join " " }} {
      {{- if .except | len | lt 0 }}
        except {{ .except | join " " }}
      {{- end }}
      {{- if .force_tcp }}
        force_tcp
      {{- end }}
      {{ if .prefer_udp }}
        prefer_udp
      {{- end }}
        max_fails {{ .max_fails | default 2 }}
        expire {{ .expire | default "10s" }}
      {{- if .tls }}
        tls {{ .tls.cert_file }} {{ .tls.key_file }} {{ .tls.ca_file }}
      {{- end }}
      {{- if .tls_servername }}
        tls_servername {{ .tls_servername }}
      {{- end }}
      {{- if .policy }}
        policy {{ .policy }}
      {{- end }}
      {{- if .health_check }}
        health_check {{ .health_check }}
      {{- end }}
      {{- if .max_concurrent }}
        max_concurrent {{ .max_concurrent }}
      {{- end }}
      }
    {{- end }}

    {{- if $.kubernetes.coredns.dns_etc_hosts | len | lt 0 }}
      hosts /etc/coredns/hosts {
        fallthrough
      }
    {{- end }}
    }
  {{- end }}

    {{ .kubernetes.networking.dns_domain }}:53 {
      errors
      cache {
         success 9984 30
          denial 9984 5
      }
      reload
      loop
      bind 169.254.25.10
      forward . {{ .kubernetes.networking.dns_service_ip }} {
        force_tcp
      }
      prometheus :9253
      health 169.254.25.10:9254
    }
    in-addr.arpa:53 {
      errors
      cache 30
      reload
      loop
      bind 169.254.25.10
      forward . {{ .kubernetes.networking.dns_service_ip }} {
        force_tcp
      }
      prometheus :9253
    }
    ip6.arpa:53 {
      errors
      cache 30
      reload
      loop
      bind 169.254.25.10
      forward . {{ .kubernetes.networking.dns_service_ip }} {
          force_tcp
      }
      prometheus :9253
    }
    .:53 {
      errors
      cache 30
      reload
      loop
      bind 169.254.25.10
      forward . /etc/resolv.conf
      prometheus :9253
    {{- if .kubernetes.coredns.dns_etc_hosts | len | lt 0 }}
      hosts /etc/coredns/hosts {
        fallthrough
      }
    {{- end }}
    }

{{- if .kubernetes.coredns.dns_etc_hosts | len | lt 0 }}
  hosts: |
  {{- range .kubernetes.coredns.dns_etc_hosts }}
    {{ . }}
  {{- end }}
{{- end }}
