Skip to content

Commit 1d8bf1c

Browse files
authored
Replace gke_container with k8s_container for stackdriver (census-instrumentation#528)
Replaces the gke_container monitored resource type with the new k8s_container for stackdriver exporters.
1 parent ba0a577 commit 1d8bf1c

File tree

7 files changed

+188
-222
lines changed

7 files changed

+188
-222
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
Use `UnknownMetricFamily` for `SumData` instead of `UntypedMetricFamily`.
77
Check if label keys and values match before exporting.
88
- Remove min and max from Distribution.
9+
- Replace stackdriver `gke_container` resources, see the [GKE migration
10+
notes](https://cloud.google.com/monitoring/kubernetes-engine/migration#incompatible)
11+
for details
912

1013
## 0.2.0
1114
Released 2019-01-18

opencensus/common/monitored_resource/gcp_metadata_config.py

Lines changed: 25 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -13,63 +13,32 @@
1313
# limitations under the License.
1414

1515
from opencensus.common.http_handler import get_request
16-
import os
1716

1817
_GCP_METADATA_URI = 'http://metadata/computeMetadata/v1/'
1918
_GCP_METADATA_URI_HEADER = {'Metadata-Flavor': 'Google'}
2019

21-
# GCE common attributes
22-
# See: https://cloud.google.com/appengine/docs/flexible/python/runtime#
23-
# environment_variables
24-
_GCE_ATTRIBUTES = {
25-
# ProjectID is the identifier of the GCP project associated with this
26-
# resource, such as "my-project".
27-
'project_id': 'project/project-id',
28-
29-
# instance_id is the numeric VM instance identifier assigned by
30-
# Compute Engine.
31-
'instance_id': 'instance/id',
32-
33-
# zone is the Compute Engine zone in which the VM is running.
34-
'zone': 'instance/zone'
35-
}
20+
# ID of the GCP project associated with this resource, such as "my-project"
21+
PROJECT_ID_KEY = 'project_id'
3622

37-
_GKE_ATTRIBUTES = {
38-
# ProjectID is the identifier of the GCP project associated with this
39-
# resource, such as "my-project".
40-
'project_id': 'project/project-id',
41-
42-
# instance_id is the numeric VM instance identifier assigned by
43-
# Compute Engine.
44-
'instance_id': 'instance/id',
45-
46-
# zone is the Compute Engine zone in which the VM is running.
47-
'zone': 'instance/zone',
48-
49-
# cluster_name is the name for the cluster the container is running in.
50-
'cluster_name': 'instance/attributes/cluster-name'
51-
}
23+
# Numeric VM instance identifier assigned by GCE
24+
INSTANCE_ID_KEY = 'instance_id'
5225

53-
# Following attributes are derived from environment variables. They are
54-
# configured via yaml file. For details refer to:
55-
# https://cloud.google.com/kubernetes-engine/docs/tutorials/
56-
# custom-metrics-autoscaling#exporting_metrics_from_the_application
57-
_GKE_ENV_ATTRIBUTES = {
58-
# ContainerName is the name of the container.
59-
'container_name': 'CONTAINER_NAME',
26+
# The GCE zone in which the VM is running
27+
ZONE_KEY = 'zone'
6028

61-
# namespace_id is the identifier for the cluster namespace the container
62-
# is running in
63-
'namespace_id': 'NAMESPACE',
29+
# GKE cluster name
30+
CLUSTER_NAME_KEY = 'instance/attributes/cluster-name'
6431

65-
# pod_id is the identifier for the pod the container is running in.
66-
'pod_id': 'HOSTNAME'
32+
# GCE common attributes
33+
# See: https://cloud.google.com/appengine/docs/flexible/python/runtime#environment_variables # noqa
34+
_GCE_ATTRIBUTES = {
35+
PROJECT_ID_KEY: 'project/project-id',
36+
INSTANCE_ID_KEY: 'instance/id',
37+
ZONE_KEY: 'instance/zone'
6738
}
6839

69-
# Kubenertes environment variables
70-
_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST'
7140

72-
gcp_metadata_map = {}
41+
_GCP_METADATA_MAP = {}
7342

7443

7544
class GcpMetadataConfig(object):
@@ -90,23 +59,19 @@ def _initialize_metadata_service(cls):
9059
if cls.inited:
9160
return
9261

93-
instance_id = cls._get_attribute('instance_id')
62+
instance_id = cls.get_attribute('instance/id')
9463

9564
if instance_id is not None:
9665
cls.is_running = True
9766

98-
gcp_metadata_map['instance_id'] = instance_id
99-
100-
attributes = _GCE_ATTRIBUTES
101-
if _KUBERNETES_SERVICE_HOST in os.environ:
102-
attributes = _GKE_ATTRIBUTES
67+
_GCP_METADATA_MAP['instance_id'] = instance_id
10368

10469
# fetch attributes from metadata request
105-
for attribute_key, attribute_uri in attributes.items():
106-
if attribute_key not in gcp_metadata_map:
107-
attribute_value = cls._get_attribute(attribute_key)
108-
if attribute_value is not None:
109-
gcp_metadata_map[attribute_key] = attribute_value
70+
for attribute_key, attribute_uri in _GCE_ATTRIBUTES.items():
71+
if attribute_key not in _GCP_METADATA_MAP:
72+
attribute_value = cls.get_attribute(attribute_uri)
73+
if attribute_value is not None: # pragma: NO COVER
74+
_GCP_METADATA_MAP[attribute_key] = attribute_value
11075

11176
cls.inited = True
11277

@@ -118,35 +83,19 @@ def is_running_on_gcp(cls):
11883
def get_gce_metadata(self):
11984
"""for GCP GCE instance"""
12085
if self.is_running_on_gcp():
121-
return gcp_metadata_map
86+
return _GCP_METADATA_MAP
12287

12388
return dict()
12489

125-
def get_gke_metadata(self):
126-
"""for GCP GKE container."""
127-
gke_metadata = {}
128-
129-
if self.is_running_on_gcp():
130-
gke_metadata = gcp_metadata_map
131-
132-
# fetch attributes from Environment Variables
133-
for attribute_key, attribute_env in _GKE_ENV_ATTRIBUTES.items():
134-
attribute_value = os.environ.get(attribute_env)
135-
if attribute_value is not None:
136-
gke_metadata[attribute_key] = attribute_value
137-
138-
return gke_metadata
139-
14090
@staticmethod
141-
def _get_attribute(attribute_key):
91+
def get_attribute(attribute_uri):
14292
"""
14393
Fetch the requested instance metadata entry.
14494
:param attribute_uri: attribute_uri: attribute name relative to the
14595
computeMetadata/v1 prefix
14696
:return: The value read from the metadata service or None
14797
"""
148-
attribute_value = get_request(_GCP_METADATA_URI +
149-
_GKE_ATTRIBUTES[attribute_key],
98+
attribute_value = get_request(_GCP_METADATA_URI + attribute_uri,
15099
_GCP_METADATA_URI_HEADER)
151100

152101
if attribute_value is not None and isinstance(attribute_value, bytes):
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright 2019, OpenCensus Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
from opencensus.common.monitored_resource import gcp_metadata_config
18+
19+
# Env var that signals that we're in a kubernetes container
20+
_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST'
21+
22+
# Name of the cluster the container is running in
23+
CLUSTER_NAME_KEY = 'k8s.io/cluster/name'
24+
25+
# ID of the instance the container is running on
26+
NAMESPACE_NAME_KEY = 'k8s.io/namespace/name'
27+
28+
# Container pod ID
29+
POD_NAME_KEY = 'k8s.io/pod/name'
30+
31+
# Container name
32+
CONTAINER_NAME_KEY = 'k8s.io/container/name'
33+
34+
# Attributes set from environment variables
35+
_K8S_ENV_ATTRIBUTES = {
36+
CONTAINER_NAME_KEY: 'CONTAINER_NAME',
37+
NAMESPACE_NAME_KEY: 'NAMESPACE',
38+
POD_NAME_KEY: 'HOSTNAME'
39+
}
40+
41+
42+
def is_k8s_environment():
43+
"""Whether the environment is a kubernetes container.
44+
45+
The KUBERNETES_SERVICE_HOST environment variable must be set.
46+
"""
47+
return _KUBERNETES_SERVICE_HOST in os.environ
48+
49+
50+
def get_k8s_metadata():
51+
"""Get kubernetes container metadata, as on GCP GKE."""
52+
k8s_metadata = {}
53+
54+
gcp_cluster = (gcp_metadata_config.GcpMetadataConfig
55+
.get_attribute(gcp_metadata_config.CLUSTER_NAME_KEY))
56+
if gcp_cluster is not None:
57+
k8s_metadata[CLUSTER_NAME_KEY] = gcp_cluster
58+
59+
for attribute_key, attribute_env in _K8S_ENV_ATTRIBUTES.items():
60+
attribute_value = os.environ.get(attribute_env)
61+
if attribute_value is not None:
62+
k8s_metadata[attribute_key] = attribute_value
63+
64+
return k8s_metadata

opencensus/common/monitored_resource/monitored_resource.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,17 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import os
16-
1715
from opencensus.common import resource
1816
from opencensus.common.monitored_resource import aws_identity_doc_utils
1917
from opencensus.common.monitored_resource import gcp_metadata_config
18+
from opencensus.common.monitored_resource import k8s_utils
2019

2120

2221
# Supported environments (resource types)
2322
_GCE_INSTANCE = "gce_instance"
24-
_GKE_CONTAINER = "gke_container"
23+
_K8S_CONTAINER = "k8s_container"
2524
_AWS_EC2_INSTANCE = "aws_ec2_instance"
2625

27-
# Kubenertes environment variables
28-
_KUBERNETES_SERVICE_HOST = 'KUBERNETES_SERVICE_HOST'
29-
30-
31-
def is_gke_environment():
32-
"""Whether the environment is a GKE container instance.
33-
34-
The KUBERNETES_SERVICE_HOST environment variable must be set.
35-
"""
36-
return _KUBERNETES_SERVICE_HOST in os.environ
37-
3826

3927
def is_gce_environment():
4028
"""Whether the environment is a virtual machine on GCE."""
@@ -52,22 +40,11 @@ def get_instance():
5240
Returns a `Resource` configured for the current environment, or None if the
5341
environment is unknown or unsupported.
5442
55-
Supported environments include:
56-
57-
1. 'gke_container'
58-
- https://cloud.google.com/monitoring/api/resources#tag_gke_container
59-
2. 'gce_instance'
60-
- https://cloud.google.com/monitoring/api/resources#tag_gce_instance
61-
3. 'aws_ec2_instance'
62-
- https://cloud.google.com/monitoring/api/resources#tag_aws_ec2_instance
63-
6443
:rtype: :class:`opencensus.common.resource.Resource` or None
6544
:return: A `Resource` configured for the current environment.
6645
"""
67-
if is_gke_environment():
68-
return resource.Resource(
69-
_GKE_CONTAINER,
70-
gcp_metadata_config.GcpMetadataConfig().get_gke_metadata())
46+
if k8s_utils.is_k8s_environment():
47+
return resource.Resource(_K8S_CONTAINER, k8s_utils.get_k8s_metadata())
7148
if is_gce_environment():
7249
return resource.Resource(
7350
_GCE_INSTANCE,

0 commit comments

Comments
 (0)