Skip to content

Commit

Permalink
Add SecurityContext to sidecars containers
Browse files Browse the repository at this point in the history
  • Loading branch information
barkbay committed Apr 21, 2023
1 parent 94568de commit 7684189
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
27 changes: 22 additions & 5 deletions pkg/controller/common/stackmon/sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"hash"

corev1 "k8s.io/api/core/v1"
ptr "k8s.io/utils/pointer"

commonv1 "github.com/elastic/cloud-on-k8s/v2/pkg/apis/common/v1"
"github.com/elastic/cloud-on-k8s/v2/pkg/controller/common/container"
Expand Down Expand Up @@ -47,12 +48,17 @@ func NewMetricBeatSidecar(
return BeatSidecar{}, err
}
image := container.ImageRepository(container.MetricbeatImage, version)
return NewBeatSidecar(ctx, client, "metricbeat", image, resource, monitoring.GetMetricsAssociation(resource), baseConfig, sourceCaVolume)

// EmptyDir volume so that MetricBeat does not write in the container image, which allows ReadOnlyRootFilesystem: true
emptyDir := volume.NewEmptyDirVolume("metricbeat-data", "/usr/share/metricbeat/data")
return NewBeatSidecar(ctx, client, "metricbeat", image, resource, monitoring.GetMetricsAssociation(resource), baseConfig, sourceCaVolume, emptyDir)
}

func NewFileBeatSidecar(ctx context.Context, client k8s.Client, resource monitoring.HasMonitoring, version string, baseConfig string, additionalVolume volume.VolumeLike) (BeatSidecar, error) {
image := container.ImageRepository(container.FilebeatImage, version)
return NewBeatSidecar(ctx, client, "filebeat", image, resource, monitoring.GetLogsAssociation(resource), baseConfig, additionalVolume)
// EmptyDir volume so that FileBeat does not write in the container image, which allows ReadOnlyRootFilesystem: true
emptyDir := volume.NewEmptyDirVolume("filebeat-data", "/usr/share/filebeat/data")
return NewBeatSidecar(ctx, client, "filebeat", image, resource, monitoring.GetLogsAssociation(resource), baseConfig, additionalVolume, emptyDir)
}

// BeatSidecar helps with building a beat sidecar container to monitor an Elastic Stack application. It focuses on
Expand All @@ -65,7 +71,7 @@ type BeatSidecar struct {
}

func NewBeatSidecar(ctx context.Context, client k8s.Client, beatName string, image string, resource monitoring.HasMonitoring,
associations []commonv1.Association, baseConfig string, additionalVolume volume.VolumeLike,
associations []commonv1.Association, baseConfig string, additionalVolumes ...volume.VolumeLike,
) (BeatSidecar, error) {
// build the beat config
config, err := newBeatConfig(ctx, client, beatName, resource, associations, baseConfig)
Expand All @@ -75,8 +81,10 @@ func NewBeatSidecar(ctx context.Context, client k8s.Client, beatName string, ima

// add additional volume (ex: CA volume of the monitored ES for Metricbeat)
volumes := config.volumes
if additionalVolume != nil {
volumes = append(volumes, additionalVolume)
for _, additionalVolume := range additionalVolumes {
if additionalVolume != nil {
volumes = append(volumes, additionalVolume)
}
}

// prepare the volume mounts for the beat container from all provided volumes
Expand All @@ -98,6 +106,15 @@ func NewBeatSidecar(ctx context.Context, client k8s.Client, beatName string, ima
Args: []string{"-c", config.filepath, "-e"},
Env: defaults.PodDownwardEnvVars(),
VolumeMounts: volumeMounts,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
Privileged: ptr.Bool(false),
RunAsNonRoot: ptr.Bool(true),
ReadOnlyRootFilesystem: ptr.Bool(true),
AllowPrivilegeEscalation: ptr.Bool(false),
},
},
ConfigHash: config.hash,
ConfigSecret: config.secret,
Expand Down
13 changes: 7 additions & 6 deletions test/e2e/test/elasticsearch/check_securitycontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package elasticsearch

import (
"strings"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -32,23 +33,23 @@ func CheckContainerSecurityContext(es esv1.Elasticsearch, k *test.K8sClient) tes
ver := version.MustParse(es.Spec.Version)
for _, p := range pods {
for _, c := range p.Spec.Containers {
asserSecurityContext(t, ver, c.SecurityContext)
asserSecurityContext(t, ver, c.SecurityContext, c.Image)
}
for _, c := range p.Spec.InitContainers {
asserSecurityContext(t, ver, c.SecurityContext)
asserSecurityContext(t, ver, c.SecurityContext, c.Image)
}
}
},
}
}

func asserSecurityContext(t *testing.T, ver version.Version, securityContext *corev1.SecurityContext) {
func asserSecurityContext(t *testing.T, ver version.Version, securityContext *corev1.SecurityContext, image string) {
t.Helper()
require.NotNil(t, securityContext)
if ver.LT(securitycontext.MinStackVersion) {
require.Nil(t, securityContext.RunAsNonRoot)
if strings.HasPrefix(image, "docker.elastic.co/elasticsearch/elasticsearch") && ver.LT(securitycontext.MinStackVersion) {
require.Nilf(t, securityContext.RunAsNonRoot, "RunAsNonRoot was expected to be nil")
} else {
require.Equal(t, ptr.Bool(true), securityContext.RunAsNonRoot)
require.Equal(t, ptr.Bool(true), securityContext.RunAsNonRoot, "RunAsNonRoot was expected to be true")
}
require.NotNil(t, securityContext.Privileged)
require.False(t, *securityContext.Privileged)
Expand Down

0 comments on commit 7684189

Please sign in to comment.