Fundamentals of Kubernetes for Django developers by Graham Dumpleton

This video features Graham Dumpleton at DjangoCon US 2018 in San Diego, California, USA.

Fundamentals of Kubernetes for Django developers by Graham Dumpleton
0:48:54
Published November 8, 2018
3,508 views

DjangoCon US 2018 - Fundamentals of Kubernetes for Django developers by Graham Dumpleton

A hot topic in recent years is running applications in containers. Tools such as docker and rkt have made deployment of applications using Linux containers easier, but they do not alone provide everything that is needed to easily manage many applications, or run containers at scale across a cluster of machines.

In this talk you will learn about the fundamental concepts and terminology of Kubernetes and why it is emerging as the de-facto standard for container orchestration and scheduling.

The talk will step through how to deploy to Kubernetes a Python web application, implemented using Django, as a way of seeing what happens under the covers when you do so.

This talk was presented at: https://2018.djangocon.us/talk/fundamentals-of-kubernetes-for-django/

LINKS:
Follow Graham Dumpleton đŸ‘‡
On Twitter: https://twitter.com/GrahamDumpleton
Official homepage: http://blog.dscpl.com.au

Follow DjangCon US đŸ‘‡
https://twitter.com/djangocon

Follow DEFNA đŸ‘‡
https://twitter.com/defnado
https://www.defna.org/

Summary

Kubernetes is best understood as the kernel of a cluster: it manages containerised applications across multiple machines, while distributions and hosted offerings add the tooling needed to use it. Containers package an application and its dependencies without running a separate operating system, and Kubernetes turns deployment descriptions into running pods, replaces failed instances, scales replicas, assigns cluster networking, and exposes applications through services and ingress. The speaker explains the declarative model behind deployments, replica sets, pods, labels, rolling and recreate updates, health probes, deployment hooks, versioned images, and custom blue-green or canary strategies. He also introduces persistent volumes, noting that the storage mode matters when an application is scaled across nodes.

Key takeaways

  • Kubernetes manages containerised applications across a cluster and continually makes the actual state match a declarative configuration.
  • A deployment creates replica sets and pods, and Kubernetes can replace failed pods or move workloads when a node is lost.
  • Services provide stable internal access and load balancing, while ingress routes external HTTP traffic to applications.
  • Rolling updates, recreate deployments, health probes, and deployment hooks control how applications are updated safely.
  • Container images should use explicit version tags rather than the mutable `latest` tag.
  • Persistent volumes support applications needing storage, but their read/write capabilities affect whether they can be shared across multiple nodes.

Summarised automatically from the transcript.

Chapters

  1. 0:16 Kubernetes Background and Ecosystem An introduction to Kubernetes, its broad ecosystem, and why beginners may want a packaged distribution rather than raw Kubernetes.
  2. 3:24 Containers and Docker A comparison of containers with virtual machines and an overview of Docker images, registries, and container execution.
  3. 9:31 Kubernetes Cluster Management Why managing many containers across multiple hosts becomes difficult and how Kubernetes schedules and maintains them across a cluster.
  4. 11:50 Application Deployment The basic kubectl workflow for deploying a container image into a Kubernetes cluster.
  5. 13:22 Declarative Configuration How Kubernetes uses YAML configuration, etcd, and reconciliation to make the cluster match the desired state.
  6. 15:43 Deployments, ReplicaSets, and Pods How a deployment creates replica sets and pods, and how Kubernetes replaces failed instances or nodes.
  7. 20:19 Services and Cluster Networking How pod IP addresses, services, and internal load balancing provide stable access to replicated applications.
  8. 24:18 Ingress and External Routing How node ports, load balancers, and ingress controllers expose applications outside the cluster.
  9. 26:38 Labels and Resource Management Using labels and selectors to identify related Kubernetes resources and query or operate on them together.
  10. 28:08 Deployment Strategies Restarting applications safely with rolling updates, recreate deployments, migration hooks, and custom blue-green or canary approaches.
  11. 34:25 Health Checks, Image Updates, and Storage Readiness and liveness probes, versioned container images, and the introduction of persistent volumes for applications that need storage.

Transcript

9,037 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:16

Speaker 1: Uh if you're not familiar who I am, I am not a Django developer. Um I know about the internals of Django how and how to deploy it, but I don't actually have really how to write Django apps. So my history is I am the developer of Mod Whiskey for Apache, for hosting Also responsible for a Python package called Wrapped, which is for information decorators. And you may They also know of me from uh Neurelic, where I wrote the Python agent for Neurelic and do lots of evil things to your Python code. Uh I don't work at Neurelic now. I currently work at uh OpenShift, uh Red Hat, where I am a developer. advocate for Kubernetes and OpenShift.

1:02

Speaker 1: And I always have a problem with my pointer. Okay. We'll get a backup plan. That's better. Um so Kubernetes. Uh I don't know how many here are familiar with Kubernetes. Uh Anyone want to put their hands up and know about it? Okay. So for those who have got into Kubernetes already, would be this be a fair explanation, would you say? Yes, more tears. So uh Kubernetes it's it's an up and coming thing but it's a very large ecosystem and can be very, very, very confusing when you start to get in. It's a very large learning curve. If we if we look at the like the landscape of what exists around Kubernetes, uh

1:51

Speaker 1: there is a lot and lot of stuff now starting to come around it. Uh they are software packages you can you can use with Kubernetes, but also all the different companies that bring bringing stuff to it. So there's a lot in that uh there which potentially could learn. So it can, depending on how deep you go into that, it can you can get very, very complicated. And it's very very mind blowing. So if you are getting into it, be patient because it can take a long time to get up to speed on it To make it easier rather than just dry dive in it and think, okay, I'll go and get original Kubernetes distribution and start using that. I I strongly encourage you to look around at easier ways of getting into Kubernetes and there's different ways there. We've hosted versions of Kubernetes

