<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Hausenblas</title>
    <description>The latest articles on DEV Community by Michael Hausenblas (@mhausenblas).</description>
    <link>https://dev.to/mhausenblas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1464%2F9b408466-4e0e-44b5-8ad6-94b062e3354f.jpg</url>
      <title>DEV Community: Michael Hausenblas</title>
      <link>https://dev.to/mhausenblas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mhausenblas"/>
    <language>en</language>
    <item>
      <title>10 things you didn't know about Kubernetes</title>
      <dc:creator>Michael Hausenblas</dc:creator>
      <pubDate>Fri, 25 Sep 2020 12:26:44 +0000</pubDate>
      <link>https://dev.to/aws/10-things-you-didn-t-know-about-kubernetes-24n8</link>
      <guid>https://dev.to/aws/10-things-you-didn-t-know-about-kubernetes-24n8</guid>
      <description>&lt;h2&gt;
  
  
  1. Initially written in Java
&lt;/h2&gt;

&lt;p&gt;Yeah, right? According to &lt;a href="https://archive.fosdem.org/2019/schedule/event/kubernetesclusterfuck/" rel="noopener noreferrer"&gt;Kris' FOSDEM 2019 talk&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Code named "7"
&lt;/h2&gt;

&lt;p&gt;As per the all-knowing &lt;a href="https://en.wikipedia.org/wiki/Kubernetes#History" rel="noopener noreferrer"&gt;Wikipedia entry&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The original codename for Kubernetes within Google was Project 7, a reference to the Star Trek ex-Borg character Seven of Nine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I suppose one can't hide the &lt;a href="https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43438.pdf" rel="noopener noreferrer"&gt;Borg&lt;/a&gt; origins ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  3. One of the fastest growing OSS projects
&lt;/h2&gt;

&lt;p&gt;Kubernetes is one of the &lt;a href="https://www.cncf.io/cncf-kubernetes-project-journey/" rel="noopener noreferrer"&gt;fastest growing OSS projects&lt;/a&gt; which has changed the industry quite a bit: beyond the bits, a number of concepts and terms that used to be mainly ops folks talk (rolling update deployment, load balancer, network policies, etc.) are now kinda standardized vocabulary that also developers throw around.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Lots of distributions to choose from
&lt;/h2&gt;

&lt;p&gt;Although only some 6 years old, almost 70 &lt;a href="https://www.cncf.io/certification/software-conformance/" rel="noopener noreferrer"&gt;certified distributions&lt;/a&gt; exist. It's kinda early days so still some half of the users (?) roll their own Kubernetes distro. But then, again, we used to roll our own Linux distros well into the 2000s, so there's that.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Throwing a Fedora into the ring
&lt;/h2&gt;

&lt;p&gt;Red Hat &lt;a href="https://www.redhat.com/en/blog/happy-6th-birthday-kubernetes" rel="noopener noreferrer"&gt;bet very early&lt;/a&gt; on Kubernetes, did a total rewrite of OpenShift on top of Kubernetes. This investment paid off and in the course RH not only established OpenShift as an enterprise-grade Kubernetes distro but also upstreamed a number of (typically security-related) features such as RBAC or the pod security context.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. From Raspberry Pi to Mainframe
&lt;/h2&gt;

&lt;p&gt;My former Mesosphere colleague Elizabeth K. Joseph, now with IBM, talked about &lt;a href="https://www.youtube.com/watch?v=Rgyb_9zCaeA" rel="noopener noreferrer"&gt;Wait, People Run Kubernetes on Mainframes?&lt;/a&gt; in the last pre-Covid KubeCon and Seth Kenlon of Red Hat gave us &lt;a href="https://opensource.com/article/20/8/kubernetes-raspberry-pi" rel="noopener noreferrer"&gt;5 reasons to run Kubernetes on your Raspberry Pi homelab&lt;/a&gt;. So, what will it be for you?&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Pronunciation is hard …
&lt;/h2&gt;

&lt;p&gt;… and yes, &lt;code&gt;kubectl&lt;/code&gt; is pronounced &lt;a href="http://kubectl.info/" rel="noopener noreferrer"&gt;kubecuddle&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Inclusivity rulz!
&lt;/h2&gt;

&lt;p&gt;While Kubernetes is up there with Linux in terms of OSS projects in terms of number of contributors or LOC, there's one thing that is pretty unique to Kubernetes: an extremely diverse and inclusive community. The only other community that comes to mind that is equally set up is the Rust community.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Lots and lots of upstream
&lt;/h2&gt;

