-
Notifications
You must be signed in to change notification settings - Fork 241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding containerd compatability to oom_logger - COMPINFRA-3947 #3904
Changes from 1 commit
a978a3b
070a761
ba53ddb
52b62c8
16d092d
2173227
aa1df40
8a9f0d1
e609b71
07dde6d
b79ffdf
3418ca2
cbd610f
048a1a8
0ba8fba
b6efc9f
c72a4ed
c4ffc3f
447f321
0e2f1db
47ed5a4
3f6395b
0818402
aa108c1
a9299bd
96ce384
14a16bb
4132b65
f3c13bc
416f9b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -33,10 +33,15 @@ | |||||||||||||||||||||||||||||||||
destination(paasta_oom_logger); | ||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||
import argparse | ||||||||||||||||||||||||||||||||||
import json | ||||||||||||||||||||||||||||||||||
import re | ||||||||||||||||||||||||||||||||||
import sys | ||||||||||||||||||||||||||||||||||
from collections import namedtuple | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
import grpc | ||||||||||||||||||||||||||||||||||
from containerd.services.containers.v1 import containers_pb2 | ||||||||||||||||||||||||||||||||||
from containerd.services.containers.v1 import containers_pb2_grpc | ||||||||||||||||||||||||||||||||||
from docker.errors import APIError | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
from paasta_tools.cli.utils import get_instance_config | ||||||||||||||||||||||||||||||||||
|
@@ -76,6 +81,16 @@ | |||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
def parse_args() -> argparse.Namespace: | ||||||||||||||||||||||||||||||||||
parser = argparse.ArgumentParser(description="paasta_oom_logger") | ||||||||||||||||||||||||||||||||||
parser.add_argument( | ||||||||||||||||||||||||||||||||||
"--containerd", | ||||||||||||||||||||||||||||||||||
action="store_true", | ||||||||||||||||||||||||||||||||||
help="Use containerd to inspect containers", | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Suggested change
|
||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||
return parser.parse_args() | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
def capture_oom_events_from_stdin(): | ||||||||||||||||||||||||||||||||||
process_name_regex = re.compile( | ||||||||||||||||||||||||||||||||||
r"^\d+\s[a-zA-Z0-9\-]+\s.*\]\s(.+)\sinvoked\soom-killer:" | ||||||||||||||||||||||||||||||||||
Comment on lines
95
to
97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we'll need to do some experimentation w/ an actual oomkilled pod on nodes w/ containerd to verify what format the logs look like, and if we need to update any of these regexes. |
||||||||||||||||||||||||||||||||||
|
@@ -136,11 +151,15 @@ def capture_oom_events_from_stdin(): | |||||||||||||||||||||||||||||||||
break | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
def get_container_env_as_dict(docker_inspect): | ||||||||||||||||||||||||||||||||||
def get_container_env_as_dict(is_cri_containerd: bool, container_inspect): | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Suggested change
comment: typing |
||||||||||||||||||||||||||||||||||
env_vars = {} | ||||||||||||||||||||||||||||||||||
config = docker_inspect.get("Config") | ||||||||||||||||||||||||||||||||||
if config is not None: | ||||||||||||||||||||||||||||||||||
if is_cri_containerd: | ||||||||||||||||||||||||||||||||||
config = container_inspect.get("process") | ||||||||||||||||||||||||||||||||||
env = config.get("env", []) | ||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||
config = container_inspect.get("Config") | ||||||||||||||||||||||||||||||||||
env = config.get("Env", []) | ||||||||||||||||||||||||||||||||||
if config is not None: | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically this
Suggested change
|
||||||||||||||||||||||||||||||||||
for i in env: | ||||||||||||||||||||||||||||||||||
name, _, value = i.partition("=") | ||||||||||||||||||||||||||||||||||
env_vars[name] = value | ||||||||||||||||||||||||||||||||||
|
@@ -209,18 +228,32 @@ def send_sfx_event(service, instance, cluster): | |||||||||||||||||||||||||||||||||
counter.count() | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
def get_containerd_container( | ||||||||||||||||||||||||||||||||||
is_cri_containerd: bool, container_id: str | ||||||||||||||||||||||||||||||||||
) -> containers_pb2.Container: | ||||||||||||||||||||||||||||||||||
with grpc.insecure_channel("unix:///run/containerd/containerd.sock") as channel: | ||||||||||||||||||||||||||||||||||
containersv1 = containers_pb2_grpc.ContainersStub(channel) | ||||||||||||||||||||||||||||||||||
if is_cri_containerd: | ||||||||||||||||||||||||||||||||||
namespace = "k8s.io" | ||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||
namespace = "moby" | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, could we use the containerd library for both cases? if so, we could remove the conditional in otherwise, we can just assume that if this method is being called we want the k8s namespace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yea, I was thinking of also just assuming if we call this function then we are using containerd but I wasn't sure if we would still need the moby ns |
||||||||||||||||||||||||||||||||||
return containersv1.Get( | ||||||||||||||||||||||||||||||||||
containers_pb2.GetContainerRequest(id=container_id), | ||||||||||||||||||||||||||||||||||
metadata=(("containerd-namespace", namespace),), | ||||||||||||||||||||||||||||||||||
).container | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
def main(): | ||||||||||||||||||||||||||||||||||
if clog is None: | ||||||||||||||||||||||||||||||||||
print("CLog logger unavailable, exiting.", file=sys.stderr) | ||||||||||||||||||||||||||||||||||
sys.exit(1) | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
args = parse_args() | ||||||||||||||||||||||||||||||||||
clog.config.configure( | ||||||||||||||||||||||||||||||||||
scribe_host="169.254.255.254", | ||||||||||||||||||||||||||||||||||
scribe_port=1463, | ||||||||||||||||||||||||||||||||||
monk_disable=False, | ||||||||||||||||||||||||||||||||||
scribe_disable=False, | ||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
cluster = load_system_paasta_config().get_cluster() | ||||||||||||||||||||||||||||||||||
client = get_docker_client() | ||||||||||||||||||||||||||||||||||
for ( | ||||||||||||||||||||||||||||||||||
|
@@ -229,11 +262,18 @@ def main(): | |||||||||||||||||||||||||||||||||
container_id, | ||||||||||||||||||||||||||||||||||
process_name, | ||||||||||||||||||||||||||||||||||
) in capture_oom_events_from_stdin(): | ||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||
docker_inspect = client.inspect_container(resource_id=container_id) | ||||||||||||||||||||||||||||||||||
except (APIError): | ||||||||||||||||||||||||||||||||||
continue | ||||||||||||||||||||||||||||||||||
env_vars = get_container_env_as_dict(docker_inspect) | ||||||||||||||||||||||||||||||||||
if args.containerd: | ||||||||||||||||||||||||||||||||||
# then we're using containerd to inspect containers | ||||||||||||||||||||||||||||||||||
container_info = get_containerd_container(args.containerd, container_id) | ||||||||||||||||||||||||||||||||||
container_spec_raw = container_info.spec.value.decode("utf-8") | ||||||||||||||||||||||||||||||||||
container_inspect = json.loads(container_spec_raw) | ||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||
# we're using docker to inspect containers | ||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||
container_inspect = client.inspect_container(resource_id=container_id) | ||||||||||||||||||||||||||||||||||
except (APIError): | ||||||||||||||||||||||||||||||||||
continue | ||||||||||||||||||||||||||||||||||
jfongatyelp marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||
env_vars = get_container_env_as_dict(args.containerd, container_inspect) | ||||||||||||||||||||||||||||||||||
service = env_vars.get("PAASTA_SERVICE", "unknown") | ||||||||||||||||||||||||||||||||||
instance = env_vars.get("PAASTA_INSTANCE", "unknown") | ||||||||||||||||||||||||||||||||||
mesos_container_id = env_vars.get("MESOS_CONTAINER_NAME", "mesos-null") | ||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
from paasta_tools.oom_logger import log_to_clog | ||
from paasta_tools.oom_logger import LogLine | ||
from paasta_tools.oom_logger import main | ||
from paasta_tools.oom_logger import parse_args | ||
from paasta_tools.oom_logger import send_sfx_event | ||
|
||
|
||
|
@@ -344,14 +345,21 @@ def test_send_sfx_event(mock_get_instance_config): | |
assert mock_meteorite.create_counter.return_value.count.call_count == 1 | ||
|
||
|
||
@patch("paasta_tools.oom_logger.argparse", autospec=True) | ||
def test_parse_args(mock_argparse): | ||
assert parse_args() == mock_argparse.ArgumentParser.return_value.parse_args() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think it's fine to leave this untested since we're not really checking for much here :) |
||
|
||
|
||
@patch("paasta_tools.oom_logger.sys.stdin", autospec=True) | ||
@patch("paasta_tools.oom_logger.clog", autospec=True) | ||
@patch("paasta_tools.oom_logger.send_sfx_event", autospec=True) | ||
@patch("paasta_tools.oom_logger.load_system_paasta_config", autospec=True) | ||
@patch("paasta_tools.oom_logger.log_to_clog", autospec=True) | ||
@patch("paasta_tools.oom_logger.log_to_paasta", autospec=True) | ||
@patch("paasta_tools.oom_logger.get_docker_client", autospec=True) | ||
@patch("paasta_tools.oom_logger.parse_args", autospec=True) | ||
def test_main( | ||
mock_parse_args, | ||
mock_get_docker_client, | ||
mock_log_to_paasta, | ||
mock_log_to_clog, | ||
|
@@ -365,6 +373,7 @@ def test_main( | |
): | ||
|
||
mock_sys_stdin.readline.side_effect = sys_stdin | ||
mock_parse_args.return_value.containerd = False | ||
nemacysts marked this conversation as resolved.
Show resolved
Hide resolved
|
||
docker_client = Mock(inspect_container=Mock(return_value=docker_inspect)) | ||
mock_get_docker_client.return_value = docker_client | ||
mock_load_system_paasta_config.return_value.get_cluster.return_value = ( | ||
|
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.
note: we'll want to remove any references of this from puppet if we haven't already
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'll also need to remove this from setup.py and debian/paasta-tools.links I believe.
That said, I don't think you'll need to do anything in puppet -- when I looked through for references to this script I found references to a script that had a similar name, but this specific paasta version was never actually referenced/used.