2:38

Speaker 1: and also distributions of Kubernetes. Kubernetes. Now the way to think about Kubernetes, it's like a kernel. So whereas you've got a Linux kernel, which is the guts in there, which helps you to run up applications on a Linux operating system, you're never going to install that kernel yourself. It's always better to go get a distribution. So you're always going to go get Ubuntu or Fedora or CentOS Red Hat. uh or other uh Linux distribution. So always better to go through that because they will provide you an experience which is going to provide extra bits on top of Kubernetes, which is going to make your job easier to understand it and use it. So think of Kubernetes as a bit like a kernel. And in this case it's going to be the kernel for a cluster of machines where you're going to want to deploy an application.

3:24

Speaker 1: I'll say more about that later. So stepping back that from that bit of warning about getting into Kubernetes and where you should perhaps go to start looking at it, what exactly are we talking about? We are talking about containers. Now we all heard the containers now. It's the big buzzword from the last few years. Containers has actually been around for quite a long time. Google in their infrastructure has been using containers since about 2002, 2003. I can't remember exactly when. But even before that, it was uh the similar sorts of ideas of what you were doing talking about with containers existed in In the form of chirut jails in BSD and also Solaris zones. So they're not a new concept. But containers are a thing that has come

4:10

Speaker 1: more popular of late and it was became popular because of a company which when they announced it was called Dot Cloud, but you'll know them as Docker. So this company called Doc Cloud at PyCon at Santa Clara in a lightning talk. showed a really simple way of running up an application inside of what we call a container. So what is a container? The easiest way to think about it is to compare in terms of what we've done in the past. If you're familiar with virtualization and the idea of running an operating system inside a sandbox on your operating system, so I might have a Mac and I want to run Windows or Linux, I can install a version of an operating system, Windows or Linux, inside a virtual environment or

4:56

Speaker 1: virtual machine on my box, in a little sandbox. And I can cap quite happily work away in that. And I could actually install multiple operating systems. uh mobile instance of windows or a mix of windows and and linux and then inside that I can run an application and it's providing a sandbox an environment where you can run stuff and it's protect um kept away and it's isolated from your host operating system, but also your other operating system running in a separate virtual environment. virtual machine. So containers, the idea behind them is they're a lightweight way of running up an application inside of a container or sand. box on a host operating system. Now the difference from traditional virtual machines

5:42

Speaker 1: is that in a traditional virtual machine you are running a whole operating system inside that sandbox and then you are running your apps. So you've got a whole lot of application services in there or system services in there for that operating operating system and as well as your application. In a container you are take making use of the fact you've got a host operating system running running under all underneath already and you're going to run just the processes for your application in that sandbox. So you're not going to run additional processes in there for system services. It's just the processes for your application. So with a Django conference, so in this case we're talking about a Django web application. So you might be running your Django

6:27

Speaker 1: Django application under Mod WISGI, which I hope you are, but I know you're not. You're probably using UWISGI or GUNYCON, I'm sure. So all you're doing is you're running that Whiskey server inside of that container with your Django application. unit. Okay? But because it's in this containerized environment, it's still protected. You know, if I get into that container, all I can see is those processes for that application. I cannot see operating system services in the underlying host operating system and I can't see applications inside of other containers. So it's protecting things. So that's what it is. And it's meant to be this more lightweight thing because we're not starting up a whole operating system, it's much quicker. You only need to start up your

7:13

Speaker 1: just your process. Now to run off something in a container, uh what Docker did in terms of what they announced was they provide a couple of things. And it's all focused around tooling. Containers I said are not a new thing. They've existed for a long time. And the way you use them normally is you're using what's called Linux containers or LA So there is this way of running up processes in constrained environments on the operating system. But that was always a difficult thing. Docker made it quite simple because they provided this program called Docker and there was two important things for that. There was one which was Docker build command. And the idea there is you could provide what was called a Docker file with a set of Instructions of how to

7:59

Speaker 1: build a image which contained all the bits and pieces you need. So you start out with a base image for the operating system. So it might be uh Ubuntu and then you'll add your instructions on top of how to actually install your application with all the dependencies it needs, all the different Python packages, into that. And they all get built into an image. You want to then run that image and we can run that up on our box. But what usually is going to happen is we're going to push that image up into what's called an image. registry. Once we've got an image registry, we can then do Docker run and we run it up and away we go. So that's what they made very simple process to do. Before that, using LXE was

8:45

Speaker 1: a lot of different steps to do all of that. The Docker run command when we take that image is going to do a lot of work to create that sandbox image. environment for you. But ultimately, even though we talk about Docker, it's still underneath using Linux containers. It's using the features of the operating system. Docker was just bringing the tooling to make that easy to do. Now, running single containers with your application, we can do that. You can get it working. Okay, uh bit of work to doing, but you can be happy. The problems occur when we start to want to run many, many containers, especially if we want to run across multiple hosts Because we can only scale up the applications, the number of instances or replicas of that application we're

9:31

Speaker 1: gonna run on a single host so far. We're gonna run out of resources. So we need to start to put them across hosts. Now Docker was great for running up an application in container on one machine. When we start to go beyond that one machine, that's when it got started. starts to get more difficult because you had to start tracking. Oh I need to run 10 instances for this. I can only fit five on this host. Okay, so I'll re run five here. I have to remember I've got five here. I have to run five over here But then I've got all these different instances of them and they all gonna listen. They all expect to listen on port 80 for HTTP. traffic. But they can't all listen to port 80 because they're on the same host. So we need to put worry about port assignments and put them all on different ports. But then you have to worry about, well, how do I distribute traffic?

