Skip to content

Commit 82dd6fd

Browse files
authoredJul 19, 2024
Merge pull request juju#17578 from hpidcock/rootless-3.6
juju#17578 Uses updated pebble version with pebble identities so that the charm container in a k8s deployment can run without root and connect to the pebble instances running in the workload containers (who may be running as a different user). With this patch the charm can specify in the metadata.yaml a charm-user field with either the values root, non-root or sudoer. |charm-user|user|user-id| |-|-|-| |root|root|0| |non-root|juju|170| |sudoer|sjuju|171| ## QA steps - test root charm can be deployed - test model with root charm from 3.5 can be model migrated - test rootless charm can be deployed (with charm-user: non-root and charm-user: sudoer) works - run integration tests `./main.sh -p k8s -c minikube sidecar test_rootless` ## Documentation changes Document in metadata.yaml docs the `charm-user` field. ## Links **Jira card:** JUJU-5130
2 parents f2c9fe1 + 7a6ec0e commit 82dd6fd

File tree

26 files changed

+1502
-399
lines changed

26 files changed

+1502
-399
lines changed
 

‎caas/kubernetes/provider/application/application.go

+39-3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ var (
7676
containerAgentPebbleVersion = version.MustParse("2.9.37")
7777
profileDirVersion = version.MustParse("3.5-beta1")
7878
pebbleCopyOnceVersion = version.MustParse("3.5-beta1")
79+
pebbleIdentitiesVersion = version.MustParse("3.6-beta2")
7980
)
8081

8182
type app struct {
@@ -1484,6 +1485,7 @@ func (a *app) ApplicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
14841485
},
14851486
}, charmContainerExtraVolumeMounts...),
14861487
}
1488+
pebbleIdentitiesEnabled := false
14871489
if requireSecurityContext {
14881490
switch config.CharmUser {
14891491
case caas.RunAsRoot:
@@ -1496,12 +1498,16 @@ func (a *app) ApplicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
14961498
RunAsUser: pointer.Int64(constants.JujuSudoUserID),
14971499
RunAsGroup: pointer.Int64(constants.JujuSudoGroupID),
14981500
}
1501+
pebbleIdentitiesEnabled = true
14991502
case caas.RunAsNonRoot:
15001503
charmContainer.SecurityContext = &corev1.SecurityContext{
15011504
RunAsUser: pointer.Int64(constants.JujuUserID),
15021505
RunAsGroup: pointer.Int64(constants.JujuGroupID),
15031506
}
1507+
pebbleIdentitiesEnabled = true
15041508
}
1509+
pebbleIdentitiesEnabled = pebbleIdentitiesEnabled &&
1510+
agentVersionNoBuild.Compare(pebbleIdentitiesVersion) >= 0
15051511
} else {
15061512
// Pre-3.5 logic.
15071513
charmContainer.SecurityContext = &corev1.SecurityContext{
@@ -1524,20 +1530,25 @@ func (a *app) ApplicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
15241530
})
15251531
}
15261532

1533+
containerExtraArgs := []string{}
1534+
if pebbleIdentitiesEnabled {
1535+
containerExtraArgs = append(containerExtraArgs, "--identities", "/charm/etc/pebble/identities.yaml")
1536+
}
1537+
15271538
containerSpecs := []corev1.Container{charmContainer}
15281539
for i, v := range containers {
15291540
container := corev1.Container{
15301541
Name: v.Name,
15311542
ImagePullPolicy: corev1.PullIfNotPresent,
15321543
Image: v.Image.RegistryPath,
15331544
Command: []string{"/charm/bin/pebble"},
1534-
Args: []string{
1545+
Args: append([]string{
15351546
"run",
15361547
"--create-dirs",
15371548
"--hold",
15381549
"--http", fmt.Sprintf(":%s", pebble.WorkloadHealthCheckPort(i)),
15391550
"--verbose",
1540-
},
1551+
}, containerExtraArgs...),
15411552
Env: append([]corev1.EnvVar{{
15421553
Name: "JUJU_CONTAINER_NAME",
15431554
Value: v.Name,
@@ -1587,6 +1598,14 @@ func (a *app) ApplicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
15871598
RunAsGroup: pointer.Int64(0),
15881599
}
15891600
}
1601+
if pebbleIdentitiesEnabled {
1602+
container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
1603+
Name: constants.CharmVolumeName,
1604+
MountPath: "/charm/etc/pebble/identities.yaml",
1605+
SubPath: "charm/etc/pebble/identities.yaml",
1606+
ReadOnly: true,
1607+
})
1608+
}
15901609
if v.Image.Password != "" {
15911610
imagePullSecrets = append(imagePullSecrets, corev1.LocalObjectReference{Name: a.imagePullSecretName(v.Name)})
15921611
}
@@ -1609,7 +1628,7 @@ func (a *app) ApplicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
16091628
}
16101629
// (tlm) lp1997253. If the agent version is less then containerAgentPebbleVersion
16111630
// we need to keep still using the old args supported by the init command
1612-
if config.AgentVersion.Compare(containerAgentPebbleVersion) < 0 {
1631+
if agentVersionNoBuild.Compare(containerAgentPebbleVersion) < 0 {
16131632
charmInitAdditionalMounts = []corev1.VolumeMount{}
16141633
containerAgentArgs = []string{
16151634
"init",
@@ -1627,6 +1646,23 @@ func (a *app) ApplicationPodSpec(config caas.ApplicationConfig) (*corev1.PodSpec
16271646
})
16281647
}
16291648

1649+
if pebbleIdentitiesEnabled {
1650+
containerAgentArgs = append(containerAgentArgs, "--pebble-identities-file", "/charm/etc/pebble/identities.yaml")
1651+
charmInitAdditionalMounts = append(charmInitAdditionalMounts, corev1.VolumeMount{
1652+
Name: constants.CharmVolumeName,
1653+
MountPath: "/charm/etc/pebble/",
1654+
SubPath: "charm/etc/pebble/",
1655+
})
1656+
uid := 0
1657+
switch config.CharmUser {
1658+
case caas.RunAsSudoer:
1659+
uid = constants.JujuSudoUserID
1660+
case caas.RunAsNonRoot:
1661+
uid = constants.JujuUserID
1662+
}
1663+
containerAgentArgs = append(containerAgentArgs, "--pebble-charm-identity", strconv.Itoa(uid))
1664+
}
1665+
16301666
appSecret := a.secretName()
16311667
charmInitContainer := corev1.Container{
16321668
Name: constants.ApplicationInitContainer,

0 commit comments

Comments
 (0)
Merge pull request #17578 from hpidcock/rootless-3.6 &middot; JoseFMP/juju@82dd6fd · GitHub