Skip to content

Commit 745a324

Browse files
committed
Fix storage issues - the init container is still needed (#1036)
* Fix storage issues - the init container is stil needed * Use correct user ID
1 parent 4951609 commit 745a324

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

cluster-operator/src/main/java/io/strimzi/operator/cluster/model/AbstractModel.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.fabric8.kubernetes.api.model.ConfigMapVolumeSource;
1111
import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder;
1212
import io.fabric8.kubernetes.api.model.Container;
13+
import io.fabric8.kubernetes.api.model.ContainerBuilder;
1314
import io.fabric8.kubernetes.api.model.ContainerPort;
1415
import io.fabric8.kubernetes.api.model.ContainerPortBuilder;
1516
import io.fabric8.kubernetes.api.model.EnvVar;
@@ -23,6 +24,8 @@
2324
import io.fabric8.kubernetes.api.model.OwnerReferenceBuilder;
2425
import io.fabric8.kubernetes.api.model.PersistentVolumeClaim;
2526
import io.fabric8.kubernetes.api.model.PersistentVolumeClaimBuilder;
27+
import io.fabric8.kubernetes.api.model.PodSecurityContext;
28+
import io.fabric8.kubernetes.api.model.PodSecurityContextBuilder;
2629
import io.fabric8.kubernetes.api.model.Probe;
2730
import io.fabric8.kubernetes.api.model.ProbeBuilder;
2831
import io.fabric8.kubernetes.api.model.Quantity;
@@ -86,6 +89,11 @@ public abstract class AbstractModel {
8689
protected static final int CERTS_EXPIRATION_DAYS = 365;
8790
protected static final String DEFAULT_JVM_XMS = "128M";
8891

92+
private static final String VOLUME_MOUNT_HACK_IMAGE = "busybox";
93+
protected static final String VOLUME_MOUNT_HACK_NAME = "volume-mount-hack";
94+
private static final Long VOLUME_MOUNT_HACK_USERID = 1001L;
95+
private static final Long VOLUME_MOUNT_HACK_GROUPID = 0L;
96+
8997
public static final String ANCILLARY_CM_KEY_METRICS = "metrics-config.yml";
9098
public static final String ANCILLARY_CM_KEY_LOG_CONFIG = "log4j.properties";
9199
public static final String ENV_VAR_DYNAMIC_HEAP_FRACTION = "DYNAMIC_HEAP_FRACTION";
@@ -744,9 +752,11 @@ protected Service createHeadlessService(List<ServicePort> ports, Map<String, Str
744752
protected StatefulSet createStatefulSet(
745753
List<Volume> volumes,
746754
List<PersistentVolumeClaim> volumeClaims,
755+
List<VolumeMount> volumeMounts,
747756
Affinity affinity,
748757
List<Container> initContainers,
749-
List<Container> containers) {
758+
List<Container> containers,
759+
boolean isOpenShift) {
750760

751761
Map<String, String> annotations = new HashMap<>();
752762

@@ -755,6 +765,25 @@ protected StatefulSet createStatefulSet(
755765
&& ((PersistentClaimStorage) storage).isDeleteClaim()));
756766

757767
List<Container> initContainersInternal = new ArrayList<>();
768+
PodSecurityContext securityContext = null;
769+
// if a persistent volume claim is requested and the running cluster is a Kubernetes one
770+
// there is an hack on volume mounting which needs an "init-container"
771+
if (this.storage instanceof PersistentClaimStorage && !isOpenShift) {
772+
String chown = String.format("chown -R %d:%d %s",
773+
AbstractModel.VOLUME_MOUNT_HACK_USERID,
774+
AbstractModel.VOLUME_MOUNT_HACK_GROUPID,
775+
volumeMounts.get(0).getMountPath());
776+
Container initContainer = new ContainerBuilder()
777+
.withName(AbstractModel.VOLUME_MOUNT_HACK_NAME)
778+
.withImage(AbstractModel.VOLUME_MOUNT_HACK_IMAGE)
779+
.withVolumeMounts(volumeMounts.get(0))
780+
.withCommand("sh", "-c", chown)
781+
.build();
782+
initContainersInternal.add(initContainer);
783+
securityContext = new PodSecurityContextBuilder()
784+
.withFsGroup(AbstractModel.VOLUME_MOUNT_HACK_GROUPID)
785+
.build();
786+
}
758787
// add all the other init containers provided by the specific model implementation
759788
if (initContainers != null) {
760789
initContainersInternal.addAll(initContainers);
@@ -782,6 +811,7 @@ protected StatefulSet createStatefulSet(
782811
.withNewSpec()
783812
.withServiceAccountName(getServiceAccountName())
784813
.withAffinity(affinity)
814+
.withSecurityContext(securityContext)
785815
.withInitContainers(initContainersInternal)
786816
.withContainers(containers)
787817
.withVolumes(volumes)

cluster-operator/src/main/java/io/strimzi/operator/cluster/model/KafkaCluster.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,11 @@ public StatefulSet generateStatefulSet(boolean isOpenShift) {
516516
return createStatefulSet(
517517
getVolumes(isOpenShift),
518518
getVolumeClaims(),
519+
getVolumeMounts(),
519520
getMergedAffinity(),
520521
getInitContainers(),
521-
getContainers());
522+
getContainers(),
523+
isOpenShift);
522524
}
523525

524526
/**

cluster-operator/src/main/java/io/strimzi/operator/cluster/model/ZookeeperCluster.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,11 @@ public StatefulSet generateStatefulSet(boolean isOpenShift) {
277277
return createStatefulSet(
278278
getVolumes(isOpenShift),
279279
getVolumeClaims(),
280+
getVolumeMounts(),
280281
getMergedAffinity(),
281282
getInitContainers(),
282-
getContainers());
283+
getContainers(),
284+
isOpenShift);
283285
}
284286

285287
/**

cluster-operator/src/test/java/io/strimzi/operator/cluster/model/KafkaClusterTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import io.strimzi.api.kafka.model.KafkaBuilder;
2424
import io.strimzi.api.kafka.model.KafkaClusterSpec;
2525
import io.strimzi.api.kafka.model.KafkaListenerAuthenticationTls;
26+
import io.strimzi.api.kafka.model.PersistentClaimStorage;
2627
import io.strimzi.api.kafka.model.PersistentClaimStorageBuilder;
2728
import io.strimzi.api.kafka.model.Rack;
2829
import io.strimzi.api.kafka.model.TlsSidecarLogLevel;
@@ -250,6 +251,20 @@ private void checkStatefulSet(StatefulSet ss, Kafka cm, boolean isOpenShift) {
250251
assertEquals(KafkaCluster.TLS_SIDECAR_KAFKA_CERTS_VOLUME_MOUNT, containers.get(1).getVolumeMounts().get(0).getMountPath());
251252
assertEquals(KafkaCluster.TLS_SIDECAR_CLUSTER_CA_CERTS_VOLUME_MOUNT, containers.get(1).getVolumeMounts().get(1).getMountPath());
252253

254+
if (cm.getSpec().getKafka().getStorage() != null) {
255+
io.strimzi.api.kafka.model.Storage storage = cm.getSpec().getKafka().getStorage();
256+
if (storage instanceof PersistentClaimStorage && !isOpenShift) {
257+
PodSpec podSpec = ss.getSpec().getTemplate().getSpec();
258+
// check that pod spec contains the volume hack container for Kubernetes
259+
List<Container> initContainers = podSpec.getInitContainers();
260+
assertNotNull(initContainers);
261+
assertTrue(initContainers.size() > 0);
262+
boolean isVolumeHack =
263+
initContainers.stream().anyMatch(container -> container.getName().equals(AbstractModel.VOLUME_MOUNT_HACK_NAME));
264+
assertTrue(isVolumeHack);
265+
}
266+
}
267+
253268
if (cm.getSpec().getKafka().getRack() != null) {
254269

255270
Rack rack = cm.getSpec().getKafka().getRack();

0 commit comments

Comments
 (0)