10:18

Speaker 1: You have to start putting load balances across it and distribute traffic. So very very quickly starts to become very complicated to be able to do that all yourself and track it. And this is where Kubernetes comes in. Kubernetes as a my kernel as I mentioned before. is a means of managing the deployment of applications inside containers distributed across a cluster of machines, or what we call NO. So a typical Kubernetes cluster, what you'll have is some masternodes. I've got one here, but if we talk about fault tolerant or high availability systems, you'll actually have more uh three at least an odd an odd number and you may have other infrastructure nodes in there which have other bits and pieces like the router. But I've simplified this. I've got one master node and I'm saying everything's running on the

11:04

Speaker 1: there. That's the smart main smart of of uh Kubernetes. It's where the the database is there, which tracking how what we're deploying and so on. uh and also router and other bits and pieces. And then we all have our nodes. That's where your applications are going to run. So that's what Kubernetes is going to do, is provide that ability. So in this talk, I'm not going to delve down too into the depths of how Kubernetes works. I'm just going to step through running a or deploying an application inside of Kubernetes using uh Kubernetes uh command line tool and I'm going to use that as a means to just introduce different concepts of Kubernetes so that if you are going into Kubernetes at least then you've heard what these concepts are once before at least and then

11:50

Speaker 1: might make a bit more sense to you. So deploying. We've already built our image with with Docker Build, for example. We have it already up in an image registry somewhere. And a popular place that people do store images. up uh a place called Docker Hub. That was a public image registry which was run originally created by the Docker Company, Inc. But there are other image registries you can run your own as well. well. So if I want to run up an image inside of Kubernetes, so if you're using Docker, I'd use Docker run. Here I'm just going to use kubectl run so very very similar. I want to name that. So my I'm going to name my application blog. I tell it where my image is and I tell it the port that I need to expose. If you've used Docker before, you'll see very, very similar to Docker run.

12:36

Speaker 1: The difference is that if I use Docker run, it's going to run it on my own machine where the Docker service is or the one you've logged into. Here, because we've got a cluster of machines and I've just said, okay, I want to run run instance, Kubernetes is going to go, okay, I've got a cluster of machines I can run this on, it will go and work out for us where to run that and make a decision for us and get it up and running. Now when we do that, there's actually like when we run Docker run, it's actually taking an action of doing that. It's actually going to essentially go right through and run it up. and start it. Kubernetes works a bit different to how Docker is. When I run that Docker run command, it's not actually really starting things up.

13:22

Speaker 1: What it's actually doing is going to set up some configuration. And if we actually run that same command and put dry run minus output yaml file in there, you can see see what it's doing. What all it's actually going to do is create a YAML description of what it is I want deployed. And that's actually going to be stuck inside of a what's called a data store. inside of Kubernetes, which actually uses etcd. And that's effectively all it's going to do. That's all the command does. Updates that database of information. Way Kubernetes works is what's called a declarative model. So rather than actually you do something that causes an action immediately, all you're doing is updating a configuration of what I want my application to be. deployment to look like. Kubernetes comes along and is always checking these configuration objects

14:10

Speaker 1: which exist inside of the database and go, oh I've got a new configuration object or a configuration object has changed. And I need to now go make the cluster or what you wanted for your deployment or make what you have in the cluster agree with what that configuration uh says. So because it's a new one, Kubernetes go good, oh, new deployment configuration, I'll go and do the steps needed to actually satisfy what your configuration says. So in this case our deployment, it was given a name. It was given some labels automatically to help us identify our configuration later on. which is very important. Had an in number of instances, which was just one initially. And we have a description of a container of what our image and our image which we're going to run inside of that container.

14:57

Speaker 1: container. Okay? So Kubernetes will go off and run up an instance of that for me. I've told it I only want one, so it'll go and do one. I can then query back once I've done that. I can query do a query back of the resources which were created. And you'll actually see my deployment there. You will actually see some other resources created. there as well. And this is where my command only created one, the deployment. But Kubernetes has stepped in and said, okay, to satisfy your requirement of having your deployment, well I actually need to go and create some other resource objects. in there uh more configuration now the first one is what's called a replica set uh it's the thing which is going to manage your uh instances of your application

15:43

Speaker 1: So it pulls out of that deployment config the information about the number of replicas you needed, the description of the container and the image that you needed to run. It's created a replica set for me. There's an aspect of uh Kubernetes which sits in there and looks for now for replica sets. When it sees that's created, it goes, oh, I need to now do something based on this replica set. So it pulls out the description of the container. It knows only one instance and it creates what's called a pod. Now, pod, I mentioned containers. Well, what's the relationship? Normally, when I say container, pod is the same thing. But in effect, a pod can be one or more containers. So when we talked about our description back there, you can see our containers in our

16:29

Speaker 1: GAML description is actually a list. But I'm only describing one. So technically I can have more than one container in what's called called a pod. This name pod, where does it come from? Pod of whales. And Docker, well they had their logo of a whale. So that's where the naming come from. But you can more or less think about a pod as being a container. uh most of the time. So now we've introduced a deployment that triggers the creation of a replica set and I've got a pod which is my running instance in my container. I if I now need to look at what my application is doing, I can use that pod as the name of that pod as a means of getting out say logs and find out that what happened when my application started up.

17:15

