<?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>Forem: Kyle Wagner</title>
    <description>The latest articles on Forem by Kyle Wagner (@kaikeru).</description>
    <link>https://forem.com/kaikeru</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%2F255663%2Fa5e08239-8e88-4640-a554-f93e0e7e9c48.jpg</url>
      <title>Forem: Kyle Wagner</title>
      <link>https://forem.com/kaikeru</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kaikeru"/>
    <language>en</language>
    <item>
      <title>How I Fell Into DevOps</title>
      <dc:creator>Kyle Wagner</dc:creator>
      <pubDate>Wed, 27 Nov 2019 22:43:59 +0000</pubDate>
      <link>https://forem.com/kaikeru/how-i-fell-into-devops-474n</link>
      <guid>https://forem.com/kaikeru/how-i-fell-into-devops-474n</guid>
      <description>&lt;p&gt;This post is basically how I learned to DevOps. It's not "How to Become a DevOps Engineer". There is no one answer. I had a lot of luck and a lot of passion. Instead, this is about my career path, and how I ended up the Lead SRE of a multi-national company.&lt;/p&gt;

&lt;p&gt;First of all, I love CLI tools. My everyday toolkit is &lt;code&gt;zsh&lt;/code&gt;, &lt;code&gt;vim&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;ssh&lt;/code&gt;, and &lt;code&gt;git&lt;/code&gt;. I learned all these at my first job working on custom hardware. At the time, I was a new CS grad with a go-get-em attitude towards proper software design and building apps. The iPhone had just come out, and I was sure I'd work on apps for the rest of my career. Side note: I have never published a single app.&lt;/p&gt;

&lt;p&gt;The job wasn't like that. Instead, I wrote kernel modules and learned all about &lt;code&gt;/var/logs&lt;/code&gt;. Grep became indispensable. I wrote GTK+ widgets in object oriented C (not Objective-C), and that is the worst thing I've done in my career. On the plus side, I learned how to read some Chinese due to all the helpful Google results on GTK+ being Chinese forums.&lt;/p&gt;

&lt;p&gt;Linux became second nature and its low level machinery was no longer a mystery. My very own patch was accepted into the kernel to fix a &lt;code&gt;ioctl&lt;/code&gt; call that was causing our systems to crash. Even more insane, I wrote a complex build/deployment system in bash that required translating a home brew &lt;code&gt;cmake&lt;/code&gt; like build system from Perl to Python.&lt;/p&gt;

&lt;p&gt;One day, Google contacted me for a job interview. I passed the initial foot-in-the-door part of the process, and the recruiter asked me where I'd like to apply to within the company. I had no clue. I thought maybe Android? She asked me to describe my abilities and current job. Without hesitation, she suggested the Site Reliability Engineering group, which I had no idea what that was.&lt;/p&gt;

&lt;p&gt;Sadly (or gladly), I didn't get the job at Google. Instead, I took a year off to teach myself about modern application design. I built microservices, messed around with these things called Docker, started learning the then brand new React framework. After a bunch of interviews, I ended up a mid-level QA Automation Engineer for a local mid-stage startup. &lt;/p&gt;

&lt;p&gt;There was good year of work there in the automation role before things started to sour. I gained knowledge in build systems, integration testing and continuous integration with TravisCI. Then, they made some high level decisions that saw engineers leave. As the guy with the most knowledge of the cloud infrastructure, I was suddenly promoted to lead DevOps.&lt;/p&gt;

&lt;p&gt;I was in way over my head, so I bought &lt;em&gt;&lt;a href="https://itrevolution.com/book/the-devops-handbook"&gt;The DevOps Handbook&lt;/a&gt;&lt;/em&gt;. That single book changed, I'm not exaggerating, everything. It all clicked. All the skills I had gathered over the years since graduation made sense. I wanted to learn all the best practices, the Toyota Manufacturing System, what an SRE is, and how to put it all in place. I was determined to try.&lt;/p&gt;

&lt;p&gt;The following year was filled with putting forth the lessons in the book. I did my best to achieve the DevOps transformation, but it didn't happen. The failure still hurts and is lessons learned. The problem was management buy-in. They didn't see the need for the changes and just wanted me to continuously fight fires. So, I quit.&lt;/p&gt;

&lt;p&gt;Finding a company with the management buy-in is how I found my current job. I interviewed them as much as they interviewed me. So far, they haven't lied to me. Even when they merged with another company, they allowed me to move the DevOps way up the chain so all our teams can practice those best practices. I feel lucky. I'm happy to be a SRE doing the best DevOps I can.&lt;/p&gt;

&lt;p&gt;I know this isn't a helpful post about "How to Become a DevOps Engineer" but it's how I did it. I just kept learning. That's the real answer.&lt;/p&gt;

&lt;p&gt;Cover: &lt;a href="https://www.flickr.com/photos/mattmflickr/7461949414"&gt;Source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>beginners</category>
      <category>career</category>
    </item>
    <item>
      <title>Continuous Integration Builds using Docker</title>
      <dc:creator>Kyle Wagner</dc:creator>
      <pubDate>Wed, 23 Oct 2019 17:11:06 +0000</pubDate>
      <link>https://forem.com/kaikeru/continuous-integration-builds-using-docker-1ifa</link>
      <guid>https://forem.com/kaikeru/continuous-integration-builds-using-docker-1ifa</guid>
      <description>&lt;p&gt;In my current position, we define continuous integration builds for all our projects in a &lt;code&gt;Dockerfile&lt;/code&gt;. For us, Docker provides a set of guarantees that are perfect for CI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker builds are reproducible.&lt;/li&gt;
&lt;li&gt;Docker is available on every major OS.&lt;/li&gt;
&lt;li&gt;Docker produces universal artifacts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Builds are Reproducible Everywhere
&lt;/h2&gt;

&lt;p&gt;A standard Jenkins build runs directly on the system. It's nothing against Jenkins, but if you are just building on a raw node, the underlying instance will have discrepancies. This could be security patch, library versions, or even OS versions. For us, a runner might be Ubuntu or OSX. This means out of date local packages cause build failures. Don't get me wrong, that's a worst case scenario. Worst case always happens in DevOps.&lt;/p&gt;

&lt;p&gt;The ideal state of our build is "reproducible state". A successful build that is rerun should succeed with the same output. A build that changes between runs of the same git commit means someone somewhere messed up. Mostlikely, you aren't versioning build dependencies...I'm not saying we had this exact problem, but we had this exact problem. &lt;/p&gt;

&lt;p&gt;The beauty of Docker builds, they are immutable unless you try really hard like not versioning. The steps in a &lt;code&gt;Dockerfile&lt;/code&gt; run in the same order every time. Wonderful.&lt;/p&gt;

&lt;p&gt;The biggest boon is the system that runs the build doesn't need to care what language or packages a build needs. The Docker build handles that via &lt;code&gt;Dockerfile&lt;/code&gt; instead at the encompassing OS. There are no tricks to create virtual environments like in Python. No race conditions on which packages are installed by different builds. Everything is self contained and way faster than spinning up a fresh dedicated VM.&lt;/p&gt;

&lt;p&gt;The glaring question one may ask, "Why not use the already built in Docker runner environments that CI solutions like Jenkins support?" Yes, that's a solution, but it doesn't solve another problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run Builds Anywhere
&lt;/h2&gt;

&lt;p&gt;Running a build anywhere is a dream chased by many a developer. If we guarantee that if the build works on a dev system will work in production, that's gold. Docker is a solution to the problem. A Docker build that works on Windows will work on a Mac. Sure, it's trickery if you look too hard at the man behind the curtain (the VM running Linux). Devs usually don't care about that. When a build and its tests succeed on their machine but fails on the build box, they are rightfully upset. So why not let them run the exact same process on their machine that the Jenkins box uses?&lt;/p&gt;

&lt;p&gt;This portability provides robust builds and increased developer productivity. Jenkins pipeline files are opaque at best so we don't expect devs to learn the syntax. DevOps doesn't want to write a new Jenkins file for every project either. Rather, we encourage each team write their project's &lt;code&gt;Dockerfile&lt;/code&gt;. Once the hump of Dockerphobia is surmounted, the teams are more productive since they don't wait on DevOps for their build changes. They don't even have to trigger their Jenkins build to see if it will fail. Less waste overall.&lt;/p&gt;

&lt;p&gt;As a side anecdote, I explained this build system to friend of mine. He implemented it on a new service his team was working on while doing builds on AWS CodeBuild. For various reasons, CodeBuild wasn't the best solution, so he moved everything to CircleCI. The overall process took him 45 minutes, because all the build scripts were in &lt;code&gt;Dockerfile&lt;/code&gt;s already. I'm not saying you couldn't move that quickly with normal build systems, but it's worth noting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker as Artifacts
&lt;/h2&gt;

&lt;p&gt;Dockers are a great universal artifact for build systems. Related to &lt;code&gt;Run Builds Anywhere&lt;/code&gt; you can deploy Dockers practically everywhere. That's kind of the point of Dockers. What's more interesting is we can use Dockers as a storage for libraries. &lt;/p&gt;

&lt;p&gt;We've experimented with this a bit over the last year. Every library is built using Docker as describe above. The resulting image is never used alone as docker itself is the storage for that artifact. Then when other Docker builds need a library we will import that upstream dependency using multi-stage Docker builds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; cool-java-lib:2.0.0 as lib&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk as builder&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; /app
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from lib mavencache/* mavencache/*&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./src/* /app/src&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;mvn build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This isn't a perfect solution as it requires we still push the library to a Nexus repo for local development. Overall, this is not a recommendation. It's something to consider if you have problems with external library repos and only want to limit dependencies to a Docker repo at build time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Downsides
&lt;/h2&gt;

&lt;p&gt;There are downsides to using Docker builds for CI. The big one is the use of Docker itself. Containers are great things, but they can be heavier than a cached library. This may not be true in some sense on the repository level since we can reuse layers. You can't do that in Maven repos. This caching requires a good knowledge of how Docker build layers work.&lt;/p&gt;

&lt;p&gt;The intimate understanding of how to use Docker to build software is an entry barrier to developers. Dockers often seem like this magical tech that DevOps community peddles. Because of this, there is a lot more upfront work to get devs up to speed on Dockers but the tail is usually a lot better in our experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reality
&lt;/h2&gt;

&lt;p&gt;We've been using Docker builds like this for the better part of a year and it's made life a lot easier. Everyone has a much better idea of how projects build and exactly what went wrong. Is this for everyone? No, nothing is. This works for our use case as we rely heavily on container orchestration systems and have that expertise. In the cases we are not using containers to run a system, we do have to shoehorn this build style in. This is a minority of our services and the benefits are great for now. Like all things in DevOps, we will have a different philosophy in 6 months.&lt;/p&gt;

</description>
      <category>sre</category>
      <category>devops</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
