diff --git a/pkg/resource/statefulset.go b/pkg/resource/statefulset.go index beeafbe..590f2cb 100644 --- a/pkg/resource/statefulset.go +++ b/pkg/resource/statefulset.go @@ -25,6 +25,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" client "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -34,12 +35,10 @@ func NewStatefulSetBuilder() PerNodeBuilder { return &StatefulSetBuilder{} } - func (b *StatefulSetBuilder) Build(ctx context.Context, cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBNode) (client.Object, error) { return BuildStatefulSet(cluster, node) } - func BuildStatefulSet(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBNode) (*appsv1.StatefulSet, error) { stsName := common.NodeResourceName(node.Tag) @@ -61,7 +60,6 @@ func BuildStatefulSet(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBN affinity := buildAWSNodeAffinity(cluster, node.Tag) - sts := &appsv1.StatefulSet{ TypeMeta: metav1.TypeMeta{ APIVersion: "apps/v1", @@ -87,16 +85,7 @@ func BuildStatefulSet(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBN Affinity: affinity, ServiceAccountName: common.RavenDbNodeServiceAccount, - // alows us to bind lower ports like 443 - // considered safe. see: https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#safe-and-unsafe-sysctls - SecurityContext: &corev1.PodSecurityContext{ - Sysctls: []corev1.Sysctl{ - { - Name: "net.ipv4.ip_unprivileged_port_start", - Value: "0", - }, - }, - }, + SecurityContext: buildPodSecurityContext(), }, }, VolumeClaimTemplates: volumeClaims, @@ -106,6 +95,23 @@ func BuildStatefulSet(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBN return sts, nil } +func buildPodSecurityContext() *corev1.PodSecurityContext { + fsGroupChangePolicy := corev1.FSGroupChangeOnRootMismatch + + return &corev1.PodSecurityContext{ + FSGroup: pointer.Int64(999), + FSGroupChangePolicy: &fsGroupChangePolicy, + + // Allows RavenDB to bind lower ports like 443. This sysctl is considered safe. + // See: https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#safe-and-unsafe-sysctls + Sysctls: []corev1.Sysctl{ + { + Name: "net.ipv4.ip_unprivileged_port_start", + Value: "0", + }, + }, + } +} func buildContainers(image string, env []corev1.EnvVar, ports []corev1.ContainerPort, mounts []corev1.VolumeMount, ipp corev1.PullPolicy, cluster *ravendbv1.RavenDBCluster) []corev1.Container { rdbContainer := BuildRavenDBContainer(image, env, ports, mounts, ipp) @@ -119,14 +125,11 @@ func buildContainers(image string, env []corev1.EnvVar, ports []corev1.Container } - - func buildStatefulsetSelector(node ravendbv1.RavenDBNode) map[string]string { return map[string]string{ common.LabelNodeTag: node.Tag} } - func buildStatefulsetLabels(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBNode) map[string]string { return map[string]string{ common.LabelAppName: common.App, @@ -142,7 +145,6 @@ func buildStatefulsetAnnotations() map[string]string { } } - func buildEnvVars(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBNode) ([]corev1.EnvVar, error) { env := common.BuildCommonEnvVars(cluster, node) @@ -176,7 +178,6 @@ func buildPorts() []corev1.ContainerPort { } } - func buildVolumes(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBNode) []corev1.Volume { var volumes []corev1.Volume @@ -226,7 +227,6 @@ func buildVolumes(cluster *ravendbv1.RavenDBCluster, node ravendbv1.RavenDBNode) return volumes } - func buildVolumeMounts(cluster *ravendbv1.RavenDBCluster) []corev1.VolumeMount { vMounts := []corev1.VolumeMount{ buildVolumeMount(common.DataVolumeName, common.DataMountPath), @@ -278,7 +278,6 @@ func buildVolumeMounts(cluster *ravendbv1.RavenDBCluster) []corev1.VolumeMount { return vMounts } - func BuildPVCs(cluster *ravendbv1.RavenDBCluster) []corev1.PersistentVolumeClaim { var pvcs []corev1.PersistentVolumeClaim @@ -317,7 +316,6 @@ func BuildPVCs(cluster *ravendbv1.RavenDBCluster) []corev1.PersistentVolumeClaim return pvcs } - func buildAWSNodeAffinity(cluster *ravendbv1.RavenDBCluster, tag string) *corev1.Affinity { if cluster.Spec.ExternalAccessConfiguration == nil || diff --git a/pkg/resource/statefulset_test.go b/pkg/resource/statefulset_test.go new file mode 100644 index 0000000..546fcf4 --- /dev/null +++ b/pkg/resource/statefulset_test.go @@ -0,0 +1,22 @@ +package resource + +import ( + "testing" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" +) + +func TestBuildPodSecurityContextSetsRavenDBFsGroup(t *testing.T) { + sc := buildPodSecurityContext() + + require.NotNil(t, sc) + require.NotNil(t, sc.FSGroup) + require.EqualValues(t, 999, *sc.FSGroup) + require.NotNil(t, sc.FSGroupChangePolicy) + require.Equal(t, corev1.FSGroupChangeOnRootMismatch, *sc.FSGroupChangePolicy) + require.Contains(t, sc.Sysctls, corev1.Sysctl{ + Name: "net.ipv4.ip_unprivileged_port_start", + Value: "0", + }) +}