diff --git a/stable/coredns/Chart.yaml b/stable/coredns/Chart.yaml index 6666e4d873..5ae4954100 100644 --- a/stable/coredns/Chart.yaml +++ b/stable/coredns/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: coredns -version: 1.8.5 +version: 1.9.0 appVersion: 1.6.6 description: CoreDNS is a DNS server that chains plugins and provides Kubernetes DNS Services keywords: diff --git a/stable/coredns/README.md b/stable/coredns/README.md index e0813bb956..7c4292c5b6 100644 --- a/stable/coredns/README.md +++ b/stable/coredns/README.md @@ -67,14 +67,29 @@ The command removes all the Kubernetes components associated with the chart and | `rbac.create` | If true, create & use RBAC resources | true | | `rbac.pspEnable` | Specifies whether a PodSecurityPolicy should be created. | `false` | | `isClusterService` | Specifies whether chart should be deployed as cluster-service or normal k8s app. | true | -| `priorityClassName` | Name of Priority Class to assign pods | `nil` | +| `priorityClassName` | Name of Priority Class to assign pods | `""` | | `servers` | Configuration for CoreDNS and plugins | See values.yml | | `affinity` | Affinity settings for pod assignment | {} | | `nodeSelector` | Node labels for pod assignment | {} | | `tolerations` | Tolerations for pod assignment | [] | | `zoneFiles` | Configure custom Zone files | [] | | `extraSecrets` | Optional array of secrets to mount inside the CoreDNS container | [] | -| `customLabels` | Optional labels for Deployment, Pod, Service, ServiceMonitor objects | {} | +| `customLabels` | Optional labels for Deployment(s), Pod, Service, ServiceMonitor objects | {} | +| `autoscaler.enabled` | Optionally enabled a cluster-proportional-autoscaler for CoreDNS | `false` | +| `autoscaler.coresPerReplica` | Number of cores in the cluster per CoreDNS replica | `256` | +| `autoscaler.nodesPerReplica` | Number of nodes in the cluster per CoreDNS replica | `16` | +| `autoscaler.image.repository` | The image repository to pull autoscaler from | k8s.gcr.io/cluster-proportional-autoscaler-amd64 | +| `autoscaler.image.tag` | The image tag to pull autoscaler from | `1.7.1` | +| `autoscaler.image.pullPolicy` | Image pull policy for the autoscaler | IfNotPresent | +| `autoscaler.priorityClassName` | Optional priority class for the autoscaler pod. `priorityClassName` used if not set. | `""` | +| `autoscaler.affinity` | Affinity settings for pod assignment for autoscaler | {} | +| `autoscaler.nodeSelector` | Node labels for pod assignment for autoscaler | {} | +| `autoscaler.tolerations` | Tolerations for pod assignment for autoscaler | [] | +| `autoscaler.resources.limits.cpu` | Container maximum CPU for cluster-proportional-autoscaler | `20m` | +| `autoscaler.resources.limits.memory` | Container maximum memory for cluster-proportional-autoscaler | `10Mi` | +| `autoscaler.resources.requests.cpu` | Container requested CPU for cluster-proportional-autoscaler | `20m` | +| `autoscaler.resources.requests.memory` | Container requested memory for cluster-proportional-autoscaler | `10Mi` | + See `values.yaml` for configuration notes. Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, ```console @@ -104,3 +119,18 @@ create external loadbalancers with both "TCP" and "UDP" protocols. So When deploying CoreDNS with `serviceType="LoadBalancer"` on such cloud environments, make sure you do not attempt to use both protocols at the same time. + +## Autoscaling + +By setting `autoscaler.enabled = true` a +[cluster-proportional-autoscaler](https://github.com/kubernetes-incubator/cluster-proportional-autoscaler) +will be deployed. This will default to a coredns replica for every 256 cores, or +16 nodes in the cluster. These can be changed with `autoscaler.coresPerReplica` +and `autoscaler.nodesPerReplica`. When cluster is using large nodes (with more +cores), `coresPerReplica` should dominate. If using small nodes, +`nodesPerReplica` should dominate. + +This also creates a ServiceAccount, ClusterRole, and ClusterRoleBinding for +the autoscaler deployment. + +`replicaCount` is ignored if this is enabled. diff --git a/stable/coredns/templates/clusterrole-autoscaler.yaml b/stable/coredns/templates/clusterrole-autoscaler.yaml new file mode 100644 index 0000000000..748c62bf76 --- /dev/null +++ b/stable/coredns/templates/clusterrole-autoscaler.yaml @@ -0,0 +1,35 @@ +{{- if and .Values.autoscaler.enabled .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "coredns.fullname" . }}-autoscaler + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + {{- if .Values.isClusterService }} + k8s-app: {{ .Chart.Name }}-autoscaler + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" + {{- end }} + app.kubernetes.io/name: {{ template "coredns.name" . }}-autoscaler +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels | indent 4 }} +{{- end }} +rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["list","watch"] + - apiGroups: [""] + resources: ["replicationcontrollers/scale"] + verbs: ["get", "update"] + - apiGroups: ["extensions", "apps"] + resources: ["deployments/scale", "replicasets/scale"] + verbs: ["get", "update"] +# Remove the configmaps rule once below issue is fixed: +# kubernetes-incubator/cluster-proportional-autoscaler#16 + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "create"] +{{- end }} diff --git a/stable/coredns/templates/clusterrolebinding-autoscaler.yaml b/stable/coredns/templates/clusterrolebinding-autoscaler.yaml new file mode 100644 index 0000000000..eafb38f9e6 --- /dev/null +++ b/stable/coredns/templates/clusterrolebinding-autoscaler.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.autoscaler.enabled .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "coredns.fullname" . }}-autoscaler + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + {{- if .Values.isClusterService }} + k8s-app: {{ .Chart.Name }}-autoscaler + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" + {{- end }} + app.kubernetes.io/name: {{ template "coredns.name" . }}-autoscaler +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels | indent 4 }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "coredns.fullname" . }}-autoscaler +subjects: +- kind: ServiceAccount + name: {{ template "coredns.fullname" . }}-autoscaler + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/stable/coredns/templates/configmap-autoscaler.yaml b/stable/coredns/templates/configmap-autoscaler.yaml new file mode 100644 index 0000000000..f03cc2a8a2 --- /dev/null +++ b/stable/coredns/templates/configmap-autoscaler.yaml @@ -0,0 +1,30 @@ +{{- if .Values.autoscaler.enabled }} +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: {{ template "coredns.fullname" . }}-autoscaler + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + {{- if .Values.isClusterService }} + k8s-app: {{ .Chart.Name }}-autoscaler + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" + {{- end }} + app.kubernetes.io/name: {{ template "coredns.name" . }}-autoscaler +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels | indent 4 }} +{{- end }} +data: + # When cluster is using large nodes(with more cores), "coresPerReplica" should dominate. + # If using small nodes, "nodesPerReplica" should dominate. + linear: |- + { + "coresPerReplica": {{ .Values.autoscaler.coresPerReplica | float64 }}, + "nodesPerReplica": {{ .Values.autoscaler.nodesPerReplica | float64 }}, + "preventSinglePointFailure": true + } +{{- end }} diff --git a/stable/coredns/templates/deployment-autoscaler.yaml b/stable/coredns/templates/deployment-autoscaler.yaml new file mode 100644 index 0000000000..8ecafb6949 --- /dev/null +++ b/stable/coredns/templates/deployment-autoscaler.yaml @@ -0,0 +1,76 @@ +{{- if .Values.autoscaler.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "coredns.fullname" . }}-autoscaler + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + {{- if .Values.isClusterService }} + k8s-app: {{ .Chart.Name }}-autoscaler + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" + {{- end }} + app.kubernetes.io/name: {{ template "coredns.name" . }}-autoscaler +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels | indent 4 }} +{{- end }} +spec: + selector: + matchLabels: + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- if .Values.isClusterService }} + k8s-app: {{ .Chart.Name }}-autoscaler + {{- end }} + app.kubernetes.io/name: {{ template "coredns.name" . }}-autoscaler + template: + metadata: + labels: + {{- if .Values.isClusterService }} + k8s-app: {{ .Chart.Name }}-autoscaler + {{- end }} + app.kubernetes.io/name: {{ template "coredns.name" . }}-autoscaler + app.kubernetes.io/instance: {{ .Release.Name | quote }} + {{- if .Values.customLabels }} + {{ toYaml .Values.customLabels | nindent 8 }} + {{- end }} + annotations: + {{- if .Values.isClusterService }} + scheduler.alpha.kubernetes.io/critical-pod: '' + scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]' + {{- end }} + spec: + serviceAccountName: {{ template "coredns.fullname" . }}-autoscaler + {{- $priorityClassName := default .Values.priorityClassName .Values.autoscaler.priorityClassName }} + {{- if $priorityClassName }} + priorityClassName: {{ $priorityClassName | quote }} + {{- end }} + {{- if .Values.autoscaler.affinity }} + affinity: +{{ toYaml .Values.autoscaler.affinity | indent 8 }} + {{- end }} + {{- if .Values.autoscaler.tolerations }} + tolerations: +{{ toYaml .Values.autoscaler.tolerations | indent 8 }} + {{- end }} + {{- if .Values.autoscaler.nodeSelector }} + nodeSelector: +{{ toYaml .Values.autoscaler.nodeSelector | indent 8 }} + {{- end }} + containers: + - name: autoscaler + image: "{{ .Values.autoscaler.image.repository }}:{{ .Values.autoscaler.image.tag }}" + imagePullPolicy: {{ .Values.autoscaler.image.pullPolicy }} + resources: +{{ toYaml .Values.autoscaler.resources | indent 10 }} + command: + - /cluster-proportional-autoscaler + - --namespace={{ .Release.Namespace }} + - --configmap={{ template "coredns.fullname" . }}-autoscaler + - --target=Deployment/{{ template "coredns.fullname" . }} + - --logtostderr=true + - --v=2 +{{- end }} diff --git a/stable/coredns/templates/deployment.yaml b/stable/coredns/templates/deployment.yaml index f61c9e31d0..11db35a0f6 100644 --- a/stable/coredns/templates/deployment.yaml +++ b/stable/coredns/templates/deployment.yaml @@ -16,7 +16,14 @@ metadata: {{ toYaml .Values.customLabels | indent 4 }} {{- end }} spec: + {{- if not .Values.autoscaler.enabled }} replicas: {{ .Values.replicaCount }} + {{- end }} + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + maxSurge: 10% selector: matchLabels: app.kubernetes.io/instance: {{ .Release.Name | quote }} diff --git a/stable/coredns/templates/servicemonitor-autoscaler.yaml b/stable/coredns/templates/servicemonitor-autoscaler.yaml new file mode 100644 index 0000000000..08f9540df3 --- /dev/null +++ b/stable/coredns/templates/servicemonitor-autoscaler.yaml @@ -0,0 +1,21 @@ +{{- if .Values.autoscaler.enabled }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "coredns.fullname" . }}-autoscaler + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + {{- if .Values.isClusterService }} + k8s-app: {{ .Chart.Name }}-autoscaler + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" + {{- end }} + app.kubernetes.io/name: {{ template "coredns.name" . }}-autoscaler +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels | indent 4 }} +{{- end }} +{{- end }} diff --git a/stable/coredns/values.yaml b/stable/coredns/values.yaml index ecda7f8588..b250a53950 100644 --- a/stable/coredns/values.yaml +++ b/stable/coredns/values.yaml @@ -51,7 +51,7 @@ rbac: # isClusterService specifies whether chart should be deployed as cluster-service or normal k8s app. isClusterService: true -# Optional priority class to be used for the coredns pods +# Optional priority class to be used for the coredns pods. Used for autoscaler if autoscaler.priorityClassName not set. priorityClassName: "" # Default zone is what Kubernetes recommends: @@ -147,5 +147,43 @@ extraSecrets: [] # - name: some-fancy-secret # mountPath: /etc/wherever -# Custom labels to apply to Deployment, Pod, Service, ServiceMonitor +# Custom labels to apply to Deployment, Pod, Service, ServiceMonitor. Including autoscaler if enabled. customLabels: {} + +## Configue a cluster-proportional-autoscaler for coredns +# See https://github.com/kubernetes-incubator/cluster-proportional-autoscaler +autoscaler: + # Enabled the cluster-proportional-autoscaler + enabled: false + + # Number of cores in the cluster per coredns replica + coresPerReplica: 256 + # Number of nodes in the cluster per coredns replica + nodesPerReplica: 16 + + image: + repository: k8s.gcr.io/cluster-proportional-autoscaler-amd64 + tag: "1.7.1" + pullPolicy: IfNotPresent + + # Optional priority class to be used for the autoscaler pods. priorityClassName used if not set. + priorityClassName: "" + + # expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#affinity-v1-core + affinity: {} + + # Node labels for pod assignment + # Ref: https://kubernetes.io/docs/user-guide/node-selection/ + nodeSelector: {} + + # expects input structure as per specification https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.11/#toleration-v1-core + tolerations: [] + + # resources for autoscaler pod + resources: + requests: + cpu: "20m" + memory: "10Mi" + limits: + cpu: "20m" + memory: "10Mi"