Speaker 1: But more importantly is if I want to scale it, what happens then? If I want to scale, it's a command called kubectl scale, and I can actually refer to my deployment config for that. And I say I now actually want to have two replicas of my application. And all again, this has gone back. All has gone back has changed that deployment config. Kubernetes has noticed the change in the configuration and says I need to now make the cluster match that. So it will go and up update the replica set, say I've got two replicas, and then controller for that looking at replicate kicks in and goes, oh two, I'll create another pod for you And Kubernetes is once again making decisions for you about where it's going to run them.

18:03

Speaker 1: Now if I come along and delete a pod, it's just a configuration object. So I can delete that configuration object. Now this is where the power of Kubernetes comes in. I've deleted that Kubernetes that pod object and because that pod descriptor , that particular pod configuration option that's gone away, Kubernetes says, oh, you don't want that anymore. It will actually shut down that, terminate that container, shut down your application, and it will go away. But something magic is gonna happen now. You said that you wanted two instances of your application. Now that is the truth. You always want two. I deleted one PO. So what happens is that even though I delete it, And Kubernetes shuts it down, it knows I wanted to, so what happens?

18:48

Speaker 1: It goes and gives me another one back in its place. So I deleted the pod here explicitly, but if this was your application, your application had actually cracked crashed and the whole server had exit and and so that container had exited, your app your application will replace for you automatically. If I just run Docker run command and don't do anything extra extra and my pod stops, it's gone. It's not there anymore. Kubernetes in this case will replace it for you and keep things running for you Ow, you mentioned before that we're Kubernetes is running a cluster of machines. So take an example if I lose a whole machine now. Kubernetes will notice I've lost a whole machine. All those pods effectively invisible to it anyway.

19:34

Speaker 1: Again, it will notice this and will start up new instances to your application for you on other nodes in that cluster or automatically. So you're now not going to have a problem with If you've got a very basic system of getting a page at 3 a. m. in the morning, say your application's down, Kubernetes will worry about keeping things, everything running for you So we have pods, that is our application effectively. Now if I do query on those pods, I can get back and I'll find that each of them has an IP. address. When I run Docker on a box of my by myself and I need multiple instances, there is that whole host is one IP address. In case of a pod, each pod has an own separate IP address.

20:19

Speaker 1: So it's like a little host of its own. Even though they may be running on the same underlying host, each has their own IP address. Now this is very important. Because example before about running having to keep track of uh instances of your app all running on the same host. If you're doing using Docker, you can't all use port eighty. So you have to have this one has to run port eighty, this one has to run port to run port 81, this one 82. Because each one has its own IP address, it also has its own port namespace. This means they can all run on port 80 and they don't have a problem having to track all that. Now those IP addresses, if I take that IP address and try to access that from my own local machine, that will not work. These are IP addresses which are internal to the cluster only.

21:08

Speaker 1: So how do I access it? I got multiple instances, and that's a problem because I only want one entry point. And I can't even access it from outside the cluster. So just to prove that um they do work though, you can actually get into a a pod. So one way of getting into pod is very similar to Docker. You can go Docker exec. Same thing. at Kube Kubernetes and go KubeCand exact and get into pod. I can use that IP address, but like I said, it's not useful there outside of the cluster. So what we need to do is we first off is we need to to somehow come up with a single IP address for all of these instances. And that's done using what's called by creating a service ob resource object. And we can do that using the kubectl expose command. So we expose our deployment for our blog, that creates a service object and it's created a new

22:00

Speaker 1: IP address. In this case we have one IP address and what it's actually effectively doing under the covers and how this works depends a bit on how the Kubernetes cluster. to set up, but it's setting up an IP router. So I've now got one IP address and if I contact that IP address, the traffic will go to one of the instances of the pod. So it's handling that load balancing for me across all of those instances. But that IP address is still not accessible outside of the cluster. That IP address though will have a hostname. Kubernetes has an internal DNS server. So when that is created, that IP address has a hostname of blog. because that's what my service was created as. So if I needed to access that internally, so it was a backend

22:47

Speaker 1: service, like a uh your back-end service for your not a database, because that's a bad example because you're not having have multiple instances. But if um if I need to access it, I can just use that as a host name. So I don't have to hardwire host names. But to get access to this outside, there are a few different methods you can use Kubernetes supports the idea of when exposing a service, you can call it uh expose it as what's called a node port service. Now that by default when I created it was a what's called a cloud cluster IP. So for node port, it will automatically can create you access to it from outside of your cluster. But a node port all this gonna do is give you a magic port number to access. It's not going to be the port number you originally exposed. So it can't be port 80, for example.

23:32

Speaker 1: It's going to be a random port, which is not very useful to us if we want to have a web service because we need them to be on port 80 or 443. The next option is you can use what's called a load balancer service. This one, the underlying infrastructure of Kubernetes, You can have a pool of IP addresses here. When I create a load balancer service, it will allocate me an IP address of my own outside of the cluster. That way, if I use that IP address from outside, it can route traffic through to Uh one of the instances of my pod internally. And that way I can use a particular port that I want. So you could expose it on port 80. So that's one way. If you're going to use a hosted service for Kubernetes, Such as uh Google Cloud, that's what they'll use in that particular case. But there's actually a better way.

24:18

Speaker 1: When we if if we're going to use a load balancer service and we have lots and lots of service we need to expose, we have to have an individual IP address for all of them. them. More useful way of doing it is to have one entry point for the whole cluster and have a router in there such as HAProxy or Nginx or even a hardware-based router like F5. And use the fact that when a web browser makes a request with HTTP traffic, it puts a host header on there telling me which host I'm going there. So the alternative is what we can use is what's called an ingress in Kubernetes. Now ingresses start to get more complicated because there isn't a simple way of creating them from the KubeCon. You have to start delving down into uh creating YAML descriptions yourself.

