{"id":88666,"date":"2020-10-08T15:05:11","date_gmt":"2020-10-08T15:05:11","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=88666"},"modified":"2022-04-24T21:18:07","modified_gmt":"2022-04-24T21:18:07","slug":"checking-the-pulse-of-kubernetes","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/devops\/containers-and-virtualization\/checking-the-pulse-of-kubernetes\/","title":{"rendered":"Checking the pulse of Kubernetes"},"content":{"rendered":"<p>Over just a few years, Kubernetes has taken the computing world by storm, so many software developers know and use it on a daily basis. However, because it is still relatively new, there are many more who are just getting started. In my recent (and ongoing) journey towards Kubernetes enlightenment, the first thing that struck me was that there are a lot of moving parts. Not by itself, perhaps, but Kubernetes is not used in isolation. It is a container orchestration system. That means you are going to have containers, you are going to put your things in those containers, and you are going to connect your things to other, third-party things. So, in short order, you have, well, a lot of things.<\/p>\n<h2>There\u2019s buried treasure: Where do you start digging?<\/h2>\n<p>The world begins, of course, with <a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/kubectl\/\"><strong>kubectl<\/strong><\/a>, the command-line interface to Kubernetes. The commands you start using early on help you examine your Kubernetes resources.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">kubectl get . . .<\/pre>\n<p>With that command, you can examine your deployments, which rollout your replica sets, which create pods. Then you need services, which are logical sets of pods that provide an interface for external access. What can you examine with <code>kubectl get<\/code> ?<\/p>\n<p>Use <code>kubectl api-resources<\/code> to see the list. At the time of this writing, there are 66 different resource types! That number will likely only grow over time. Here is a partial list of them:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1288\" height=\"624\" class=\"wp-image-88667\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-16.png\" \/><\/p>\n<p>So where do you even begin to look for interesting things? Well, I have already mentioned some key players: pods, replica sets, and deployments. Do not take my word for it; instead, ask Kubernetes to show the interesting things:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">kubectl -n YOUR_NAMESPACE get \\\r\n   $(kubectl api-resources --verbs=list --namespaced -o name | paste -s -d, -)<\/pre>\n<p>Let\u2019s break that down:<\/p>\n<p>The inner <code>kubectl<\/code> command is just asking for all the api-resources, as mentioned above. It\u2019s filtering that just a bit to those resources that support listing <code>(--verbs=list<\/code>) and to those resources that are <code>namespaced<\/code> (i.e. specific to a namespace rather than global). Finally, <code>-o name<\/code> is asking for the output to be the list of those resource names, rather than the usual multi-field output.<\/p>\n<p>You pipe that into <code>paste<\/code> in order to massage it into a comma-separated list.<\/p>\n<p>That list is then fed to the outer <code>kubectl<\/code> along with your namespace, to give you a customized list of interesting things. My cluster is not too complicated, so I get most everything on one screenful:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"906\" class=\"wp-image-88668\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-17.png\" \/><\/p>\n<p>A snapshot like that really helps when you have something not working quite right, and you have the daunting task of figuring out what. If you are fortunate, you might see something right off; perhaps the desired replica count does not equal the actual, so you have some idea where to start looking. If not, it is helpful to be able to dig further. You can do that individually with <code>kubectl describe<\/code>, but I find it immensely more productive to have a GUI that helps with that.<\/p>\n<h2>Bring in the GUIs<\/h2>\n<p>If you don\u2019t want to spend all your time in code, you can also explore these interfaces.<\/p>\n<h3>Kubernetes built-in dashboard<\/h3>\n<p>I first found that Kubernetes itself provides a dashboard. That shows you in real-time what is happening in your cluster. Here, for example, you see successive screenshots, a few seconds apart, as my cluster was stood up (and had not quite finished in the last screenshot).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"1382\" class=\"wp-image-88669\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-18.png\" \/><\/p>\n<p>You have to do just a bit of work to set this up.<\/p>\n<h4>Step 1: Deploy the dashboard<\/h4>\n<pre class=\"lang:ps theme:powershell-ise\">kubectl apply -f https:\/\/raw.githubusercontent.com\/Kubernetes\/dashboard\/v2.0.0\/aio\/deploy\/recommended.yaml<\/pre>\n<p>Reference: https:\/\/Kubernetes.io\/docs\/tasks\/access-application-cluster\/web-ui-dashboard\/#deploying-the-dashboard-ui<\/p>\n<h4>Step 2: Expose the URL<\/h4>\n<p>This next command does the necessary magic to expose the URL you will use in step 5 to access the dashboard. This command remains running until you terminate it, so you either need to run it in a separate window or add an ampersand (<code>&amp;<\/code>) to the end to run it in the background (assuming a Linux environment).<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">kubectl proxy<\/pre>\n<h4>Step 3: Setup an admin user to access your dashboard<\/h4>\n<p>You need to create a <em>dashboard.yaml<\/em> file like this, filling in your admin name.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">apiVersion: v1\r\nkind: ServiceAccount\r\nmetadata:\r\n  name: YOUR_ADMIN_NAME\r\n  namespace: kubernetes-dashboard\r\n---\r\napiVersion: rbac.authorization.k8s.io\/v1\r\nkind: ClusterRoleBinding\r\nmetadata:\r\n  name: chef-cloud-admin\r\nroleRef:\r\n  apiGroup: rbac.authorization.k8s.io\r\n  kind: ClusterRole\r\n  name: cluster-admin\r\nsubjects:\r\n- kind: ServiceAccount\r\n  name: chef-cloud-admin\r\n  namespace: Kubernetes-dashboard<\/pre>\n<p>Then deploy that with <code>kubectl apply -f dashboard.yaml<\/code><\/p>\n<p>Reference: https:\/\/github.com\/Kubernetes\/dashboard\/blob\/master\/docs\/user\/access-control\/creating-sample-user.md<\/p>\n<h4>Step 4: Extract your admin user token and use that to login<\/h4>\n<p>You will need to install the JSON processor <a href=\"https:\/\/stedolan.github.io\/jq\/\"><strong>jq<\/strong><\/a> for this:<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">kubectl -n Kubernetes-dashboard get secret -o json \\\r\n| jq -r '.items[] | select(.metadata.name | contains(\"YOUR_ADMIN_NAME\")).data.token | @base64d'<\/pre>\n<h4>Step 5: Open the dashboard in your browser<\/h4>\n<p>Navigate to this URL and login with that token obtained above:<\/p>\n<p>http:\/\/localhost:8001\/api\/v1\/namespaces\/Kubernetes-dashboard\/services\/https:Kubernetes-dashboard:\/proxy<\/p>\n<h3>K9s<\/h3>\n<p>At first glance, <a href=\"https:\/\/k9scli.io\/\"><strong>k9s<\/strong><\/a> looks, well, antiquated. The first hint may be the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Curses_(programming_library)\">curses<\/a> style look&#8211;that is, it is a text-based GUI that runs in your terminal. But <strong>k9s<\/strong> is great; it provides a lightweight, responsive, concise monitor of your cluster. The header shows some basic info. Here you can see I am running Kubernetes via Docker Desktop on my Mac. It also shows some of the most common command keys; you can get a full list of commands by pressing a question mark (<code>?<\/code>).<\/p>\n<p>The main body of this home page shows all pods in all namespaces by default&#8211;you can even see the pods for the Kubernetes dashboard (discussed earlier) at the very bottom.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"636\" class=\"wp-image-88670\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-19.png\" \/><\/p>\n<p>From the list of pods, you use vi-like controls (or arrows if you prefer) to select your pod of interest, press enter to drill down to the containers, select one container, and press enter again to drill down to its logs. Keyboard commands make navigating around and exploring your cluster very snappy.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"766\" class=\"wp-image-88671\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-20.png\" \/><\/p>\n<p>Prefer to dig around your container yourself? Select it from the container list and just press \u201cs\u201d to open a shell to that container!<\/p>\n<p>I am impressed with the tight, easy interface of <strong>k9s, <\/strong>but I only achieved this karmic delight after figuring out some essential things omitted in the documentation. Remember the list of all api-resources you could generate with kubectl? The first key fact is that <strong>k9s<\/strong> gives that to you with a single keystroke, Ctrl + A. Surely that must be documented, you wonder? Well, yes, it is documented by this obscure reference to \u201caliases\u201d:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1892\" height=\"426\" class=\"wp-image-88672\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-21.png\" \/><\/p>\n<p>When you invoke that keystroke you get this familiar-looking list:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1896\" height=\"890\" class=\"wp-image-88673\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-22.png\" \/><\/p>\n<p>While that might seem anticlimactic, it is actually a big deal, because that is the key to navigating to all-the-things within <strong>k9s<\/strong>. As a first exposure, <strong>k9s<\/strong> launches with a pod view, and as I showed above, you could drill down (by highlighting then pressing enter) to containers, then again to logs. And you could traverse upward by pressing Escape once or twice. While nice, surely there must be more than that, I thought.<\/p>\n<p>The second key fact is that <strong>k9s<\/strong> has a command mode. Like vi, just press colon (:). You can, in fact, see that listed in the help view above, the third entry down in the second column, <em>General<\/em>.<\/p>\n<p>But what are the commands? That is the third key, undocumented fact: any resource from the list of aliases. Want to see endpoints? Type :ep. (Not the period; that\u2019s just the end of the sentence!) Want to see configmaps? Type :cm. How do you go back to pods? Just type :pods.<\/p>\n<h3>Lens<\/h3>\n<p>Prefer more graphical user interfaces (like the dashboard) but still like the richness of information (like <strong>k9s<\/strong>)? Take a look at <a href=\"https:\/\/k8slens.dev\/\"><strong>Lens<\/strong><\/a> as another alternative. Here\u2019s the overview page, showing a summary of resources plus the latest events. In the left navigation pane, you can see the selection of resources available to view.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"854\" class=\"wp-image-88674\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-23.png\" \/><\/p>\n<p>Here is the pod view, which is very similar to <strong>k9s<\/strong>, but with a few different columns. For example, you can see at a glance how many containers are in the pod. But <strong>Lens<\/strong> does not show the number of replicas currently running, as <strong>k9s<\/strong> does.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1278\" height=\"628\" class=\"wp-image-88675\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-24.png\" \/><\/p>\n<p>One very convenient feature about replicas, though, is available in the deployment view. Opening the control menu for a given deployment, you can select the \u201cScale\u201d option, and then adjust your desired replica count with the slider!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"1106\" class=\"wp-image-88676\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-25.png\" \/><\/p>\n<p>One thing that <strong>Lens<\/strong> revealed to me (because you have to pick your cluster upon startup): it found <em>two<\/em> clusters on my development box: <strong>docker-desktop<\/strong> and <strong>docker-for-desktop<\/strong>. (You can also see both from <code>kubectl config get-contexts<\/code>.) Two different cluster names, yes, but they both point to the same actual cluster! It turns out that it was an artifact introduced a few months ago by Docker because they decided a name change was in order. They chose to leave the legacy <strong>docker-for-desktop<\/strong> in place so as not to break user scripts that might rely on it. However, due to feedback on the issue (https:\/\/github.com\/docker\/for-mac\/issues\/4089) they have fixed it (removed it) as of the latest Edge release 2.3.2.0 (at the time of writing).<\/p>\n<h3>Stern<\/h3>\n<p>There is one more piece of crucial tooling for me that none of the previous tools can offer: when I am trying to diagnose a failure during development, I usually pore over the logs. It is tedious to have to do that one log at a time, particularly when you do not have a notion of where to start looking. The good folks at Wercker have a multi-log viewing tool called <a href=\"https:\/\/github.com\/wercker\/stern\"><strong>stern<\/strong><\/a> that lets you tail all the logs you might want. For example, with this command, I am asking to see the latest entries in real-time from the \u201cgloo-system\u201d namespace (<code>-n gloo-system<\/code>), except for any message that is involved in health checks (<code>-e health<\/code>), going back only as far as one minute ago (<code>--since 1m<\/code>). You can also filter by the content of messages, too, with regular expressions. I have just given a single dot as the final argument, meaning any character&#8211;in other words, unfiltered by message.<\/p>\n<pre class=\"lang:ps theme:powershell-ise\">stern -n gloo-system -t -e health --since 1m .<\/pre>\n<p>Here is a partial output when I exercised my API. <strong>Stern<\/strong> color codes each pod name so you can see three different pods have reported new log messages here.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1280\" height=\"800\" class=\"wp-image-88677\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2020\/10\/word-image-26.png\" \/><\/p>\n<h2>Summary<\/h2>\n<p>This article just scratches the surface of what one can do to check the pulse of your Kubernetes installation. These tools have been invaluable to me as I have been learning to understand the state of my k8s world and to diagnose issues with it. There are likely many more useful tools out there; please post a comment to share your favorites!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, Michael Sorens describes the many ways that you can monitor Kubernetes.&hellip;<\/p>\n","protected":false},"author":221868,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143513],"tags":[124952],"coauthors":[6802],"class_list":["post-88666","post","type-post","status-publish","format-standard","hentry","category-containers-and-virtualization","tag-redgate-deploy"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/88666","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221868"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=88666"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/88666\/revisions"}],"predecessor-version":[{"id":88680,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/88666\/revisions\/88680"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=88666"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=88666"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=88666"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=88666"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}