diff --git a/chart/templates/_affinity.yaml b/chart/templates/_affinity.yaml new file mode 100644 index 0000000000000..cd6b92a021884 --- /dev/null +++ b/chart/templates/_affinity.yaml @@ -0,0 +1,22 @@ +{{- define "pod-affinity" }} +affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ .Label }} + operator: In + values: + - {{ .Component }} + topologyKey: failure-domain.beta.kubernetes.io/zone + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: {{ .Label }} + operator: In + values: + - {{ .Component }} + topologyKey: kubernetes.io/hostname +{{- end }} diff --git a/chart/templates/controller.yaml b/chart/templates/controller.yaml index a3fb4697cbd13..874271261600c 100644 --- a/chart/templates/controller.yaml +++ b/chart/templates/controller.yaml @@ -131,4 +131,8 @@ spec: - name: config configMap: name: linkerd-config + {{- if .HighAvailability }} + {{- $local := dict "Label" .ControllerComponentLabel "Component" "controller" }} + {{- include "pod-affinity" $local | nindent 6 }} + {{- end }} {{end -}} diff --git a/chart/templates/identity.yaml b/chart/templates/identity.yaml index e731f36a3627f..62110c7158f35 100644 --- a/chart/templates/identity.yaml +++ b/chart/templates/identity.yaml @@ -101,6 +101,10 @@ spec: name: linkerd-config - name: identity-issuer secret: - secretName: linkerd-identity-issuer + secretName: linkerd-identity-issuer + {{- if .HighAvailability }} + {{- $local := dict "Label" .ControllerComponentLabel "Component" "identity" }} + {{- include "pod-affinity" $local | nindent 6 }} + {{- end }} {{end -}} {{end -}} diff --git a/chart/templates/proxy_injector.yaml b/chart/templates/proxy_injector.yaml index 81c3eb32285b1..ce50f1d8edc17 100644 --- a/chart/templates/proxy_injector.yaml +++ b/chart/templates/proxy_injector.yaml @@ -67,6 +67,11 @@ spec: - name: tls secret: secretName: linkerd-proxy-injector-tls + {{- if .HighAvailability }} + {{- $local := dict "Label" .ControllerComponentLabel "Component" "proxy-injector" }} + {{- include "pod-affinity" $local | nindent 6 }} + {{- end }} + --- kind: Service apiVersion: v1 diff --git a/chart/templates/sp_validator.yaml b/chart/templates/sp_validator.yaml index 3837753c33940..c7c4cd35a6e22 100644 --- a/chart/templates/sp_validator.yaml +++ b/chart/templates/sp_validator.yaml @@ -81,4 +81,8 @@ spec: - name: tls secret: secretName: linkerd-sp-validator-tls + {{- if .HighAvailability }} + {{- $local := dict "Label" .ControllerComponentLabel "Component" "sp-validator" }} + {{- include "pod-affinity" $local | nindent 6 }} + {{- end }} {{end -}} diff --git a/chart/templates/tap.yaml b/chart/templates/tap.yaml index 6db30bbfe8c9e..2ddd8a71bc040 100644 --- a/chart/templates/tap.yaml +++ b/chart/templates/tap.yaml @@ -71,4 +71,8 @@ spec: {{ end -}} securityContext: runAsUser: {{.ControllerUID}} + {{- if .HighAvailability }} + {{- $local := dict "Label" .ControllerComponentLabel "Component" "tap" }} + {{- include "pod-affinity" $local | nindent 6 }} + {{- end }} {{end -}} diff --git a/cli/cmd/install.go b/cli/cmd/install.go index a7533904cac5f..49fffbf240fa0 100644 --- a/cli/cmd/install.go +++ b/cli/cmd/install.go @@ -57,6 +57,7 @@ type ( LinkerdNamespaceLabel string ControllerUID int64 EnableH2Upgrade bool + HighAvailability bool NoInitContainer bool WebhookFailurePolicy string OmitWebhookSideEffects bool @@ -606,6 +607,7 @@ func (options *installOptions) buildValuesWithoutIdentity(configs *pb.All) (*ins ControllerReplicas: options.controllerReplicas, ControllerLogLevel: options.controllerLogLevel, ControllerUID: options.controllerUID, + HighAvailability: options.highAvailability, EnableH2Upgrade: !options.disableH2Upgrade, NoInitContainer: options.noInitContainer, WebhookFailurePolicy: "Ignore", @@ -701,6 +703,7 @@ func (values *installValues) render(w io.Writer, configs *pb.All) error { if values.stage == "" || values.stage == controlPlaneStage { files = append(files, []*chartutil.BufferedFile{ {Name: "templates/_resources.yaml"}, + {Name: "templates/_affinity.yaml"}, {Name: "templates/config.yaml"}, {Name: "templates/identity.yaml"}, {Name: "templates/controller.yaml"}, diff --git a/cli/cmd/testdata/install_ha_output.golden b/cli/cmd/testdata/install_ha_output.golden index 67171199adbd9..d70537f32a8a8 100644 --- a/cli/cmd/testdata/install_ha_output.golden +++ b/cli/cmd/testdata/install_ha_output.golden @@ -702,6 +702,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-identity spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - identity + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - identity + topologyKey: kubernetes.io/hostname containers: - args: - identity @@ -936,6 +956,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-controller spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - controller + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname containers: - args: - public-api @@ -1965,6 +2005,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-proxy-injector spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - proxy-injector + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - proxy-injector + topologyKey: kubernetes.io/hostname containers: - args: - proxy-injector @@ -2203,6 +2263,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-sp-validator spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - sp-validator + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - sp-validator + topologyKey: kubernetes.io/hostname containers: - args: - sp-validator @@ -2414,6 +2494,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-tap spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - tap + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - tap + topologyKey: kubernetes.io/hostname containers: - args: - tap diff --git a/cli/cmd/testdata/install_ha_with_overrides_output.golden b/cli/cmd/testdata/install_ha_with_overrides_output.golden index f599b8fe0a99e..f81f61073ccd9 100644 --- a/cli/cmd/testdata/install_ha_with_overrides_output.golden +++ b/cli/cmd/testdata/install_ha_with_overrides_output.golden @@ -702,6 +702,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-identity spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - identity + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - identity + topologyKey: kubernetes.io/hostname containers: - args: - identity @@ -936,6 +956,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-controller spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - controller + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname containers: - args: - public-api @@ -1965,6 +2005,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-proxy-injector spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - proxy-injector + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - proxy-injector + topologyKey: kubernetes.io/hostname containers: - args: - proxy-injector @@ -2203,6 +2263,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-sp-validator spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - sp-validator + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - sp-validator + topologyKey: kubernetes.io/hostname containers: - args: - sp-validator @@ -2414,6 +2494,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-tap spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - tap + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - tap + topologyKey: kubernetes.io/hostname containers: - args: - tap diff --git a/cli/cmd/testdata/upgrade_ha.golden b/cli/cmd/testdata/upgrade_ha.golden index b5a07fefe94a2..6f8a7450247ef 100644 --- a/cli/cmd/testdata/upgrade_ha.golden +++ b/cli/cmd/testdata/upgrade_ha.golden @@ -702,6 +702,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-identity spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - identity + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - identity + topologyKey: kubernetes.io/hostname containers: - args: - identity @@ -937,6 +957,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-controller spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - controller + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - controller + topologyKey: kubernetes.io/hostname containers: - args: - public-api @@ -1970,6 +2010,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-proxy-injector spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - proxy-injector + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - proxy-injector + topologyKey: kubernetes.io/hostname containers: - args: - proxy-injector @@ -2209,6 +2269,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-sp-validator spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - sp-validator + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - sp-validator + topologyKey: kubernetes.io/hostname containers: - args: - sp-validator @@ -2421,6 +2501,26 @@ spec: linkerd.io/control-plane-ns: linkerd linkerd.io/proxy-deployment: linkerd-tap spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - tap + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: linkerd.io/control-plane-component + operator: In + values: + - tap + topologyKey: kubernetes.io/hostname containers: - args: - tap