Skip to content

Commit

Permalink
refactor(cri): restructure parsing of the pod sandbox container itself
Browse files Browse the repository at this point in the history
Signed-off-by: Melissa Kilby <[email protected]>
  • Loading branch information
incertum committed Dec 21, 2023
1 parent 6996c16 commit fa2e23e
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 12 deletions.
36 changes: 26 additions & 10 deletions userspace/libsinsp/cri.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,20 @@ template<class api> class cri_interface
Json::Value get_info_jvalue(const google::protobuf::Map<std::string, std::string> &info);

/**
* @brief fill out pod sandbox labels
* @brief fill out status base fields
* @param status `status` field of the ContainerStatusResponse
* @param container the container info to fill out
* @return true if successful
*/
bool parse_cri_base(const typename api::ContainerStatus &status, sinsp_container_info &container);
bool parse_cri_base(const typename api::ContainerStatus &status, sinsp_container_info &container);

/**
* @brief fill out status base fields; overloaded w/ PodSandboxStatus
* @param status `status` field of the PodSandboxStatusResponse
* @param container the container info to fill out
* @return true if successful
*/
bool parse_cri_base(const typename api::PodSandboxStatus &status, sinsp_container_info &container);

/**
* @brief fill out container image information based on CRI response
Expand All @@ -191,7 +199,7 @@ template<class api> class cri_interface
bool parse_cri_mounts(const typename api::ContainerStatus &status, sinsp_container_info &container);

/**
* @brief fill out container environment variables based on CRI response
* @brief fill out container environment variables based on CRI response, valid for containerd only
* @param root Json::Value of status.info() at "info of the ContainerStatusResponse
* @param container the container info to fill out
* @return true if successful
Expand All @@ -201,7 +209,7 @@ template<class api> class cri_interface
bool parse_cri_env(const Json::Value &root, sinsp_container_info &container);

/**
* @brief fill out extra image info based on CRI response
* @brief fill out extra image info based on CRI response, valid for containerd only
* @param root Json::Value of status.info() at "info of the ContainerStatusResponse
* @param container the container info to fill out
* @return true if successful
Expand Down Expand Up @@ -229,24 +237,32 @@ template<class api> class cri_interface
bool parse_cri_user_info(const Json::Value &root, sinsp_container_info &container);

/**
* @brief fill out pod sandbox labels
* @brief fill out container labels
* @param status `status` field of the ContainerStatusResponse
* @param container the container info to fill out
* @return true if successful
*/
bool parse_cri_labels(const typename api::ContainerStatus &status, sinsp_container_info &container);
bool parse_cri_labels(const typename api::ContainerStatus &status, sinsp_container_info &container);

/**
* @brief fill out pod sandbox labels
* @param root Json::Value of status.info() at "info of the PodSandboxStatusResponse
* @brief fill out container labels; overloaded w/ PodSandboxStatus
* @param status `status` field of the PodSandboxStatusResponse
* @param container the container info to fill out
* @return true if successful
*/
bool parse_cri_labels(const typename api::PodSandboxStatus &status, sinsp_container_info &container);

/**
* @brief fill out pod sandbox id
* @param root Json::Value of status.info() at "info of the ContainerStatusResponse
* @param container the container info to fill out
* @return true if successful
*/
bool parse_cri_pod_sandbox_id(const Json::Value &root,
sinsp_container_info &container);

/**
* @brief fill out pod sandbox labels
* @brief fill out pod sandbox network info
* @param status `status` field of the PodSandboxStatusResponse
* @param root Json::Value of status.info() at "info of the PodSandboxStatusResponse
* @param container the container info to fill out
Expand All @@ -262,7 +278,7 @@ template<class api> class cri_interface
* @param container the container info to fill out
* @return true if successful
*/
bool parse_cri_pod_sandbox_labels(const typename api::PodSandboxStatus &status, sinsp_container_info &container);
bool parse_cri_pod_sandbox_labels(const typename api::PodSandboxStatus &status, sinsp_container_info &container);