&lt;p&gt;You would not believe what you find when trawling the Kubernetes source code (and what else would you want to do, since we're not travelling anymore, LOL). Some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/kubernetes/kubernetes/search?q=websockets" rel="noopener noreferrer"&gt;Websockets&lt;/a&gt; to &lt;code&gt;exec&lt;/code&gt; into and &lt;code&gt;log&lt;/code&gt; from pods.&lt;/li&gt;
&lt;li&gt;The venerable secure copy protocol &lt;a href="https://github.com/kubernetes/kubernetes/search?q=scp" rel="noopener noreferrer"&gt;&lt;code&gt;scp&lt;/code&gt;&lt;/a&gt; as well as the good old &lt;a href="https://github.com/kubernetes/kubernetes/search?l=Go&amp;amp;q=tar" rel="noopener noreferrer"&gt;&lt;code&gt;tar&lt;/code&gt;&lt;/a&gt; to copy stuff from and to containers (immutable infra, much?).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. First commit? First commit!
&lt;/h2&gt;

&lt;p&gt;Thanks to the magic of time travel (erm, Git history) we can see what the &lt;a href="https://github.com/kubernetes/kubernetes/commit/2c4b3a562ce34cddc3f8218a2c4d11c7310e6d56" rel="noopener noreferrer"&gt;first commit&lt;/a&gt; was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;First commit 

jbeda committed on 7 Jun 2014
0 parents commit 2c4b3a562ce34cddc3f8218a2c4d11c7310e6d56
Showing  with 47,501 additions and 0 deletions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.vmware.com/company/leadership/joe-beda.html" rel="noopener noreferrer"&gt;Joe&lt;/a&gt; was sure busy on that day :)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;With that, thanks for stopping by and I'm wondering: what's your favorite thing about Kubernetes that few people know? Care to share?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;The cover image uses a photo by Marcin Wichary - &lt;a href="https://commons.wikimedia.org/w/index.php?curid=7254146" rel="noopener noreferrer"&gt;originally posted to Flickr&lt;/a&gt;, CC BY 2.0.&lt;/p&gt;

</description>
      <category>kubernetes</category>
    </item>
    <item>
      <title>10 things you didn't know about the terminal</title>
      <dc:creator>Michael Hausenblas</dc:creator>
      <pubDate>Thu, 24 Sep 2020 08:49:30 +0000</pubDate>
      <link>https://dev.to/aws/10-things-you-didn-t-know-about-the-terminal-2a8c</link>
      <guid>https://dev.to/aws/10-things-you-didn-t-know-about-the-terminal-2a8c</guid>
      <description>&lt;h2&gt;
  
  
  1. Why still 80 characters default
&lt;/h2&gt;

&lt;p&gt;We regularly use monitors that have a gazillion of pixels available and yet, the &lt;a href="https://stackoverflow.com/questions/4651012/why-is-the-default-terminal-width-80-characters" rel="noopener noreferrer"&gt;default terminal width is 80 characters&lt;/a&gt;. Why, oh why? &lt;/p&gt;

&lt;p&gt;TL;DR: we owe this one to IBM and their standardized punchcards, introduced in the 1920s, sporting 80 columns:&lt;/p&gt;

&lt;p&gt;&lt;a title="Pete Birkinshaw from Manchester, UK / CC BY (https://creativecommons.org/licenses/by/2.0)" href="https://commons.wikimedia.org/wiki/File:Used_Punchcard_(5151286161).jpg" rel="noopener noreferrer"&gt;&lt;img alt="Used Punchcard (5151286161)" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2Ff%2Ffe%2FUsed_Punchcard_%25285151286161%2529.jpg%2F1024px-Used_Punchcard_%25285151286161%2529.jpg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Terminal: not the same as the shell or CLI
&lt;/h2&gt;

&lt;p&gt;Terminal. Shell. Command Line Interface (CLI). Three distinct and different things. Very much related, but they are and do different things: terminal is that window that may host a shell as well as other programs using a textual interface. CLIs are line-oriented, textual interfaces and come in all forms and shapes, for example the &lt;code&gt;aws&lt;/code&gt; CLI or when you are looking for something (aka: Google search). Learn more about the differences from this &lt;a href="https://askubuntu.com/questions/506510/what-is-the-difference-between-terminal-console-shell-and-command-line" rel="noopener noreferrer"&gt;Q&amp;amp;A piece&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. It's literally the end
&lt;/h2&gt;

&lt;p&gt;The word terminal &lt;a href="https://www.etymonline.com/word/terminus?ref=etymonline_crossreference" rel="noopener noreferrer"&gt;comes from&lt;/a&gt; Latin "terminus", meaning "an end, a limit, boundary line". Not too surprising: from where the mainframe sits, the people working on &lt;a href="https://en.wikipedia.org/wiki/Computer_terminal" rel="noopener noreferrer"&gt;computer terminals&lt;/a&gt; are indeed the end of the communication line.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Not the real thing? Emulator much!
&lt;/h2&gt;

&lt;p&gt;Unless you're in a museum, you're not really using a terminal these days. What you're using is a program called a &lt;a href="https://en.wikipedia.org/wiki/Terminal_emulator" rel="noopener noreferrer"&gt;terminal emulator&lt;/a&gt;, rather directly emulating a good old video or computer terminal from the 70s. Nice!&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Tame the beast
&lt;/h2&gt;

&lt;p&gt;Since the terminal emulator is a piece of software, one would expect to be able to &lt;a href="https://tldp.org/HOWTO/Text-Terminal-HOWTO-16.html" rel="noopener noreferrer"&gt;configure it&lt;/a&gt; to their liking. And indeed there are a number of things you can learn from your terminal's configuration and even set some. Here's what I see when I look at mine (Alacritty on macOS; edited down to only show the beginning):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ infocmp -L -1                                                                                                                                                                                                                                     
# Reconstructed via infocmp from file: /usr/share/terminfo/73/screen-256color
screen-256color|GNU Screen with 256 colors,
        auto_right_margin,
        backspaces_with_bs,
        eat_newline_glitch,
        has_hardware_tabs,
        has_meta_key,
        move_insert_mode,
        move_standout_mode,
        columns#80,
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Why &lt;code&gt;vi&lt;/code&gt; and YouTube use &lt;code&gt;j&lt;/code&gt; and &lt;code&gt;l&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Ever used &lt;code&gt;vi&lt;/code&gt; and wondered why pressing the &lt;code&gt;j&lt;/code&gt; key sends you a line down? Or, likewise, when you're watching a YouTube video and you want to fast-forward some 10 sec by hitting the &lt;code&gt;l&lt;/code&gt; key?&lt;/p&gt;

&lt;p&gt;Peter has the &lt;a href="https://catonmat.net/why-vim-uses-hjkl-as-arrow-keys" rel="noopener noreferrer"&gt;answer&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When Bill Joy created the &lt;code&gt;vi&lt;/code&gt; text editor he used the &lt;code&gt;ADM-3A&lt;/code&gt; terminal, which had the arrows on &lt;code&gt;hjkl&lt;/code&gt; keys. Naturally he reused the same keys and the rest is history.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, we can thank Bill Joy's terminal or more specifically its builtin keyboard layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. One terminal is not enough!
&lt;/h2&gt;

&lt;p&gt;As the title suggests and your monitor confirms: one terminal is not enough. Sure, you can launch multiple terminal windows or use tabs or whatever is kewl these days. We elderly people &lt;a href="https://superuser.com/questions/236158/tmux-vs-screen" rel="noopener noreferrer"&gt;use terminal multiplexer&lt;/a&gt; such as &lt;code&gt;tmux&lt;/code&gt; (preferred) or &lt;code&gt;screen&lt;/code&gt; (if you're really, really old). &lt;/p&gt;

&lt;h2&gt;
  
  
  8. GPU here I come
&lt;/h2&gt;

&lt;p&gt;You have a GPU I'm sure and you don't know how to keep its cache lines warm? Here's a suggestion: ditch your old terminal and give one of the GPU-powered terminals a try. I've personally migrated from iTerm2 to &lt;a href="https://github.com/alacritty/alacritty" rel="noopener noreferrer"&gt;alacritty&lt;/a&gt; and have only good things to say about it (moar YAML for config, yay) but there are also other options like &lt;a href="https://github.com/kovidgoyal/kitty" rel="noopener noreferrer"&gt;kitty&lt;/a&gt;. Might take you a day or so to move over but totally worth it, if you spend more than 50% of your time in the terminal ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Terminal vs. &lt;code&gt;tty&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Remember when we talked about software terminals in 4., above? I didn't really tell you the whole truth back then. Now that you're a terminal expert: meet &lt;code&gt;tty&lt;/code&gt; which is short for “teletypewriter.” Learn more about &lt;a href="https://www.howtogeek.com/428174/what-is-a-tty-on-linux-and-how-to-use-the-tty-command/" rel="noopener noreferrer"&gt;What is a TTY on Linux? (and How to Use the tty Command)&lt;/a&gt; and thank me later.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Terminal vs &lt;code&gt;stdin&lt;/code&gt;, &lt;code&gt;stdout&lt;/code&gt;, and &lt;code&gt;stderr&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;In the context of the shell and from programming languages you've almost certainly come across terms like &lt;code&gt;stdin&lt;/code&gt; or &lt;code&gt;stdout&lt;/code&gt;. Turns out those are simply per-process fixed files (with well-known file descriptors) that you're using to interact with, in the case of &lt;code&gt;stdout&lt;/code&gt; … wait for it … your terminal! Read more in &lt;a href="https://lucasfcosta.com/2019/04/07/streams-introduction.html" rel="noopener noreferrer"&gt;Your terminal is not a terminal: An Introduction to Streams&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;With that, thanks for stopping by and I'm wondering: what's your favorite thing about the terminal that few people know? Care to share?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Cover image kudos to &lt;a href="https://www.youtube.com/watch?v=tc4ROCJYbm0&amp;amp;t=881s" rel="noopener noreferrer"&gt;AT&amp;amp;T Archives&lt;/a&gt;, depicting Brian Kernighan rocking an early terminal.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>bash</category>
    </item>
    <item>
      <title>10 things you didn't know about Docker</title>
      <dc:creator>Michael Hausenblas</dc:creator>
      <pubDate>Tue, 22 Sep 2020 15:12:33 +0000</pubDate>
      <link>https://dev.to/aws/10-things-you-didn-t-know-about-docker-3n8p</link>
      <guid>https://dev.to/aws/10-things-you-didn-t-know-about-docker-3n8p</guid>
      <description>&lt;p&gt;You have heard of Docker, right? Maybe done a &lt;code&gt;docker run …&lt;/code&gt;, yes? Here are 10 things about Docker you (likely) did not know …&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Docker is French
&lt;/h2&gt;

&lt;p&gt;To be precise, &lt;a href="https://web.archive.org/web/20140702231323/https://www.dotcloud.com/about.html" rel="noopener noreferrer"&gt;dotCloud&lt;/a&gt;, the original company creating it, had its origins in France. Three well-known names, connected with the original company, in that context are Solomon Hykes, Sebastien Pahl, and Jérôme Petazzoni should help driving this point home. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Docker: software or company?
&lt;/h2&gt;

&lt;p&gt;Docker can be either seen as the &lt;a href="https://en.wikipedia.org/wiki/Docker_(software)" rel="noopener noreferrer"&gt;software&lt;/a&gt; or the &lt;a href="https://en.wikipedia.org/wiki/Docker,_Inc." rel="noopener noreferrer"&gt;company&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. What is OCI and how does it relate to Docker?
&lt;/h2&gt;

&lt;p&gt;In June 2015 Docker (the company) established the &lt;a href="https://opencontainers.org/" rel="noopener noreferrer"&gt;Open Container Initiative &lt;/a&gt; and many of its specifications are based on or directly derived from the original Docker (software).&lt;/p&gt;

&lt;h2&gt;
  
  
  4. What is Moby and how does it relate to Docker?
&lt;/h2&gt;

&lt;p&gt;To make the go-to-market and relationship with the software clearer Docker (the company) created &lt;a href="https://github.com/moby/moby" rel="noopener noreferrer"&gt;Moby&lt;/a&gt;, explaining it with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The components and tools in the Moby Project are initially the open source components that Docker and the community have built for the Docker Project. [...] Docker is committed to using Moby as the upstream for the Docker Product.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. Docker and Go
&lt;/h2&gt;

&lt;p&gt;Docker (both the software and the company) has contributed greatly to making Go (the programming language) mainstream.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Docker running on fruits?
&lt;/h2&gt;

&lt;p&gt;You can use Docker on many different platforms, &lt;a href="https://docs.docker.com/engine/faq/#does-docker-run-on-linux-macos-and-windows" rel="noopener noreferrer"&gt;from Linux to macOS to Windows&lt;/a&gt;. My fav has got to be Docker on &lt;a href="https://www.raspberrypi.org/blog/docker-comes-to-raspberry-pi/" rel="noopener noreferrer"&gt;Raspberry Pi&lt;/a&gt; … since 2016, nonetheless(!)&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Docker in the cloud
&lt;/h2&gt;

&lt;p&gt;Not only can you run Docker on almost any desktop (yeah, I know, laptop) but also on pretty much any cloud. For example, here at AWS it's super easy launching Docker containers using &lt;a href="https://aws.amazon.com/blogs/containers/introducing-aws-copilot/" rel="noopener noreferrer"&gt;Copilot&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Docker the company (part 2)
&lt;/h2&gt;

&lt;p&gt;As of end of 2019, Docker really exists in two companies: &lt;a href="https://techcrunch.com/2019/11/13/mirantis-acquires-docker-enterprise/" rel="noopener noreferrer"&gt;Mirantis acquired Docker’s Enterprise business and team&lt;/a&gt; and Docker, Inc. &lt;a href="https://www.docker.com/company" rel="noopener noreferrer"&gt;focuses on developer tooling&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Docker has many ancestors
&lt;/h2&gt;

&lt;p&gt;Starting in 1979 where the &lt;code&gt;chroot&lt;/code&gt; system call was introduced to FreeBSD jails and Solaris zones in the 2000s, Docker continued the ops tradition and made it mainstream for devs. Learn more about the history in this nice &lt;a href="https://www.k2io.com/container-history-adoption-trends-2020/#The_Evolution_of_Containers_-_A_Brief_History_of_Container_Technology" rel="noopener noreferrer"&gt;K2 Cyber Security&lt;/a&gt; article.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Docker is a world-wide topic
&lt;/h2&gt;

&lt;p&gt;Hundreds of &lt;a href="https://events.docker.com/chapters/" rel="noopener noreferrer"&gt;Docker User Groups&lt;/a&gt; exist world-wide and the conferences (pre-Covid) were legend. I remember &lt;a href="https://thenewstack.io/dockercon-2015-what-did-we-learn-this-week/" rel="noopener noreferrer"&gt;DockerCon 2015&lt;/a&gt; in San Francisco and the excitement around the technology as if it was yesterday.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;With that, thanks for stopping by and I'm wondering: what's your favorite thing about Docker that few people know? Care to share?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Cover image kudos to &lt;span&gt; &lt;a href="https://unsplash.com/@rubavi78?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Rubén Bagüés&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/container?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>linux</category>
      <category>aws</category>
      <category>devops</category>
    </item>
    <item>
      <title>A Lesson Learned In Going Serverless</title>
      <dc:creator>Michael Hausenblas</dc:creator>
      <pubDate>Tue, 04 Dec 2018 14:44:42 +0000</pubDate>
      <link>https://dev.to/mhausenblas/a-lesson-learned-in-going-serverless-1ko8</link>
      <guid>https://dev.to/mhausenblas/a-lesson-learned-in-going-serverless-1ko8</guid>
      <description>&lt;p&gt;When I was working on the &lt;a href="https://github.com/mhausenblas/imgn/tree/master/functions" rel="noopener noreferrer"&gt;serverless variant of imgn&lt;/a&gt;, a simple image sharing demo app, I ran into an issue around handling multipart form-data &lt;code&gt;POST&lt;/code&gt; requests with the API Gateway and AWS Lambda. This post shows how I solved it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;imgn&lt;/code&gt; app is really very simple: it allows you to upload image files and then you can view them in a public gallery. In the background, it extracts some image metadata (just the dimensions, for now) and displays it along with the images: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmlrz6lqk7uuqoz30ck4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzmlrz6lqk7uuqoz30ck4.png" alt="imgn app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During the development of the serverless variant of &lt;code&gt;imgn&lt;/code&gt; I ran into an issue in the context of uploading the image to S3 using a Lambda function via the API Gateway. You can read up on the issue description in greater detail on &lt;a href="https://stackoverflow.com/questions/53537939/posting-image-using-form-data-via-api-gateway-to-lambda-function-results-in-inva" rel="noopener noreferrer"&gt;StackOverflow&lt;/a&gt;, but the essence is: the payload that the API Gateway hands over to the Lambda function gets somehow butchered, so the images end up being corrupted when they land in the respective S3 bucket. &lt;/p&gt;

&lt;p&gt;To narrow down where this SNAFU happens, I first replaced my initial code that would create a &lt;code&gt;http.request&lt;/code&gt; and use the &lt;a href="https://golang.org/pkg/net/http/#Request.ParseForm" rel="noopener noreferrer"&gt;ParseForm&lt;/a&gt; method to get to the image data with my own implementation of &lt;a href="https://github.com/mhausenblas/imgn/blob/42912b2334400f969d08481b3d5341042211c31a/functions/app/uploadimg/main.go#L31" rel="noopener noreferrer"&gt;parsing the multipart form-data&lt;/a&gt;. Still, the corruption was the same.&lt;/p&gt;

&lt;p&gt;Next, in  order to exclude the "upload to the S3 bucket" part as the culprit for the data corruption, I returned the parsed image data I got from the API Gateway as a result of the Lambda call. This allowed me to use &lt;code&gt;hexdump&lt;/code&gt; to compare the resulting file with the original, but still no bueno. The problem persisted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fit6zbbk7tbartkwwb96t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fit6zbbk7tbartkwwb96t.png" alt="CloudWatch logs of the UploadImageFunction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only thing left in the request path was the handover of the (binary) image data from the API Gateway to the Lambda function. &lt;/p&gt;

&lt;p&gt;After trawling StackOverflow and reading many seemingly relevant posts in AWS fora, I decided it was time for a different approach. I read up on &lt;a href="https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/s3-example-presigned-urls.html" rel="noopener noreferrer"&gt;pre-signed URLs&lt;/a&gt; and decided to give this a try. These pre-signed URLs enable you to allow people to manipulate objects in S3 buckets and you can set restrictions in terms of what operation, on which object, and for how long you allow it to happen.&lt;/p&gt;

&lt;p&gt;So, the idea would be that when a user issues a multipart form-data &lt;code&gt;POST&lt;/code&gt; request via the UI, the &lt;code&gt;UploadImageFunction&lt;/code&gt; would not directly upload the image to S3 but create a &lt;a href="https://github.com/mhausenblas/imgn/blob/master/functions/app/uploadimg/main.go#L118-L126" rel="noopener noreferrer"&gt;pre-signed URL&lt;/a&gt; for a &lt;code&gt;PUT&lt;/code&gt; request into said S3 bucket, valid for the file referenced in the previous form-data &lt;code&gt;POST&lt;/code&gt; request and restricted to 5 minutes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s3c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PutObjectRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PutObjectInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gallerybucket&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;aws&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imgname&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;presurl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Presign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Minute&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;… and the &lt;a href="https://github.com/mhausenblas/imgn/blob/42912b2334400f969d08481b3d5341042211c31a/functions/ui/upload.js#L31" rel="noopener noreferrer"&gt;JavaScript code&lt;/a&gt; in the UI would then issue a second &lt;code&gt;PUT&lt;/code&gt; request, using the pre-signed URL to directly upload the image into the S3 bucket. And that works like a charm!&lt;/p&gt;

&lt;p&gt;I'm still unsure if I should qualify this strategy as a hack or a good practice and would certainly appreciate to hear from other serverless practitioners what they think.&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>aws</category>
      <category>lambda</category>
      <category>apigateway</category>
    </item>
    <item>
      <title>Revisiting PromCon 2018 Panel On Prometheus Long-Term Storage</title>
      <dc:creator>Michael Hausenblas</dc:creator>
      <pubDate>Tue, 20 Nov 2018 11:06:26 +0000</pubDate>
      <link>https://dev.to/mhausenblas/revisiting-promcon-2018-panel-on-prometheus-long-term-storage-5f1p</link>
      <guid>https://dev.to/mhausenblas/revisiting-promcon-2018-panel-on-prometheus-long-term-storage-5f1p</guid>
      <description>

&lt;p&gt;While Prometheus itself does not offer a clustered storage solution to store data across multiple machines out of the box, there are a number of so called Long-Term Storage (LTS) options available. In this article we do a high-level review of some the LTS options that were the topic of a &lt;a href="https://youtu.be/VvJx0WTiGcA?t=23774"&gt;PromCon 2018 panel&lt;/a&gt; I had the pleasure to witness in person, back in August of this year: &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/3pTG_N8yGSU"&gt; &lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;Note that below I won't provide a recommendation &lt;em&gt;which&lt;/em&gt; LTS solution you should pick, since it very much depends on your specific requirements and preferences.&lt;/p&gt;

&lt;p&gt;Prometheus &lt;a href="https://prometheus.io/docs/prometheus/latest/storage/"&gt;stores&lt;/a&gt; data on local storage, which limits the data you can query or otherwise process to the most recent days or weeks, depending on how much space you have available, locally. If you, however, have the need to retain data for longer time periods, for example for long-term capacity planning, analyzing usage trends, or for regulatory reasons in a certain vertical—think: financial domain or health care—then you likely benefit from a LTS solution. Let's have a look at the offerings discussed in the PromCon panel (in alphabetical order):&lt;/p&gt;

&lt;h2&gt;Cortex&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/weaveworks/cortex"&gt;Cortex&lt;/a&gt; provides horizontally scalable, multi-tenant, long term storage for Prometheus metrics when used as a remote write destination, and a horizontally scalable, Prometheus-compatible query API.&lt;/p&gt;

&lt;p&gt;See also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=Xi4jq2IUbLs"&gt;Cortex: open-source, horizontally-scalable, distributed Prometheus&lt;/a&gt;, 06/2017&lt;/li&gt;
&lt;li&gt;Project Frankenstein: Multitenant, Scale-Out Prometheus: &lt;a href="https://youtu.be/3Tb4Wc0kfCM"&gt;video&lt;/a&gt; | &lt;a href="http://www.slideshare.net/weaveworks/project-frankenstein-a-multitenant-horizontally-scalable-prometheus-as-a-service"&gt;slides&lt;/a&gt;, 09/2016&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;InfluxDB&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.influxdata.com/time-series-platform/influxdb/"&gt;InfluxDB&lt;/a&gt; is a time series database designed to handle high write and query loads and is meant to be used as a backing store for any use case involving large amounts of timestamped data, including DevOps monitoring, application metrics, IoT sensor data, and real-time analytics. InfluxDB supports the &lt;a href="https://docs.influxdata.com/influxdb/v1.6/supported_protocols/prometheus"&gt;Prometheus remote read and write API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.influxdata.com/blog/influxdb-now-supports-prometheus-remote-read-write-natively/"&gt;InfluxDB Now Supports Prometheus&lt;/a&gt;, 09/2017&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://speakerdeck.com/pauldix/influxdb-plus-prometheus"&gt;InfluxDB + Prometheus&lt;/a&gt; presentation, 08/2017 &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;M3&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://m3db.github.io/m3/"&gt;M3&lt;/a&gt; is a metrics platform, originally developed at Uber, that is built on M3DB, a distributed time     series database and it provides an &lt;a href="http://m3db.github.io/m3/integrations/prometheus/"&gt;integration of M3DB with Prometheus&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://eng.uber.com/m3/"&gt;M3: Uber’s Open Source, Large-scale Metrics Platform for Prometheus&lt;/a&gt;, 08/2018&lt;/li&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=17707842"&gt;Hacker News thread&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Thanos&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/improbable-eng/thanos"&gt;Thanos&lt;/a&gt; is a set of components that can be composed into a highly available metric system with unlimited storage capacity. It can be added seamlessly on top of existing Prometheus deployments and leverages the Prometheus 2.0 storage format to cost-efficiently store historical metric data in any object storage while retaining fast query latencies. Additionally, it provides a global query view across all Prometheus installations and can merge data from Prometheus HA pairs on the fly.&lt;/p&gt;

&lt;p&gt;See also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=6P-RmOWWA4U"&gt;The new Prometheus storage engine&lt;/a&gt;, 06/2018&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://improbable.io/games/blog/thanos-prometheus-at-scale"&gt;Introducing Thanos: Prometheus at scale&lt;/a&gt;, 05/2018&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;So to sum up: while Prometheus itself does not support long-term retention of the time series data of interest, there are a number of solutions you can choose from to keep the metrics around for as long as needed. Hope this quick review gives you an idea of some of the available options and can serve as the basis for your own research, should you find yourself in the a situation to have to select one. I wish you successful monitoring and please do share your findings and/or hands-on experiences with above discussed or other LTS solutions not covered here.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cover image kudos to &lt;a href="https://unsplash.com/photos/h6xNSDlgciU"&gt;jesse orrico via Unsplash&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


</description>
      <category>prometheus</category>
      <category>monitoring</category>
      <category>storage</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>On defaults in Kubernetes RBAC</title>
      <dc:creator>Michael Hausenblas</dc:creator>
      <pubDate>Sun, 11 Nov 2018 17:33:19 +0000</pubDate>
      <link>https://dev.to/mhausenblas/on-some-defaults-in-kubernetes-rbac-270l</link>
      <guid>https://dev.to/mhausenblas/on-some-defaults-in-kubernetes-rbac-270l</guid>
      <description>&lt;p&gt;In Kubernetes, the Role-Based Access Control (RBAC) method defines a number of &lt;a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings" rel="noopener noreferrer"&gt;default roles and bindings&lt;/a&gt;. In this article, we will have a closer look at some of those and discuss where and how to use them.&lt;/p&gt;

&lt;p&gt;Let's start with the user-facing cluster roles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get clusterroles | grep -v '^system'
NAME                                                                   AGE
admin                                                                  33h
cluster-admin                                                          33h
edit                                                                   33h
view                                                                   33h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we found four cluster roles, &lt;code&gt;admin&lt;/code&gt;, &lt;code&gt;cluster-admin&lt;/code&gt;, &lt;code&gt;edit&lt;/code&gt;, and &lt;code&gt;view&lt;/code&gt; available by default in this setup (a Kubernetes 1.11 install). What can you do with them? Using commands such as &lt;code&gt;kubectl get clusterrole/admin -o yaml&lt;/code&gt; reveals what each of these roles is about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both &lt;code&gt;cluster-admin&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt; give read-write access to all (respectively many) resources. In general, if you want to make someone superuser or cluster root, then use the &lt;code&gt;cluster-admin&lt;/code&gt; cluster-role with a cluster role binding. Think hard if you want to do that. If your organization sports the responsibility of a namespace admin, you can use either &lt;code&gt;cluster-admin&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt; with a role binding and that enables this person then to do everything or mostly everything with all (respectively almost all) resources in the namespace the role binding exists. The only real difference between &lt;code&gt;cluster-admin&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt; is that the latter is a little more restrictive when it comes to certain resources such as the namespaces themselves.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;edit&lt;/code&gt; role allows one to create, update, delete many of the normal core resources such as deployments, services, or configmaps, however manipulating RBAC permissions is not allowed.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;view&lt;/code&gt; role is for read-only access on most resources (besides secrets).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Oftentimes these default roles are a nice starting point for human users. For apps, in reality you will likely end up using tools like &lt;a href="https://github.com/liggitt/audit2rbac" rel="noopener noreferrer"&gt;audit2rbac&lt;/a&gt; to figure out tailored permissions, based on concrete access patterns.&lt;/p&gt;

&lt;p&gt;Next, we have a look at the one and only default cluster binding &lt;code&gt;cluster-admin&lt;/code&gt; which in my install is defined as follows (edited in the following for clarity by dropping irrelevant fields):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get clusterrolebindings/cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:masters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seems that the cluster role binding &lt;code&gt;cluster-admin&lt;/code&gt; gives the &lt;code&gt;system:masters&lt;/code&gt; group super powers; that's good to know but not directly super useful.&lt;/p&gt;

&lt;p&gt;OK, let's move on with service accounts (the identities for non-human users such as Kubernetes components like nodes, controllers, or your own app):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl get sa --all-namespaces
NAMESPACE     NAME                                 SECRETS   AGE
default       default                              1         1d
kube-public   default                              1         1d
kube-system   attachdetach-controller              1         1d
kube-system   bootstrap-signer                     1         1d
kube-system   certificate-controller               1         1d
kube-system   clusterrole-aggregation-controller   1         1d
kube-system   coredns                              1         1d
kube-system   cronjob-controller                   1         1d
kube-system   daemon-set-controller                1         1d
kube-system   default                              1         1d
kube-system   deployment-controller                1         1d
kube-system   disruption-controller                1         1d
kube-system   endpoint-controller                  1         1d
kube-system   expand-controller                    1         1d
kube-system   generic-garbage-collector            1         1d
kube-system   horizontal-pod-autoscaler            1         1d
kube-system   job-controller                       1         1d
kube-system   kube-proxy                           1         1d
kube-system   namespace-controller                 1         1d
kube-system   nginx-ingress                        1         1d
kube-system   node-controller                      1         1d
kube-system   persistent-volume-binder             1         1d
kube-system   pod-garbage-collector                1         1d
kube-system   pv-protection-controller             1         1d
kube-system   pvc-protection-controller            1         1d
kube-system   replicaset-controller                1         1d
kube-system   replication-controller               1         1d
kube-system   resourcequota-controller             1         1d
kube-system   service-account-controller           1         1d
kube-system   service-controller                   1         1d
kube-system   statefulset-controller               1         1d
kube-system   storage-provisioner                  1         1d
kube-system   token-cleaner                        1         1d
kube-system   ttl-controller                       1         1d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, there are tons of control plane components with their own service accounts each and the infamous &lt;code&gt;default&lt;/code&gt; service accounts, which you shouldn't be using, &lt;a href="https://itnext.io/the-abc-of-kubernetes-access-control-e7d280af5c88" rel="noopener noreferrer"&gt;always create a dedicated one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're ever in doubt if a certain entity, that is, a user or a service account is permitted to carry out a certain action (like creating a secret), you can use the &lt;code&gt;kubectl auth can-i&lt;/code&gt; command to check that, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# let's create a dedicated namespace called secdemo:
$ kubectl create ns secdemo
kubectl create ns secdemo

# let's create a service account nsadmin:
$ kubectl --namespace=secdemo create sa nsadmin
serviceaccount/nsadmin created

# checking if that service account is allowed to create secrets:
$ kubectl --namespace=secdemo auth can-i create secrets \ 
          --as=system:serviceaccount:secdemo:nsadmin
no

# let's give the service account nsadmin the permissions:
$ kubectl --namespace=secdemo create rolebinding nsadmin \
          --clusterrole=admin \
          --serviceaccount=secdemo:nsadmin 
rolebinding.rbac.authorization.k8s.io/nsadmin created

# … and now the service account nsadmin is allowed to 
# create secrets in the namespace secdemo:
$ kubectl --namespace=secdemo auth can-i create secrets \ 
          --as=system:serviceaccount:secdemo:nsadmin
yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK, that was it and if you want to learn more about RABC, I recommend to watch this awesome KubeCon 2017 talk:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Nw1ymxcLIDI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;And if you want some more info on RBAC usage, check out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://blog.cowger.us/2018/07/03/a-read-only-kubernetes-dashboard.html" rel="noopener noreferrer"&gt;A Read Only Kubernetes Dashboard&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://jeremievallee.com/2018/05/28/kubernetes-rbac-namespace-user.html" rel="noopener noreferrer"&gt;Kubernetes and RBAC: Restrict user access to one namespace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mhausenblas.info/kubectl-in-action/#rbac" rel="noopener noreferrer"&gt;kubectl in action—RBAC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for checking in here and see you around some time soon.&lt;/p&gt;

</description>
      <category>rbac</category>
      <category>authorization</category>
      <category>kubernetes</category>
      <category>security</category>
    </item>
  </channel>
</rss>
