diff --git a/api/config/v1alpha1/shared_types.go b/api/config/v1alpha1/shared_types.go index 129c705fd33..9bff59ab0fc 100644 --- a/api/config/v1alpha1/shared_types.go +++ b/api/config/v1alpha1/shared_types.go @@ -75,6 +75,14 @@ type KubernetesPodSpec struct { // // +optional SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + + // If specified, the pod's scheduling constraints. + // +optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + + // If specified, the pod's tolerations. + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` } // KubernetesContainerSpec defines the desired state of the Kubernetes container resource. diff --git a/api/config/v1alpha1/zz_generated.deepcopy.go b/api/config/v1alpha1/zz_generated.deepcopy.go index 940857266c3..ed36cc74ff2 100644 --- a/api/config/v1alpha1/zz_generated.deepcopy.go +++ b/api/config/v1alpha1/zz_generated.deepcopy.go @@ -478,6 +478,18 @@ func (in *KubernetesPodSpec) DeepCopyInto(out *KubernetesPodSpec) { *out = new(v1.PodSecurityContext) (*in).DeepCopyInto(*out) } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(v1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesPodSpec. diff --git a/charts/gateway-helm/crds/generated/config.gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/config.gateway.envoyproxy.io_envoyproxies.yaml index 4c34a053343..c6d1808e0f1 100644 --- a/charts/gateway-helm/crds/generated/config.gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/config.gateway.envoyproxy.io_envoyproxies.yaml @@ -479,6 +479,1041 @@ spec: description: Pod defines the desired annotations and securityContext of container. properties: + affinity: + description: If specified, the pod's scheduling constraints. + properties: + nodeAffinity: + description: Describes node affinity scheduling + rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to + schedule pods to nodes that satisfy the + affinity expressions specified by this field, + but it may choose a node that violates one + or more of the expressions. The node that + is most preferred is the one with the greatest + sum of weights, i.e. for each node that + meets all of the scheduling requirements + (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum + by iterating through the elements of this + field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the + most preferred. + items: + description: An empty preferred scheduling + term matches all objects with implicit + weight 0 (i.e. it's a no-op). A null preferred + scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: A node selector requirement + is a selector that contains + values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: Represents a + key's relationship to a + set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string + values. If the operator + is In or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the values + array must be empty. If + the operator is Gt or Lt, + the values array must have + a single element, which + will be interpreted as an + integer. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: A node selector requirement + is a selector that contains + values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: Represents a + key's relationship to a + set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string + values. If the operator + is In or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the values + array must be empty. If + the operator is Gt or Lt, + the values array must have + a single element, which + will be interpreted as an + integer. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with + matching the corresponding nodeSelectorTerm, + in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements + specified by this field are not met at scheduling + time, the pod will not be scheduled onto + the node. If the affinity requirements specified + by this field cease to be met at some point + during pod execution (e.g. due to an update), + the system may or may not try to eventually + evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node + selector terms. The terms are ORed. + items: + description: A null or empty node selector + term matches no objects. The requirements + of them are ANDed. The TopologySelectorTerm + type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: A node selector requirement + is a selector that contains + values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: Represents a + key's relationship to a + set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string + values. If the operator + is In or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the values + array must be empty. If + the operator is Gt or Lt, + the values array must have + a single element, which + will be interpreted as an + integer. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: A node selector requirement + is a selector that contains + values, a key, and an operator + that relates the key and values. + properties: + key: + description: The label key + that the selector applies + to. + type: string + operator: + description: Represents a + key's relationship to a + set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string + values. If the operator + is In or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the values + array must be empty. If + the operator is Gt or Lt, + the values array must have + a single element, which + will be interpreted as an + integer. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling + rules (e.g. co-locate this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to + schedule pods to nodes that satisfy the + affinity expressions specified by this field, + but it may choose a node that violates one + or more of the expressions. The node that + is most preferred is the one with the greatest + sum of weights, i.e. for each node that + meets all of the scheduling requirements + (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum + by iterating through the elements of this + field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest + sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: A label query over + a set of resources, in this case + pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: A label selector + requirement is a selector + that contains values, a + key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: operator + represents a key's relationship + to a set of values. + Valid operators are + In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is + an array of string values. + If the operator is In + or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the + values array must be + empty. This array is + replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is + a map of {key,value} pairs. + A single {key,value} in the + matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", + the operator is "In", and + the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over + the set of namespaces that the + term applies to. The term is applied + to the union of the namespaces + selected by this field and the + ones listed in the namespaces + field. null selector and null + or empty namespaces list means + "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: A label selector + requirement is a selector + that contains values, a + key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: operator + represents a key's relationship + to a set of values. + Valid operators are + In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is + an array of string values. + If the operator is In + or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the + values array must be + empty. This array is + replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is + a map of {key,value} pairs. + A single {key,value} in the + matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", + the operator is "In", and + the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies + a static list of namespace names + that the term applies to. The + term is applied to the union of + the namespaces listed in this + field and the ones selected by + namespaceSelector. null or empty + namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be + co-located (affinity) or not co-located + (anti-affinity) with the pods + matching the labelSelector in + the specified namespaces, where + co-located is defined as running + on a node whose value of the label + with key topologyKey matches that + of any node on which any of the + selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with + matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements + specified by this field are not met at scheduling + time, the pod will not be scheduled onto + the node. If the affinity requirements specified + by this field cease to be met at some point + during pod execution (e.g. due to a pod + label update), the system may or may not + try to eventually evict the pod from its + node. When there are multiple elements, + the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all + terms must be satisfied. + items: + description: Defines a set of pods (namely + those matching the labelSelector relative + to the given namespace(s)) that this pod + should be co-located (affinity) or not + co-located (anti-affinity) with, where + co-located is defined as running on a + node whose value of the label with key + matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set + of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the + set of namespaces that the term applies + to. The term is applied to the union + of the namespaces selected by this + field and the ones listed in the namespaces + field. null selector and null or empty + namespaces list means "this pod's + namespace". An empty selector ({}) + matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a + static list of namespace names that + the term applies to. The term is applied + to the union of the namespaces listed + in this field and the ones selected + by namespaceSelector. null or empty + namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where + co-located is defined as running on + a node whose value of the label with + key topologyKey matches that of any + node on which any of the selected + pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same + node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to + schedule pods to nodes that satisfy the + anti-affinity expressions specified by this + field, but it may choose a node that violates + one or more of the expressions. The node + that is most preferred is the one with the + greatest sum of weights, i.e. for each node + that meets all of the scheduling requirements + (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute + a sum by iterating through the elements + of this field and adding "weight" to the + sum if the node has pods which matches the + corresponding podAffinityTerm; the node(s) + with the highest sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added + per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity + term, associated with the corresponding + weight. + properties: + labelSelector: + description: A label query over + a set of resources, in this case + pods. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: A label selector + requirement is a selector + that contains values, a + key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: operator + represents a key's relationship + to a set of values. + Valid operators are + In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is + an array of string values. + If the operator is In + or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the + values array must be + empty. This array is + replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is + a map of {key,value} pairs. + A single {key,value} in the + matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", + the operator is "In", and + the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over + the set of namespaces that the + term applies to. The term is applied + to the union of the namespaces + selected by this field and the + ones listed in the namespaces + field. null selector and null + or empty namespaces list means + "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions + is a list of label selector + requirements. The requirements + are ANDed. + items: + description: A label selector + requirement is a selector + that contains values, a + key, and an operator that + relates the key and values. + properties: + key: + description: key is the + label key that the selector + applies to. + type: string + operator: + description: operator + represents a key's relationship + to a set of values. + Valid operators are + In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is + an array of string values. + If the operator is In + or NotIn, the values + array must be non-empty. + If the operator is Exists + or DoesNotExist, the + values array must be + empty. This array is + replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is + a map of {key,value} pairs. + A single {key,value} in the + matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", + the operator is "In", and + the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies + a static list of namespace names + that the term applies to. The + term is applied to the union of + the namespaces listed in this + field and the ones selected by + namespaceSelector. null or empty + namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be + co-located (affinity) or not co-located + (anti-affinity) with the pods + matching the labelSelector in + the specified namespaces, where + co-located is defined as running + on a node whose value of the label + with key topologyKey matches that + of any node on which any of the + selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with + matching the corresponding podAffinityTerm, + in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements + specified by this field are not met at scheduling + time, the pod will not be scheduled onto + the node. If the anti-affinity requirements + specified by this field cease to be met + at some point during pod execution (e.g. + due to a pod label update), the system may + or may not try to eventually evict the pod + from its node. When there are multiple elements, + the lists of nodes corresponding to each + podAffinityTerm are intersected, i.e. all + terms must be satisfied. + items: + description: Defines a set of pods (namely + those matching the labelSelector relative + to the given namespace(s)) that this pod + should be co-located (affinity) or not + co-located (anti-affinity) with, where + co-located is defined as running on a + node whose value of the label with key + matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set + of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the + set of namespaces that the term applies + to. The term is applied to the union + of the namespaces selected by this + field and the ones listed in the namespaces + field. null selector and null or empty + namespaces list means "this pod's + namespace". An empty selector ({}) + matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a + static list of namespace names that + the term applies to. The term is applied + to the union of the namespaces listed + in this field and the ones selected + by namespaceSelector. null or empty + namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where + co-located is defined as running on + a node whose value of the label with + key topologyKey matches that of any + node on which any of the selected + pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object annotations: additionalProperties: type: string @@ -688,6 +1723,53 @@ spec: type: string type: object type: object + tolerations: + description: If specified, the pod's tolerations. + items: + description: The pod this Toleration is attached + to tolerates any taint that matches the triple + using the matching operator + . + properties: + effect: + description: Effect indicates the taint effect + to match. Empty means match all taint effects. + When specified, allowed values are NoSchedule, + PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; + this combination means to match all values + and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and + Equal. Defaults to Equal. Exists is equivalent + to wildcard for value, so that a pod can tolerate + all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the + period of time the toleration (which must + be of effect NoExecute, otherwise this field + is ignored) tolerates the taint. By default, + it is not set, which means tolerate the taint + forever (do not evict). Zero and negative + values will be treated as 0 (evict immediately) + by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the + value should be empty, otherwise just a regular + string. + type: string + type: object + type: array type: object replicas: description: Replicas is the number of desired pods. Defaults diff --git a/docs/latest/api/config_types.md b/docs/latest/api/config_types.md index b3648050bc2..4d8d599a33f 100644 --- a/docs/latest/api/config_types.md +++ b/docs/latest/api/config_types.md @@ -297,6 +297,8 @@ _Appears in:_ | --- | --- | | `annotations` _object (keys:string, values:string)_ | Annotations are the annotations that should be appended to the pods. By default, no pod annotations are appended. | | `securityContext` _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#podsecuritycontext-v1-core)_ | SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field. | +| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#affinity-v1-core)_ | If specified, the pod's scheduling constraints. | +| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#toleration-v1-core) array_ | If specified, the pod's tolerations. | ## KubernetesServiceSpec diff --git a/internal/gatewayapi/testdata/envoyproxy-valid.in.yaml b/internal/gatewayapi/testdata/envoyproxy-valid.in.yaml index d02d956f86d..ced8e16bc11 100644 --- a/internal/gatewayapi/testdata/envoyproxy-valid.in.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-valid.in.yaml @@ -18,7 +18,7 @@ envoyproxy: value: env_a_value - name: env_b value: env_b_name - image: "envoyproxy/gateway:v0.4.0" + image: "envoyproxy/envoy-dev:latest" resources: requests: cpu: 100m @@ -30,6 +30,20 @@ envoyproxy: annotations: key1: val1 key2: val2 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: "router" securityContext: runAsUser: 1000 runAsGroup: 3000 diff --git a/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml b/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml index ca21c891758..d1eb5d7656f 100644 --- a/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-valid.out.yaml @@ -67,7 +67,7 @@ infraIR: value: env_a_value - name: env_b value: env_b_name - image: "envoyproxy/gateway:v0.4.0" + image: "envoyproxy/envoy-dev:latest" resources: requests: cpu: 100m @@ -79,6 +79,20 @@ infraIR: annotations: key1: val1 key2: val2 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: "router" securityContext: runAsUser: 1000 runAsGroup: 3000 diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go index d16f6900bbb..460da025ec8 100644 --- a/internal/infrastructure/kubernetes/proxy/resource_provider.go +++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go @@ -197,6 +197,8 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { RestartPolicy: corev1.RestartPolicyAlways, SchedulerName: "default-scheduler", SecurityContext: deploymentConfig.Pod.SecurityContext, + Affinity: deploymentConfig.Pod.Affinity, + Tolerations: deploymentConfig.Pod.Tolerations, Volumes: []corev1.Volume{ { Name: "certs", diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go index eac73e29c49..bfa392bdfd3 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource_provider.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider.go @@ -148,6 +148,8 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) { RestartPolicy: corev1.RestartPolicyAlways, SchedulerName: "default-scheduler", SecurityContext: r.rateLimitDeployment.Pod.SecurityContext, + Affinity: r.rateLimitDeployment.Pod.Affinity, + Tolerations: r.rateLimitDeployment.Pod.Tolerations, Volumes: []corev1.Volume{ { Name: InfraName, diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/affinity.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/affinity.yaml new file mode 100644 index 00000000000..315af673ec8 --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/affinity.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + name: envoy-ratelimit + namespace: envoy-gateway-system +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + template: + metadata: + labels: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + annotations: + prometheus.io/scrape: "true" + spec: + automountServiceAccountToken: false + containers: + - command: + - /bin/ratelimit + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "true" + image: custom-image + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: http + protocol: TCP + securityContext: + privileged: true + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data/ratelimit/config + name: envoy-ratelimit + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-ratelimit + securityContext: + runAsUser: 1000 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + terminationGracePeriodSeconds: 300 + volumes: + - configMap: + defaultMode: 420 + name: envoy-ratelimit + optional: false + name: envoy-ratelimit diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml index 59c83a242d4..ca1683b94ea 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml @@ -25,47 +25,47 @@ spec: spec: automountServiceAccountToken: false containers: - - command: - - /bin/ratelimit - env: - - name: REDIS_SOCKET_TYPE - value: tcp - - name: REDIS_URL - value: redis.redis.svc:6379 - - name: RUNTIME_ROOT - value: /data - - name: RUNTIME_SUBDIRECTORY - value: ratelimit - - name: RUNTIME_IGNOREDOTFILES - value: "true" - - name: RUNTIME_WATCH_ROOT - value: "false" - - name: LOG_LEVEL - value: info - - name: USE_STATSD - value: "false" - image: custom-image - imagePullPolicy: IfNotPresent + - command: + - /bin/ratelimit + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + image: custom-image + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: http + protocol: TCP + securityContext: + privileged: true + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data/ratelimit/config name: envoy-ratelimit - ports: - - containerPort: 8081 - name: http - protocol: TCP - securityContext: - privileged: true - resources: - limits: - cpu: 400m - memory: 2Gi - requests: - cpu: 200m - memory: 1Gi - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - volumeMounts: - - mountPath: /data/ratelimit/config - name: envoy-ratelimit - readOnly: true + readOnly: true dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -74,8 +74,8 @@ spec: runAsUser: 1000 terminationGracePeriodSeconds: 300 volumes: - - configMap: - defaultMode: 420 - name: envoy-ratelimit - optional: false + - configMap: + defaultMode: 420 name: envoy-ratelimit + optional: false + name: envoy-ratelimit diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml index 59c83a242d4..ca1683b94ea 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml @@ -25,47 +25,47 @@ spec: spec: automountServiceAccountToken: false containers: - - command: - - /bin/ratelimit - env: - - name: REDIS_SOCKET_TYPE - value: tcp - - name: REDIS_URL - value: redis.redis.svc:6379 - - name: RUNTIME_ROOT - value: /data - - name: RUNTIME_SUBDIRECTORY - value: ratelimit - - name: RUNTIME_IGNOREDOTFILES - value: "true" - - name: RUNTIME_WATCH_ROOT - value: "false" - - name: LOG_LEVEL - value: info - - name: USE_STATSD - value: "false" - image: custom-image - imagePullPolicy: IfNotPresent + - command: + - /bin/ratelimit + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + image: custom-image + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: http + protocol: TCP + securityContext: + privileged: true + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data/ratelimit/config name: envoy-ratelimit - ports: - - containerPort: 8081 - name: http - protocol: TCP - securityContext: - privileged: true - resources: - limits: - cpu: 400m - memory: 2Gi - requests: - cpu: 200m - memory: 1Gi - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - volumeMounts: - - mountPath: /data/ratelimit/config - name: envoy-ratelimit - readOnly: true + readOnly: true dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -74,8 +74,8 @@ spec: runAsUser: 1000 terminationGracePeriodSeconds: 300 volumes: - - configMap: - defaultMode: 420 - name: envoy-ratelimit - optional: false + - configMap: + defaultMode: 420 name: envoy-ratelimit + optional: false + name: envoy-ratelimit diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml index 17944a8f2d0..bc59c203290 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml @@ -23,50 +23,50 @@ spec: spec: automountServiceAccountToken: false containers: - - command: - - /bin/ratelimit - env: - - name: REDIS_SOCKET_TYPE - value: tcp - - name: REDIS_URL - value: redis.redis.svc:6379 - - name: RUNTIME_ROOT - value: /data - - name: RUNTIME_SUBDIRECTORY - value: ratelimit - - name: RUNTIME_IGNOREDOTFILES - value: "true" - - name: RUNTIME_WATCH_ROOT - value: "false" - - name: LOG_LEVEL - value: info - - name: USE_STATSD - value: "false" - image: envoyproxy/ratelimit:master - imagePullPolicy: IfNotPresent + - command: + - /bin/ratelimit + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + image: envoyproxy/ratelimit:master + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: http + protocol: TCP + resources: + requests: + cpu: 100m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data/ratelimit/config name: envoy-ratelimit - ports: - - containerPort: 8081 - name: http - protocol: TCP - resources: - requests: - cpu: 100m - memory: 512Mi - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - volumeMounts: - - mountPath: /data/ratelimit/config - name: envoy-ratelimit - readOnly: true + readOnly: true dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler serviceAccountName: envoy-ratelimit terminationGracePeriodSeconds: 300 volumes: - - configMap: - defaultMode: 420 - name: envoy-ratelimit - optional: false + - configMap: + defaultMode: 420 name: envoy-ratelimit + optional: false + name: envoy-ratelimit diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml index 918a6b566bf..ced1c6141f6 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml @@ -25,51 +25,51 @@ spec: spec: automountServiceAccountToken: false containers: - - command: - - /bin/ratelimit - env: - - name: REDIS_SOCKET_TYPE - value: tcp - - name: REDIS_URL - value: redis.redis.svc:6379 - - name: RUNTIME_ROOT - value: /data - - name: RUNTIME_SUBDIRECTORY - value: ratelimit - - name: RUNTIME_IGNOREDOTFILES - value: "true" - - name: RUNTIME_WATCH_ROOT - value: "false" - - name: LOG_LEVEL - value: info - - name: USE_STATSD - value: "false" - - name: env_a - value: env_a_value - - name: env_b - value: env_b_value - image: custom-image - imagePullPolicy: IfNotPresent + - command: + - /bin/ratelimit + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "false" + - name: env_a + value: env_a_value + - name: env_b + value: env_b_value + image: custom-image + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: http + protocol: TCP + securityContext: + privileged: true + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data/ratelimit/config name: envoy-ratelimit - ports: - - containerPort: 8081 - name: http - protocol: TCP - securityContext: - privileged: true - resources: - limits: - cpu: 400m - memory: 2Gi - requests: - cpu: 200m - memory: 1Gi - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - volumeMounts: - - mountPath: /data/ratelimit/config - name: envoy-ratelimit - readOnly: true + readOnly: true dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -78,8 +78,8 @@ spec: runAsUser: 1000 terminationGracePeriodSeconds: 300 volumes: - - configMap: - defaultMode: 420 - name: envoy-ratelimit - optional: false + - configMap: + defaultMode: 420 name: envoy-ratelimit + optional: false + name: envoy-ratelimit diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml index 24ed8e42ff8..66d97a64b1a 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml @@ -25,47 +25,47 @@ spec: spec: automountServiceAccountToken: false containers: - - command: - - /bin/ratelimit - env: - - name: REDIS_SOCKET_TYPE - value: tcp - - name: REDIS_URL - value: redis.redis.svc:6379 - - name: RUNTIME_ROOT - value: /data - - name: RUNTIME_SUBDIRECTORY - value: ratelimit - - name: RUNTIME_IGNOREDOTFILES - value: "true" - - name: RUNTIME_WATCH_ROOT - value: "false" - - name: LOG_LEVEL - value: info - - name: USE_STATSD - value: "true" - image: custom-image - imagePullPolicy: IfNotPresent + - command: + - /bin/ratelimit + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "true" + image: custom-image + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: http + protocol: TCP + securityContext: + privileged: true + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data/ratelimit/config name: envoy-ratelimit - ports: - - containerPort: 8081 - name: http - protocol: TCP - securityContext: - privileged: true - resources: - limits: - cpu: 400m - memory: 2Gi - requests: - cpu: 200m - memory: 1Gi - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - volumeMounts: - - mountPath: /data/ratelimit/config - name: envoy-ratelimit - readOnly: true + readOnly: true dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -74,8 +74,8 @@ spec: runAsUser: 1000 terminationGracePeriodSeconds: 300 volumes: - - configMap: - defaultMode: 420 - name: envoy-ratelimit - optional: false + - configMap: + defaultMode: 420 name: envoy-ratelimit + optional: false + name: envoy-ratelimit diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml new file mode 100644 index 00000000000..d18dec7d312 --- /dev/null +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + name: envoy-ratelimit + namespace: envoy-gateway-system +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + template: + metadata: + labels: + app.kubernetes.io/name: envoy-ratelimit + app.kubernetes.io/component: ratelimit + app.kubernetes.io/managed-by: envoy-gateway + annotations: + prometheus.io/scrape: "true" + spec: + automountServiceAccountToken: false + containers: + - command: + - /bin/ratelimit + env: + - name: REDIS_SOCKET_TYPE + value: tcp + - name: REDIS_URL + value: redis.redis.svc:6379 + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_IGNOREDOTFILES + value: "true" + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: LOG_LEVEL + value: info + - name: USE_STATSD + value: "true" + image: custom-image + imagePullPolicy: IfNotPresent + name: envoy-ratelimit + ports: + - containerPort: 8081 + name: http + protocol: TCP + securityContext: + privileged: true + resources: + limits: + cpu: 400m + memory: 2Gi + requests: + cpu: 200m + memory: 1Gi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data/ratelimit/config + name: envoy-ratelimit + readOnly: true + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + serviceAccountName: envoy-ratelimit + securityContext: + runAsUser: 1000 + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: "router" + terminationGracePeriodSeconds: 300 + volumes: + - configMap: + defaultMode: 420 + name: envoy-ratelimit + optional: false + name: envoy-ratelimit