Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New container locator for docker/k8s on linux #5076

Merged
merged 11 commits into from
Apr 24, 2024

Conversation

azdagron
Copy link
Member

@azdagron azdagron commented Apr 18, 2024

The docker and k8s workload attestors work backwards from pid to container by inspecting the proc filesystem. Today, this happens by inspecting the cgroup file. Identifying the container ID (and pod UID) from the cgroup file has been a continual arms race. The k8s and docker workload attestors grew different mechanisms for trying to deal with the large variety in the output.

Further, with cgroups v2 and private namespaces, the cgroup file might not have the container ID or pod UID information within it.

This PR unifies the container ID (and pod UID) extraction for both the docker and k8s workload attestors. The new implementation searches the mountinfo file first for cgroups mounts. If not found, it will fall back to the cgroup file (typically necessary only when the workload is running in the same container as the agent).

The extraction algorithm is the same for both mountinfo and cgroup entries, and is as follows:

  1. Iterator over each entry in the file being searched, extracting either the cgroup mount root (mountinfo) or the cgroup group path (cgroup) as the source path.
  2. Walk backwards through the segments in the source path looking for the 64-bit hex digit container ID.
  3. If looking for the pod UID (K8s only), then walk backwards through the segments in the path looking for the pod UID pattern used by kubelet. Start with the segment the container ID was found in (truncated to remove the container ID portion).
  4. If there are pod UID/container ID conflicts after searching these files then log and abort. Entries that have a pod UID override those that don't.

The container ID is very often contained in the last segment in the path but there are situations where it isn't.

This new functionality is NOT enabled by default, but opted in using the use_new_container_locator configurable in each plugin. In 1.10, we can consider enabling it by default.

The testing for the new code is spread out a little bit. The cgroups fallback functionality is mostly tested by the existing tests in the k8s and docker plugin tests. The mountinfo tests are only in the new containerinfo package.

In the long term, I'd like to see all of the container info extraction related tests moved solely to the containerinfo package and removed from the individual plugins.

Resolves #4004, resolves #4682, resolves #4917.

The docker and k8s workload attestors work backwards from pid to
container by inspecting the proc filesystem. Today, this happens by
inspecting the cgroup file. Identifying the container ID (and pod UID)
from the cgroup file has been a continual arms race. The k8s and docker
workload attestors grew different mechanisms for trying to deal with the
large variety in the output.

Further, with cgroups v2 and private namespaces, the cgroup file might
not have the container ID or pod UID information within it.

This PR unifies the container ID (and pod UID) extraction for both the
docker and k8s workload attestors. The new implementation searches the
mountinfo file first for cgroups mounts. If not found, it will fall back
to the cgroup file (typically necessary only when the workload is
running in the same container as the agent).

The extraction algorithm is the same for both mountinfo and cgroup
entries, and is as follows:
1. Iterator over each entry in the file being searched, extracting
   either the cgroup mount root (mountinfo) or the cgroup group
   path (cgroup) as the source path.
2. Walk backwards through the segments in the source path looking for
   the 64-bit hex digit container ID.
3. If looking for the pod UID (K8s only), then walk backwards through
   the segments in the path looking for the pod UID pattern used by
   kubelet. Start with the segment the container ID was found in
   (truncated to remove the container ID portion).
4. If there are pod UID/container ID conflicts after searching these
   files then log and abort. Entries that have a pod UID override those
   that don't.

The container ID is very often contained in the last segment in the path
but there are situations where it isn't.

This new functionality is NOT enabled by default, but opted in using the
`use_new_container_locator` configurable in each plugin. In 1.10, we can
consider enabling it by default.

The testing for the new code is spread out a little bit. The cgroups
fallback functionality is mostly tested by the existing tests in the
k8s and docker plugin tests. The mountinfo tests are only in the new
containerinfo package.

In the long term, I'd like to see all of the container info extraction
related tests moved solely to the containerinfo package and removed from
the individual plugins.

Resolves spiffe#4004, resolves spiffe#4682, resolves spiffe#4917.

Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
@MarcosDY MarcosDY self-assigned this Apr 18, 2024
pkg/agent/plugin/workloadattestor/docker/docker_posix.go Outdated Show resolved Hide resolved
pkg/agent/plugin/workloadattestor/k8s/k8s.go Outdated Show resolved Hide resolved
pkg/agent/plugin/workloadattestor/k8s/k8s_posix.go Outdated Show resolved Hide resolved
pkg/common/containerinfo/extract.go Outdated Show resolved Hide resolved
pkg/common/containerinfo/extract.go Outdated Show resolved Hide resolved
pkg/common/containerinfo/extract_test.go Show resolved Hide resolved
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
Signed-off-by: Andrew Harding <azdagron@gmail.com>
@azdagron azdagron merged commit 8090bf3 into spiffe:main Apr 24, 2024
32 checks passed
@azdagron azdagron deleted the new-container-locator branch April 24, 2024 14:01
@amartinezfayo amartinezfayo added this to the 1.9.6 milestone May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants