Skip to content

Commit

Permalink
(psa) make workloads compatible with psa:restricted profile (#2820)
Browse files Browse the repository at this point in the history
* (psa) make workloads compatible with psa:restricted profile

With the introduction of [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-admission-labels-for-namespaces), the reccomeneded
best practice is to enforce the Restricted policy of admission (see [1] for more details).
This PR
*) Lables the olm namespace as `enforce:restricted`
*) Labels the operators namespace as `enforce:baseline` (to allow existing CSV deployments
without securityContext set to deploy in the namespace, which won't be possible with
`enforce:resticted`)
*) updates the securityContext of olm workload pods(olm-operator, catalog-operator,
and CatalogSource registry pods) to adhere to the `Restricted` policy.
*) updates the bundle unpacking job to create a pod that adheres to the `Restricted` policy,
so that bundles can be unpacked in the `Restricted` namespace.

Signed-off-by: Anik Bhattacharjee <anikbhattacharya93@gmail.com>

* (flaky text fix): GC CSV with wrong namespace annotation

The test was modifying the `olm.operatornamespace` to an incorrect value,
and checking to make sure that the CSV was garbage collected as a result.
However, the olm-controller was copying a fresh copy back into the namespace,
so whenever the test was able to get a yes reply to the question "is the CSV
gone", in the brief window before it was copied back again, the test was passing.
This commit fixes that by making sure that if find a CSV that we expected to be
garbage collected, it passes if it determines that the CSV is a fresh copy, and
not the one modified before.

Signed-off-by: Anik Bhattacharjee <anikbhattacharya93@gmail.com>
  • Loading branch information
anik120 committed Aug 2, 2022
1 parent b2086bd commit 67177c0
Show file tree
Hide file tree
Showing 20 changed files with 331 additions and 69 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ COPY --from=builder /build/bin/olm /bin/olm
COPY --from=builder /build/bin/catalog /bin/catalog
COPY --from=builder /build/bin/package-server /bin/package-server
COPY --from=builder /build/bin/cpb /bin/cpb
USER 1001
EXPOSE 8080
EXPOSE 5443
CMD ["/bin/olm"]
1 change: 1 addition & 0 deletions Dockerfile.goreleaser
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ COPY package-server /bin/package-server
COPY cpb /bin/cpb
EXPOSE 8080
EXPOSE 5443
USER 1001
ENTRYPOINT ["/bin/olm"]
6 changes: 6 additions & 0 deletions cmd/catalog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
defaultOPMImage = "quay.io/operator-framework/upstream-opm-builder:latest"
defaultUtilImage = "quay.io/operator-framework/olm:latest"
defaultOperatorName = ""
defaultWorkLoadUserID = int64(1001)
)

// config flags defined globally so that they appear on the test binary as well
Expand Down Expand Up @@ -83,6 +84,10 @@ func (o *options) run(ctx context.Context, logger *logrus.Logger) error {
return fmt.Errorf("error configuring client: %s", err.Error())
}

