Set user and group in security context (#1083)

* Set user and group in security context
This commit is contained in:
Rico Berger 2020-09-15 13:27:59 +02:00 committed by GitHub
parent d8884a4003
commit d09e418b56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 119 additions and 3 deletions

View File

@ -200,6 +200,10 @@ spec:
type: string
secret_name_template:
type: string
spilo_runasuser:
type: integer
spilo_runasgroup:
type: integer
spilo_fsgroup:
type: integer
spilo_privileged:

View File

@ -374,6 +374,10 @@ spec:
items:
type: object
additionalProperties: true
spiloRunAsUser:
type: integer
spiloRunAsGroup:
type: integer
spiloFSGroup:
type: integer
standby:

View File

@ -127,6 +127,9 @@ configKubernetes:
pod_terminate_grace_period: 5m
# template for database user secrets generated by the operator
secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
# set user and group for the spilo container (required to run Spilo as non-root process)
# spilo_runasuser: "101"
# spilo_runasgroup: "103"
# group ID with write-access to volumes (required to run Spilo as non-root process)
# spilo_fsgroup: 103

View File

@ -118,6 +118,9 @@ configKubernetes:
pod_terminate_grace_period: 5m
# template for database user secrets generated by the operator
secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
# set user and group for the spilo container (required to run Spilo as non-root process)
# spilo_runasuser: "101"
# spilo_runasgroup: "103"
# group ID with write-access to volumes (required to run Spilo as non-root process)
# spilo_fsgroup: "103"

View File

@ -65,6 +65,16 @@ 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.
* **spiloRunAsUser**
sets the user ID which should be used in the container to run the process.
This must be set to run the container without root. By default the container
runs with root. This option only works for Spilo versions >= 1.6-p3.
* **spiloRunAsGroup**
sets the group ID which should be used in the container to run the process.
This must be set to run the container without root. By default the container
runs with root. This option only works for Spilo versions >= 1.6-p3.
* **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**

View File

@ -317,6 +317,16 @@ 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_runasuser**
sets the user ID which should be used in the container to run the process.
This must be set to run the container without root. By default the container
runs with root. This option only works for Spilo versions >= 1.6-p3.
* **spilo_runasgroup**
sets the group ID which should be used in the container to run the process.
This must be set to run the container without root. By default the container
runs with root. This option only works for Spilo versions >= 1.6-p3.
* **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

View File

@ -68,6 +68,8 @@ spec:
# name: my-config-map
enableShmVolume: true
# spiloRunAsUser: 101
# spiloRunAsGroup: 103
# spiloFSGroup: 103
# podAnnotations:
# annotation.key: value

View File

@ -99,6 +99,8 @@ data:
secret_name_template: "{username}.{cluster}.credentials"
# sidecar_docker_images: ""
# set_memory_request_to_limit: "false"
# spilo_runasuser: 101
# spilo_runasgroup: 103
# spilo_fsgroup: 103
spilo_privileged: "false"
# storage_resize_mode: "off"

View File

@ -196,6 +196,10 @@ spec:
type: string
secret_name_template:
type: string
spilo_runasuser:
type: integer
spilo_runasgroup:
type: integer
spilo_fsgroup:
type: integer
spilo_privileged:

View File

@ -68,6 +68,8 @@ configuration:
# pod_service_account_role_binding_definition: ""
pod_terminate_grace_period: 5m
secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
# spilo_runasuser: 101
# spilo_runasgroup: 103
# spilo_fsgroup: 103
spilo_privileged: false
storage_resize_mode: ebs

View File

@ -370,6 +370,10 @@ spec:
items:
type: object
additionalProperties: true
spiloRunAsUser:
type: integer
spiloRunAsGroup:
type: integer
spiloFSGroup:
type: integer
standby:

View File

@ -519,6 +519,12 @@ var PostgresCRDResourceValidation = apiextv1beta1.CustomResourceValidation{
},
},
},
"spiloRunAsUser": {
Type: "integer",
},
"spiloRunAsGroup": {
Type: "integer",
},
"spiloFSGroup": {
Type: "integer",
},
@ -1018,6 +1024,12 @@ var OperatorConfigCRDResourceValidation = apiextv1beta1.CustomResourceValidation
"secret_name_template": {
Type: "string",
},
"spilo_runasuser": {
Type: "integer",
},
"spilo_runasgroup": {
Type: "integer",
},
"spilo_fsgroup": {
Type: "integer",
},

View File

@ -49,6 +49,8 @@ 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,omitempty"`
SpiloRunAsUser *int64 `json:"spilo_runasuser,omitempty"`
SpiloRunAsGroup *int64 `json:"spilo_runasgroup,omitempty"`
SpiloFSGroup *int64 `json:"spilo_fsgroup,omitempty"`
WatchedNamespace string `json:"watched_namespace,omitempty"`
PDBNameFormat config.StringTemplate `json:"pdb_name_format,omitempty"`

View File