25:04

Speaker 1: And this is this has actually begun to become the norm. I started out with using kubectl command line. commands, but in practice when you start getting anything more complicated, a very simple use case, you're going to have to start learning YAML and J or JSON and all of these resource descriptions. for Kubernetes. You have to start constructing them. That's why your main your mind starts blowing very quickly with Kubernetes. In the case of an ingress, I can create a YAML description I need to expose this service with particular host name and I want to have all traffic for that routed through to it. And the port internally is going to be AD. But I'm going to expose this as port 80. So that's all in a YAML file, and I can use KuberCud or create with that YAML file, pass it in, and it will go and create me this ingress object

25:52

Speaker 1: Again, it's an object, but the magic in there of Kubernetes is going to see that ingress object created and it's going to dynamically reconfigure the routing layer for me to do whatever is needed to do to be able to route that traffic through. So it might reconfigure Nginx or HAProxy or whatever router system you have, such that now as long as you have a DNS C name outside in the real world which points to the IP address of your router, when someone accessed that host name, your tra traffic or HTTP traffic will get routed. through into your application. So they're all the bits and pieces. Now if we step back now and look at all the different things we we We uh have got running.

26:38

Speaker 1: We can get use kubectl get to to query things. Now I mentioned very briefly before about how labels got added onto things. Labels are very important in Kubernetes. It's the way you identify your application. applications. Because you may have lots of different applications in your Kubernetes cluster and if they're all in the same namespace, they're all together. But I need a way of being able to pick out just the ones for my applications. So what you do is you label them. So I can then start to make do queries or operations based on based on labels. So I'm querying these here is based on on what's called a label selector and the label was run and the name was blog and I can pull them back out. And it's really weird. You can go kubecettle get all and you'd think, oh that'll give me back everything in there

27:23

Speaker 1: which has this label? No, all only actually means a few things. It's really weird. So in this case, ingress is not part of all. So to get them I had to go query on all in ingress, but I can pull out now back based on my label, and I see I've got my deployment, right raptor cassette, my pod, my service from when I expose the deployment and my ingress. So lots of different things. But effectively they're all just configuration objects and Kubernetes is all working off them to essentially make that cluster look like what you wanted. Now I mentioned before deleting pods. Now imagine we want to restart our application Now we could be brute force and go in there and just delete all our pods using our label selector so we're only deleting the ones for our application.

28:08

Speaker 1: And it will. It'll terminate all those pods and it will replace them. Great. This is not actually a very good way of deleting or restarting an app. Because it's going to delete all the instances of your application at the same time. And there could be a period there where there's none, no instances of your application running. So people will start getting you know five hundreds or five oh three service undervailable. Uh now Kubernetes unfortunately doesn't provide a really nice way of of doing a restart unless this has changed in newer versions of Kubernetes. So I did this. So there are some various tricks you can use. Now I mentioned before how Kubernetes watches those configuration objects. And when it sees a change, it will do something. to actually to the cluster to make it agree with that. Now we can actually trigger a restart

28:56

Speaker 1: by updating a part of what's called the pod template. which is a part of our deployment. In this case we can update an annotation. We can put the date time on there. And by doing that, there's a change. Kubernetes C said, oh, that has changed. I better restart all my application because I've made this change. I'll restart it in case that's significant. It's a bit of a mess. Uh I know there's people who are in here who probably know a lot more about aspects of Kubernetes and running it in production than me that might might tell me, ah no, I'm really stupid. There's actually a really easy way of doing this, but that's the best Way I know of doing it. Now, when we do do it in this way, rather than having a situation where we're deleting all our pods at the same time

29:41

Speaker 1: and having air a period of of time when application may not be available, what happens is dictated by what's called a deployment strategy. And there's different deployment strategies that you can have in Kubernetes, the default one is what's called a rolling update. So when I do trigger my my redeployment using my nasty little technique, there the default is this rolling update so what will actually happen is rather than delete everything and shut everything down it will go okay you have two instances app running already, I I'll leave those alone for now, but I'll start up a new instance of my application as a new pod. So I've now got three. Once that's up and running properly, it'll shut one of the other ones down. And it'll start a new one.

30:26

Speaker 1: So another second new one. Get that right up right and then shut down there. So essentially we're able to do a rolling update, and that is a built-in feature of Kubernetes. You don't have to yourself worry about all the mechanics of doing that. It'll be all handled for you. Now, rolling updates are not necessarily always a good idea. They're good for ensuring no uptime redeployment or restart. But if you need to do something like a database migration, you know, using Django , and you've you've made some changes, you've done your make migrations, you've rebuilt your image, you need to put out that change. And you've set up your your um image to do a Python managed Python. migrate as when the just before the application starts up inside the container.

31:14

Speaker 1: Rolling updates are not necessarily a good idea for that because if you're making a change to the schema of your database and you're starting starting up a new instance of your application while the old ones are running, it's going to do that migrate. Meanwhile, your old instance is still handling requests. requests and you've changed the schema underneath. If the change to that schema is not compatible, then your old instance will start failing requests. Okay. So the alternative there is if you did need to have a uh schema uh change happening in there, is you can swap to what's called a recreate deployment strategy. And that is where it'll shut everything down and then start everything up anew. So that way if you do doing it, it gives you that option.

32:00

