From 6372a7f7f09511d864aa6bd894109d937f4fda65 Mon Sep 17 00:00:00 2001 From: Jake Hunsaker Date: Thu, 12 Jul 2018 12:36:25 -0400 Subject: [PATCH 1/3] [kubernetes|etcd] Support OpenShift 3.10 deployments The 3.10 version of OCP changes the deployment configurations for etcd and kubernetes components, and additionally changes the way the etcdctl command is called when running in a static pod. Update these plugins to support this new deployment style. Signed-off-by: Jake Hunsaker --- sos/plugins/etcd.py | 11 ++- sos/plugins/kubernetes.py | 148 +++++++++++++++++++------------------- 2 files changed, 83 insertions(+), 76 deletions(-) diff --git a/sos/plugins/etcd.py b/sos/plugins/etcd.py index c343f750..c8ee3849 100644 --- a/sos/plugins/etcd.py +++ b/sos/plugins/etcd.py @@ -10,6 +10,7 @@ # See the LICENSE file in the source distribution for further information. from sos.plugins import Plugin, RedHatPlugin +from os import path class etcd(Plugin, RedHatPlugin): @@ -19,10 +20,14 @@ class etcd(Plugin, RedHatPlugin): plugin_name = 'etcd' packages = ('etcd',) profiles = ('container', 'system', 'services', 'cluster') - - cmd = 'etcdctl' + files = ('/etc/origin/node/pods/etcd.yaml',) def setup(self): + if path.exists('/etc/origin/node/pods/etcd.yaml'): + etcd_cmd = 'master-exec etcd etcd etcdctl' + else: + etcd_cmd = 'etcdctl' + etcd_url = self.get_etcd_url() self.add_forbidden_path('/etc/etcd/ca') @@ -35,7 +40,7 @@ class etcd(Plugin, RedHatPlugin): 'ls --recursive', ] - self.add_cmd_output(['%s %s' % (self.cmd, sub) for sub in subcmds]) + self.add_cmd_output(['%s %s' % (etcd_cmd, sub) for sub in subcmds]) urls = [ '/v2/stats/leader', diff --git a/sos/plugins/kubernetes.py b/sos/plugins/kubernetes.py index e75c7a37..21cb51df 100644 --- a/sos/plugins/kubernetes.py +++ b/sos/plugins/kubernetes.py @@ -18,11 +18,16 @@ class kubernetes(Plugin, RedHatPlugin): """Kubernetes plugin """ - # Red Hat Atomic Platform and OpenShift Enterprise use the - # atomic-openshift-master package to provide kubernetes + # OpenShift Container Platform uses the atomic-openshift-master package + # to provide kubernetes packages = ('kubernetes', 'kubernetes-master', 'atomic-openshift-master') profiles = ('container',) - files = ("/etc/origin/master/master-config.yaml",) + # use files only for masters, rely on package list for nodes + files = ( + "/var/run/kubernetes/apiserver.key", + "/etc/origin/master/", + "/etc/origin/node/pods/master-config.yaml" + ) option_list = [ ("all", "also collect all namespaces output separately", @@ -33,12 +38,7 @@ class kubernetes(Plugin, RedHatPlugin): ] def check_is_master(self): - if any([ - path.exists("/var/run/kubernetes/apiserver.key"), - path.exists("/etc/origin/master/master-config.yaml") - ]): - return True - return False + return any([path.exists(f) for f in self.files]) def setup(self): self.add_copy_spec("/etc/kubernetes") @@ -56,74 +56,76 @@ class kubernetes(Plugin, RedHatPlugin): self.add_journal(units=svc) # We can only grab kubectl output from the master - if self.check_is_master(): - kube_cmd = "kubectl " - if path.exists('/etc/origin/master/admin.kubeconfig'): - kube_cmd += "--config=/etc/origin/master/admin.kubeconfig" - - kube_get_cmd = "get -o json " - for subcmd in ['version', 'config view']: - self.add_cmd_output('%s %s' % (kube_cmd, subcmd)) - - # get all namespaces in use - kn = self.get_command_output('%s get namespaces' % kube_cmd) - knsps = [n.split()[0] for n in kn['output'].splitlines()[1:] if n] - - resources = [ - 'limitrange', - 'pods', - 'pvc', - 'rc', - 'resourcequota', - 'services' - ] - - # nodes and pvs are not namespaced, must pull separately. - # Also collect master metrics - self.add_cmd_output([ - "{} get -o json nodes".format(kube_cmd), - "{} get -o json pv".format(kube_cmd), - "{} get --raw /metrics".format(kube_cmd) - ]) - - for n in knsps: - knsp = '--namespace=%s' % n - if self.get_option('all'): - k_cmd = '%s %s %s' % (kube_cmd, kube_get_cmd, knsp) - - self.add_cmd_output('%s events' % k_cmd) + if not self.check_is_master(): + return + + kube_cmd = "kubectl " + if path.exists('/etc/origin/master/admin.kubeconfig'): + kube_cmd += "--config=/etc/origin/master/admin.kubeconfig" + + kube_get_cmd = "get -o json " + for subcmd in ['version', 'config view']: + self.add_cmd_output('%s %s' % (kube_cmd, subcmd)) + + # get all namespaces in use + kn = self.get_command_output('%s get namespaces' % kube_cmd) + knsps = [n.split()[0] for n in kn['output'].splitlines()[1:] if n] + + resources = [ + 'limitrange', + 'pods', + 'pvc', + 'rc', + 'resourcequota', + 'services' + ] + + # nodes and pvs are not namespaced, must pull separately. + # Also collect master metrics + self.add_cmd_output([ + "{} get -o json nodes".format(kube_cmd), + "{} get -o json pv".format(kube_cmd), + "{} get --raw /metrics".format(kube_cmd) + ]) + + for n in knsps: + knsp = '--namespace=%s' % n + if self.get_option('all'): + k_cmd = '%s %s %s' % (kube_cmd, kube_get_cmd, knsp) + + self.add_cmd_output('%s events' % k_cmd) - for res in resources: - self.add_cmd_output('%s %s' % (k_cmd, res)) - - if self.get_option('describe'): - # need to drop json formatting for this - k_cmd = '%s get %s' % (kube_cmd, knsp) - for res in resources: - r = self.get_command_output( - '%s %s' % (k_cmd, res)) - if r['status'] == 0: - k_list = [k.split()[0] for k in - r['output'].splitlines()[1:]] - for k in k_list: - k_cmd = '%s %s' % (kube_cmd, knsp) - self.add_cmd_output( - '%s describe %s %s' % (k_cmd, res, k)) - - if self.get_option('podlogs'): - k_cmd = '%s %s' % (kube_cmd, knsp) - r = self.get_command_output('%s get pods' % k_cmd) - if r['status'] == 0: - pods = [p.split()[0] for p in - r['output'].splitlines()[1:]] - for pod in pods: - self.add_cmd_output('%s logs %s' % (k_cmd, pod)) - - if not self.get_option('all'): - k_cmd = '%s get --all-namespaces=true' % kube_cmd for res in resources: self.add_cmd_output('%s %s' % (k_cmd, res)) + if self.get_option('describe'): + # need to drop json formatting for this + k_cmd = '%s get %s' % (kube_cmd, knsp) + for res in resources: + r = self.get_command_output( + '%s %s' % (k_cmd, res)) + if r['status'] == 0: + k_list = [k.split()[0] for k in + r['output'].splitlines()[1:]] + for k in k_list: + k_cmd = '%s %s' % (kube_cmd, knsp) + self.add_cmd_output( + '%s describe %s %s' % (k_cmd, res, k)) + + if self.get_option('podlogs'): + k_cmd = '%s %s' % (kube_cmd, knsp) + r = self.get_command_output('%s get pods' % k_cmd) + if r['status'] == 0: + pods = [p.split()[0] for p in + r['output'].splitlines()[1:]] + for pod in pods: + self.add_cmd_output('%s logs %s' % (k_cmd, pod)) + + if not self.get_option('all'): + k_cmd = '%s get --all-namespaces=true' % kube_cmd + for res in resources: + self.add_cmd_output('%s %s' % (k_cmd, res)) + def postproc(self): # First, clear sensitive data from the json output collected. # This will mask values when the "name" looks susceptible of -- 2.17.1 From 63ad6c251ab88ab2f0e07ae9e3f1b2771d5e90ca Mon Sep 17 00:00:00 2001 From: Jake Hunsaker Date: Thu, 12 Jul 2018 13:07:34 -0400 Subject: [PATCH 2/3] [kubernetes] Correct config option syntax Versions of kubernetes after 1.5 use --kubeconfig instead of --config to specify a configuration file to use for kubectl commands. Update the kubernetes plugin to use the proper syntax. Signed-off-by: Jake Hunsaker --- sos/plugins/kubernetes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sos/plugins/kubernetes.py b/sos/plugins/kubernetes.py index 21cb51df..c14e078e 100644 --- a/sos/plugins/kubernetes.py +++ b/sos/plugins/kubernetes.py @@ -61,7 +61,7 @@ class kubernetes(Plugin, RedHatPlugin): kube_cmd = "kubectl " if path.exists('/etc/origin/master/admin.kubeconfig'): - kube_cmd += "--config=/etc/origin/master/admin.kubeconfig" + kube_cmd += "--kubeconfig=/etc/origin/master/admin.kubeconfig" kube_get_cmd = "get -o json " for subcmd in ['version', 'config view']: -- 2.17.1 From 46fffd469f4f3d07337dc335cfc24341e836f23b Mon Sep 17 00:00:00 2001 From: Jake Hunsaker Date: Thu, 12 Jul 2018 13:11:44 -0400 Subject: [PATCH 3/3] [origin] Collect statistics information Adds collection of 'oc adm top' output for images and imagestreams. Resolves: #1165 Closes: #1383 Signed-off-by: Jake Hunsaker --- sos/plugins/origin.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/sos/plugins/origin.py b/sos/plugins/origin.py index 02bc047a..0e384117 100644 --- a/sos/plugins/origin.py +++ b/sos/plugins/origin.py @@ -124,14 +124,28 @@ class OpenShiftOrigin(Plugin): # # Note: Information about nodes, events, pods, and services # is already collected by the Kubernetes plugin + + subcmds = [ + "describe projects", + "adm top images", + "adm top imagestreams" + ] + self.add_cmd_output([ - "%s describe projects" % oc_cmd_admin, - "%s get -o json hostsubnet" % oc_cmd_admin, - "%s get -o json clusternetwork" % oc_cmd_admin, - "%s get -o json netnamespaces" % oc_cmd_admin, - # Registry and router configs are typically here - "%s get -o json dc -n default" % oc_cmd_admin, + '%s %s' % (oc_cmd_admin, subcmd) for subcmd in subcmds ]) + + jcmds = [ + "hostsubnet", + "clusternetwork", + "netnamespaces", + "dc -n default" + ] + + self.add_cmd_output([ + '%s get -o json %s' % (oc_cmd_admin, jcmd) for jcmd in jcmds + ]) + if self.get_option('diag'): diag_cmd = "%s adm diagnostics -l 0" % oc_cmd_admin if self.get_option('diag-prevent'): -- 2.17.1