/**
* @brief make request and get PodSandboxStatusResponse
Expand Down
52 changes: 51 additions & 1 deletion userspace/libsinsp/cri.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,18 @@ inline bool cri_interface<api>::parse_cri_base(const typename api::ContainerStat
return true;
}

// overloaded w/ PodSandboxStatus
template<typename api>
inline bool cri_interface<api>::parse_cri_base(const typename api::PodSandboxStatus &status, sinsp_container_info &container)
{
container.m_full_id = status.id();
container.m_name = status.metadata().name();
// This is in Nanoseconds(in CRI API). Need to convert it to seconds.
container.m_created_time = static_cast<int64_t>(status.created_at() / ONE_SECOND_IN_NS);

return true;
}

template<typename api>
inline bool cri_interface<api>::parse_cri_image(const typename api::ContainerStatus &status,
const Json::Value &root,
Expand Down Expand Up @@ -498,6 +510,24 @@ inline bool cri_interface<api>::parse_cri_labels(const typename api::ContainerSt
return true;
}

// overloaded w/ PodSandboxStatus
template<typename api>
inline bool cri_interface<api>::parse_cri_labels(const typename api::PodSandboxStatus &status, sinsp_container_info &container)
{
for(const auto &pair : status.labels())
{
if(pair.second.length() <= sinsp_container_info::m_container_label_max_length)
{
container.m_labels[pair.first] = pair.second;
}
}
container.m_labels["io.kubernetes.pod.uid"] = status.metadata().uid();
container.m_labels["io.kubernetes.pod.name"] = status.metadata().name();
container.m_labels["io.kubernetes.pod.namespace"] = status.metadata().namespace_();

return true;
}

template<typename api>
inline bool cri_interface<api>::parse_cri_pod_sandbox_id(const Json::Value &root,
sinsp_container_info &container)
Expand All @@ -518,7 +548,6 @@ inline bool cri_interface<api>::parse_cri_pod_sandbox_id(const Json::Value &root
return true;
}


template<typename api>
inline bool cri_interface<api>::parse_cri_pod_sandbox_labels(const typename api::PodSandboxStatus &status, sinsp_container_info &container)
{
Expand Down Expand Up @@ -680,7 +709,21 @@ inline bool cri_interface<api>::parse(const libsinsp::cgroup_limits::cgroup_limi
status = get_pod_sandbox_status_resp(container.m_id, pod_sandbox_status_resp);
if(status.ok())
{
/*
* We also want to ensure that the pod sandbox container stored in the container cache is
* fully filled out with available information as applicable.
* Most notably, the container's m_full_id and m_pod_sandbox_id will be the same, and the
* absence of container images can be attributed to the fact that they are not available for
* pod sandbox container processes.
*/
container.m_is_pod_sandbox = true;
const auto &resp_pod_sandbox_container = pod_sandbox_status_resp.status();
const auto &resp_pod_sandbox_container_info = pod_sandbox_status_resp.info();
const auto root_pod_sandbox = get_info_jvalue(resp_pod_sandbox_container_info);
parse_cri_base(resp_pod_sandbox_container, container);
parse_cri_labels(resp_pod_sandbox_container, container);
parse_cri_pod_sandbox_network(resp_pod_sandbox_container, root_pod_sandbox, container);
parse_cri_pod_sandbox_labels(resp_pod_sandbox_container, container);
return true;
}
else
Expand Down Expand Up @@ -730,6 +773,13 @@ inline bool cri_interface<api>::parse(const libsinsp::cgroup_limits::cgroup_limi

if(s_cri_extra_queries)
{
/*
* The recent refactor makes full use of PodSandboxStatusResponse, removing the need to access pod sandbox containers
* in k8s filterchecks. Now, we also store the pod labels in the container.
* While this might seem redundant in cases where multiple containers exist in a pod, considering that the concurrent
* number of containers on a node is typically capped at 100-300, it doesn't add significant overhead. Moreover, these
* extra lookups have always been performed for container ips in the past.
*/
typename api::PodSandboxStatusResponse pod_sandbox_status_resp;
status = get_pod_sandbox_status_resp(container.m_pod_sandbox_id, pod_sandbox_status_resp);
const auto &resp_pod_sandbox_container = pod_sandbox_status_resp.status();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ runtime::v1alpha2::PodSandboxStatusResponse get_default_cri_crio_pod_status_resp

TEST_F(sinsp_with_test_input, container_parser_cri_crio)
{
std::string cri_path = "/run/containerd/containerd_mock.sock";
std::string cri_path = "/run/crio/crio_mock.sock";
auto cri_api_v1alpha2 = std::make_unique<libsinsp::cri::cri_interface_v1alpha2>(cri_path);
ASSERT_FALSE(cri_api_v1alpha2->is_ok()); // we are not querying a container runtime socket in this mock test

Expand Down

0 comments on commit fa2e23e

Please sign in to comment.