Speaker 1: Um now by default the our role the rolling update was where changing it is a case of having to go in and modify those configs. And there are a few different ways of of modifying configs. Now I've done a one particular way here just using kubectl patch and it allows you essentially selectively say I want to make a change inside of an existing config and I can actually go and change that deployment strategy. You do have to be a little bit careful though, because some things like deployment strategy for example, you can have a type which is recreated I want to set that to that, but I may have to remove bits and pieces which are in there from the existing rolling update. In this case, there is a uh rolling update parameters part of the configuration. If I leave that in there and just change it to create, it will uh have

32:48

Speaker 1: pro I'll get an error. It won't actually allow me to do it because I've got a thing in there which is not valid for that so you do a little bit tricky um but you can do this with patch and i i mentioned patch only because i can show it easily on a slide but if you're starting to try and script these things you do need an easy way of scripting. You don't want to be able to necessarily jumping in and edit can edit raw configurations yourself. But these are the ways you can edit things. There's QPetal patch which is that's one example. You can use kupadl edit and what it will do is actually just throw you into an editor with the raw YAML and you can start making changes. You save it and it will go up and just replace the existing in config and it'll do that. Other options, and this is more typical option you'll end up using, more complicated ones, is

33:34

Speaker 1: you've created resources using kubectl create. from original raw file and if you want to make changes you're going to use replace or apply to essentially have a copy of your original config your make the changes and you'll apply that then to replace the whole lot in one go. And preferably you'll have your um your config under version control so that you can you know recreate it later and stuff on. So avoid patch and edit. They're great for doing ad hoc, mucking around in and so on, but not good if you want um replicate our ability to reproduce things. Docs will tell you about all the different attributes you can change in things. There's actually a kubectl explain command where you can actually get very simple docs out very quickly on resource if you want to need to. to jump into things.

34:20

Speaker 1: Now, deployment strategy. I mentioned rolling update. When you start up that new instance of the application, how though do you know that is ready to handle requests? What if there's a failure with that starting up and it's not ready to accept requests? You can add what's in called health checks. First one is a readiness probe. So what happens you can define a readiness probe on there and you can define in uh different ways. Typical ways is using HTTP GET. And as that when that application instance is started up, it'll start triggering that probe and when it gets back successful. response that it has worked, it'll go good, that one's fine. I can I can add that into my service, the list of endpoints that the service maps to and

35:05

Speaker 1: shut down my old one. So health checks are very important in being able to do things like roll updates nicely such that you know your application is going to be ready. Liveness probe is another one which is the thing that's actually going to always run as well, which can tell you whether your application is actually ready. Working properly. If either of those fails, readiness probe fails, it can take that particular instance out of the service so it's no longer being traffic routed to it, and liveness probe fails, it will actually shut the pod down and replace it. So I can create that, I can again just patch it in and it's a case of working out where in the config I need to do it. And I said you can also instead of HTTP get you can also use for certain things sock. connections or run it to hand-demand inside a container to implement those probes.

35:52

Speaker 1: We have database gross regulations. Part of that rop that deployment strategy, you can also deploy define what a called uh deployment hooks. Uh so in the case of a rolling deployment, uh when I trigger that deployment, I can have what's called a pre-hook. Before anything happens, I can define something. When it's finished and it's done all the replacements, I can to have another hook which is I can have a post hook. For database migrations, our Python migrate, um, Python managed to Pythonigrate. Okay, rather than embedding it into the container itself, such it's run when the container starts, uh which would get run every for every single container if you have more than one, an alternative there is to break that out. And if you're using recreate deployment strategy, you can define what's deployment hook. So you can actually run up a container which just is going to do the migration.

36:39

Speaker 1: So what in this case what would happen is that you have all your existing apps running. Shut them all down, you can run a container to do the migration, and then you can actually start up all the new ones. So deployment strategy. All these things are in part of Kubernetes as a default thing, and you don't have to build them in You can now build on your top of this and build up your own custom deployment strategies. You can do blue-green deployment. So blue ground deployments, you might, for example, have one deployment. You might decide, okay, I'll leave that one alone, I'll create a totally new deployment. Get all that up and running and test it. And then all I need to do with BlueGroon strategy. essentially switch the the ingress to point at my alternate deployment. So you can build up these alternate deployment strategies as well

37:25

Speaker 1: if you want. Canary, A-B testing and various complications. Next one is how do I update my application? Now I cheated. When I cheated originally I said kubectl run, I said run up my image and use the latest. version. That's actually really bad. Never do that. Always use a version number. Because latest can map to anything. Every time I do a Docker build and I do a Docker tag, latest effectively can map that so it can change under me. So if I did want to upgrade my application now, uh I have 1. 0 version running. I can just change the image name in the deployment config and change a new tag and it will do a redeployment for me.

38:12

Speaker 1: Okay? All automatically for you. Storage. I'm running out of time so um storage. People originally with Docker saw it as being uh for 12 factor apps or twelve clouds native uh apps that didn't have any storage if you're using Heroku you're very very familiar with that if you deploy stuff to Heroku there is no storage if I write to the local file system my application shuts down I've lost that. You always had to have data outside in a separate database or storing stuff in S3 or other some other external mechanism. One of the good things about Kubernetes is it supports the concept of persistent volumes. And this is very handy if you need to bring in apps, so-called legacy apps or non-twelve factor apps, which do have a requirement for storage, or if you need to just support storing of image uploads in a in a blog app, for example.

39:02

Speaker 1: So I can actually mount in persistent volumes into my container. Now the way this works is that I essentially tell Kubernetes I need persistent storage, I need this amount. And this is the type of storage I need, and this is very important. So there's different types of storage. Read write once, read only many, and read might many. Now, read write once, if you're familiar with Amazon, that equates to elastic block. storage. Elastic block storage volumes can only be mounted on one node at a time. Read-write many down the bottom is traditional file system storage like NFS. You can mount that wherever you want. And this is important because if I have an app and I want to scale it up and have multiple instances, then I can't use the top one.

