StatefulSet fsGroup config option to allow non-root spilo (#531)
* StatefulSet fsGroup config option to allow non-root spilo * Allow Postgres CRD to overide SpiloFSGroup of the Operator. * Document FSGroup of a Pod cannot be changed after creation.
This commit is contained in:
parent
5a0e95ac45
commit
ec5b1d4d58
|
|
@ -31,6 +31,7 @@ configKubernetes:
|
|||
# node_readiness_label: ""
|
||||
# oauth_token_secret_name: postgresql-operator
|
||||
# pod_environment_configmap: ""
|
||||
# spilo_fsgroup: "103"
|
||||
pod_management_policy: "ordered_ready"
|
||||
pdb_name_format: "postgres-{cluster}-pdb"
|
||||
pod_role_label: spilo-role
|
||||
|
|
|
|||
|
|
@ -58,6 +58,13 @@ 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.
|
||||
|
||||
* **spiloFSGroup**
|
||||
the Persistent Volumes for the spilo pods in the StatefulSet will be owned
|
||||
and writable by the group ID specified. This will override the **spilo_fsgroup**
|
||||
operator parameter. This is required to run Spilo as a non-root process, but
|
||||
requires a custom spilo image. Note the FSGroup of a Pod cannot be changed
|
||||
without recreating a new Pod.
|
||||
|
||||
* **enableMasterLoadBalancer**
|
||||
boolean flag to override the operator defaults (set by the
|
||||
`enable_master_load_balancer` parameter) to define whether to enable the load
|
||||
|
|
|
|||
|
|
@ -228,6 +228,11 @@ configuration they are grouped under the `kubernetes` key.
|
|||
that should be assigned to the Postgres pods. The priority class itself must
|
||||
be defined in advance. Default is empty (use the default priority class).
|
||||
|
||||
* **spilo_fsgroup**
|
||||
the Persistent Volumes for the spilo pods in the StatefulSet will be owned and writable by the group ID specified.
|
||||
This is required to run Spilo as a non-root process, but requires a custom spilo image. Note the FSGroup of a Pod
|
||||
cannot be changed without recreating a new Pod.
|
||||
|
||||
* **spilo_privileged**
|
||||
whether the Spilo container should run in privileged mode. Privileged mode is
|
||||
used for AWS volume resizing and not required if you don't need that
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ spec:
|
|||
limits:
|
||||
cpu: 300m
|
||||
memory: 300Mi
|
||||
# spiloFSGroup: 103
|
||||
patroni:
|
||||
initdb:
|
||||
encoding: "UTF8"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ configuration:
|
|||
cluster_domain: cluster.local
|
||||
oauth_token_secret_name: postgresql-operator
|
||||
pod_role_label: spilo-role
|
||||
# spilo_fsgroup: 103
|
||||
spilo_privileged: false
|
||||
cluster_labels:
|
||||
application: spilo
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ type KubernetesMetaConfiguration struct {
|
|||
PodServiceAccountRoleBindingDefinition string `json:"pod_service_account_role_binding_definition,omitempty"`
|
||||
PodTerminateGracePeriod Duration `json:"pod_terminate_grace_period,omitempty"`
|
||||
SpiloPrivileged bool `json:"spilo_privileged,omitemty"`
|
||||
SpiloFSGroup *int64 `json:"spilo_fsgroup,omitempty"`
|
||||
WatchedNamespace string `json:"watched_namespace,omitempty"`
|
||||
PDBNameFormat config.StringTemplate `json:"pdb_name_format,omitempty"`
|
||||
SecretNameTemplate config.StringTemplate `json:"secret_name_template,omitempty"`
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ type PostgresSpec struct {
|
|||
TeamID string `json:"teamId"`
|
||||
DockerImage string `json:"dockerImage,omitempty"`
|
||||
|
||||
SpiloFSGroup *int64 `json:"spiloFSGroup,omitempty"`
|
||||
|
||||
// vars that enable load balancers are pointers because it is important to know if any of them is omitted from the Postgres manifest
|
||||
// in that case the var evaluates to nil and the value is taken from the operator config
|
||||
EnableMasterLoadBalancer *bool `json:"enableMasterLoadBalancer,omitempty"`
|
||||
|
|
|
|||
|
|
@ -66,6 +66,11 @@ func (in *CloneDescription) DeepCopy() *CloneDescription {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubernetesMetaConfiguration) DeepCopyInto(out *KubernetesMetaConfiguration) {
|
||||
*out = *in
|
||||
if in.SpiloFSGroup != nil {
|
||||
in, out := &in.SpiloFSGroup, &out.SpiloFSGroup
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
out.OAuthTokenSecretName = in.OAuthTokenSecretName
|
||||
out.InfrastructureRolesSecretName = in.InfrastructureRolesSecretName
|
||||
if in.ClusterLabels != nil {
|
||||
|
|
@ -402,6 +407,11 @@ func (in *PostgresSpec) DeepCopyInto(out *PostgresSpec) {
|
|||
out.Volume = in.Volume
|
||||
in.Patroni.DeepCopyInto(&out.Patroni)
|
||||
out.Resources = in.Resources
|
||||
if in.SpiloFSGroup != nil {
|
||||
in, out := &in.SpiloFSGroup, &out.SpiloFSGroup
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.EnableMasterLoadBalancer != nil {
|
||||
in, out := &in.EnableMasterLoadBalancer, &out.EnableMasterLoadBalancer
|
||||
*out = new(bool)
|
||||
|
|
|
|||
|
|
@ -432,6 +432,7 @@ func generatePodTemplate(
|
|||
initContainers []v1.Container,
|
||||
sidecarContainers []v1.Container,
|
||||
tolerationsSpec *[]v1.Toleration,
|
||||
spiloFSGroup *int64,
|
||||
nodeAffinity *v1.Affinity,
|
||||
terminateGracePeriod int64,
|
||||
podServiceAccountName string,
|
||||
|
|
@ -445,6 +446,11 @@ func generatePodTemplate(
|
|||
terminateGracePeriodSeconds := terminateGracePeriod
|
||||
containers := []v1.Container{*spiloContainer}
|
||||
containers = append(containers, sidecarContainers...)
|
||||
securityContext := v1.PodSecurityContext{}
|
||||
|
||||
if spiloFSGroup != nil {
|
||||
securityContext.FSGroup = spiloFSGroup
|
||||
}
|
||||
|
||||
podSpec := v1.PodSpec{
|
||||
ServiceAccountName: podServiceAccountName,
|
||||
|
|
@ -452,6 +458,7 @@ func generatePodTemplate(
|
|||
Containers: containers,
|
||||
InitContainers: initContainers,
|
||||
Tolerations: *tolerationsSpec,
|
||||
SecurityContext: &securityContext,
|
||||
}
|
||||
|
||||
if shmVolume {
|
||||
|
|
@ -831,6 +838,12 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State
|
|||
tolerationSpec := tolerations(&spec.Tolerations, c.OpConfig.PodToleration)
|
||||
effectivePodPriorityClassName := util.Coalesce(spec.PodPriorityClassName, c.OpConfig.PodPriorityClassName)
|
||||
|
||||
// determine the FSGroup for the spilo pod
|
||||
effectiveFSGroup := c.OpConfig.Resources.SpiloFSGroup
|
||||
if spec.SpiloFSGroup != nil {
|
||||
effectiveFSGroup = spec.SpiloFSGroup
|
||||
}
|
||||
|
||||
// generate pod template for the statefulset, based on the spilo container and sidecars
|
||||
if podTemplate, err = generatePodTemplate(
|
||||
c.Namespace,
|
||||
|
|
@ -839,6 +852,7 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*v1beta1.State
|
|||
spec.InitContainers,
|
||||
sidecarContainers,
|
||||
&tolerationSpec,
|
||||
effectiveFSGroup,
|
||||
nodeAffinity(c.OpConfig.NodeReadinessLabel),
|
||||
int64(c.OpConfig.PodTerminateGracePeriod.Seconds()),
|
||||
c.OpConfig.PodServiceAccountName,
|
||||
|
|
@ -1340,6 +1354,7 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1beta1.CronJob, error) {
|
|||
[]v1.Container{},
|
||||
[]v1.Container{},
|
||||
&[]v1.Toleration{},
|
||||
nil,
|
||||
nodeAffinity(c.OpConfig.NodeReadinessLabel),
|
||||
int64(c.OpConfig.PodTerminateGracePeriod.Seconds()),
|
||||
c.OpConfig.PodServiceAccountName,
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
|||
result.PodEnvironmentConfigMap = fromCRD.Kubernetes.PodEnvironmentConfigMap
|
||||
result.PodTerminateGracePeriod = time.Duration(fromCRD.Kubernetes.PodTerminateGracePeriod)
|
||||
result.SpiloPrivileged = fromCRD.Kubernetes.SpiloPrivileged
|
||||
result.SpiloFSGroup = fromCRD.Kubernetes.SpiloFSGroup
|
||||
result.ClusterDomain = fromCRD.Kubernetes.ClusterDomain
|
||||
result.WatchedNamespace = fromCRD.Kubernetes.WatchedNamespace
|
||||
result.PDBNameFormat = fromCRD.Kubernetes.PDBNameFormat
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ type Resources struct {
|
|||
PodLabelWaitTimeout time.Duration `name:"pod_label_wait_timeout" default:"10m"`
|
||||
PodDeletionWaitTimeout time.Duration `name:"pod_deletion_wait_timeout" default:"10m"`
|
||||
PodTerminateGracePeriod time.Duration `name:"pod_terminate_grace_period" default:"5m"`
|
||||
SpiloFSGroup *int64 `name:"spilo_fsgroup"`
|
||||
PodPriorityClassName string `name:"pod_priority_class_name"`
|
||||
ClusterDomain string `name:"cluster_domain" default:"cluster.local"`
|
||||
SpiloPrivileged bool `name:"spilo_privileged" default:"false"`
|
||||
|
|
|
|||
Loading…
Reference in New Issue