workloadUserID := int64(-1)
if o.setWorkloadUserID {
workloadUserID = defaultWorkLoadUserID
}
// TODO(tflannag): Use options pattern for catalog operator
// Create a new instance of the operator.
op, err := catalog.NewOperator(
Expand All @@ -98,6 +103,7 @@ func (o *options) run(ctx context.Context, logger *logrus.Logger) error {
k8sscheme.Scheme,
o.installPlanTimeout,
o.bundleUnpackTimeout,
workloadUserID,
)
if err != nil {
return fmt.Errorf("error configuring catalog operator: %s", err.Error())
Expand Down
2 changes: 2 additions & 0 deletions cmd/catalog/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type options struct {
tlsKeyPath string
tlsCertPath string
clientCAPath string
setWorkloadUserID bool

installPlanTimeout time.Duration
bundleUnpackTimeout time.Duration
Expand Down Expand Up @@ -66,6 +67,7 @@ func newRootCmd() *cobra.Command {
cmd.Flags().StringVar(&o.opmImage, "opmImage", defaultOPMImage, "the image to use for unpacking bundle content with opm")
cmd.Flags().StringVar(&o.utilImage, "util-image", defaultUtilImage, "an image containing custom olm utilities")
cmd.Flags().StringVar(&o.writeStatusName, "writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.")
cmd.Flags().BoolVar(&o.setWorkloadUserID, "set-workload-user-id", false, "set user ID for all workloads (registry pods/bundle unpack jobs to default 1001")

cmd.Flags().BoolVar(&o.debug, "debug", false, "use debug log level")
cmd.Flags().BoolVar(&o.version, "version", false, "displays the olm version")
Expand Down
6 changes: 6 additions & 0 deletions deploy/chart/templates/0000_50_olm_00-namespace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.namespace }}
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest

---
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.operator_namespace }}
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: latest
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ spec:
labels:
app: olm-operator
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccountName: olm-operator-serviceaccount
{{- if or .Values.olm.tlsSecret .Values.olm.clientCASecret }}
volumes:
Expand All @@ -33,6 +37,10 @@ spec:
{{- end }}
containers:
- name: olm-operator
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ "ALL" ]
{{- if or .Values.olm.tlsSecret .Values.olm.clientCASecret }}
volumeMounts:
{{- end }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ spec:
labels:
app: catalog-operator
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccountName: olm-operator-serviceaccount
{{- if or .Values.catalog.tlsSecret .Values.catalog.clientCASecret }}
volumes:
Expand All @@ -33,6 +37,10 @@ spec:
{{- end }}
containers:
- name: catalog-operator
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ "ALL" ]
{{- if or .Values.catalog.tlsSecret .Values.catalog.clientCASecret }}
volumeMounts:
{{- end }}
Expand Down Expand Up @@ -76,6 +84,8 @@ spec:
- --client-ca
- /profile-collector-cert/tls.crt
{{- end }}
- --set-workload-user-id
- "true"
image: {{ .Values.catalog.image.ref }}
imagePullPolicy: {{ .Values.catalog.image.pullPolicy }}
ports:
Expand Down
12 changes: 8 additions & 4 deletions deploy/chart/templates/_packageserver.deployment-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ spec:
labels:
app: packageserver
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccountName: olm-operator-serviceaccount
{{- if .Values.package.nodeSelector }}
nodeSelector:
Expand All @@ -25,6 +29,10 @@ spec:
{{- end }}
containers:
- name: packageserver
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ "ALL" ]
command:
- /bin/package-server
- -v=4
Expand Down Expand Up @@ -61,10 +69,6 @@ spec:
resources:
{{ toYaml .Values.package.resources | indent 10 }}
{{- end }}
{{- if .Values.package.securityContext }}
securityContext:
runAsUser: {{ .Values.package.securityContext.runAsUser }}
{{- end }}
volumeMounts:
- name: tmpfs
mountPath: /tmp
Expand Down
1 change: 1 addition & 0 deletions e2e.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ FROM busybox
COPY olm catalog package-server wait cpb /bin/
EXPOSE 8080
EXPOSE 5443
USER 1001
CMD ["/bin/olm"]
36 changes: 35 additions & 1 deletion pkg/controller/bundle/bundle_unpacker.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
listersbatchv1 "k8s.io/client-go/listers/batch/v1"
listerscorev1 "k8s.io/client-go/listers/core/v1"
listersrbacv1 "k8s.io/client-go/listers/rbac/v1"
"k8s.io/utils/pointer"

"github.com/operator-framework/api/pkg/operators/reference"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
Expand Down Expand Up @@ -101,6 +102,11 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string
// See: https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-backoff-failure-policy
RestartPolicy: corev1.RestartPolicyNever,
ImagePullSecrets: secrets,
SecurityContext: &corev1.PodSecurityContext{
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
},
Containers: []corev1.Container{
{
Name: "extract",
Expand Down Expand Up @@ -129,6 +135,12 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: &corev1.SecurityContext{
AllowPrivilegeEscalation: pointer.Bool(false),
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
},
},
},
InitContainers: []corev1.Container{
Expand All @@ -148,6 +160,12 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: &corev1.SecurityContext{
AllowPrivilegeEscalation: pointer.Bool(false),
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
},
},
{
Name: "pull",
Expand All @@ -170,6 +188,12 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: &corev1.SecurityContext{
AllowPrivilegeEscalation: pointer.Bool(false),
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
},
},
},
Volumes: []corev1.Volume{
Expand All @@ -193,7 +217,10 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string
job.SetNamespace(cmRef.Namespace)
job.SetName(cmRef.Name)
job.SetOwnerReferences([]metav1.OwnerReference{ownerRef(cmRef)})

if c.runAsUser > 0 {
job.Spec.Template.Spec.SecurityContext.RunAsUser = &c.runAsUser
job.Spec.Template.Spec.SecurityContext.RunAsNonRoot = pointer.Bool(true)
}
// By default the BackoffLimit is set to 6 which with exponential backoff 10s + 20s + 40s ...
// translates to ~10m of waiting time.
// We want to fail faster than that when we have repeated failures from the bundle unpack pod
Expand Down Expand Up @@ -246,6 +273,7 @@ type ConfigMapUnpacker struct {
loader *configmap.BundleLoader
now func() metav1.Time
unpackTimeout time.Duration
runAsUser int64
}

type ConfigMapUnpackerOption func(*ConfigMapUnpacker)
Expand Down Expand Up @@ -335,6 +363,12 @@ func WithNow(now func() metav1.Time) ConfigMapUnpackerOption {
}
}

func WithUserID(id int64) ConfigMapUnpackerOption {
return func(unpacker *ConfigMapUnpacker) {
unpacker.runAsUser = id
}
}

func (c *ConfigMapUnpacker) apply(options ...ConfigMapUnpackerOption) {
for _, option := range options {
option(c)
Expand Down
Loading

0 comments on commit 67177c0

Please sign in to comment.