39:49

Speaker 1: Because Kubernetes is going to make decisions about where it runs the instances of my apps and it could run multiple instances across different nodes. So if you're using the wrong storage type and you say uh rewrite once it'll only bring up one instance or or whatever instance it puts on that node and this is a really thing about Kubernetes you've got to be careful careful of is you can set up a configuration and that configuration could be wrong or be telling Kubernetes to do something that it can't satisfy. And when I run that command or update the config, you do not get an error Kubernetes will just spin its wheels because it can't actually satisfy it. That's one of the weird things. And storage is an example. If I use rewrite one storage I think we ran on one node, ten instances. Why have I only got

40:34

Speaker 1: four no four instances running? It's because Kubernetes couldn't satisfy that request because it couldn't perhaps put more instances of wrap on that one node. It's tried to district them elsewhere and it's just sitting there waiting for storage which it can't get. So if you do have stuck are stuck with uh using EBS on on Amazon, uh you are stuck with uh one replica or you have to do tricks like uh tell Kubernetes to uh set up all my instances, my app to run on one node. But then you lose your your fault tolerance a bit because if I lose the whole node I've got no instances because you know the idea of Kubernetes is it will distribute the instances So that if you do lose a node, then it's still got other instances running. Again, persistent volumes is like uh ingress, you have to start marking around with uh

41:21

Speaker 1: um raw definitions uh and then you can just create it get your persistent volume claim you have to then also start marking around the deployment config you change the deployment config and say, okay, I need this persistent volume claim for this deployment, but I also need to then say where that is going to be mounted inside of that particular container. Okay, so there's lots of mucking around to bring all these things together. But then once we do have storage, with Django, we want to get in there and do things like set up our super user cell, we can do that. We can go in there cubic set. Run out create super user. I'm using SQLite, then fine, I've got my storage. If I want to change config, like various systems Systems like this, I can set environment reels which pass

42:06

Speaker 1: down into configs. So if I'm using ModWiz, I can make that deployment config or re-redo. More importantly, environment passing is good for linking up things like databases. So I could here have just passed in all the details of where my database is and environment variables, but Kubernetes offers another thing called secret. And that is the ability to put configuration in what's called a secret, and I can actually have that as a separate object, and I can use then use that from multiple things. I may have here I've already pre-deployed my database. It has a secret with my credentials in it. And without needing to know what they are, I can say, okay, set my environment, but pull those variables from the C secret and set them all automatically. And I can link them together. In addition to secrets, there's another thing called config

42:52

Speaker 1: maps. They essentially work exactly the same, but secrets have some better guarantees on how that information is managed. uh such that it's not stored on disk. So if I shut down a machine, ship it out, I haven't put my secrets out and given them away to somewhere. And I can get back and view my configuration, you can see where it's coming from Now, that's the guts of it. That's a very simple example of running an app. Now I mentioned these distributions earlier. Distributions can make things simpler because they can add on extra bits which make you simply your life, uh make it easy for from a developer's perspective. Kubernetes is very much regarded as being an operations platform. But as developers that's not great. Operations tend to, oh that's our stuff. We don't want to touch it.

43:37

Speaker 1: That's where you might look at some of the the distributions. So OpenShift from Red Hat and OK OKD which is the upstream version of that. And also Pivotal with with with coming over from Cloud Foundry. They have mechanisms or tooling which allow which are much more developer-friendly and allow you to build up things. And I'm going to skip through a quick example of of how to do what I just did, but using OpenShift using their tooling. It's still Kubernetes underneath. There's a few little things that are different, but I can go into Overshift and one of the One of the things here is that in when I did it before I had an existing image. Here I'm going to go into OpenShift and say, here is my source code repository on GitHub. Deploy it for me. And it's going to do that platform as a service

44:22

Speaker 1: type thing that you've me with Heroku. It'll take my source code and build it into an image for me. And it will go off and create a deployment for me, create a server service and get it all running for me. I can also do things like adding in volume very easily because it has extra commands in there to very easily claim storage and mount it in straight away away. So I've deployed it, got my service already, it didn't have to expose it. And uh I can add in my storage and I can then expose it. So three steps I've very quickly done all of what I did before. And in this case Um some of the things underneath, if I now query it back, you'll see a lot of the things are a bit different. And this is a bit of a historical because when OpenShift was first created, things like deployment didn't exist in Kubernetes, things like ingress didn't exist in Kubernetes

45:15

Speaker 1: So you might see people talking about, well, OpenShift's not really Kubernetes because it's it's different. It's just the history of it. Things like these didn't exist. So OpenShift went and created their own and that's actually fed into then Kubernetes in developing things like develop deployments and and uh ingress in um uh Kubernetes. OpenShift is in the process of migrating across to using these new ones in there. But do look at some of the distributions. They do provide simpler uh tool tooling for this. And one further example in Kubernetes in do OpenShift is that if I want to deploy a database, there is thing uh OpenShift has a concept of templates in there, and I can say here, create my database, and that's all I need to do. do it'll go and create it create my credentials create that secret which I can then bring in from environment into

46:02

Speaker 1: map uh just like that There's also have uh web consoles which are much more developer-friendly. Um a default plain vanilla Kubernetes doesn't really have a console. There is a a management console you can deploy yourself. All that stuff comes out of the box with with OpenShift. And that's it, I'm running out of time. So cleaning up, I've mentioned label before as being very important. That's where it comes in important. Deleting stuff. You use your label for deleting things. I mentioned templates. There are other templating systems too to look at Helm and CaseOnet , but there are others as well. They help you to essentially define your application. There's a whole lot of Templates and they to very easily do reproducible deployments.

