Skip to content

Commit 8559376

Browse files
committed
Cherry-pick 'OWLS-111184' into 'release/4.1'
1 parent 4ab6fe0 commit 8559376

File tree

15 files changed

+449
-12
lines changed

15 files changed

+449
-12
lines changed

documentation/domains/Domain.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,10 @@
636636
"InitializeDomainOnPV": {
637637
"type": "object",
638638
"properties": {
639+
"runDomainInitContainerAsRoot": {
640+
"description": "Specifies whether the operator will run the domain initialization init container in the introspector job as root. This may be needed in some environments to create the domain home directory on PV. Defaults to false.",
641+
"type": "boolean"
642+
},
639643
"waitForPvcToBind": {
640644
"description": "Specifies whether the operator will wait for the PersistentVolumeClaim to be bound before proceeding with the domain creation. Defaults to true.",
641645
"type": "boolean"
@@ -651,6 +655,10 @@
651655
"persistentVolumeClaim": {
652656
"description": "An optional field that describes the configuration for creating a PersistentVolumeClaim for `Domain on PV`. PersistentVolumeClaim is a user\u0027s request for and claim to a persistent volume. The operator will perform this one-time create operation only if the persistent volume claim does not already exist. Omit this section if you have manually created a persistent volume claim. If specified, the name must match one of the volumes under `serverPod.volumes` and the domain home must reside in the mount path of the volume using this claim. More info: https://oracle.github.io/weblogic-kubernetes-operator/managing-domains/domain-on-pv-initialization#pvc",
653657
"$ref": "#/definitions/PersistentVolumeClaim"
658+
},
659+
"setDefaultSecurityContextFsGroup": {
660+
"description": "Specifies whether the operator will set the default \u0027fsGroup\u0027 in the introspector job pod security context. This is needed to create the domain home directory on PV in some environments. If the \u0027fsGroup\u0027 is specified as part of \u0027spec.introspector.serverPod.podSecurityContext\u0027, then the operator will use that \u0027fsGroup\u0027 instead of the default \u0027fsGroup\u0027. Defaults to true.",
661+
"type": "boolean"
654662
}
655663
}
656664
},
@@ -666,6 +674,10 @@
666674
"IntrospectorJobPod": {
667675
"type": "object",
668676
"properties": {
677+
"podSecurityContext": {
678+
"description": "Pod-level security attributes. See `kubectl explain pods.spec.securityContext`. Beginning with operator version 4.0.5, if no value is specified for this field, the operator will use default content for the pod-level `securityContext`. More info: https://oracle.github.io/weblogic-kubernetes-operator/security/domain-security/pod-and-container/.",
679+
"$ref": "https://github.com/garethr/kubernetes-json-schema/blob/master/v1.13.5/_definitions.json#/definitions/io.k8s.api.core.v1.PodSecurityContext"
680+
},
669681
"resources": {
670682
"description": "Memory and CPU minimum requirements and limits for the Introspector Job Pod. See `kubectl explain pods.spec.containers.resources`.",
671683
"$ref": "https://github.com/garethr/kubernetes-json-schema/blob/master/v1.13.5/_definitions.json#/definitions/io.k8s.api.core.v1.ResourceRequirements"

documentation/domains/Domain.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ The current status of the operation of the WebLogic domain. Updated automaticall
226226
| `domain` | [Domain On PV](#domain-on-pv) | Describes the configuration for creating an initial WebLogic Domain in persistent volume (`Domain in PV`). The operator will not recreate or update the domain if it already exists. Required. |
227227
| `persistentVolume` | [Persistent Volume](#persistent-volume) | An optional field that describes the configuration to create a PersistentVolume for `Domain on PV` domain. Omit this section if you have manually created a persistent volume. The operator will perform this one-time create operation only if the persistent volume does not already exist. The operator will not recreate or update the PersistentVolume when it exists. More info: https://oracle.github.io/weblogic-kubernetes-operator/managing-domains/domain-on-pv-initialization#pv |
228228
| `persistentVolumeClaim` | [Persistent Volume Claim](#persistent-volume-claim) | An optional field that describes the configuration for creating a PersistentVolumeClaim for `Domain on PV`. PersistentVolumeClaim is a user's request for and claim to a persistent volume. The operator will perform this one-time create operation only if the persistent volume claim does not already exist. Omit this section if you have manually created a persistent volume claim. If specified, the name must match one of the volumes under `serverPod.volumes` and the domain home must reside in the mount path of the volume using this claim. More info: https://oracle.github.io/weblogic-kubernetes-operator/managing-domains/domain-on-pv-initialization#pvc |
229+
| `runDomainInitContainerAsRoot` | Boolean | Specifies whether the operator will run the domain initialization init container in the introspector job as root. This may be needed in some environments to create the domain home directory on PV. Defaults to false. |
230+
| `setDefaultSecurityContextFsGroup` | Boolean | Specifies whether the operator will set the default 'fsGroup' in the introspector job pod security context. This is needed to create the domain home directory on PV in some environments. If the 'fsGroup' is specified as part of 'spec.introspector.serverPod.podSecurityContext', then the operator will use that 'fsGroup' instead of the default 'fsGroup'. Defaults to true. |
229231
| `waitForPvcToBind` | Boolean | Specifies whether the operator will wait for the PersistentVolumeClaim to be bound before proceeding with the domain creation. Defaults to true. |
230232

231233
### Model
@@ -256,6 +258,7 @@ The current status of the operation of the WebLogic domain. Updated automaticall
256258
| --- | --- | --- |
257259
| `env` | Array of [Env Var](k8s1.13.5.md#env-var) | A list of environment variables to set in the Introspector Job Pod container. More info: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-resource/#jvm-memory-and-java-option-environment-variables. See `kubectl explain pods.spec.containers.env`. |
258260
| `envFrom` | Array of [Env From Source](k8s1.13.5.md#env-from-source) | List of sources to populate environment variables in the Introspector Job Pod container. The sources include either a config map or a secret. The operator will not expand the dependent variables in the 'envFrom' source. More details: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#define-an-environment-variable-for-a-container. Also see: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-resource/#jvm-memory-and-java-option-environment-variables. |
261+
| `podSecurityContext` | [Pod Security Context](k8s1.13.5.md#pod-security-context) | Pod-level security attributes. See `kubectl explain pods.spec.securityContext`. Beginning with operator version 4.0.5, if no value is specified for this field, the operator will use default content for the pod-level `securityContext`. More info: https://oracle.github.io/weblogic-kubernetes-operator/security/domain-security/pod-and-container/. |
259262
| `resources` | [Resource Requirements](k8s1.13.5.md#resource-requirements) | Memory and CPU minimum requirements and limits for the Introspector Job Pod. See `kubectl explain pods.spec.containers.resources`. |
260263

261264
### Probe Tuning

kubernetes/crd/domain-crd.yaml

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ apiVersion: apiextensions.k8s.io/v1
55
kind: CustomResourceDefinition
66
metadata:
77
annotations:
8-
weblogic.sha256: d96104036903924b0d3ff60ec7427ffb6fc25d8d27628c96488798e5d7520fd0
8+
weblogic.sha256: dfb1401d47ad44961c30bb2ab266cb8adcf12e8933bf510d48838ffb80766065
99
name: domains.weblogic.oracle
1010
spec:
1111
group: weblogic.oracle
@@ -100,6 +100,12 @@ spec:
100100
when they already exist. For more information, see https://oracle.github.io/weblogic-kubernetes-operator/managing-domains/choosing-a-model/
101101
and https://oracle.github.io/weblogic-kubernetes-operator/managing-domains/domain-on-pv '
102102
properties:
103+
runDomainInitContainerAsRoot:
104+
description: Specifies whether the operator will run the domain
105+
initialization init container in the introspector job as
106+
root. This may be needed in some environments to create
107+
the domain home directory on PV. Defaults to false.
108+
type: boolean
103109
waitForPvcToBind:
104110
description: Specifies whether the operator will wait for
105111
the PersistentVolumeClaim to be bound before proceeding
@@ -471,6 +477,15 @@ spec:
471477
type: object
472478
type: object
473479
type: object
480+
setDefaultSecurityContextFsGroup:
481+
description: Specifies whether the operator will set the default
482+
'fsGroup' in the introspector job pod security context.
483+
This is needed to create the domain home directory on PV
484+
in some environments. If the 'fsGroup' is specified as part
485+
of 'spec.introspector.serverPod.podSecurityContext', then
486+
the operator will use that 'fsGroup' instead of the default
487+
'fsGroup'. Defaults to true.
488+
type: boolean
474489
type: object
475490
overrideDistributionStrategy:
476491
default: Dynamic
@@ -3848,6 +3863,71 @@ spec:
38483863
description: Customization affecting the generation of the Introspector
38493864
Job Pod.
38503865
properties:
3866+
podSecurityContext:
3867+
description: 'Pod-level security attributes. See `kubectl
3868+
explain pods.spec.securityContext`. Beginning with operator
3869+
version 4.0.5, if no value is specified for this field,
3870+
the operator will use default content for the pod-level
3871+
`securityContext`. More info: https://oracle.github.io/weblogic-kubernetes-operator/security/domain-security/pod-and-container/.'
3872+
properties:
3873+
runAsUser:
3874+
type: integer
3875+
seLinuxOptions:
3876+
properties:
3877+
role:
3878+
type: string
3879+
level:
3880+
type: string
3881+
type:
3882+
type: string
3883+
user:
3884+
type: string
3885+
type: object
3886+
fsGroup:
3887+
type: integer
3888+
seccompProfile:
3889+
properties:
3890+
localhostProfile:
3891+
type: string
3892+
type:
3893+
type: string
3894+
required:
3895+
- type
3896+
type: object
3897+
windowsOptions:
3898+
properties:
3899+
gmsaCredentialSpec:
3900+
type: string
3901+
runAsUserName:
3902+
type: string
3903+
hostProcess:
3904+
type: boolean
3905+
gmsaCredentialSpecName:
3906+
type: string
3907+
type: object
3908+
fsGroupChangePolicy:
3909+
type: string
3910+
supplementalGroups:
3911+
items:
3912+
type: integer
3913+
type: array
3914+
runAsGroup:
3915+
type: integer
3916+
runAsNonRoot:
3917+
type: boolean
3918+
sysctls:
3919+
items:
3920+
type: object
3921+
properties:
3922+
name:
3923+
type: string
3924+
value:
3925+
type: string
3926+
required:
3927+
- name
3928+
- value
3929+
type: array
3930+
type: object
38513931
resources:
38523932
description: Memory and CPU minimum requirements and limits
38533933
for the Introspector Job Pod. See `kubectl explain pods.spec.containers.resources`.

operator/src/main/java/oracle/kubernetes/operator/helpers/BasePodStepContext.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
import io.kubernetes.client.openapi.models.V1EnvVarSource;
2424
import io.kubernetes.client.openapi.models.V1HostAlias;
2525
import io.kubernetes.client.openapi.models.V1Pod;
26+
import io.kubernetes.client.openapi.models.V1PodSecurityContext;
2627
import io.kubernetes.client.openapi.models.V1PodSpec;
2728
import io.kubernetes.client.openapi.models.V1ResourceRequirements;
29+
import io.kubernetes.client.openapi.models.V1SecurityContext;
2830
import io.kubernetes.client.openapi.models.V1Toleration;
2931
import io.kubernetes.client.openapi.models.V1Volume;
3032
import io.kubernetes.client.openapi.models.V1VolumeMount;
@@ -154,13 +156,15 @@ protected V1Container createInitContainerForAuxiliaryImage(DeploymentImage auxil
154156
.command(Collections.singletonList(AUXILIARY_IMAGE_INIT_CONTAINER_WRAPPER_SCRIPT))
155157
.env(createEnv(auxiliaryImage, getName(index)))
156158
.resources(createResources())
157-
.securityContext(PodSecurityHelper.getDefaultContainerSecurityContext())
159+
.securityContext(getInitContainerSecurityContext())
158160
.volumeMounts(Arrays.asList(
159161
new V1VolumeMount().name(AUXILIARY_IMAGE_INTERNAL_VOLUME_NAME)
160162
.mountPath(AUXILIARY_IMAGE_TARGET_PATH),
161163
new V1VolumeMount().name(SCRIPTS_VOLUME).mountPath(SCRIPTS_MOUNTS_PATH)));
162164
}
163165

166+
abstract V1SecurityContext getInitContainerSecurityContext();
167+
164168
private String getName(int index) {
165169
return AUXILIARY_IMAGE_INIT_CONTAINER_NAME_PREFIX + (index + 1);
166170
}
@@ -219,10 +223,12 @@ protected V1PodSpec createPodSpec() {
219223
.tolerations(getTolerations())
220224
.hostAliases(getHostAliases())
221225
.restartPolicy(getServerSpec().getRestartPolicy())
222-
.securityContext(getServerSpec().getPodSecurityContext())
226+
.securityContext(getPodSecurityContext())
223227
.imagePullSecrets(getServerSpec().getImagePullSecrets());
224228
}
225229

230+
abstract V1PodSecurityContext getPodSecurityContext();
231+
226232
private List<V1Toleration> getTolerations() {
227233
List<V1Toleration> tolerations = getServerSpec().getTolerations();
228234
return tolerations.isEmpty() ? null : tolerations;

operator/src/main/java/oracle/kubernetes/operator/helpers/JobStepContext.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import oracle.kubernetes.weblogic.domain.model.InitializeDomainOnPV;
6363
import oracle.kubernetes.weblogic.domain.model.IntrospectorJobEnvVars;
6464
import oracle.kubernetes.weblogic.domain.model.ServerEnvVars;
65+
import org.jetbrains.annotations.NotNull;
6566

6667
import static oracle.kubernetes.common.AuxiliaryImageConstants.AUXILIARY_IMAGE_TARGET_PATH;
6768
import static oracle.kubernetes.common.CommonConstants.COMPATIBILITY_MODE;
@@ -486,11 +487,39 @@ private void addInitDomainOnPVInitContainer(List<V1Container> initContainers) {
486487
.value(getDomainHomeOnPVHomeOwnership()))
487488
.addEnvItem(new V1EnvVar().name(AuxiliaryImageEnvVars.AUXILIARY_IMAGE_TARGET_PATH)
488489
.value(AuxiliaryImageConstants.AUXILIARY_IMAGE_TARGET_PATH))
489-
.securityContext(new V1SecurityContext().runAsGroup(0L).runAsUser(0L))
490+
.securityContext(getInitContainerSecurityContext())
490491
.command(List.of(INIT_DOMAIN_ON_PV_SCRIPT))
491492
);
492493
}
493494

495+
@Override
496+
V1SecurityContext getInitContainerSecurityContext() {
497+
if (isInitDomainOnPVRunAsRoot()) {
498+
return new V1SecurityContext().runAsGroup(0L).runAsUser(0L);
499+
}
500+
if (getPodSecurityContext().equals(new V1PodSecurityContext())) {
501+
return PodSecurityHelper.getDefaultContainerSecurityContext();
502+
}
503+
return creatSecurityContextFromPodSecurityContext(getPodSecurityContext());
504+
}
505+
506+
@NotNull
507+
private Boolean isInitDomainOnPVRunAsRoot() {
508+
return Optional.ofNullable(getDomain().getInitializeDomainOnPV())
509+
.map(p -> p.getRunDomainInitContainerAsRoot()).orElse(false);
510+
}
511+
512+
private V1SecurityContext creatSecurityContextFromPodSecurityContext(
513+
V1PodSecurityContext podSecurityContext) {
514+
return new V1SecurityContext()
515+
.runAsUser(podSecurityContext.getRunAsUser())
516+
.runAsGroup(podSecurityContext.getRunAsGroup())
517+
.runAsNonRoot(podSecurityContext.getRunAsNonRoot())
518+
.seccompProfile(podSecurityContext.getSeccompProfile())
519+
.seLinuxOptions(podSecurityContext.getSeLinuxOptions())
520+
.windowsOptions(podSecurityContext.getWindowsOptions());
521+
}
522+
494523
private String getDomainHomeOnPVHomeOwnership() {
495524
Long uid = Optional.ofNullable(getDomain().getAdminServerSpec())
496525
.map(EffectiveServerSpec::getPodSecurityContext)
@@ -555,9 +584,33 @@ protected V1PodSpec createPodSpec() {
555584
if (getDefaultAntiAffinity().equals(podSpec.getAffinity())) {
556585
podSpec.affinity(null);
557586
}
587+
588+
if (isInitializeDomainOnPV()) {
589+
V1PodSecurityContext podSecurityContext = getPodSecurityContext();
590+
if (getDomain().getInitializeDomainOnPV().getSetDefaultSecurityContextFsGroup()) {
591+
if (podSecurityContext.getFsGroup() == null && podSecurityContext.getRunAsGroup() != null) {
592+
podSpec.securityContext(podSecurityContext.fsGroup(podSecurityContext.getRunAsGroup()));
593+
} else if (podSecurityContext.getFsGroup() == null) {
594+
Optional.ofNullable(TuningParameters.getInstance()).ifPresent(instance -> {
595+
if (!"OpenShift".equalsIgnoreCase(instance.getKubernetesPlatform())) {
596+
podSpec.securityContext(podSecurityContext.fsGroup(0L));
597+
}
598+
});
599+
}
600+
if (podSpec.getSecurityContext().getFsGroupChangePolicy() == null) {
601+
podSpec.getSecurityContext().fsGroupChangePolicy("OnRootMismatch");
602+
}
603+
}
604+
}
558605
return podSpec;
559606
}
560607

608+
@Override
609+
V1PodSecurityContext getPodSecurityContext() {
610+
return Optional.ofNullable(getDomain().getIntrospectorSpec()).map(s -> s.getPodSecurityContext())
611+
.orElse(getDomain().getAdminServerSpec().getPodSecurityContext());
612+
}
613+
561614
private void addConfigOverrideSecretVolume(V1PodSpec podSpec, String secretName) {
562615
podSpec.addVolumesItem(
563616
new V1Volume()

0 commit comments

Comments
 (0)