Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add imagePullSecrets option for using a private registry to host the spilo postgres pod #2725

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
11 changes: 11 additions & 0 deletions charts/postgres-operator/crds/postgresqls.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ spec:
# Note: usernames specified here as database owners must be declared in the users key of the spec key.
dockerImage:
type: string
imagePullSecrets:
type: array
nullable: true
description: "Optionally specify an array of imagePullSecrets for the spilo pod"
items:
type: object
required:
- name
properties:
name:
type: string
enableConnectionPooler:
type: boolean
enableReplicaConnectionPooler:
Expand Down
3 changes: 3 additions & 0 deletions charts/postgres-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ configGeneral:
etcd_host: ""
# Spilo docker image
docker_image: ghcr.io/zalando/spilo-16:3.3-p1
# Optionally specify an array of imagePullSecrets for the spilo pod
# image_pull_secrets:
# - myRegistryKeySecretName

# key name for annotation to ignore globally configured instance limits
# ignore_instance_limits_annotation_key: ""
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/cluster_manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ These parameters are grouped directly under the `spec` key in the manifest.
custom Docker image that overrides the **docker_image** operator parameter.
It should be a [Spilo](https://github.com/zalando/spilo) image. Optional.

* **imagePullSecrets**
Specify an array of imagePullSecrets to pull the spilo image (if you want
to pull your own spilo image from a private registry). Optional.

* **schedulerName**
specifies the scheduling profile for database pods. If no value is provided
K8s' `default-scheduler` will be used. Optional.
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/operator_parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ Those are top-level keys, containing both leaf keys and groups.
your own Spilo image from the [github
repository](https://github.com/zalando/spilo).

* **image_pull_secrets**
Specify an array of imagePullSecrets to pull the spilo image (if you
want to pull your own spilo image from a private registry). Optional.

* **sidecar_docker_images**
*deprecated*: use **sidecars** instead. A map of sidecar names to Docker
images to run with Spilo. In case of the name conflict with the definition in
Expand Down
2 changes: 2 additions & 0 deletions manifests/complete-postgres-manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ metadata:
# "delete-clustername": "acid-test-cluster" # can only be deleted when name matches if "delete-clustername" key is configured
spec:
dockerImage: ghcr.io/zalando/spilo-16:3.3-p1
# imagePullSecrets:
# - name: myRegistryKeySecretName
teamId: "acid"
numberOfInstances: 2
users: # Application/Robot users
Expand Down
1 change: 1 addition & 0 deletions manifests/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ data:
# delete_annotation_date_key: delete-date
# delete_annotation_name_key: delete-clustername
docker_image: ghcr.io/zalando/spilo-16:3.3-p1
# image_pull_secrets: "myRegistryKeySecretName,myOtherRegistryKeySecretName"
# downscaler_annotations: "deployment-time,downscaler/*"
enable_admin_role_for_users: "true"
enable_crd_registration: "true"
Expand Down
10 changes: 10 additions & 0 deletions manifests/operatorconfiguration.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ spec:
docker_image:
type: string
default: "ghcr.io/zalando/spilo-16:3.3-p1"
image_pull_secrets:
type: array
nullable: true
items:
type: object
required:
- name
properties:
name:
type: string
enable_crd_registration:
type: boolean
default: true
Expand Down
2 changes: 2 additions & 0 deletions manifests/postgresql-operator-default-configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ metadata:
name: postgresql-operator-default-configuration
configuration:
docker_image: ghcr.io/zalando/spilo-16:3.3-p1
# image_pull_secrets:
# - name: myRegistryKeySecretName
# enable_crd_registration: true
# crd_categories:
# - all
Expand Down
11 changes: 11 additions & 0 deletions manifests/postgresql.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,17 @@ spec:
# Note: usernames specified here as database owners must be declared in the users key of the spec key.
dockerImage:
type: string
imagePullSecrets:
type: array
nullable: true
description: "Optionally specify an array of imagePullSecrets for the spilo pod"
items:
type: object
required:
- name
properties:
name:
type: string
enableConnectionPooler:
type: boolean
enableReplicaConnectionPooler:
Expand Down
16 changes: 16 additions & 0 deletions pkg/apis/acid.zalan.do/v1/crds.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,22 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
"dockerImage": {
Type: "string",
},
"imagePullSecrets": {
Type: "array",
Description: "Optionally specify an array of imagePullSecrets for the spilo pod",
Nullable: true,
Items: &apiextv1.JSONSchemaPropsOrArray{
Schema: &apiextv1.JSONSchemaProps{
Type: "object",
Required: []string{"name"},
Properties: map[string]apiextv1.JSONSchemaProps{
"name": {
Type: "string",
},
},
},
},
},
"enableConnectionPooler": {
Type: "boolean",
},
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/acid.zalan.do/v1/operator_configuration_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ type OperatorConfigurationData struct {
EtcdHost string `json:"etcd_host,omitempty"`
KubernetesUseConfigMaps bool `json:"kubernetes_use_configmaps,omitempty"`
DockerImage string `json:"docker_image,omitempty"`
ImagePullSecrets []string `json:"image_pull_secrets,omitempty"`
Workers uint32 `json:"workers,omitempty"`
ResyncPeriod Duration `json:"resync_period,omitempty"`
RepairPeriod Duration `json:"repair_period,omitempty"`
Expand Down
5 changes: 3 additions & 2 deletions pkg/apis/acid.zalan.do/v1/postgresql_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ type PostgresSpec struct {
EnableReplicaConnectionPooler *bool `json:"enableReplicaConnectionPooler,omitempty"`
ConnectionPooler *ConnectionPooler `json:"connectionPooler,omitempty"`

TeamID string `json:"teamId"`
DockerImage string `json:"dockerImage,omitempty"`
TeamID string `json:"teamId"`
DockerImage string `json:"dockerImage,omitempty"`
ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"`

// deprecated field storing cluster name without teamId prefix
ClusterName string `json:"-"`
Expand Down
10 changes: 10 additions & 0 deletions pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 15 additions & 2 deletions pkg/cluster/k8sres.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ func (c *Cluster) generatePodTemplate(
additionalSecretMount string,
additionalSecretMountPath string,
additionalVolumes []acidv1.AdditionalVolume,
imagePullSecrets []v1.LocalObjectReference,
) (*v1.PodTemplateSpec, error) {

terminateGracePeriodSeconds := terminateGracePeriod
Expand Down Expand Up @@ -849,6 +850,10 @@ func (c *Cluster) generatePodTemplate(
SecurityContext: &securityContext,
}

if imagePullSecrets != nil {
podSpec.ImagePullSecrets = imagePullSecrets
}

if schedulerName != nil {
podSpec.SchedulerName = *schedulerName
}
Expand Down Expand Up @@ -1332,6 +1337,12 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
// pickup the docker image for the spilo container
effectiveDockerImage := util.Coalesce(spec.DockerImage, c.OpConfig.DockerImage)

// get ImagePullSecrets for spilo pod
effectiveImagePullSecrets := c.OpConfig.ImagePullSecrets
if spec.ImagePullSecrets != nil {
effectiveImagePullSecrets = spec.ImagePullSecrets
}

// determine the User, Group and FSGroup for the spilo pod
effectiveRunAsUser := c.OpConfig.Resources.SpiloRunAsUser
if spec.SpiloRunAsUser != nil {
Expand Down Expand Up @@ -1476,7 +1487,8 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
c.OpConfig.PodAntiAffinityPreferredDuringScheduling,
c.OpConfig.AdditionalSecretMount,
c.OpConfig.AdditionalSecretMountPath,
additionalVolumes)
additionalVolumes,
effectiveImagePullSecrets)

if err != nil {
return nil, fmt.Errorf("could not generate pod template: %v", err)
Expand Down Expand Up @@ -2334,7 +2346,8 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1.CronJob, error) {
false,
c.OpConfig.AdditionalSecretMount,
c.OpConfig.AdditionalSecretMountPath,
[]acidv1.AdditionalVolume{}); err != nil {
[]acidv1.AdditionalVolume{},
nil); err != nil {
return nil, fmt.Errorf("could not generate pod template for logical backup pod: %v", err)
}

Expand Down
1 change: 1 addition & 0 deletions pkg/controller/operator_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.EtcdHost = fromCRD.EtcdHost
result.KubernetesUseConfigMaps = fromCRD.KubernetesUseConfigMaps
result.DockerImage = util.Coalesce(fromCRD.DockerImage, "ghcr.io/zalando/spilo-16:3.3-p1")
result.ImagePullSecrets = util.StrArrToLocalObjectReferenceArr(fromCRD.ImagePullSecrets)
result.Workers = util.CoalesceUInt32(fromCRD.Workers, 8)
result.MinInstances = fromCRD.MinInstances
result.MaxInstances = fromCRD.MaxInstances
Expand Down
1 change: 1 addition & 0 deletions pkg/util/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ type Config struct {
KubernetesUseConfigMaps bool `name:"kubernetes_use_configmaps" default:"false"`
EtcdHost string `name:"etcd_host" default:""` // special values: the empty string "" means Patroni will use K8s as a DCS
DockerImage string `name:"docker_image" default:"ghcr.io/zalando/spilo-16:3.3-p1"`
ImagePullSecrets []v1.LocalObjectReference `name:"image_pull_secrets"`
SidecarImages map[string]string `name:"sidecar_docker_images"` // deprecated in favour of SidecarContainers
SidecarContainers []v1.Container `name:"sidecars"`
PodServiceAccountName string `name:"pod_service_account_name" default:"postgres-pod"`
Expand Down
10 changes: 10 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"time"

"github.com/motomux/pretty"
corev1 "k8s.io/api/core/v1"
resource "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -379,6 +380,15 @@ func IsSmallerQuantity(requestStr, limitStr string) (bool, error) {
return request.Cmp(limit) == -1, nil
}

// StrArrToLocalObjectReferenceArr : Converts an array of strings into an array of v1.LocalObjectReference
func StrArrToLocalObjectReferenceArr(arr []string) []corev1.LocalObjectReference {
ret := make([]corev1.LocalObjectReference, len(arr))
for k, v := range arr {
ret[k] = corev1.LocalObjectReference{Name: v}
}
return ret
}

func MinResource(maxRequestStr, requestStr string) (resource.Quantity, error) {

isSmaller, err := IsSmallerQuantity(maxRequestStr, requestStr)
Expand Down