Skip to content
This repository has been archived by the owner on Aug 19, 2019. It is now read-only.

Implement new Kubernetes resources and metadata. #25

Merged
merged 4 commits into from
Sep 12, 2017

Conversation

igorpeshansky
Copy link
Member

No description provided.

@@ -49,56 +62,197 @@ KubernetesReader::KubernetesReader(const MetadataAgentConfiguration& config)
std::vector<PollingMetadataUpdater::ResourceMetadata>
KubernetesReader::MetadataQuery() const {
LOG(INFO) << "Kubernetes Query called";
std::vector<PollingMetadataUpdater::ResourceMetadata> result;

const std::string platform = "gce"; // TODO

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

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
Copy link

@qingling128 qingling128 Sep 8, 2017

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.

Copy link
Member Author

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?

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.

path_component.second + "/" + name);
}

json::value KubernetesReader::FindPrimary(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:%s/FindPrimary/FindPrimaryController/g?

Copy link
Member Author

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.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Thanks.

@@ -38,8 +41,18 @@ constexpr const char kKubernetesApiVersion[] = "1.6";
constexpr const char kKubernetesEndpointPath[] = "/api/v1";
constexpr const char kResourceTypeSeparator[] = ".";

constexpr const char kRawContentVersion[] = "0.1";

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?

Copy link
Member Author

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.

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)},
Copy link
Contributor

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?

Copy link
Member Author

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.

const std::string pod_label_selector(
config_.KubernetesPodLabelSelector().empty()
? "" : "?" + config_.KubernetesPodLabelSelector());
? "" : "&" + config_.KubernetesPodLabelSelector());
const std::string node_selector(kNodeSelectorPrefix + node_name);
Copy link
Contributor

@bmoyles0117 bmoyles0117 Sep 11, 2017

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.

Copy link
Member Author

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 << ")";
Copy link
Contributor

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?

Copy link
Member Author

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.

@@ -107,29 +262,69 @@ std::vector<PollingMetadataUpdater::ResourceMetadata>
//const json::Object* state = container->Get<json::Object>("state");
bool is_deleted = false;

const MonitoredResource resource("gke_container", {
const MonitoredResource gke_resource("gke_container", {
Copy link
Contributor

@bmoyles0117 bmoyles0117 Sep 11, 2017

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?

Copy link
Member Author

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", {
Copy link
Contributor

@bmoyles0117 bmoyles0117 Sep 11, 2017

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"?

Copy link
Member Author

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.

try {
http::client::response response = client.get(request);
#ifdef DEBUG
LOG(INFO) << "QueryMaster: Response: " << body(response);
Copy link
Contributor

@bmoyles0117 bmoyles0117 Sep 11, 2017

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?

Copy link
Member Author

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();
Copy link
Contributor

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?

Copy link
Member Author

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");
Copy link
Contributor

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 /?

Copy link
Member Author

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...

Copy link
Member Author

@igorpeshansky igorpeshansky left a 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.

@@ -38,8 +41,18 @@ constexpr const char kKubernetesApiVersion[] = "1.6";
constexpr const char kKubernetesEndpointPath[] = "/api/v1";
constexpr const char kResourceTypeSeparator[] = ".";

constexpr const char kRawContentVersion[] = "0.1";
Copy link
Member Author

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.

@@ -49,56 +62,197 @@ KubernetesReader::KubernetesReader(const MetadataAgentConfiguration& config)
std::vector<PollingMetadataUpdater::ResourceMetadata>
KubernetesReader::MetadataQuery() const {
LOG(INFO) << "Kubernetes Query called";
std::vector<PollingMetadataUpdater::ResourceMetadata> result;

const std::string platform = "gce"; // TODO
Copy link
Member Author

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
Copy link
Member Author

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?

path_component.second + "/" + name);
}

json::value KubernetesReader::FindPrimary(
Copy link
Member Author

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)},
Copy link
Member Author

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.

@@ -107,29 +262,69 @@ std::vector<PollingMetadataUpdater::ResourceMetadata>
//const json::Object* state = container->Get<json::Object>("state");
bool is_deleted = false;

const MonitoredResource resource("gke_container", {
const MonitoredResource gke_resource("gke_container", {
Copy link
Member Author

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", {
Copy link
Member Author

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.

try {
http::client::response response = client.get(request);
#ifdef DEBUG
LOG(INFO) << "QueryMaster: Response: " << body(response);
Copy link
Member Author

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();
Copy link
Member Author

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");
Copy link
Member Author

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...

Copy link

@qingling128 qingling128 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@@ -38,8 +41,18 @@ constexpr const char kKubernetesApiVersion[] = "1.6";
constexpr const char kKubernetesEndpointPath[] = "/api/v1";
constexpr const char kResourceTypeSeparator[] = ".";

constexpr const char kRawContentVersion[] = "0.1";

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.

@@ -49,56 +62,197 @@ KubernetesReader::KubernetesReader(const MetadataAgentConfiguration& config)
std::vector<PollingMetadataUpdater::ResourceMetadata>
KubernetesReader::MetadataQuery() const {
LOG(INFO) << "Kubernetes Query called";
std::vector<PollingMetadataUpdater::ResourceMetadata> result;

const std::string platform = "gce"; // TODO

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

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.

path_component.second + "/" + name);
}

json::value KubernetesReader::FindPrimary(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Thanks.

Copy link
Contributor

@bmoyles0117 bmoyles0117 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@bmoyles0117 bmoyles0117 left a 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)},
Copy link
Contributor

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.

Copy link
Member Author

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()
Copy link
Contributor

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?

Copy link
Member Author

@igorpeshansky igorpeshansky Sep 12, 2017

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thanks.

std::lock_guard<std::recursive_mutex> lock(mutex_);
if (kubernetes_api_token_.empty()) {
std::string filename =
"/var/run/secrets/kubernetes.io/serviceaccount/token";
Copy link
Contributor

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.

Copy link
Member Author

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).

Copy link
Member Author

@igorpeshansky igorpeshansky left a 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)},
Copy link
Member Author

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()
Copy link
Member Author

@igorpeshansky igorpeshansky Sep 12, 2017

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?

std::lock_guard<std::recursive_mutex> lock(mutex_);
if (kubernetes_api_token_.empty()) {
std::string filename =
"/var/run/secrets/kubernetes.io/serviceaccount/token";
Copy link
Member Author

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).

Copy link
Contributor

@dhrupadb dhrupadb left a 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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thanks.

@igorpeshansky igorpeshansky force-pushed the igorp-kubernetes-resources branch from ed0756a to be35e2f Compare September 12, 2017 23:52
@igorpeshansky igorpeshansky merged commit 02d4b8f into master Sep 12, 2017
@igorpeshansky igorpeshansky deleted the igorp-kubernetes-resources branch September 12, 2017 23:55
igorpeshansky added a commit that referenced this pull request Sep 14, 2017
igorpeshansky added a commit that referenced this pull request Sep 14, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants