Skip to content

Commit 03c7dbf

Browse files
authored
Fixing an issue with multi acount support. (#1259)
1 parent b514d71 commit 03c7dbf

File tree

7 files changed

+649
-690
lines changed

7 files changed

+649
-690
lines changed

k8s/scalyr-service-account.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ metadata:
1111
name: scalyr-clusterrole
1212
rules:
1313
- apiGroups: [""]
14-
resources: ["namespaces","pods","replicationcontrollers"]
14+
resources: ["namespaces","pods","replicationcontrollers", "secrets"]
1515
verbs: ["get","list"]
1616
- apiGroups: [""]
1717
resources: ["nodes"]

scalyr_agent/builtin_monitors/kubernetes_monitor.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3476,13 +3476,18 @@ def __get_log_config_for_container(self, cid, info, k8s_cache, base_attributes):
34763476
# Based on the pod annotations in a format {container_name}.{team}.secret={secret_name}
34773477
# we might want to add api_keys parameter
34783478

3479-
if container_annotations or all_annotations or namespace_annotations:
3479+
self._logger.log(
3480+
scalyr_logging.DEBUG_LEVEL_0,
3481+
"log_config_for_container Checking for teams in annotations for container %s(%s), pod %s, namespace %s. Container annotations = %s, Pod annotations = %s, Namespace annotations = %s " \
3482+
% (info["name"], short_cid, pod_name, pod_namespace, container_annotations, all_annotations, namespace_annotations)
3483+
)
34803484

3481-
api_keys = self.__container_api_keys_from_annotations(k8s_cache, pod_namespace, container_annotations)
3485+
if container_annotations or all_annotations or namespace_annotations:
3486+
api_keys = self.__container_api_keys_from_annotations(k8s_cache, pod_namespace, container_annotations, "container", info["name"])
34823487
if not api_keys:
3483-
api_keys = self.__container_api_keys_from_annotations(k8s_cache, pod_namespace, all_annotations)
3488+
api_keys = self.__container_api_keys_from_annotations(k8s_cache, pod_namespace, all_annotations, "pod", info["name"])
34843489
if not api_keys:
3485-
api_keys = self.__container_api_keys_from_annotations(k8s_cache, pod_namespace, namespace_annotations)
3490+
api_keys = self.__container_api_keys_from_annotations(k8s_cache, pod_namespace, namespace_annotations, "namespace", info["name"])
34863491
if api_keys:
34873492
# Multiple matching api keys will result in multiple log configs, which will differ in the api_key field only.
34883493
results = [
@@ -3492,7 +3497,7 @@ def __get_log_config_for_container(self, cid, info, k8s_cache, base_attributes):
34923497

34933498
return results
34943499

3495-
def __container_api_keys_from_annotations(self, k8s_cache, namespace, annotations):
3500+
def __container_api_keys_from_annotations(self, k8s_cache, namespace, annotations, annotation_kind, container_name):
34963501
def fetch_secret(name):
34973502
if not name:
34983503
return None
@@ -3530,17 +3535,31 @@ def get_secret_api_key(secret):
35303535

35313536
return api_key
35323537

3533-
api_keys = [
3534-
get_secret_api_key(fetch_secret(team.get("secret")))
3538+
secrets_names = [
3539+
team.get("secret")
35353540
for team in annotations.get("teams", [])
35363541
]
35373542

3538-
return [
3543+
secrets = [
3544+
secret
3545+
for secret in map(fetch_secret, secrets_names)
3546+
if secret
3547+
]
3548+
3549+
api_keys = [
35393550
api_key
3540-
for api_key in api_keys
3551+
for api_key in map(get_secret_api_key, secrets)
35413552
if api_key
35423553
]
35433554

3555+
self._logger.log(
3556+
scalyr_logging.DEBUG_LEVEL_0,
3557+
"log_config_for_container From %s annotations of container %s and namespace %s, got %d non-empty api keys, %d secrets for secret names %s" \
3558+
% (annotation_kind, container_name, namespace, len(api_keys), len(secrets), ",".join(secrets_names))
3559+
)
3560+
3561+
return api_keys
3562+
35443563
def __get_docker_logs(self, containers, k8s_cache):
35453564
# type: (Dict, KubernetesCache) -> List[DockerLog]
35463565
"""Returns a list of dicts containing the container id, stream, and a log_config

scalyr_agent/configuration.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,18 @@ def __verify_and_match_workers_in_logs(self):
568568
for worker_config in self.__config.get_json_array("workers"):
569569
worker_ids.add(worker_config["id"])
570570

571+
572+
# get all lists where log files entries may be defined and require worker_id param.
573+
# __k8s_log_configs is left out because it interferes with the kubernetes monitor container checker and CopyingManager itself sets default worker_id while adding logs.
574+
log_config_lists_worker_id_required = [
575+
self.__log_configs,
576+
self.__journald_log_configs,
577+
]
578+
579+
for log_config_list in log_config_lists_worker_id_required:
580+
for log_file_config in log_config_list:
581+
log_file_config["worker_id"] = log_file_config.get("worker_id", default_value=DEFAULT_WORKER_ID)
582+
571583
# get all lists where log files entries may be defined.
572584
log_config_lists = [
573585
self.__log_configs,
@@ -578,11 +590,7 @@ def __verify_and_match_workers_in_logs(self):
578590
for log_config_list in log_config_lists:
579591
for log_file_config in log_config_list:
580592
worker_id = log_file_config.get("worker_id", none_if_missing=True)
581-
582-
if worker_id is None:
583-
# set a default worker if worker_id is not specified.
584-
log_file_config["worker_id"] = DEFAULT_WORKER_ID
585-
else:
593+
if worker_id is not None:
586594
# if log file entry has worker_id which is not defined in the 'workers' list, then throw an error.
587595
if worker_id not in worker_ids:
588596
valid_worker_ids = ", ".join(sorted(worker_ids))

scalyr_agent/copying_manager/copying_manager.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,11 +609,44 @@ def config(self):
609609
def __worker_id_from_log_config(self, log_config):
610610
# type: (Dict) -> six.text_type
611611

612+
log.log(
613+
scalyr_logging.DEBUG_LEVEL_0,
614+
(
615+
"Finding suitable worker for path %s, log_config_keys=%s"
616+
% (log_config.get("path"), log_config.keys())
617+
)
618+
)
619+
612620
if "worker_id" in log_config:
621+
log.info(
622+
(
623+
"Using worker_id %s from log_config for path %s."
624+
% (log_config['worker_id'], log_config.get('path'))
625+
)
626+
)
627+
613628
return log_config["worker_id"]
614629

615630
if "api_key" in log_config:
616-
return self.__dynamic_workers.get_or_create_worker(log_config["api_key"], self.__config).worker_id
631+
worker_id = self.__dynamic_workers.get_or_create_worker(log_config["api_key"], self.__config).worker_id
632+
633+
log.log(
634+
scalyr_logging.DEBUG_LEVEL_0,
635+
(
636+
"Using dynamic worker %s based on api_key from log_config for path %s."
637+
% (worker_id, log_config.get('path'))
638+
)
639+
)
640+
641+
return worker_id
642+
643+
log.log(
644+
scalyr_logging.DEBUG_LEVEL_0,
645+
(
646+
"Fallback to default worker_id %s for path %s."
647+
% (DEFAULT_WORKER_ID, log_config.get('path'))
648+
)
649+
)
617650

618651
return DEFAULT_WORKER_ID
619652

@@ -628,6 +661,7 @@ def add_log_config(self, monitor_name, log_config, force_add=False):
628661
the container restart where the log file is not immediately removed.
629662
returns: an updated log_config object
630663
"""
664+
631665
worker_id = self.__worker_id_from_log_config(log_config)
632666
log_config["worker_id"] = worker_id
633667
log_config = self.__config.parse_log_config(
@@ -681,6 +715,14 @@ def add_log_config(self, monitor_name, log_config, force_add=False):
681715
return log_config
682716

683717
def update_log_configs_on_path(self, path, monitor_name, log_configs):
718+
log.log(
719+
scalyr_logging.DEBUG_LEVEL_0,
720+
(
721+
"log_config_for_container update_log_configs_on_path path=%s monitor_name=%s log_configs=%s"
722+
% (path, monitor_name, len(log_configs))
723+
)
724+
)
725+
684726
worker_ids = []
685727
new_log_configs = []
686728
for log_config in log_configs:

tests/e2e/scalyr-agent-2-daemonset.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,47 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: scalyr-config-agent-d
5+
namespace: scalyr
6+
data:
7+
k8s_logs.json: |-
8+
{
9+
"k8s_logs": [
10+
{
11+
"attributes": {
12+
"container_name": "${k8s_container_name}"}
13+
}
14+
]
15+
}
16+
api-key.json: |-
17+
{
18+
"import_vars": [ "SCALYR_API_KEY" ],
19+
"api_key": "$SCALYR_API_KEY"
20+
}
21+
k8s_events.json: |-
22+
{
23+
"monitors": [
24+
{
25+
"module": "scalyr_agent.builtin_monitors.kubernetes_events_monitor"
26+
}
27+
]
28+
}
29+
docker.json: |-
30+
{
31+
"monitors":[
32+
{
33+
"module": "scalyr_agent.builtin_monitors.kubernetes_monitor",
34+
"stop_agent_on_failure": true
35+
}
36+
]
37+
}
38+
scalyr-server.json: |-
39+
{
40+
"import_vars": [ { "var": "SCALYR_SERVER", "default": "https://agent.scalyr.com" } ],
41+
"scalyr_server": "$SCALYR_SERVER"
42+
}
43+
---
44+
---
145
apiVersion: apps/v1
246
kind: DaemonSet
347
metadata:
@@ -63,6 +107,8 @@ spec:
63107
terminationMessagePath: /dev/termination-log
64108
terminationMessagePolicy: File
65109
volumeMounts:
110+
- name: scalyr-config-agent-d-vol
111+
mountPath: /etc/scalyr-agent-2/agent.d
66112
- mountPath: /var/lib/docker/containers
67113
name: varlibdockercontainers
68114
readOnly: true
@@ -101,6 +147,9 @@ spec:
101147
serviceAccountName: scalyr-service-account
102148
terminationGracePeriodSeconds: 30
103149
volumes:
150+
- name: scalyr-config-agent-d-vol
151+
configMap:
152+
name: scalyr-config-agent-d
104153
- hostPath:
105154
path: /var/lib/docker/containers
106155
type: ""

0 commit comments

Comments
 (0)