diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 4bb89145a864..6d52b5ad55d2 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -135,3 +135,4 @@ - Add new --enroll-delay option for install and enroll commands. {pull}27118[27118] - Add link to troubleshooting guide on fatal exits. {issue}26367[26367] {pull}27236[27236] - Agent now adapts the beats queue size based on output settings. {issue}26638[26638] {pull}27429[27429] +- Support ephemeral containers in Kubernetes dynamic provider. {issue}#27020[#27020] {pull}27707[27707] diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go index b0b3ab3b5258..7c48f7559763 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod.go @@ -67,7 +67,11 @@ func (p *pod) emitRunning(pod *kubernetes.Pod) { // TODO: deal with init containers stopping after initialization p.emitContainers(pod, pod.Spec.InitContainers, pod.Status.InitContainerStatuses) - // TODO: deal with ephemeral containers + + // Get ephemeral containers and their status + ephContainers, ephContainersStatuses := getEphemeralContainers(pod) + p.emitContainers(pod, ephContainers, ephContainersStatuses) + } func (p *pod) emitContainers(pod *kubernetes.Pod, containers []kubernetes.Container, containerstatuses []kubernetes.PodContainerStatus) { @@ -222,3 +226,16 @@ func generateContainerData( comm.AddOrUpdate(eventID, ContainerPriority, mapping, processors) } } + +func getEphemeralContainers(pod *kubernetes.Pod) ([]kubernetes.Container, []kubernetes.PodContainerStatus) { + var ephContainers []kubernetes.Container + var ephContainersStatuses []kubernetes.PodContainerStatus + for _, c := range pod.Spec.EphemeralContainers { + c := kubernetes.Container(c.EphemeralContainerCommon) + ephContainers = append(ephContainers, c) + } + for _, s := range pod.Status.EphemeralContainerStatuses { + ephContainersStatuses = append(ephContainersStatuses, s) + } + return ephContainers, ephContainersStatuses +} diff --git a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go index 1e85557a2d62..00c7ee84766e 100644 --- a/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go +++ b/x-pack/elastic-agent/pkg/composable/providers/kubernetes/pod_test.go @@ -166,6 +166,79 @@ func TestGenerateContainerPodData(t *testing.T) { } +func TestGetEphemeralContainers(t *testing.T) { + name := "filebeat" + namespace := "default" + podIP := "127.0.0.1" + containerID := "docker://foobar" + uid := "005f3b90-4b9d-12f8-acf0-31020a840133" + containerImage := "elastic/filebeat:6.3.0" + node := "node" + + expectedEphemeralContainers := + []kubernetes.Container{ + { + Name: "filebeat", + Image: "elastic/filebeat:6.3.0", + }, + } + expectedephemeralContainersStatuses := + []kubernetes.PodContainerStatus{ + { + Name: "filebeat", + State: v1.ContainerState{ + Running: &v1.ContainerStateRunning{ + StartedAt: metav1.Time{}, + }, + }, + Ready: false, + ContainerID: "docker://foobar", + }, + } + + pod := + &kubernetes.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + UID: types.UID(uid), + Namespace: namespace, + Labels: map[string]string{}, + Annotations: map[string]string{}, + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pod", + APIVersion: "v1", + }, + Status: v1.PodStatus{ + PodIP: podIP, + Phase: kubernetes.PodRunning, + EphemeralContainerStatuses: []kubernetes.PodContainerStatus{ + { + Name: name, + ContainerID: containerID, + State: v1.ContainerState{ + Running: &v1.ContainerStateRunning{}, + }, + }, + }, + }, + Spec: v1.PodSpec{ + NodeName: node, + EphemeralContainers: []v1.EphemeralContainer{ + { + EphemeralContainerCommon: v1.EphemeralContainerCommon{ + Image: containerImage, + Name: name, + }, + }, + }, + }, + } + ephContainers, ephContainersStatuses := getEphemeralContainers(pod) + assert.Equal(t, expectedEphemeralContainers, ephContainers) + assert.Equal(t, expectedephemeralContainersStatuses, ephContainersStatuses) +} + // MockDynamicComm is used in tests. type MockDynamicComm struct { context.Context