@ -35,7 +35,9 @@ type PostgresSpec struct {
TeamID string `json:"teamId"`
DockerImage string `json:"dockerImage,omitempty"`
SpiloFSGroup *int64 `json:"spiloFSGroup,omitempty"`
SpiloRunAsUser *int64 `json:"spiloRunAsUser,omitempty"`
SpiloRunAsGroup *int64 `json:"spiloRunAsGroup,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

View File

@ -147,6 +147,16 @@ func (in *ConnectionPoolerConfiguration) DeepCopy() *ConnectionPoolerConfigurati
// 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.SpiloRunAsUser != nil {
in, out := &in.SpiloRunAsUser, &out.SpiloRunAsUser
*out = new(int64)
**out = **in
}
if in.SpiloRunAsGroup != nil {
in, out := &in.SpiloRunAsGroup, &out.SpiloRunAsGroup
*out = new(int64)
**out = **in
}
if in.SpiloFSGroup != nil {
in, out := &in.SpiloFSGroup, &out.SpiloFSGroup
*out = new(int64)
@ -527,6 +537,16 @@ func (in *PostgresSpec) DeepCopyInto(out *PostgresSpec) {
*out = new(ConnectionPooler)
(*in).DeepCopyInto(*out)
}
if in.SpiloRunAsUser != nil {
in, out := &in.SpiloRunAsUser, &out.SpiloRunAsUser
*out = new(int64)
**out = **in
}
if in.SpiloRunAsGroup != nil {
in, out := &in.SpiloRunAsGroup, &out.SpiloRunAsGroup
*out = new(int64)
**out = **in
}
if in.SpiloFSGroup != nil {
in, out := &in.SpiloFSGroup, &out.SpiloFSGroup
*out = new(int64)

View File

@ -557,6 +557,8 @@ func (c *Cluster) generatePodTemplate(
initContainers []v1.Container,
sidecarContainers []v1.Container,
tolerationsSpec *[]v1.Toleration,
spiloRunAsUser *int64,
spiloRunAsGroup *int64,
spiloFSGroup *int64,
nodeAffinity *v1.Affinity,
terminateGracePeriod int64,
@ -576,6 +578,14 @@ func (c *Cluster) generatePodTemplate(
containers = append(containers, sidecarContainers...)
securityContext := v1.PodSecurityContext{}
if spiloRunAsUser != nil {
securityContext.RunAsUser = spiloRunAsUser
}
if spiloRunAsGroup != nil {
securityContext.RunAsGroup = spiloRunAsGroup
}
if spiloFSGroup != nil {
securityContext.FSGroup = spiloFSGroup
}
@ -1073,7 +1083,17 @@ 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)
// determine the FSGroup for the spilo pod
// determine the User, Group and FSGroup for the spilo pod
effectiveRunAsUser := c.OpConfig.Resources.SpiloRunAsUser
if spec.SpiloRunAsUser != nil {
effectiveRunAsUser = spec.SpiloRunAsUser
}
effectiveRunAsGroup := c.OpConfig.Resources.SpiloRunAsGroup
if spec.SpiloRunAsGroup != nil {
effectiveRunAsGroup = spec.SpiloRunAsGroup
}
effectiveFSGroup := c.OpConfig.Resources.SpiloFSGroup
if spec.SpiloFSGroup != nil {
effectiveFSGroup = spec.SpiloFSGroup
@ -1217,6 +1237,8 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
initContainers,
sidecarContainers,
&tolerationSpec,
effectiveRunAsUser,
effectiveRunAsGroup,
effectiveFSGroup,
nodeAffinity(c.OpConfig.NodeReadinessLabel),
int64(c.OpConfig.PodTerminateGracePeriod.Seconds()),
@ -1897,6 +1919,8 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1beta1.CronJob, error) {
[]v1.Container{},
&[]v1.Toleration{},
nil,
nil,
nil,
nodeAffinity(c.OpConfig.NodeReadinessLabel),
int64(c.OpConfig.PodTerminateGracePeriod.Seconds()),
c.OpConfig.PodServiceAccountName,

View File

@ -1302,6 +1302,8 @@ func TestTLS(t *testing.T) {
var err error
var spec acidv1.PostgresSpec
var cluster *Cluster
var spiloRunAsUser = int64(101)
var spiloRunAsGroup = int64(103)
var spiloFSGroup = int64(103)
var additionalVolumes = spec.AdditionalVolumes
@ -1329,7 +1331,9 @@ func TestTLS(t *testing.T) {
ReplicationUsername: replicationUserName,
},
Resources: config.Resources{
SpiloFSGroup: &spiloFSGroup,
SpiloRunAsUser: &spiloRunAsUser,
SpiloRunAsGroup: &spiloRunAsGroup,
SpiloFSGroup: &spiloFSGroup,
},
},
}, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger, eventRecorder)

View File

@ -61,6 +61,8 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.PodEnvironmentSecret = fromCRD.Kubernetes.PodEnvironmentSecret
result.PodTerminateGracePeriod = util.CoalesceDuration(time.Duration(fromCRD.Kubernetes.PodTerminateGracePeriod), "5m")
result.SpiloPrivileged = fromCRD.Kubernetes.SpiloPrivileged
result.SpiloRunAsUser = fromCRD.Kubernetes.SpiloRunAsUser
result.SpiloRunAsGroup = fromCRD.Kubernetes.SpiloRunAsGroup
result.SpiloFSGroup = fromCRD.Kubernetes.SpiloFSGroup
result.ClusterDomain = util.Coalesce(fromCRD.Kubernetes.ClusterDomain, "cluster.local")
result.WatchedNamespace = fromCRD.Kubernetes.WatchedNamespace

View File

@ -28,6 +28,8 @@ 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"`
SpiloRunAsUser *int64 `json:"spilo_runasuser,omitempty"`
SpiloRunAsGroup *int64 `json:"spilo_runasgroup,omitempty"`
SpiloFSGroup *int64 `name:"spilo_fsgroup"`
PodPriorityClassName string `name:"pod_priority_class_name"`
ClusterDomain string `name:"cluster_domain" default:"cluster.local"`