Merge branch 'master' of https://github.com/silenium-dev/postgres-operator into silenium-dev-master
This commit is contained in:
		
						commit
						43bbe615d8
					
				
							
								
								
									
										21
									
								
								docs/user.md
								
								
								
								
							
							
						
						
									
										21
									
								
								docs/user.md
								
								
								
								
							|  | @ -690,6 +690,27 @@ manifest the operator will raise the limits to the configured minimum values. | ||||||
| If no resources are defined in the manifest they will be obtained from the | If no resources are defined in the manifest they will be obtained from the | ||||||
| configured [default requests](reference/operator_parameters.md#kubernetes-resource-requests). | configured [default requests](reference/operator_parameters.md#kubernetes-resource-requests). | ||||||
| 
 | 
 | ||||||
|  | ### HugePages support | ||||||
|  | 
 | ||||||
|  | The operator supports [HugePages](https://www.postgresql.org/docs/15/kernel-resources.html#LINUX-HUGEPAGES). | ||||||
|  | To enable HugePages, set the matching resource requests and/or limits in the manifest: | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | spec: | ||||||
|  |   resources: | ||||||
|  |     requests: | ||||||
|  |       hugepages-2Mi: 250Mi | ||||||
|  |       hugepages-1Gi: 1Gi | ||||||
|  |     limits: | ||||||
|  |       hugepages-2Mi: 500Mi | ||||||
|  |       hugepages-1Gi: 2Gi | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | There are no minimums or maximums and the default is 0 for both HugePage sizes, | ||||||
|  | but Kubernetes will not spin up the pod if the requested HugePages cannot be allocated. | ||||||
|  | For more information on HugePages in Kubernetes, see also | ||||||
|  | [https://kubernetes.io/docs/tasks/manage-hugepages/scheduling-hugepages/](https://kubernetes.io/docs/tasks/manage-hugepages/scheduling-hugepages/) | ||||||
|  | 
 | ||||||
| ## Use taints, tolerations and node affinity for dedicated PostgreSQL nodes | ## Use taints, tolerations and node affinity for dedicated PostgreSQL nodes | ||||||
| 
 | 
 | ||||||
| To ensure Postgres pods are running on nodes without any other application pods, | To ensure Postgres pods are running on nodes without any other application pods, | ||||||
|  |  | ||||||
|  | @ -439,6 +439,12 @@ spec: | ||||||
|                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' |                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' | ||||||
|                         # Note: the value specified here must not be zero or be higher |                         # Note: the value specified here must not be zero or be higher | ||||||
|                         # than the corresponding limit. |                         # than the corresponding limit. | ||||||
|  |                       hugepages-2Mi: | ||||||
|  |                         type: string | ||||||
|  |                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' | ||||||
|  |                       hugepages-1Gi: | ||||||
|  |                         type: string | ||||||
|  |                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' | ||||||
|                   requests: |                   requests: | ||||||
|                     type: object |                     type: object | ||||||
|                     properties: |                     properties: | ||||||
|  | @ -448,6 +454,12 @@ spec: | ||||||
|                       memory: |                       memory: | ||||||
|                         type: string |                         type: string | ||||||
|                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' |                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' | ||||||
|  |                       hugepages-2Mi: | ||||||
|  |                         type: string | ||||||
|  |                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' | ||||||
|  |                       hugepages-1Gi: | ||||||
|  |                         type: string | ||||||
|  |                         pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' | ||||||
|               schedulerName: |               schedulerName: | ||||||
|                 type: string |                 type: string | ||||||
|               serviceAnnotations: |               serviceAnnotations: | ||||||
|  |  | ||||||
|  | @ -3,10 +3,11 @@ package v1 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	acidzalando "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do" |  | ||||||
| 	"github.com/zalando/postgres-operator/pkg/util" |  | ||||||
| 	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" | 	apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
|  | 
 | ||||||
|  | 	acidzalando "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do" | ||||||
|  | 	"github.com/zalando/postgres-operator/pkg/util" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // CRDResource* define names necesssary for the k8s CRD API
 | // CRDResource* define names necesssary for the k8s CRD API
 | ||||||
|  | @ -684,6 +685,14 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{ | ||||||
| 										Type:    "string", | 										Type:    "string", | ||||||
| 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | ||||||
| 									}, | 									}, | ||||||
|  | 									"hugepages-2Mi": { | ||||||
|  | 										Type:    "string", | ||||||
|  | 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | ||||||
|  | 									}, | ||||||
|  | 									"hugepages-1Gi": { | ||||||
|  | 										Type:    "string", | ||||||
|  | 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | ||||||
|  | 									}, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 							"requests": { | 							"requests": { | ||||||
|  | @ -697,6 +706,14 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{ | ||||||
| 										Type:    "string", | 										Type:    "string", | ||||||
| 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | ||||||
| 									}, | 									}, | ||||||
|  | 									"hugepages-2Mi": { | ||||||
|  | 										Type:    "string", | ||||||
|  | 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | ||||||
|  | 									}, | ||||||
|  | 									"hugepages-1Gi": { | ||||||
|  | 										Type:    "string", | ||||||
|  | 										Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$", | ||||||
|  | 									}, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  |  | ||||||
|  | @ -153,8 +153,10 @@ type PostgresqlParam struct { | ||||||
| 
 | 
 | ||||||
| // ResourceDescription describes CPU and memory resources defined for a cluster.
 | // ResourceDescription describes CPU and memory resources defined for a cluster.
 | ||||||
| type ResourceDescription struct { | type ResourceDescription struct { | ||||||
| 	CPU    string `json:"cpu"` | 	CPU          string `json:"cpu"` | ||||||
| 	Memory string `json:"memory"` | 	Memory       string `json:"memory"` | ||||||
|  | 	HugePages2Mi string `json:"hugepages-2Mi"` | ||||||
|  | 	HugePages1Gi string `json:"hugepages-1Gi"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Resources describes requests and limits for the cluster resouces.
 | // Resources describes requests and limits for the cluster resouces.
 | ||||||
|  |  | ||||||
|  | @ -20,6 +20,10 @@ import ( | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	"k8s.io/apimachinery/pkg/util/intstr" | 	"k8s.io/apimachinery/pkg/util/intstr" | ||||||
| 
 | 
 | ||||||
|  | 	"golang.org/x/exp/maps" | ||||||
|  | 	batchv1 "k8s.io/api/batch/v1" | ||||||
|  | 	"k8s.io/apimachinery/pkg/labels" | ||||||
|  | 
 | ||||||
| 	acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" | 	acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" | ||||||
| 	"github.com/zalando/postgres-operator/pkg/spec" | 	"github.com/zalando/postgres-operator/pkg/spec" | ||||||
| 	"github.com/zalando/postgres-operator/pkg/util" | 	"github.com/zalando/postgres-operator/pkg/util" | ||||||
|  | @ -28,9 +32,6 @@ import ( | ||||||
| 	"github.com/zalando/postgres-operator/pkg/util/k8sutil" | 	"github.com/zalando/postgres-operator/pkg/util/k8sutil" | ||||||
| 	"github.com/zalando/postgres-operator/pkg/util/patroni" | 	"github.com/zalando/postgres-operator/pkg/util/patroni" | ||||||
| 	"github.com/zalando/postgres-operator/pkg/util/retryutil" | 	"github.com/zalando/postgres-operator/pkg/util/retryutil" | ||||||
| 	"golang.org/x/exp/maps" |  | ||||||
| 	batchv1 "k8s.io/api/batch/v1" |  | ||||||
| 	"k8s.io/apimachinery/pkg/labels" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -267,6 +268,19 @@ func fillResourceList(spec acidv1.ResourceDescription, defaults acidv1.ResourceD | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if spec.HugePages2Mi != "" { | ||||||
|  | 		requests[v1.ResourceHugePagesPrefix+"2Mi"], err = resource.ParseQuantity(spec.HugePages2Mi) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("could not parse hugepages-2Mi quantity: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if spec.HugePages1Gi != "" { | ||||||
|  | 		requests[v1.ResourceHugePagesPrefix+"1Gi"], err = resource.ParseQuantity(spec.HugePages1Gi) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("could not parse hugepages-1Gi quantity: %v", err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return requests, nil | 	return requests, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,9 +5,8 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"time" |  | ||||||
| 
 |  | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| 
 | 
 | ||||||
|  | @ -2979,6 +2978,131 @@ func TestGenerateResourceRequirements(t *testing.T) { | ||||||
| 				ResourceLimits:   acidv1.ResourceDescription{CPU: "1", Memory: "2Gi"}, | 				ResourceLimits:   acidv1.ResourceDescription{CPU: "1", Memory: "2Gi"}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			subTest: "test HugePages are not set on container when not requested in manifest", | ||||||
|  | 			config: config.Config{ | ||||||
|  | 				Resources:           configResources, | ||||||
|  | 				PodManagementPolicy: "ordered_ready", | ||||||
|  | 			}, | ||||||
|  | 			pgSpec: acidv1.Postgresql{ | ||||||
|  | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 					Name:      clusterName, | ||||||
|  | 					Namespace: namespace, | ||||||
|  | 				}, | ||||||
|  | 				Spec: acidv1.PostgresSpec{ | ||||||
|  | 					Resources: &acidv1.Resources{ | ||||||
|  | 						ResourceRequests: acidv1.ResourceDescription{}, | ||||||
|  | 						ResourceLimits:   acidv1.ResourceDescription{}, | ||||||
|  | 					}, | ||||||
|  | 					TeamID: "acid", | ||||||
|  | 					Volume: acidv1.Volume{ | ||||||
|  | 						Size: "1G", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResources: acidv1.Resources{ | ||||||
|  | 				ResourceRequests: acidv1.ResourceDescription{ | ||||||
|  | 					CPU:    "100m", | ||||||
|  | 					Memory: "100Mi", | ||||||
|  | 				}, | ||||||
|  | 				ResourceLimits: acidv1.ResourceDescription{ | ||||||
|  | 					CPU:    "1", | ||||||
|  | 					Memory: "500Mi", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			subTest: "test HugePages are passed through to the postgres container", | ||||||
|  | 			config: config.Config{ | ||||||
|  | 				Resources:           configResources, | ||||||
|  | 				PodManagementPolicy: "ordered_ready", | ||||||
|  | 			}, | ||||||
|  | 			pgSpec: acidv1.Postgresql{ | ||||||
|  | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 					Name:      clusterName, | ||||||
|  | 					Namespace: namespace, | ||||||
|  | 				}, | ||||||
|  | 				Spec: acidv1.PostgresSpec{ | ||||||
|  | 					Resources: &acidv1.Resources{ | ||||||
|  | 						ResourceRequests: acidv1.ResourceDescription{ | ||||||
|  | 							HugePages2Mi: "128Mi", | ||||||
|  | 							HugePages1Gi: "1Gi", | ||||||
|  | 						}, | ||||||
|  | 						ResourceLimits: acidv1.ResourceDescription{ | ||||||
|  | 							HugePages2Mi: "256Mi", | ||||||
|  | 							HugePages1Gi: "2Gi", | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 					TeamID: "acid", | ||||||
|  | 					Volume: acidv1.Volume{ | ||||||
|  | 						Size: "1G", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResources: acidv1.Resources{ | ||||||
|  | 				ResourceRequests: acidv1.ResourceDescription{ | ||||||
|  | 					CPU:          "100m", | ||||||
|  | 					Memory:       "100Mi", | ||||||
|  | 					HugePages2Mi: "128Mi", | ||||||
|  | 					HugePages1Gi: "1Gi", | ||||||
|  | 				}, | ||||||
|  | 				ResourceLimits: acidv1.ResourceDescription{ | ||||||
|  | 					CPU:          "1", | ||||||
|  | 					Memory:       "500Mi", | ||||||
|  | 					HugePages2Mi: "256Mi", | ||||||
|  | 					HugePages1Gi: "2Gi", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			subTest: "test HugePages are passed through on sidecars", | ||||||
|  | 			config: config.Config{ | ||||||
|  | 				Resources:           configResources, | ||||||
|  | 				PodManagementPolicy: "ordered_ready", | ||||||
|  | 			}, | ||||||
|  | 			pgSpec: acidv1.Postgresql{ | ||||||
|  | 				ObjectMeta: metav1.ObjectMeta{ | ||||||
|  | 					Name:      clusterName, | ||||||
|  | 					Namespace: namespace, | ||||||
|  | 				}, | ||||||
|  | 				Spec: acidv1.PostgresSpec{ | ||||||
|  | 					Sidecars: []acidv1.Sidecar{ | ||||||
|  | 						{ | ||||||
|  | 							Name:        "test-sidecar", | ||||||
|  | 							DockerImage: "test-image", | ||||||
|  | 							Resources: &acidv1.Resources{ | ||||||
|  | 								ResourceRequests: acidv1.ResourceDescription{ | ||||||
|  | 									HugePages2Mi: "128Mi", | ||||||
|  | 									HugePages1Gi: "1Gi", | ||||||
|  | 								}, | ||||||
|  | 								ResourceLimits: acidv1.ResourceDescription{ | ||||||
|  | 									HugePages2Mi: "256Mi", | ||||||
|  | 									HugePages1Gi: "2Gi", | ||||||
|  | 								}, | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 					TeamID: "acid", | ||||||
|  | 					Volume: acidv1.Volume{ | ||||||
|  | 						Size: "1G", | ||||||
|  | 					}, | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			expectedResources: acidv1.Resources{ | ||||||
|  | 				ResourceRequests: acidv1.ResourceDescription{ | ||||||
|  | 					CPU:          "100m", | ||||||
|  | 					Memory:       "100Mi", | ||||||
|  | 					HugePages2Mi: "128Mi", | ||||||
|  | 					HugePages1Gi: "1Gi", | ||||||
|  | 				}, | ||||||
|  | 				ResourceLimits: acidv1.ResourceDescription{ | ||||||
|  | 					CPU:          "1", | ||||||
|  | 					Memory:       "500Mi", | ||||||
|  | 					HugePages2Mi: "256Mi", | ||||||
|  | 					HugePages1Gi: "2Gi", | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, tt := range tests { | 	for _, tt := range tests { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue