Description
If you've heard of containers and this thing called Kubernetes, but you're not sure exactly how they work and what they are, this episode is for you. Kelsey Hightower of Google gives us a newbie friendly tour of the world of containers. We talk about what problems they solve, and what new developers should know about them.
Show Notes
Transcript
[00:00:03.17] SY: Welcome to the CodeNewbie where we talk to people on their coding journey in hopes of helping you on yours. I'm your host Saron, and today we're talking about containers. (Music). So I don't know how much you know about containers, but I don't know much at all. And I keep hearing about this thing called Kubernetes. And besides being fun to say and sounding very important, I don't know exactly what it does, or what the big deal is. So I invited Kelsey on the show.
[00:00:37.11] KH: I'm Kelsey Hightower, I work at Google on the Google Cloud platform.
[00:00:41.25] SY: He's one of the biggest voices in Kubernetes. And he gives us a newbie-friendly intro into what containers are and how Kubernetes works. After this.
One of the best parts of being a coder is finally being able to bring your passions to life. You have the skills to design, to code, to create the thing you're excited about, and share that passion with the world. And Hover can help you with the first step, of sharing your passion with the world - getting your domain name. They've got a really beautiful and easy to use interface where you can find and register your new domain name in just a few steps. And to give you full control, they separate your domain name from your hosting, so you're never stuck with one service. They keep your domain name safe while giving you the flexibility to use whatever hosting service is best for you. They also give you free "who is" privacy, so your personal information is safe, too. To get started, go over to Hover.com/newbie to save ten percent off your first purchase. That's hover.com/newbie. Link is in the show notes. (Music)
[00:01:41.14] SY: First of all, how do you even say this word, and what is this, it sounds really cool. Tell us what Kubernetes is.
[00:01:48.03] KH: Yeah, so I don't think I or anyone I know pronounces it correctly. I went to Germany and they say Kubernets. So Kubernets is Greek for helmsman, so this is the person who would steer the ship. So sticking with the container analogy, this would be you packaging your software in these application containers. And putting them on a ship to manage them and get them where they need to be, hence the name Kubernetes.
[00:02:17.10] SY: That makes a lot of sense. Ok, so I think a good place to start would be to maybe define this containers world. What are containers?
[00:02:25.13] KH: So, if you write code in any form, that code has dependencies. So let's take Node.js for example - you write some JavaScript, let's say you're doing a really simple website, you may import a few libraries, so there's your first set of dependencies. And then when you look at those dependencies, you tend to describe them, and then you alternately depend on Node.js, the run time, right? So pick a version of Node.js. In your mind, you believe that as long as there is Node.js on the server, and all of my dependencies, my application should work. This is like the first mistake everyone makes, because every server or every operating system that you deploy to, could have a different default version of Node.js. Yeah, so end up in this world where you're hunting down, troubleshooting on the machine to see if it has all the right things that you need for your app. And we see this with parity between your laptop and what's on the server. So the first part of containers - and there's multiple parts, we can just focus on two parts. The first part is the packaging part. So what we want to do is have the entire environment - everything you depend on, even the stuff that would typically be on the server, for example, when you use Node.js, there's lots of things, like DNS lookup. Www.google.com, that requires a DNS lookup. For most people, that half is using what we call libc, which is the standard library for C, usually Node.js will tend to just link out to that at deploy time. So in your mind, you thought Node.js was all you needed, but the truth is, there's also things like libc and all these hidden OS dependencies. And this is where people start to run into mismatches and things behaving differently on your laptop than they do on a production server. So containers from the packaging standpoint say hey, you know what? Let's also put libc, everything you need, all of your assets, everything into one package. And the truth is, the details behind that package is, it’s a torball. This is a format where you take a bunch of files and directories, and you put them into one artifact, and then you can ship that one artifact around, and this is why the container analogy, like we talk about shipping things around the world in a container, or shipping our code in an container.
[00:04:50.21] SY: So, if you are packaging absolutely everything you could possibly need to run your app, doesn't that mean the container is really big?
[00:04:59.21] KH: It doesn't have to mean that. It depends on what language you're working with. So, for example, I write code in the Go programming language. And Go is one of those languages that is easy to produce a statically-linked executable. And in our world, we put in the run-time, so in the Node.js case, that's a dynamic programming language, right? Whereas in the Go case, we build and compile our app, which enbundles the run-time inside, so everything is compiled down to, say, machine code. And we can distribute a single artifact. To go one step further, Go makes it easy to statically link everything else you need. So in the Go world, you don't depend on any version of libc, you can just use - Go shifts on its own. So given that, if you lived in a container with a Go program that was statically linked, you'll just see one file, or one binary. And that might end up being just the size of the binary. Six to ten megs. Whereas in Node.js world, we may have to bring the entire Node.js runtime, libc, so you may end up in a world where your container's going to start at maybe 30 or 40 megs, even though your source code is only one or two kilobytes.
[00:06:10.26] SY: Oh, that's interesting. So it sounds like part of what it does is strip down the things it actually needs?
[00:06:17.16] KH: Yeah, so it just depends on the language that you're using. The trade-off is that this space is cheap. Even if you wrote your app in Java, which is going to take up a bit more space, let's say it cost you one hundred megs, that one hundred megs of being a reliable, fully self-contained package just makes you feel a little bit safer about hey, it worked on my laptop, more than likely it's also going to work on the server.
[00:06:42.26] SY: Yeah, yeah.
[00:06:44.08] KH: So it's the trade-off we make, right. Size for reliability.
[00:06:47.03] SY: Yeah, I'm a primarily a Ruby developer, so we have our gem file which lists all the gems and all the dependencies, and it sounds like that was kind of the goal of having that file, is you run Bundle and that app comes with everything that it needs and what version of it that it needs and we hit Bundle and then everything is fine. So is that trying to solve the same problem as containers, or is that different?
[00:07:10.27] KH: You have a couple of ways of thinking about this problem. One - Bundler introduced this idea of vendoring. This was super-new to people, we were used to doing something like gem install, and it would put our dependencies in a shared path. And it was cool if you used the only app on the server, but what happens when another app came onto the server that wanted a different version of a library that you needed, and then you're in what we call dependency hell.
[00:07:36.19] SY: Not a good place to be.
[00:07:38.12] KH: Yeah, exactly. There's no way to resolve it. So Bundler comes along and says hey, how about we put all of these dependencies in ann inter-directory, right next to the application, so you get some self-containment, so each app has their own vendor included, or bundle copy of all their dependencies, but you still have one problem. You're sharing the version of Ruby. So if one app wants one version of Ruby and another one wants another one, you start to get into all these weird situations with tools like RVM, the virtual Ruby environment, it's nasty and even if you do that, you still have the libc problem, so if you think about going the container route, the container route says, continue to use Bundler. There's no need to ditch that. But you're going to package not only your vendor dependencies, but you're also going to package the exact version of Ruby that you want, so if this team wants Ruby 2.0 and this other team wants Ruby 1.8.7, fine, you're going to have two independent containers. And then they're deployed, they isolate from each other at the file system level as well. So even when both are running, you don't have to resort to RVM and all this extra stuff. You can just know - whatever's in your container, won't interfere with what's in mine.
[00:08:55.02] SY: Yeah, we actually just had this problem, maybe a couple of weeks ago with the CodeNewbie app, I think it was using Ruby 2.1 something, and we upgraded it to 2.3 and oh my god! It was an absolute nightmare, it took quite some time to figure that out.
[00:09:12.22] KH: This has cost the IT industry, I guarantee you, probably a trillion dollars by now. Just this problem.
[00:09:20.05] SY: I believe it, yeah.
[00:09:20.24] KH: And I like to tell this joke that hey, after years of doing this, we need a group therapy and we call it DevOps.
[00:09:27.11] SY: (Laughs) Yeah, because I was going to say, it's also just the emotional frustrations of it too, not only are you wasting time, but also you feel so stupid.
[00:09:37.20] KH: Yeah, sounds like you know the problem well. I remember seeing a nice piece of software online and it's like hey, install this stuff on your computer. And you're like, uh, no way. The minute I install this, everything else will break. So containers really solve the packaging problem, to really let us focus on distributing something. It's like recording a song once, burning it to a CD, and then just making as many copies of that album by just mixing or burning a new CD. The equivalent on the other way would be inviting the singer or the band to your house and just trying to redo the song every single time, perfectly. And if you just record it, you can edit it, you can get it perfect, and this is why people do what we call a Dockerfile. So in the container world, you got your Bundler install, but what you can do is you use a Dockerfile, and this is what people commonly use to build a container image. And in that Dockerfile you'll say something like, from Ubuntu. And then from there let's install this exact version of Ruby, let's install these gems using Bundler, and then we package it up and we seal it. And at that point, we can give it a name. And if anyone else wants to run that app, they don't need to think about Ruby or Bundler or even the OS for the most part, and it's just highly reproducible and it makes it easy to distribute.
[00:11:00.23] SY: So you mentioned DevOps a little bit earlier - is this the role of a DevOps person? When I think about the job of containing an app, or even the job of thinking about this problem, you don't have to come up with a solution, is this something that n average developer should expect to do, or is this a specialization?
[00:11:18.14] KH: When we talk about DevOps, we talk about this idea that people that identify themselves as developers and people who identify themselves as operations collaborate on a shared goal. But when you think about it, it's all about contracts. So if I'm a developer and I know I need a specific version of Ruby and a collection of dependencies, I don't want to just give my source code to the next team, the ops team, and say, you figure out what version of Ruby I need. And if it breaks, we'll just figure it out on call or something. So from a DevOps perspective, you just say hey, let's just get this contract correctly, so if you're a developer and you're just starting now, I think this just will be the way you work going forward, this idea that I will express all the dependencies that it takes to not only build my app but to run it. And hand that contract to whatever infrastructure that needs to run it, so you can kind of cut out the middleman of handing over something that needs to be re-assembled. So then walking back on that, and saying hey, you built the app, you got it to work locally, describe and capture all of that in a way that is just reusable going forward for everyone.
[00:12:25.02] SY: So where does this fit into the workflow? Is it as soon as I have an app idea, the first thing I should do is make a container? Is it that I build the app, maybe see if I need it, and then plug it in? How does it fit into the product development process?
[00:12:40.06] KH: So this is where the community's probably going to disagree with me. I think as a developer you should focus on building your app. Then you start to think about packaging - so, to me, as a developer, once I get to the point where I know my app is working and when I really want to start to do things like integration testing, that's when I start to add a Dockerfile to the mix. So you know how people may have a little build script, they might run /build? And it just does all the right things to build the app? The Dockerfile is like that, it's like hey, if you want to just test my app out, and you don't want to fool around with a bunch of set-up, here's my Dockerfile. So to me it's one of the things that I think about on day two, I'll say alright, I'm going to package up my app, I know I'm going to put it into a container, I got something that works a little bit, now I'm ready to start the iteration bit that follows integration testing. Better use a Dockerfile for that so that I can spit out not just something that needs to be re-pushed to a server, more like, hey, we're going to spit out a docker container in our CICD process. So if you think about using something like Jenkins, which is this continuous integration tool to do your build and run your tests, you would just add another step to the mix that does your container build. So build, test pass, package in the container, and then you push that container off to a registry. So this is like pressing up that CD and sending it off to the store for others to consume. And that to me is how I think about it as a developer, where it belongs in the development cycle.
[00:14:09.01] SY: Yeah, that makes sense. So we talked about the concept of it and it makes a lot - thank you so much for explaining it so well - it makes a lot of sense. But what does that process look like to actually make this work?
[00:14:21.18] KH: So what you do is you write a Dockerfile, and there's tools out there that will generate a Dockerfile for you, butt they're generally pretty easy to build. Most people start off by copying an existing Dockerfile, so you'll have a Dockerfile that says hey, from Ruby2.0 - so you know that Ruby's going to be there, and that's what we call a base image, so it has all of the things that you need for Ruby, Bundler is in there, everything you need to kind of build your app. So inside of your Dockerfile, your next step may be the same thing you would do in a command line, bundler install. Once that's done, you kind of define what we call an entry point. So once everything is built, how should I start it? So you know how you might do forward/Ruby and some path? Your Dockerfile will have that as the last line. So from Ruby, bundler install, and then the last line is going to be your entry point, where you say, hey Docker, when you run this, just call forward/Ruby to my path, and it will run. That's probably what you will do inside of your Dockerfile. Save that Dockerfile and when you check it in - so you check in your Dockerfile into the same source tree with the rest of your app, so when CI picks it up, it'll do the build, the test, and docker build, and then you do docker push, which will then push the resulting artifact to a registry of choice, so it just gives you this meta-package that then takes your entire application - all of these dependencies - and just give people one artifact to think about.
[00:15:53.20] SY: So once I set all that up, how does the rest of my workflow change, if it does? Do I now have to push that or update that separately from how I would do a regular git-push?
[00:16:07.06] KH: Yeah, so this is why CI is so important in this world. You want to make your changes as a developer, your Dockerfile is probably still good, you may update your dependencies file so the next time Bundler runs, you get all the artifacts go in there, so you know that's reproducible. You might even run docker build and docker run on your laptop, just to make sure the container that it builds is right. Once you're done, all that stuff in your Dockerfile, you check that in, too. So you may have a commit that says, updating Dockerfile to add two new instructions, because you're using this new library. And at that point, you're back to CICD. Build, test, docker build, all your stuff in one big package, docker push and commit the version number. That usually stays static for a while, and every time you check in, your CI system, it just constantly building new docker images and bumping the version number so that people can tell the difference between 1.0 and 1.1.
[00:17:08.16] SY: Ok, so when you explain it that way, it doesn't sound as scary as I initially thought. I think when I first heard about containers, my reaction was oh god, yet another thing that I now need to understand. So how difficult is the learning curve, especially for a newer person who's just getting started, just getting comfortable with the framework that they chose, and the language that they're learning. How difficult is it to not just use it, but to use it and understand it in a meaningful way?
[00:17:37.26] KH: Yeah, I think the best part is separate the idea of packaging your app. I don't really care about all your source code, I don't care about bundler, I don't care about your Ruby version. As someone who wants to deploy your app, I don't got time to try to figure out how to rebuild it and package it. So if you approach it as maybe I can use this whole docker thing to make it easier on my teammates or other people that I want to download my software, if I make a container image, I remove all of that stuff - all that goes out, you got docker. You got a container runtime of some kind, just run this container image and people are off to the races. So that's phrase one. I have a much better packaging solution, regardless of the programming language I write. And as a developer, you can't learn all of the tools behind a package and build everything. And this is where docker really helps - there's lots of images that already has all the build tools, and all you have to do is put your source code in the right directory and it just builds it for you. Now, run time. If someone said, here's a server, go set up redis, Rostgres, and all these things. You'll be like, now I have to go and read all this documentation and set up all of this stuff on the server. Now if you have all these images available, then your world becomes docker run redis. Ok, it's running. Docker run my sequel. Oh, that's running. And Docker run my app - sweet. You just got what you need up and running. So that's where it just changes your story in terms of how you run and deploy, and this is where Kubernetes comes in. Let's just get off the servers - why are we even logging into the server, running commands in the first place? At this point, if we have a well-defined package, regardless of programming language, we can now tell some system to say hey, you're managing my one or fifty servers. Here's my container. I want you to run three copies for me. So now you have a much better deployment story than trying to pin this app to server A, it goes down, you get a page, you wake up, and you just move it to server B. (Music)
[00:19:50.13] SY: Coming up next - we talk to Kelsey about who should be using Kubernetes - is it for side projects, enterprise? And how does it relate to other deployment tools you may have used or heard of? Like digital ocean or Heroku? We're going to get into all that after this.
When I learned to code, I was so excited to finally bring my passions to life. I could build things that I really cared about, and share them with the world. And the first step in sharing is getting a great domain name. That's where Hover comes in. They've got a really slick, easy to use interface. They've got awesome domain names to pick from and they separate your domain from your hosting, so you have full control and flexibility over your online identity. So go to hover.com/newbie to save ten percent off your first purchase. That's hover.com/newbie. Link is in the show notes.
[00:20:41.19] SY: So it sounds like Kubernetes is an enterprise solution, then?
[00:20:46.16] KH: Well, it does scale down. Think of this as more of new abstractions. Today most people are used to a server, your abstractions are not very high at all. You're dealing with the shell and SSH. You're so tedious at this point that you can't even think about high-level concerns like load-balancing and storage and secrets, because you're still SSH into the server. What happens when I say, don't worry about the server. What if I had an API. As a developer, and you're building, let's say, an e-commerce site, you're not going to go figure out how to process credit cards. So what you end up saying is let me go find something like Stripe. And what I'm going to do with Stripe is I'm going to just call their API, but then do the whole thing and get a response. As a developer, this is your world. You're calling APIs to do stuff. So why not deploy with APIs? So Kubernetes says, I'm just going to give you a new API, it'll let you describe your application as a deployment. Kubernetes, run this container with this memory, this CPU, I want three copies. Oh, and a load-balancer would be nice. Kubernetes takes that and that's what we call declarative. So you're not writing any scripts - in this case, we're just saying very simple things. I want a public IP, three copies of this container, and here's the memory requirements that I want. And you give that YAML file to the API, and the API says, I'm going to translate a deployment until all the things that need to happen on this server. And that's what we mean by a new set of abstractions. Let's think about deployments, not servers.
[00:22:28.15] SY: So what does that do for me as a developer? Is the idea that I'm spending less time fussing with the server, because that's another potential place where I could waste my time? Is it about being able to think on a higher level than before? What are the benefits on the developer side?
[00:22:46.21] KH: You just built this app. You want to show someone else. All you can think of in your mind is, if I could just give them this URL so they could see it. But you write a blog post, you get that draft URL, you paste it to someone else - that's it. So wouldn't it be nice as a developer, that after you build the app, you do docker build, docker push, and you go to some API and you say, run this image and give me back a URL. Cause everything else between that is not very interesting. You don't get pumped about man, I'm going to get this deployment today. Right, you don't excited about that, right. It's about saying let's just remove that, we've been doing that for two, three decades. Let's let that go, and let's just focus on the task at hand, this is where these platforms like cloud foundry and Heroku and now Kubernetes come in to say, let's just let you focus on what you want to do. Now the second thing is once you start to have this established set of abstractions, you can start to focus on where you want to be. Even if you're a small shop, you have customers who expect you to be global, no excuse. It needs to run in Australia, it needs to run in Europe, it needs to run in the US. So as a developer, if I know something like Kubernetes is in all of these locations, I know my container is self-contained, I can say something like, Kubernetes Europe, here you go. Kubernetes UK, here you go. Kubernetes US, here you go. And it's just going to run the same. We're also going to build in things like high availability. Even if you only need one copy of your app, you're ok with a little downtime. Ok, my app died, just put it on the second backup server. You can express that in Kubernetes by saying replica count = one, and restart = true. It will do everything it takes to make sure that one copy of your app is running across at least one of those two servers, at any given time. So as a developer, you stop worrying about how am I going to keep this app up and running, and now you can just pick a platform that just does the right thing, just like when you import those libraries, right. If you need to do crypto, you don't write encryption from the ground up. You import a library, and you kind of delegate that responsibility to the library. I'm saying you can now delegate deployment and high availability to the platform.
[00:25:13.01] SY: So, solutions like Heroku and digital ocean were designed to make deployment really easy, but you're right I still go to Heroku and do things on command line and update things that way. So, does Kubernetes essentially take that deployment process and abstract it even further?
[00:25:30.25] KH: So this is a good point - you actually talked about two big ends of the spectrum. Digital ocean gives you a very cheap server. Five bucks, you can start out and you get a machine, and you get to write scripts, and SSH. And then Heroku says, hey, I'm going to give you a different abstraction and we're just going to let you do something like Heroku or git-push, as long as you have that Heroku file in there, magic happens. It gets deployed, you get a URL, and that's what we called a platform as a service, so PAS, people hear that often. So this is a very opinionated way of deploying something. So Heroku is going to pick the load-balancer, they're going to pick the metrics, they're going to pick pretty much everything you need to run a production. And for the majority of people, that's all you need. Now, how do you build a Heroku? Well, if you were to peel back the covers on Heroku, you'll find something that looks a lot like Kubernetes. A lot of the popular PAS's - platform as a service - actually have Kubernetes built in the middle, that you would ask yourself, wow, if Heroku is so good, why would I waste my time with the thing in the middle? You would be a smart person. You probably should not care about the thing in the middle. But, Kubernetes does offer some Heroku-like high-level primitives that let you do a lot of those Heroku-like things, but more flexibility. And this happens when a developer writes their first batch-job, this is when you graduate from just writing web apps, and you have a new type of task, like a batch job. So what is a batch-job? Let's say your web app was sending emails in the background, and you're like, man, my site is slow, I'm sending emails on every request. So, you know what I could do? I could take all these emails, and I could just push them to a message queue. And at some point, maybe every thirty minutes, I'll have a little job that just spins up, reads the queue, and sends email. Now, some platforms don't really let you express that. They're like, ah, that's not quite supported, it needs to make everything kind of a web app. So then it's like man, if I could just run this container, I got a container that does it, I kind of know what I'm doing. Kubernetes will let you do that, even when it comes to machine learning. I want to do something that needs a GPU now, maybe you're a developer and you're learning TensorFlow. A lot of platforms as a service don't support TensorFlow, right. And that's when people start to go back to something like digital ocean, or back to their own server. And Kubernetes, guess what, you can keep the same abstractions, because it actually works with GPUs at a very high level. You can just say this container needs a GPU. And Kubernetes will find a machine in your cluster, with a GPU and attach it to that container in a way that you can just think about using it.
[00:28:29.04] SY: So it's more modular in that way?
[00:28:32.13] KH: Yes, completely modular. High-level new primitives, but modular enough for you to express anything that comes to mind.
[00:28:40.06] SY: But when does Kubernetes, or even the idea of containers itself - when is it maybe not worth it?
[00:28:46.23] KH: Yeah, if you just got like a Wordpress site, just stop it. You know what I mean, just - I know you see all this hype around containers. Now, I always encourage people to learn, and sometimes, it's cool to go overkill if you're learning. But when it comes to production and you seriously sit down on the whiteboard, and I tell you to draw everything out, and you just draw Wordpress and my sequel, you need to just do the basics, just stick to VMs are probably going to be just great for you. It's fine. But you might see yourself in a situation where there is a platform where you don't have to manage. You might say well, if I'm not managing a platform, and I get all this stuff that seems to be for free, well, you know what, I might just package my stuff in containers, because guess what? Heroku now accepts containers. Kubernetes accepts containers. App Engine accepts containers - this is Google's Heroku-like tool. Lots of Amazon tools accept containers. So now you're starting to ask yourself, you know what, containers might just be less about premature optimization, and more about making it easy for me to adopt any platform, either locally or on an cloud provider, or something like Heroku. Maybe I start there, but maybe I don't need to learn how to set up my own Kubernetes cluster.
[00:30:05.06] SY: So, when you think about a newer programmer learning about containers and Kubernetes and trying to implement some of this stuff, what are some common things that we might get wrong?
[00:30:16.26] KH: When I meet new companies who are like, oh, we're going to switch to containers, and the first thing that I watch that they do, let's not just say wrong, but you don't know what you don't know.
[00:30:29.06] SY: Yeah, yep, yep.
[00:30:29.21] KH: Right, so on a virtual machine, you typically have the entire server to yourself. And a lot of us, when we write our web apps, we don't really think about resource utilization. Now, with something like Kubernetes, where we do this thing called bin packing. Instead of just running one app on that server, we'll try to run as many apps until we allocate all the CPU and memory. On servers, people forget to add dimensions, like how much memory, how much CPU did you need. So your app is deployed with no constraints - meaning your one app can use all the memory and CP on the server. Now think about what happens when I start bin packing that server. I put on this other critical thing, like the database. So now the database and the app are on the same server with no memory or CPU. The web app starts getting busy, it starves the database. So when people get something like Kubernetes, they start packing, packing, packing, packing. Hey, I got a thousand apps on ten servers. So without constraints, Kubernetes will over-commit the server, so one thing you can do in Kubernetes, you can be very explicit. This web app needs about half a CPU, and two hundred megs of RAM. My database needs this, you'll find out you can only run two or three things per server when you allocate, and you may not have data, because most people do not collect data about how their app actually performs. Like you go up to most developers and say, how much memory does your server use? And they're like, I don't know. I only check when it crashes. Right? So in the Kubernetes world, you have to kind of guess and tune over time, but it will give you the data to tell you - you've given this app two CPUs, but it's only really using half of that over the past six months. You might want to adjust that allocation down, so you can get more stuff onto the server. Let's go cautious, let's overcommit first in terms of what you need, and then we tweak from there.
[00:32:39.08] SY: So that was the thing, right, when you were talking about containers and Kubernetes, it sounds like the big benefit of it is abstractions. And taking these, I think, less fun parts of programming and deploying an app and putting an app together, and handing it off to someone else to deal with and kind of handle. And so that I can get back to building the app itself. But there are a lot of older developers who see that and think, look at these developers coming up nowadays, they know less and less, and they're so focused on this one little part and they don't appreciate the way the machine really runs and the way that everything else comes together. And they see that abstraction as almost like a dumbing down of what a developer does. How do you think about that?
[00:33:28.10] KH: When it comes to business and efficiency, you have to really understand when to separate one over the other. So to me I think as a developer, as you embrace these new tools, understand that they do a lot for you, but find the time to go deeper, because there's value in going deeper. You're going to make your personal value, when no one else can troubleshoot, you can. And I think that's the value.
[00:33:54.10] SY: So if I am a new developer and I'm listening to this episode and I'm getting excited about Kubernetes and containers, where's a good place to start learning about that?
[00:34:01.24] KH: Oh man, there's so many things. I guess I'll plug some of my stuff, I have a book that I wrote with some of the co-founders of Kubernetes, so Joe Beda works at Heptio, he's a co-founder of Heptio, and Brendan Burns is a principal architect over at Microsoft, and they founded Kubernetes when they were at Google years ago, and we wrote a book called Kubernetes Up and Running, and we try to go through this and tell you hey, coming from configuration management, such as Puppet, Chef, and Ansible, and those tools, here's how you think differently about those abstractions you find in Kubernetes, there's lots of hands-on examples. I also have a free course that I did with a co-worker named Carter Morgan, we did a Udacity course, so that's free, so covers all the basics so you can kind of get up to speed and put your hands on this stuff.
[00:34:54.13] SY: Very cool. So next let's do some fill in the blanks. Are you ready?
[00:34:58.06] KH: Yes.
[00:34:58.15] SY: Number one - worst advice I've ever received is?
[00:35:00.09] KH: Good things come to those who wait.
[00:35:04.18] SY: Ooh, tell me about that.
[00:35:05.20] KH: Nothing in my career came from just waiting. I think I understand the premise behind the saying, but if you want something, you cannot jump on your keyboard and just complain on Twitter or start calling things out. You really have to ask yourself, what action can I actually do to improve the situation? And sometimes waiting is not the right thing to do - sometimes you have to take a little bit of initiative, if you want to get better at programming, sitting around waiting to get better at programming is probably not as good as actually writing some programs, even if they're bad programs. And I think these things are some of the things you've got to understand, you can't just sit back and wait for great things to happen to you. They will, and I think it's because of action and if you're patient, I think that's really what that's getting at. But you have to have the action, and you have to have patience to watch those actions pay off.
[00:36:05.07] SY: Yes, and that is the distinction. Because just sitting and not doing anything and waiting for opportunities to come to you doesn't work, but even when it feels like you're doing all the right steps, and you're pushing forward, you may not see the results of that for a while, so being patient with the results, but not patient with your actions.
[00:36:21.26] KH: That's right.
[00:36:22.25] SY: Number two - my first coding project was about?
[00:36:24.26] KH: My first coding project was about creating a support script in Bash, shell-scripting.
[00:36:32.13] SY: And what did the script do?
[00:36:33.13] KH: So, this is back in the tech support job, and this is one of those situations where I had to clean up some disc space on a server, so in web-posting, you have a web server, and usually you're doing updates, you maybe have a website with your cat pictures or your blog. And every time you upload photos or you have a draft that you don't use or you iterate, usually versions of that stuff stick around. And back then, people didn't pay for a lot of disc space. So if you only have a hundred megs of disc space back then, your disc would fill up really quickly. And this is shared hosting, so the one drive is shared amongst lots of customers. So their part of the disc space filled up, their site would go down. And sometimes you would get people or customers who were like, look, there's fifty tickets in the queue, everyone's out of disc space. And you do the exact same things every time to clean it up. So I remember writing my first script, and I'll be honest with you - I didn't understand the concept of a four-loop. And I remember when I got the loop to work, it just felt like, oh my god, look at the - I can give it more servers, and it will do ten-thousand. And I remember doing a thing where you can do them in parallel, and that was like my first programming task that took me like, I don't know, three to four days to even get my head around it.
[00:37:54.15] SY: Very cool. So how did you learn those things, because you have this problem that you wanted to solve, you knew you wanted to implement it, but how did you get into the implementation details?
[00:38:03.28] KH: So I knew how to do it for one server - you log in, and you run these commands on that one server. And I knew that if I put all those commands in a single file, that got me a script. I knew that the tools I was using - SSH - you could actually just say, for this server, run this command, for this server, run this command. And I never had experience of doing anything beyond just run this command, run that command, run that command. So my scripts were very much linear in progress. So when I started to say, hm, what will it take, and back then I was just like, huh, let's go online, and you just kind of search for that. You see people doing examples where they show you the syntax, so I was just scratching my head and looking at the code on the page for so long, it was just like, there's no way this works. And then you type it in and the example you saw was for Python and not Bash, so it was like ok, that doesn't work. And you start to realize what you're doing. Every language has syntax, every language has different rules about how you capture variables and do this and do that. So when I really figured out how to do that for Bash, I was like, ah, now I understand what's going on. And then I started to learn, four means this, and here's this rule for four. Here's the rules for the body of a four-loop, and here's how you say when you’re done. And then I started to understand how to program. By following the syntax of the language I was working in.
[00:39:32.18] SY: Very cool. Number three - one thing I wish I knew when I first started to code is?
[00:39:36.23] KH: Coding is not important as we make it out to be.
[00:39:43.09] SY: Ooh, tell me more about that!
[00:39:45.14] KH: Programming is just one element of software design. Maybe you want to know what the user is going to do. There's UX, is it going to be a web app, is it going to be Mobile, is it going to be a command-line tool. There's all these things you need to think about this, security. Once you start to understand what it is you actually want to do, this is well before you start breaking out your keyboard. Now, don't get me wrong, there are cases where I'm like, look I'm going to just start hacking on this thing until it takes shape. That's cool. But what I've learned and when I really started to get good is when I can actually start to say, hm, maybe I write the documentation first, or maybe I start to just get a piece of paper and write out what the command line flag would look like and if it feels right. And then once I got to that point, alright, now it's time to code. That's what I really wish I would've known earlier, because I would've developed documentation skills earlier, I would've started to have more respect for UX earlier. But what I did was I optimized so much for syntax that I got religious - oh, I'm a Ruby developer. Every other language is garbage. Ruby only. And that just wasn't the right way to think about that problem.
[00:40:56.02] SY: Yeah, yeah. I like that - that's really good advice. So thank you so much, Kelsey, for talking to us about all these awesome things. You want to say goodbye?
[00:41:02.27] KH: Awesome, thanks for having me, and I can't wait to see what all you new programmers evolve into. I'll be watching you guys shine.
[00:41:11.01] SY: And that's the end of the episode! So let me know what you think. Tweet me @CodeNewbies, or send me an email, hello@codenewbie.org. If you're in D.C. or Philly check out our local CodeNewbie meetup groups, we've got community coding sessions and awesome events each month, so if you're looking for real-life human interaction, look us up on meetup.com. For more info on the podcast, check out www.codenewbie.org/podcast, and join us for our weekly Twitter chats. We've got our Wednesday chats at 9 PM EST and our weekly coding check-in every Sunday at 2 PM EST. Thanks for listening, see you next week. (Music).
Thank you to these sponsors for supporting the show!