 So thank you and welcome to this talk about introduction to Kubernetes My name is Bastian and I work at a company called research gate in Berlin research gate is a social network for scientists where scientists can sign up and collaborate with other scientists upload the data and so on and we have started using Kubernetes about Roughly like one-half years ago Started with the staging environment for our developers and are planning also to use it in production and with these experiences from the last One-half years. I kind of want also share a bit of information about Kubernetes with you who's been playing around with Kubernetes so far Who's been using that already somewhere in so one two brave souls So maybe if you want to we can also chat about it afterwards because I'm also very interested in your experiences using Kubernetes Because it is a very interesting and hot topic for those of you who have maybe no idea What Kubernetes is or just read a few blog posts about this Kubernetes is a container orchestration platform That means it helps you to run and scale your services in isolated containers That means with a container. I mean basically docker images It is very powerful in that and it helps to automate a lot of the things like deployment that you usually have to care about And basically helps with a lot of these things. There's a large community behind this with lots of contributors and developers There are also lots of large companies backing that For example Google Red Hat who are contributing a lot to Kubernetes Or it originated also as a Google project and they push this open source and the nice thing about this that In comparing to a lot of other cloud solutions where you can run so somewhere on a cloud hardware like AWS Azure With run using Kubernetes. There is no real vendor lock in there because Kubernetes runs perfectly fine on AWS Azure Google Cloud Platform on your business bare metal service, of course, you have to set it up yourself then but it also runs on your laptop and There are tools like mini cube or even if you just install the newest Docker desktop client on your Mac or Windows or Linux It will have in the Edge version already Kubernetes included so All these different ways to run it make this also very easy and if you want to switch at some point from bare metal to AWS or back or wanted to see what this it's very easy to say Okay, just use your whole Kubernetes configuration put it somewhere else deploy somewhere and it will work the same way On the other hand while it is very flexible and very powerful. It has also some learning curve there So in this talk, I want to help you with getting started with Kubernetes getting introduced to the core concepts So I'm going to explain some of the basics some of the things like concepts and how things are called in Kubernetes I'm also going to start deploying like a simple PHP web application to Kubernetes with like a bit of live demo And I'm already fairly scared about that But hopefully it will work on my machine and then afterwards We're going to look into some more ways how to use Kubernetes what you can do with this with this like introducing two more Advanced topics there and also cover things like logging monitoring security additional things You always have to think about when running something on deaf on production So that you also can I can give you pointers where to look it and how to get started there But first let's quickly revisit why we actually want to run things into things like containers Why we want to use Docker images also in production? The good thing about running things into containers compared to just having a server provisioning them with puppet And then are thinking your PHP files there and then kind of reloading Apache is that it decouples the operational The ops team a bit from the developer team. So that means your ops team can basically care about Running the Kubernetes cluster scaling that and the development team can care about building the docker images building the code for a service and deploying that and A lot of things like dependencies that your software application has for example a specific PHP version specific web server configuration in Apache or FPM with site grieve write rules some extensions that you need you as a developer can just put all of that into your docker image and You can upgrade this all yourself. Whereas the operation teams don't have to care about that so it makes things a lot easier to Trip things and software in docker images and the containers Deployment is a lot easier because you just say all the dependencies you need are inside of the docker images All the libraries you need the web server or the configuration you need as well as a code And then you can just put the docker image on any kind of server that just has Docker installed and you can run it there That also means it's very easier to upgrade system dependencies like the PHP version if you think back or if you think about the most normal setup where you have Your servers provisioned by puppet or something else or chef or Ansible Then you have to sync the upgrade of the PHP version that is usually done by the assist operation tools With the upgrades that you and changes you have to do in code to fix deprecation notices And whatever kind of things that happen when you upgrade the PHP version My favorite one for PHP 7 2 is for example that account on another value You know that has a warning and since we transform all warnings into exceptions. We have lots of exception I had lots of exceptions when operating the PHP 7 2 so having this like at one process of what the problem process is very nice Also, it makes it easier to scale applications because if I just have a Kubernetes cluster was 1020 whatever service all looks the same And I have my web application my service in PHP and I want to scale you need to scale it out to more Machines more instances. It's just like putting the Docker image on additional instances without having to provision anything with additionally This puppet and having to wait there Also, it makes it easier to develop applications because if I already have a Docker images image with all the Dependencies that I need for my service. I can also run it locally on my machine That means I don't have to install Like specific PHP extensions compile things on my laptop anymore And maybe also have different versions of dependencies between different developers And I don't have for the care about all the bucks that arise because of that And of course you can say yeah, I can also do this all with virtual machines and vagrant and virtual box The thing is Docker images are just way more performer because the processes run natively on the system where it's running on instead of like virtual machines that run somewhere in virtual box Okay, so you're thinking sold. It's very nice Let's then talk a bit more about details and Kubernetes first I want to define some color concepts of Kubernetes and tell you a bit about the verbs and About the resources that they are so we know all what we're gonna talking about And also if you're reading about Kubernetes a lot of these things and concept I'm going to talk about you will find in blog posts. So it's good to know what it is First of all, you have the Kubernetes cluster basically Kubernetes clusters all Notes all systems or servers where Kubernetes running on and where Kubernetes can run Docker images on it's called a big cluster On the small level you have an image an image is just a Docker image that contains all Things that is built from a Docker file and that contains all things that are necessary for a service to run all dependencies PHP Apache all the libraries you need all the app packages you want to install as best as well as the source code this image when you run it it runs into a container process on the on the server When you run an image you can only run one process inside of the container Of course, this process can then also run sub processes But it's not like a virtual machine where you can start different servers in parallel You may need to have an orchestration source for that It's also a very good practice to only have one process running inside of container Instead of like having one container that contains Apache and PHP FPM and a memcached server and whatever So you want to distribute this away if more concrete examples in a few seconds Because you oftentimes have the need that you not own for a service that you don't only have need like one process But multiple processes you may want to bundle them together and Kubernetes. That's called a pot A pot is a group of one or more containers that share the same port space So that means everything behaves like it's kind of a local host if I have one here One container that runs for example peach pfbm and one that runs engine x and you next can call call Peach pfbm or like it is on local host on the other hand both containers don't share a file system So they are very isolated. They don't share a process space. It's just a port space that are shared Then in Kubernetes Oh, yeah, and it's also important any every port that process is open here by default are not accessible from the outside of this pot You can think a bit of a pot like it's like to like an additional system It would be a server like everything that you have run locally on one server for your application would be every process Would be a container and every the whole server would be then a pot Then in Kubernetes you have the concept of a replica set Now replica set you can that defines and manages how many instances of a pot should be available So in this example have three pots here in one replica set and the replica set decides then okay on which server this pot should be These different pots should be a start and executed Around that in Kubernetes you have a deployment the deployment manages updates of replica sets So if you want to put a new version the deployment managed in a rolling way that the replica says updated Pots get all ports with the old software version get shut down and new pots get started up And it also ensures that your whole service is available through the whole point in time So it doesn't shut down all services instance at one point. I Said a few minutes ago that By default every port that is open in one of these containers is only available within this pot and not to the outside To any other services running there in order to make ports available to something else running in Kubernetes You have to define a service and that makes ports of pots accessible to other services running in Kubernetes But that's only within Kubernetes if you want to make it accessible to something outside of Kubernetes for example to a web browser or some services are not running inside of Kubernetes you have to define an ingress Which basically makes a port of a service accessible with a URL to the outside I will show you examples with concrete code and afterwards and then also this hopefully becomes clearer to finish this up Server a physical server is called a note But usually you don't care about notes because Kubernetes all does this for you to get automatically it decides on its own Where a pot should be deployed and where containers should be running Then you have config maps and secrets to store configuration in key value store These config maps in a key value store can be mounted as volumes inside of the containers where it's needed Also more examples for the later. Also, you can use volumes to get persistent storage and You also have a concept of namespaces which has an additional horizontal layer of encapsulation there We can build up features like every developer has its own namespace Can deploy their own versions of the service they are working on without affecting other services running in other namespaces So it's a way to encapsulate things So let's look at a more concrete example. We have a PHP application pot in The PHP application pot in this example We have a PHP FPM container running for serving PHP files on executing our PHP application We have an nginx container running as a web server to accept HTTP traffic and to serve static files We may have a memcached container running here for some local caching that we want to run in there and some MongoDB router for accessing MongoDB databases in the MongoDB cluster we're running as that's the demon for Monitoring and also some linker the demon that I'm going to talk about later So this would be like everything that's traditionally would run on one server And we have every process in its own container and this makes one pot One instance of our service and in a replica set we can say okay of this pot We want to have two instances. So if we deploy something that we can take this instance down and This is those serving traffic we build up a new instance with a new version and then take this down and do the same thing and The deployment instead of communities does this automatically for you without having you having to do anything Then we can store some configuration files in a config map or some configuration values in a config map because it is good practice if you have configuration that is especially environment specific to not put it into a docker image with your source code because you want to use the same docker image with the same source code in the service version in your depth environment as well as in your staging environment as well in production You don't want to have different docker images for different environments But on the other hand you want to put the configuration into a config map and mount this for example in the FPM container Also, we can define a service here that exposes port 80 from under necks to other Services running Kubernetes so that they can access our pot and then At last we can also define an ingress that then provides a URL like PHP app something So that our application is accessible from the outside To interact with Kubernetes and You need also a bit of tooling and what you first see is a tool CLI tool called Qubes ETL You can just install it with homebrew or whatever a package manager you want to use and if you use docker For Mac or docker for Windows or something also it comes Qubes ETL comes directly with it. So it's already installed Just an example if you run something like Qubes ETL get pots It will give you a list of pots that are available in your cluster and You can also get all kinds of other information about the cluster as well as modify resources create new deployments And it's a very powerful tool to do everything there in the end Qubes ETL Just uses a rest API Which also of course can use on your own to build your own tooling around this if you want to an example here to use The rest API you can also just call it and then if in this call we from the default namespace We also list all pots and we get the same results just in JSON format There's also a nice project called Kubernetes dashboard. This is URL down here Which this is a screenshot. I'll show also show it to your life in a nicer bigger font afterwards That also gives you the same information as Qubes ETL the same possibility is just in a web interface so you can click around there and Last but not least there is also there also Several projects around Kubernetes that try to solve common problems for example one I really like is harm as a package manager for Kubernetes and there you can do some thing like installing Packages and solutions that you commonly install for example wordpress where you can just say harm install stable wordpress You may give it a few more configuration options like a title some database credentials on and then it will do everything for you With like commonly shared configurations But let's look at a practical example We want to deploy a symphony demo application for that We have to first prepare our Kubernetes cluster a tiny bit first. We have to install or Docker client on a machine But if you want to do this locally Docker client installing on a Mac would be blue cast install Docker and then we have to in The Docker client from preferences We have to activate our Kubernetes cluster because by default Kubernetes is not started up because it uses kind of a bit of resources and also I figured out while working for this talk It drains battery a lot if it's running That is maybe one of the downsides there So we enable that it takes a couple minutes for everything to start up So I already prepared that on my machine So then don't have to wait for that and then we may want to install helm as a package manager Which also you can just install with a homebrew or your package measure of your choice on your operating system We have to initialize harm once so that it installs and configures your Kubernetes cluster correctly It just run home in it and then it does it and then we can start installing things like the Kubernetes dashboard with with a bit of configuration here so configuration various would be that we just give the UL for a company is that what that we want to use later on and then we can say harm install the Kubernetes dashboard This is configuration and it will install the Kubernetes dashboard and then also we need to accept traffic from the outside and Ingress controller for that. I'm using engine X. I'm going to talk more about English controllers later on so just take it as a given now that you need it and Same thing Helm install an engine X. Angus controller and then we have it and can also accept traffic from the outside These are kind of the preparations we need for our Kubernetes cluster and then let's start deploying the symphony demo application The URL file URL is here. So it's really just a symphony demo application and Yeah, let's hope that it works alive So let's synchronize the screen and Here in PHP storm. I have the symphony demo application in here. So I just did Composer create project symphony demo application The all the sources are downloaded here and I added a couple files like a docker file and the Kubernetes deployment configuration Yes. Oh, yes, sorry How do you make it bigger at the presentation, but yeah, thank you So this is a bit bigger, but I would just want to show you that and let's go maybe to the The shell first because also I already just to show you This application running so I'm just starting it now locally on my machine and if I go here Okay, that works. So I have this demo application running locally. Yeah That's not very interesting because we want to deploy this to Kubernetes I've already deployed one version here in my local Kubernetes cluster so the same version is here and What I want to show you is just like how we can get a change to our source code through the pipeline with building a Docker image and getting it into Kubernetes so let's go back to simp to PHP storm and let's go to the template here and Add like some tech Hello peach Okay, and Then let's get back to the console the first thing we have to do is we have to build a docker image for that so Let's maybe bump the version here, so I'm just saying now a docker build. I'm saying the name is symphony demo and I'm giving it the version 1.2.0 So I'm gonna build this now this gonna take a couple seconds while This is running. I can also show you the docker file that basically defines all the dependencies in here that I wrote for it Okay That is not nice. Okay. Let's restart that and hope for the best It worked earlier promise, but let's just go to the docker file So for the symphony thing I'm actually using a feature called multi-staged build in Kubernetes in docker because what we need is we have to build all the JavaScript dependencies once for that we need Node.js But we don't need Node.js in area afterwards to run our PHP application because all the JavaScript is built We just need an Apache and PHP there. So in the first step here I am saying okay I'm depending on a base image that just has Node.js and yarn because the symphony demo application is not using npm But the yarn Is and I'm just basing on that. I'm saying my working directory is var 3w html I'm copying the package JSON and the yarn lock file into that because it's the only thing I need to build my Node.js to do a yarn install. I'm running the yarn install and that's it Then I'm saying okay for my actual package for my actual image I'm basing then on the PHP 7.2 Apache Image so an image that contains PHP 7.2 Apache and some default configuration already I'm saying also my working directory is var 3w html Then I'm installing a couple packages that I need for symphony to run So this is this part here basic Debian packages then I'm Installing a couple PHP extensions at symphonies like curl and SQLite JSON and so on I'm activating a couple Apache modules like headers and rewrite. I'm Adding the necessary Apache configuration to it Then I have to install composer here Then I copy the composer lock and composer JSON file to my Docker image and then I can run composer install there After that after a run composer install and then can copy from the other Node.js image the node modules Inside of my current image so it copies from the first Zero's Image all the node modules to the current image and then I copy all the other sources into it And then I have to basically say okay I changed the owner of all those sources to 3w dash data because that's what the patch is running under and So that all the files are accessible the reason why I do this is complicated and not just do like copy dash that and then run composer install is This way if you because of the caching machine mechanism that Docker has Own I will only run a composer install or yarn install if my package JSON or composer JSON or composer lock file changes If I do any other code change Like code changes to any code. This will all stay the same because the composer JSON didn't change it doesn't have to run composer install Again, it doesn't have to copy the node modules and it will just Copy all my new PHP files or my new template files into the clock image So it makes just like building new images and iterating of it a lot faster and then let's hope This is all up running and let's hope that this is working now It looks a bit better Okay While that is still building I can also show you the next step because this is how I build a docker image The docker image is now lying locally on my machine and I need to get this some more incubators for that I have to write a bit of deployment configuration So I added a bit of configuration here Let's get this all over again. So the first thing is I defined a deployment Configuration incubators is usually done in JSON or YAML files And you often usually say see YAML files for it because they're just a bit better readable and less characters You have to write it compared to JSON So here I'm defining a deployment like think back there was deployment and replica set So I'm defining a deployment. I'm giving it a name Symphony demo and then I'm specifying this deployment And I'm saying here Basically inside of that is like the replica set definition And this is the pot definition and the pot definition is a list of containers I'm run and in this example I just have one container which is which also names if we demo and which then is Running the docker image Symphony demo in this version. It's one. What's one dot one dot three. So let's change this to one dot two dot oh Also, I defined an image pool policy I said never because I'm all everything running normally Coordinators would say, okay, I'm he wants to get a symphony demo content image So I'm gonna go to docker hub or whatever docker registry that's on and trying to pull it there Since I have everything running locally and I didn't want to push it first to the docker Just and then pull it again to my local machine I said, okay never try to pull just to make it on locals further. Normally, you would not do that Then I'm saying, okay, this container opens port 80, which is the Apache port And then I'm defining down here Lifeness probe and a readiness probe for health checks. So I'm saying hey Check frequently here every second on port 80 do a request to slash and only if that works and returns to 100 This container is available for serving traffic because Apache needs a bit of a boot up time Next I'm defining here a service To expose the port 80 of the port above to the port 80 under the name symphony demo and Then after last I'm defining ingress while I'm exposing the port 80 of the service symphony demo up here under the host name symphony dash demo local dot KS and Also a bit to cheat and make it easier. I also adapted my ETC host file to just serve symphony demo Local KS on my local IP address Okay, so let's see Yeah, everything worked. So down here. It says successfully attacked the image Let's double check that I did everything correctly and updated this year to one to go and then We can say, okay We have the image now locally here. So let's just say cube CTL apply dash F and the YAML files in the deployment folder. So I want to apply all YAML files that are in the deployment folder to my Kubernetes cluster And then it says, okay The service is unchanged. So it Kubernetes apply didn't do anything the ingress is unchanged But the deployment changed because I bumped the version So communities did something and if we just look at The pots that are running inside of my cluster I see there are Two symphony demo clusters that just 17 seconds ago restarted and If we go to the browser and do a reload here. Yeah, it worked So This is like a bit. So it's actually fairly easy like the configuration you have to write for this small demo is not a lot Just a couple of lines Of course in a real world scenario you have only have a bit more things like you have a database and stuff like that So it gets a bit more complicated or it's get a bit more, but it's also Not that hard and there's good documentation for it as well So let's go back to the slides a bit So we had the Docker file This is just my backup file if the demo didn't work. So we had the Docker file was installing everything and Installing composer running couple install The command it actually runs is inside of a rocker file already inside of the base rocker file So the command runs just patchy to the foreground Then we build the image Then we don't need to push it because it's all local then we have to tell Kubernetes what to do with the image or So it's a yaml. So we have the deployment here with the version down here. We have the health checks Actually what you can do in these deployment configurations in the container configuration is a lot more So it's not just these complex settings. You can also define many more options For example, you can set environment variables You can mount volumes there to get persistent data or to put configuration into it You can request resources saying okay my pot or my container needs like 200 megabytes of memory So companies should ensure that wherever it schedules the pot to run 200 megabytes of memory should be available You can define rollout and deployment strategies the command you can override the commands that are executed there You can configure network settings Affinities where you can say okay on one physical note only one or two instance of a pot should run in parallel Just for scaling issues You can create like attach life cycle events so that you can execute certain things if the pot starts or stops Things like that and a lot more and We also defined a service to expose it to other things running in Kubernetes and we defined an ingress Great, and we created everything with cube CDL apply, and it looked like that Symphony demo. Yeah, and we did deployment Great. So these are the basics of getting a service into Kubernetes Let's talk a bit about more other interesting and important aspects of it because there are other types of things that you can deploy and Do in Kubernetes one of them is called a demon set So we have deployments which is usually a default way to get a service into Kubernetes a demon set is a special kind of deployment and A demon set ensures that a certain pot runs once on every physical note Usually you don't need that you don't care about physical notes But for some things like lock collection demons I'll come to that also later monitoring agents You want to have one instance on every physical note and it was a demon set you can do that They basically work and are looking like deployments Just the rollout strategy and deployment strategy is different and thus you also have to compare configure them annually Documentation on that is in the good Kubernetes documentation repository and this is like a bit of an example So the kind here is not deployment as before the kind is demon set I also I'm giving a name and labels to find it later on the spec would be the same for a deployment I would have my containers down here The important thing is that I have to define an update strategy how the demons that should be updated in what way For example here I couldn't do a rolling deployment or would I would just say I don't care if I lock demon For example, it goes down then it puts up with a new version and then it starts collecting the locks Where it stopped before so they wouldn't care for it for other things. I may want to do is enroll in real way also What you can deploy in or what's great supports are cron jobs So these are good for regular repeating jobs that you want to run like on a with a cron demon usually they have on your system And it looks also very similar. The kind is here cron job. So I'm not demons that are deployment I also can give it a name then I have to give it a schedule How often it's and when it's supposed to run basic cron tap syntax and then I have the same kind of template spec where I have in the end a list of containers and There it's a bit expected that these Commands that run into this containers don't run forever like Apache runs forever until you kill it or it breaks But they should finish at some point, of course So this is good for any kind of cron jobs you want to do and Kubernetes then cares on its own where it's going to be executed various their space You can also say I need resources for that and specify I need like for memory like one CPU for it or so on So this is a very powerful tool also to run the cron jobs in a smarter way than having like one machine Where all the cron jobs are defined if that dies you have a problem Let's talk a bit more about how Kubernetes works internally and One important thing there is that you have to be aware of a service discovery So I'm not going like very deep into like internals how the scheduling works and how Kubernetes decides where to run a pot or that but service discovery is very essential because usually A bit more complex system at least have a web service like in PHP and a database and they have to talk to each other somehow Within a pot as I said you share a pot namespace. So everything behaves like local host But it's get a bit more complicated between pots Because usually in the example, I have a PHP application. I have a database I don't want to put the database in the same pot as my HP application because I will need to scale the web service and the database differently Also, if I deploy a new version of the web service, I don't want to restart the database It doesn't make any sense. So usually I have one Deployment for the database with its own pot and one deployment for the web application with its own pot And they have to talk to each other for that. You have to expose the ports with services So to revisit this this is a configuration where I'm saying hey This is a service and I want to make port 80 of the pot available to something else Internally what Kubernetes does that for the service name symphony demo, it will assign a virtual API address And you actually can see this so if you run QPCTL get service and then the name of the service It will tell you okay There's a service symphony demo and this is the virtual IP address for the service and this is a post Ports that are exposed on this IP address this IP address is virtual and with IP table routing Kubernetes if you just call this IP address will automatically Forward the traffic to the IP address of one of the running ports that are available. So it does Kind of like round robin local and saying they are automatically for you. The next thing is now, you know Okay, there's a service under this IP address. Somehow you have to In the service that wants to talk to the symphony demo application You have to find out what the IP address is and since this is not can change at any point in time It's not stable. You shouldn't hard-code it But it's easily discoverable in other containers either by environment variables because every Container that is started will get a lot of environment variables automatically injected by Kubernetes And it will get one environment variable for every service that is in the current namespace So in this example, I would have a symphony demo service environment for the host and port That gives me the IP address and the port that I can connect to so in my application I could read all this and these environment variables and then just go to these IP addresses or even more convenient Kubernetes also comes with a DNS interface for that so I can also just use the name of my service To look up the IP address and get it. So in the end I can just do curl symphony demo or use guzzled and go to HTTP symphony demo and in another container and accesses to that Alternatively, I also can use service mesh tools A couple examples for that that are fairly popular are linker D STU or conduit and These service mesh tools run either as a demon set in the cluster So that I install an instance of linker D For example on every physical node that I have and then my pots can use this to connect to other services or As a sidecar container, which would be this example that you've seen before that in my pot I don't only have like PHP FPM and nginx But I also have an instance of a linker D service mesh container and what I can do then is if my PHP FPM application wants to talk to an instance of this other service that is running node.js It does this request first To on localhost to the local linker D instance that we're just running on port 41 40 or whatever So it's going to localhost 41 40 saying hey, please Do a request to this other service wherever it is the linker D instance will look then on the Kubernetes API up Where on which IP addresses this is running? Basically the same as when it is already doing and then basically forward this request to one of the pot instances It is very similar what Kubernetes is already doing Out of the box. So why would you use something like this? Why would you put up another process to do this which also needs resources or that it has the benefits that you Can do advanced routing for example, you couldn't do something like Prefer the service that is running in the current namespace for example if I have my developer Bastion namespace I can just say okay. I deploy one service there But the other service I'm not caring about because I'm not developing on that So if the service is running a current namespace I go to that Otherwise it can fall back to the default namespace So these advanced routing things you can't do with Kubernetes out of the box so that you need like some kind of Service mesh mesh technology, but more importantly it also makes it much easier to add monitoring to it because all these tools come With my monitoring directly built in so what I can see there Then I can have dashboards. This is not really nice Okay, believe me what's in there that you can then automatically monitor the success rate of these calls to one service The latency and the request volume so that you have this monitoring already built in otherwise This is a bit more of a black box same with profiling all these tools Also support profiling tools like zipkin for example where you can follow one request that comes in at the beginning of your community discuss That's all the calls that you're making to other services databases and you get like a big break Large breakdown of different service calls and can profile this the whole way through with all the whole so that you know What time amount of time you spent on what time? In which part of your infrastructure on which service and it's not a black box anymore why a request took like two seconds So this is why you may want to use one of these service mesh containers as a sidecar as a demon said even if it uses If you if some of the things committees can do out of the box Also, let's talk a bit more about accessing things in communities from the outside For development you can also just use port forwarding through Ctl So Ctl has a functionality where you can say okay We can call Ctl port forward and then just enter a pod name here Then we can say the port 80 in this part. We're just going forward to Port 88 on local host on my local machine and it doesn't matter where the Kubernetes Cluster is running if it is on my local machine or somewhere on cloud platform or wherever I can basically make any port of any port accessible so that which is nice for development Of course, it doesn't work for users They can't you can't tell them use Ctl to access the website For that we need Ingress define ingress and we need to deploy an ingress controller You saw in the beginning with the preparations that I did like with harm deploy an ingress controller an ingress controller Usually is either in gen X or h a proxy But there's also Istio that can be run as an ingress controller and also potentially any kind of other tools and the way it works That an ingress controller is also just a docker image where engine X is running and there is like a special Demon Process running also inside of the docker image and that listens on the Kubernetes API for all ingress resources And as soon as there's a new ingress resource it rephrase the engine X configuration and reloads engine X and then forwards the Traffic that comes from the outside another given host name to the correct service to the correct virtual IP address So That is like if I define an ingress resource like that Saying I want to go to the service name symphony demo port 80 if anyone comes in with this host name Then the ingress controller will pick up on that Listen on that and then will automatically rewrite the engine X configuration or the h a proxy configuration correctly to support that Let's also talk a bit about data and storage because we have been talking about so far We haven't seen anything there We have seen things like a web application that is usually stateless or all the data that is in there can also go away Any time at point in time because a problem problem with docker images and Kubernetes is that you can't ensure that the image is running infinitely At any point in time Kubernetes can decide okay. I have to re-square your things to make space for other things so I'm gonna Can't exit the port stop it and put it somewhere else And of course all data that was created inside of the port is in lost because the data is not stored anywhere In order to have persistent storage we need volumes Documentation more documentation there is on that And this is like a very simplified example We have our port definition here with like one container and we also define a volume We name this volume cash volume in this case is just an empty directory So this is good for caching things because this empty directory will also go away when the pod cancels again But just to give you a very small example. We can then can say we mount this Volume this cash volume inside the pass slash cash So all the data there is an in slash cash and it will be stored not into the container directly But inside of this volume, of course, this is like this example. You probably don't need that often with an empty caching There are also other types of volumes for example persistent storage volumes for that You have to define a persistent volume and there are tons of providers there that you can use for example It can be volume that is on some NFS share It can be on S3 or all kinds of other storage technologies that you may need and then the pot can Specify a persistent volume claim saying I need a volume with like five gigabytes of data Please Kubernetes ensure that I get that Kubernetes will ensure that and this persistent volume claim can then be mounted inside of the container the same way as we saw before More information on that on persistent volumes can be found here Of course, this is also a bit more to configure than because you have to configure NFS and the storage itself And make sure that this is available and depending on the storage solution also latency of course is different If I have an NFS share, it's probably way faster than saving things on S3 So it's not good some storage for storage solutions for example I'm not very good for persistent caches or something like that and if I have a MySQL database I should not use an S3 storage volume for that So you have to kind of like it depends if you if I have file uploads for example S3 may be a good solution Also I already said Configuration is one thing to keep in mind because we don't want to store configuration inside of a Docker image We want to have this injected from the outside into a Docker image Because it's not a lot of data in configuration size-wise We don't need persistent volumes for that We can just use something else called config maps which is built in key value store and the Configuration in a YAML file could look like this So I have the kind config map that I also can just apply with kubectl to Kubernetes I give it a name special config special config here and in the data I have two key value pairs a special key with a value value and a bool value key with a value true and This Config map and this data here can then be accessed in the port either through environment variables so in my Container definition I can say okay with this NFR these I want to define a environment variable variable called special key and The value from for that environment variable should come from the config map Special config and I want to get the value from the key special key So then I would have an environment variable here Also, if I need I want to create environment variables for all keys in my config map I can also do it like this and I'll say okay Take the environment from this configuration this config map and then it would automatically create all of them It easier maybe or I can access also config maps for volumes where I can say okay I want to create a volume and It's not an empty dear here or not a persistent volume claim, but it's actually a config map I want to reference this too So this is a company makes special config and then I can mount this config volume inside of my container here under the Pass EDC config and what this will do it will create a file for every key that is inside of my config map and It will the value or the content of the file will be the value of the key So these are the different ways to do configuration Also, I put a reference here to like more things to read up on that Also, there's a concept called secrets which behave like config maps But they are there for storing more sensitive information like passwords because they are additional access security concept around that Also, I can't go into much more detail there because it gets very complicated quickly with C But usage-wise they behave the same as config maps and if you want to read up on that this is a reference Additional thing with Kubernetes I want to talk about quickly because it is something that is very common for PHP applications is a complex in its in its processes For that Kubernetes supports in it containers, which allows us to run a process inside of a container before the rest of the pot starts So before I start my Apache or my memcache or whatever The use case for that could be for example database migrations Like running them before the pot starts could be interesting or if multiple this is a more common one if multiple containers need the same sources What do I mean with that if I if I'm not using Apache, but if I'm using engine X and FPM my PHP application would look like this I have PHP FM running in one container. I have engine X running another container engine X should serve all the static content Like CSS JavaScript files images because I if I'm getting want to get an image I don't want to serve this through PHP it would slow it down Unnecessarily and PHP of course should execute my PHP scripts and serve traffic for that Of course, that means both of these containers have their own file system, but need access to my source code for that so That means when I want to build that I actually not only need to build one Container for my PhD application But actually to like an PHP FM container with also source code and then engine X container with all the source code and PHP applications tend to grow quite large So several hundred megabytes sometimes is all the images and all the resources there That means I have two very big images that I have to store my registry and update and this is kind of like tedious What you can do there is instead of that you create an init container Which just is like a very basic image that contains your source code and maybe our sync as a tool And then you can define this in communities as an in container and the command for that is so this connects only the source code Basically, and what it does then in a container you mount an empty dear volume inside of the internet container Then you can copy with our thing for example all the sources from the internet container into this empty dear volume Which will also go away when the pod gets stopped what gets stopped afterward, and then you can mount this mount this volume Both inside of the fpm container and the engine X container which both contain only engine X and fpm and not the source code But then the source code through this volume is accessible Sounds complicated sounds slow It's actually not because it's all on the local file system and there is no virtualization between that It's all done with Linux kernel features, and so it's the same speed you get there But you don't have to build like two big images only one Let's talk a bit more To finish it up about figuring out what's going on inside of Kubernetes for that. We need one monitoring Kubernetes comes with an additional project called heaps there Officially maintained by the Kubernetes project and heaps that allows us to take Take metrics from Kubernetes that Kubernetes already exposes and store them into any kind of monitoring solution that I have Things like influx to be from ethos graphite Whatever and then I can tools use the monitoring tool I may already be using like Rafaana for displaying the data for example, this is already quite small again So believe me here would see the overall cluster CPU usage the CPU usage by note Individual CPU usage on like IP addresses memory usage and so on so I get all this information in a time series database And not only on the cluster or node level, but also on an individual pot level so that is like kind of very convenient to know and See what is going on into my cluster? I Also put like a bit reference to a blog post there that explains this in way more detail. The second thing I need to know is logging Kubernetes, that's what the Qubectl comes directly with a command Qubectl locks So I can run Qubectl locks and then any kind of pot name to get the locks of this container of this pot there Which only works if your service locks not to a file inside of a Docker image But if it locks to standard out or standard error Which is good practice for running Docker images anyways because the file system is going to go away as soon as the image restarts So any kind of log files are lost so instead of that I should log to standard out and send error and that Kubernetes the container orchestration platform care about persisting the locks somewhere and Kubernetes locks everything that a container locks out on standard out or standard error Automatically writes it to disk on the local node where the pot is running and then I can run a demon set lock collector Something like lock stash fluent D or file beat also inside of Kubernetes A demon set runs once on every host and this lock collector would then just mount the lock folder like while lock Docker or why lock containers where all the locks are in and then tail on these locks and forward them to your central log management solution for example elastic search with kibana and then you can have it also automatically enriches all the Information or the lock messages with additional information from Kubernetes like what pot this lock messages from what services this More lock message from on which IP address it was running so that you can nicely filter things here For example, I can't really see this. I hear filtered for all Containers that we have in the name switchboard service in the namespace default and I can Then accesses as long as it's data stored in elastic search. There's a good blog post that also explains is a bit further from elastic That is called shipping Kubernetes locks to elastic search was far beat also that can you can read up on that? Earlier I also talked a bit about like scaling is very easy with Docker containers And I want to show you how easy it is because you can do things like manual scaling very nicely and Let's for that do the last short demo So if I'm gonna go here and let's look again I have here two symphony demo pots, which I've been running for 25 minutes now, right? So Let's say cube CTL scale Demo situations There's replicas and I want to have three now for the deployment symphony demo So it said now Symphony demo scaled and if we look at the pots that are running We see no three and One is running since 11 seconds So that is how you scale in Kubernetes manually So that is makes it is very easy. You don't have to do anything any provisioning any puppet magic Just say cube CTL scale if you need more instances Also, you can auto scale in Kubernetes So there is a thing called horizontal pot auto scaler and what it does is it's basically automatically watches How many resources or CPU usage? For example, your individual pots have and you can configure thresholds and if it goes over certain threshold Kubernetes automatically spawn up a new pot and also stop pots again if it goes below a certain threshold Which is very nice if you have for example batch shops that hit some servers very hard during the night when they're running and Then communities can directly detect that up to a certain amount of pots put up Spawn up new pots dynamically and also stop them again Very similar to also what AWS can do of course You can also write cron job that do that beforehand if you know every time every night at 2 a.m I have this one thing running that needs like 500 percent more resources on one service. I can also automatically do this before So this all very powerful if you want to read up more on that there is this documentation about horizontal pot auto scaling and Lastly keeping services secure you should read up on Docker container security Because it's very nice that everything is encapsulated But you have to also configure it Docker especially running Docker images in a way that if someone goes gets into a document image Like an attacker you can't get out of that or can't get root access to anything More information here is on this documentation conferring a pot container Security contacts and also you should maybe think about depending on your Organization about role-based access control because by default all users have access to the whole Kubernetes API Which may be fine in a development environment, which may be fine your company completely But in some organizations you want to limit this further for example You can say if I have Dedicated namespaces for every user a developer the developer has full API access to his namespace But not API access to other people's namespace things like that You can do also configure in communities with role-based access control And you can do this for users as well as services that you can also allow certain service only to access certain resources More information there also in the documentation and I'm going to point on that And I guess if you could talk a whole hour about role-based access control in Kubernetes because it's very powerful You can do a lot of things there to sum it up Kubernetes is very powerful. It can help you greatly with And also very helpful so it can help you greatly with automating deployments making this all easier for you scaling things It has a learning curve and also it's very fast-paced in development There are four big Kubernetes releases every year and a lot of things are added there changed not really changed in a backwards Could be a VC breaking way so they're very good with that But there are always like new things where you can this can make your life easier So there's a bit of information here about the release cycle But that also means you have to stay up to date if you're using Kubernetes to Benefit from all these new things that are happening where you can do things better in a more performant way the good place for that is the Kubernetes documentation which is Fairly large, but also very good with lots of tutorials for things. So they're getting better and better also writing documentation But what also can recommend is Cube cons which are a dedicated conference for Kubernetes and the nice thing about this They record every talk and a few weeks later. They're on YouTube So even if you can't afford the ticket to go there It's also very good to just watch some of the talks to know what's going on there And especially there's the last fast pace also on Cuban is tooling or cooling around when it's like helm Or things like that. They also change rapidly and advance rapidly because it's still a fairly new technology and ecosystem Also, I'm gonna upload the slides for reference with all the links later on hopefully today latest tomorrow morning on speaker deck I'll link it on joined in and also tweet about this and speaking about joined in It's a great platform where you can give feedback for the talk and I would encourage you to do that Because feedback makes my life easier to improve this talk and also the life of the organ is easier because they also know What you liked and can make the conference better next year So go to the joint in joint in and trade all the talks you have been seeing so far on the conference And they're gonna see in the next few slots