-
Notifications
You must be signed in to change notification settings - Fork 11
Implement new Kubernetes resources and metadata. #25
Conversation
5dcfa20 to
3060b15
Compare
src/kubernetes.cc
Outdated
| LOG(INFO) << "Kubernetes Query called"; | ||
| std::vector<PollingMetadataUpdater::ResourceMetadata> result; | ||
|
|
||
| const std::string platform = "gce"; // TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add some description for this TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
| result.emplace_back( | ||
| std::vector<std::string>{k8s_node_name}, | ||
| k8s_node, | ||
| #ifdef ENABLE_KUBERNETES_METADATA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, for which case will we set ENABLE_KUBERNETES_METADATA false? I guess the Logging Agent / Monitoring Agent does not need metadata to be present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, this is a compile-time flag. We might need to make it a configuration option at some point.
I'd prefer to leave it here, but we could also take it out and make this code unconditional. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. I think it's fine to leave it as it is for now.
src/kubernetes.cc
Outdated
| path_component.second + "/" + name); | ||
| } | ||
|
|
||
| json::value KubernetesReader::FindPrimary( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:%s/FindPrimary/FindPrimaryController/g?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gave an even more accurate name to this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Thanks.
| constexpr const char kKubernetesEndpointPath[] = "/api/v1"; | ||
| constexpr const char kResourceTypeSeparator[] = "."; | ||
|
|
||
| constexpr const char kRawContentVersion[] = "0.1"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we decide which metadata is versioned by kRawContentVersion, while others are versioned by kKubernetesEndpointPath? Maybe a brief comment for clarification?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't version anything by kKubernetesEndpointPath -- I assume you meant kKubernetesApiVersion. This is the format defined by the target API. Blobs that come directly from Kubernetes and are ingested verbatim are versioned with the API version, while blobs that we have to construct are versioned by kRawContentVersion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. And yeah, I meant kKubernetesApiVersion.
| {"association", json::object({ | ||
| {"version", json::string(kRawContentVersion)}, | ||
| {"raw", json::object({ | ||
| {"providerPlatform", json::string(platform)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this camel cased for consistency with another reference to providerPlatform?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what the metadata API will be looking for. We can coordinate and change this if it becomes an issue.
src/kubernetes.cc
Outdated
| config_.KubernetesPodLabelSelector().empty() | ||
| ? "" : "?" + config_.KubernetesPodLabelSelector()); | ||
| ? "" : "&" + config_.KubernetesPodLabelSelector()); | ||
| const std::string node_selector(kNodeSelectorPrefix + node_name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: It was a little confusing having the node_selector defined second here, yet having the pod_label_selector appended with a & as the delimiter. For the mental sequencing, I feel that node_selector should be defined first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Done.
| << "have different sizes: " | ||
| << container_specs->size() << " vs " | ||
| << container_list->size() << " for pod " | ||
| << pod_id << "(" << pod_name << ")"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need some form of a return here? Will some sort of error occur in the next loop if these sizes don't align?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've picked the minimum of the two for the loop.
src/kubernetes.cc
Outdated
| bool is_deleted = false; | ||
|
|
||
| const MonitoredResource resource("gke_container", { | ||
| const MonitoredResource gke_resource("gke_container", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we call this gke_resource instead of gke_container?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No good reason other than it used to be called resource and I was lazy. Renamed.
| gke_resource, | ||
| MetadataAgent::Metadata::IGNORED()); | ||
|
|
||
| const MonitoredResource k8s_container("k8s_container", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we should call the variable mentioned above "gke_resource", should this be called "k8s_resource"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It started that way, but there are multiple k8s_* resources... Renamed gke_resource to gke_container to match.
src/kubernetes.cc
Outdated
| try { | ||
| http::client::response response = client.get(request); | ||
| #ifdef DEBUG | ||
| LOG(INFO) << "QueryMaster: Response: " << body(response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional here is DEBUG, should we be logging with level DEBUG?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be an unfortunate clash of a macro with an enum value, actually... I've renamed the macro to VERBOSE, and changed the logging to DEBUG.
| if (current_node_.empty()) { | ||
| const std::string& ns = KubernetesNamespace(); | ||
| // TODO: This is unreliable, find a better way. | ||
| const std::string pod_name = boost::asio::ip::host_name(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed that this is unreliable, what are the alternatives?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const std::string& version, const std::string& kind) const { | ||
| std::lock_guard<std::recursive_mutex> lock(mutex_); | ||
| const std::string prefix( | ||
| (version.find('/') == std::string::npos) ? "/api" : "/apis"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to check specifically against extensions instead of /?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not just extensions/*, it's also batch/* and a couple of others...
igorpeshansky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reviews. PTAL.
| constexpr const char kKubernetesEndpointPath[] = "/api/v1"; | ||
| constexpr const char kResourceTypeSeparator[] = "."; | ||
|
|
||
| constexpr const char kRawContentVersion[] = "0.1"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't version anything by kKubernetesEndpointPath -- I assume you meant kKubernetesApiVersion. This is the format defined by the target API. Blobs that come directly from Kubernetes and are ingested verbatim are versioned with the API version, while blobs that we have to construct are versioned by kRawContentVersion.
src/kubernetes.cc
Outdated
| LOG(INFO) << "Kubernetes Query called"; | ||
| std::vector<PollingMetadataUpdater::ResourceMetadata> result; | ||
|
|
||
| const std::string platform = "gce"; // TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| result.emplace_back( | ||
| std::vector<std::string>{k8s_node_name}, | ||
| k8s_node, | ||
| #ifdef ENABLE_KUBERNETES_METADATA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, this is a compile-time flag. We might need to make it a configuration option at some point.
I'd prefer to leave it here, but we could also take it out and make this code unconditional. WDYT?
src/kubernetes.cc
Outdated
| path_component.second + "/" + name); | ||
| } | ||
|
|
||
| json::value KubernetesReader::FindPrimary( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gave an even more accurate name to this function.
| {"association", json::object({ | ||
| {"version", json::string(kRawContentVersion)}, | ||
| {"raw", json::object({ | ||
| {"providerPlatform", json::string(platform)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what the metadata API will be looking for. We can coordinate and change this if it becomes an issue.
src/kubernetes.cc
Outdated
| bool is_deleted = false; | ||
|
|
||
| const MonitoredResource resource("gke_container", { | ||
| const MonitoredResource gke_resource("gke_container", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No good reason other than it used to be called resource and I was lazy. Renamed.
| gke_resource, | ||
| MetadataAgent::Metadata::IGNORED()); | ||
|
|
||
| const MonitoredResource k8s_container("k8s_container", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It started that way, but there are multiple k8s_* resources... Renamed gke_resource to gke_container to match.
src/kubernetes.cc
Outdated
| try { | ||
| http::client::response response = client.get(request); | ||
| #ifdef DEBUG | ||
| LOG(INFO) << "QueryMaster: Response: " << body(response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be an unfortunate clash of a macro with an enum value, actually... I've renamed the macro to VERBOSE, and changed the logging to DEBUG.
| if (current_node_.empty()) { | ||
| const std::string& ns = KubernetesNamespace(); | ||
| // TODO: This is unreliable, find a better way. | ||
| const std::string pod_name = boost::asio::ip::host_name(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const std::string& version, const std::string& kind) const { | ||
| std::lock_guard<std::recursive_mutex> lock(mutex_); | ||
| const std::string prefix( | ||
| (version.find('/') == std::string::npos) ? "/api" : "/apis"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not just extensions/*, it's also batch/* and a couple of others...
qingling128
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
| constexpr const char kKubernetesEndpointPath[] = "/api/v1"; | ||
| constexpr const char kResourceTypeSeparator[] = "."; | ||
|
|
||
| constexpr const char kRawContentVersion[] = "0.1"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. And yeah, I meant kKubernetesApiVersion.
src/kubernetes.cc
Outdated
| LOG(INFO) << "Kubernetes Query called"; | ||
| std::vector<PollingMetadataUpdater::ResourceMetadata> result; | ||
|
|
||
| const std::string platform = "gce"; // TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
| result.emplace_back( | ||
| std::vector<std::string>{k8s_node_name}, | ||
| k8s_node, | ||
| #ifdef ENABLE_KUBERNETES_METADATA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. I think it's fine to leave it as it is for now.
src/kubernetes.cc
Outdated
| path_component.second + "/" + name); | ||
| } | ||
|
|
||
| json::value KubernetesReader::FindPrimary( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Thanks.
bmoyles0117
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
bmoyles0117
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| {"version", json::string(kRawContentVersion)}, | ||
| {"raw", json::object({ | ||
| {"providerPlatform", json::string(platform)}, | ||
| {"instance_id", json::string(instance_id)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a TODO here just to ensure we fix this inconsistency cases? i.e. change to instanceId once fix is implemented on the API side as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| /*deleted=*/false, created_at, collected_at, | ||
| std::move(node_raw_metadata)) | ||
| #else | ||
| MetadataAgent::Metadata::IGNORED() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't we doing away with IGNORED metadata anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we still need it for the old GKE container resources, at the very least. And we'll reuse it for instance resources, at least initially.
Or are you asking about ENABLE_KUBERNETES_METADATA?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thanks.
src/kubernetes.cc
Outdated
| std::lock_guard<std::recursive_mutex> lock(mutex_); | ||
| if (kubernetes_api_token_.empty()) { | ||
| std::string filename = | ||
| "/var/run/secrets/kubernetes.io/serviceaccount/token"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this to a constant? The /var/run/secrets/kubernetes.io/serviceaccount/ bit can be shared across two methods and "token" or "namespace" appended on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (also extracted the common functionality into a function).
igorpeshansky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, PTAL.
| {"version", json::string(kRawContentVersion)}, | ||
| {"raw", json::object({ | ||
| {"providerPlatform", json::string(platform)}, | ||
| {"instance_id", json::string(instance_id)}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
| /*deleted=*/false, created_at, collected_at, | ||
| std::move(node_raw_metadata)) | ||
| #else | ||
| MetadataAgent::Metadata::IGNORED() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we still need it for the old GKE container resources, at the very least. And we'll reuse it for instance resources, at least initially.
Or are you asking about ENABLE_KUBERNETES_METADATA?
src/kubernetes.cc
Outdated
| std::lock_guard<std::recursive_mutex> lock(mutex_); | ||
| if (kubernetes_api_token_.empty()) { | ||
| std::string filename = | ||
| "/var/run/secrets/kubernetes.io/serviceaccount/token"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (also extracted the common functionality into a function).
dhrupadb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👌
| /*deleted=*/false, created_at, collected_at, | ||
| std::move(node_raw_metadata)) | ||
| #else | ||
| MetadataAgent::Metadata::IGNORED() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thanks.
ed0756a to
be35e2f
Compare
No description provided.