46:47

Speaker 1: So look at those. Building, you may be familiar with Docker builds, because that all becomes standard It's under the Open Container Initiative. There are now alternative tools for doing builds. Builder is an example doing build , has a companion program called Scopio for doing uh pushing images and so on, and they're all wrapped together with a thing called Podman. The source to image is what OpenShift uses for doing its past type builds. Very quick one, don't run up, don't design your app images so to run as root. Please, please do don't do that. Run them so that they can run as arbitrary ideas. user ID is much better. And there's various tricks. So I'll skip this because I'm running out of time but you can go back. If you want to um

47:32

Speaker 1: play with it, some uh resource we can go. Kubernetes by example is a great place where you can go to learn about some of the low-level concepts in Kubernetes. Kubernetes and what they are for, how to use them. There's a site called Catacoda where you can go and it'll spin up an instance of Kubernetes for you. It will have on one side a set of instructions a terminal and you can go through and just do it all on the on the spot. Just click on the instructions and it'll run them all for you. You can play with Kubernetes that way. If you want to run Kubernetes yourself on your own box, uh mini kube, so rather than go and try and do the whole hog of setting up a whole cluster you can use minikube it just runs it up inside of a VM and there are similar things for OpenShift. OpenShift has a Catacode environment as well which is learner openshift. com has mini shift same as minikube uh and finally if you want resources um

48:21

Speaker 1: i've got my name on a couple of books if you want to look at this from OpenShift side more. And they are free, free downloads. And that's it. Um I don't think we've got any time for questions, so a bit over.

48:32

Speaker 2: No time for questions if Graham's willing to take questions. questions in the hall afterwards you can find them then. So thank you, Graham.

Questions this talk answers

What is the difference between a Docker container and a virtual machine?

A virtual machine runs a complete guest operating system, while a container uses the host operating system and isolates only the application processes. Containers are therefore lighter and faster to start.

Discussed at 5:42

How do Docker images get built and deployed?

A Dockerfile describes how to start from a base image and install the application and its dependencies; Docker builds those instructions into an image. The image can be pushed to a registry and then run on a host or deployed through Kubernetes.

Discussed at 7:13

What is Kubernetes, and what problem does it solve for containerized applications?

Kubernetes manages the deployment of containerized applications across a cluster of machines. It handles placement, scaling, traffic distribution, and replacing failed application instances instead of requiring developers to track those tasks manually.

Discussed at 10:18

How does Kubernetes deploy an application with kubectl run?

The command creates a declarative YAML-style deployment description rather than directly starting a process. Kubernetes stores that desired configuration, then controllers create the resources needed to make the cluster match it.

Discussed at 13:22

What are deployments, replica sets, and pods in Kubernetes?

A deployment describes the application, a replica set maintains the requested number of instances, and a pod is the running unit that normally contains one container, though it can contain more than one. Creating a deployment causes Kubernetes to create the replica set and pods beneath it.

Discussed at 14:57

How do you scale a Kubernetes application?

You change the deployment's desired replica count, such as with kubectl scale. Kubernetes updates the replica set and creates or removes pods, choosing where to run them in the cluster.

Discussed at 17:15

How does Kubernetes recover when a pod or node fails?

If a pod disappears or its application crashes, Kubernetes notices that the actual state no longer matches the desired replica count and creates a replacement. If an entire node is lost, it starts replacement instances on other nodes in the cluster.

Discussed at 18:48

How do Kubernetes services provide access to multiple pods?

A service gives a group of pods a stable cluster IP and distributes incoming traffic among them. Kubernetes also provides internal DNS, so other applications can reach the service by name instead of tracking individual pod addresses.

Discussed at 21:00

How can a Kubernetes application be exposed to traffic outside the cluster?

A NodePort exposes the service through an assigned high port, and a LoadBalancer can provide an external IP and the desired application port. An ingress is often more practical: one router can use hostnames to direct HTTP traffic to different services.

Discussed at 23:11

What is the difference between a Kubernetes rolling update and a recreate deployment?

A rolling update starts new pods and removes old ones gradually, allowing the application to remain available during the change. A recreate strategy shuts down the old pods before starting the new ones, which is safer when a change such as a database migration is incompatible with the old application version.

Discussed at 29:01

How should you deploy database migrations with Kubernetes?

For schema changes that are not compatible with the old application, the talk recommends avoiding a rolling update and using a recreate strategy. A deployment hook or separate migration container can run the migration after the old instances stop and before the new instances start.

Discussed at 31:14

How do Kubernetes readiness and liveness probes work?

A readiness probe determines whether a pod is ready to receive service traffic; if it fails, the pod is removed from the service endpoints. A liveness probe checks whether the application is still functioning; if it fails, Kubernetes terminates and replaces the pod.

Discussed at 34:20

Why should Kubernetes deployments use versioned image tags instead of latest?

The latest tag can point to a different image every time an image is rebuilt, making deployments unpredictable. A versioned tag makes the running application explicit, and changing that tag in the deployment configuration triggers a controlled redeployment.

Discussed at 37:25

How can Kubernetes support applications that need persistent storage?

Kubernetes can mount persistent volumes into containers, which is useful for legacy applications or data such as uploaded images. The storage access mode matters: read-write-once storage is limited to one node, while read-write-many storage, such as NFS-style storage, can be mounted across nodes.

Discussed at 38:12

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos by Graham Dumpleton

More videos from DjangoCon US