0:30
Hello, friends, and welcome to another session of the Kubernetes Fundamental Series
0:39
My name is Rodrigo, and today I'm going to talk about multi-container pods
0:45
So this is another session about how we can create these kind of applications with different containers
0:58
But of course, this time I'm going to talk about how and why would we want to do that
1:07
I mean, deploying different containers in a single pod, okay? So before I do that, let me do a quick recap of the last session
1:21
You might remember that I talked about resource management and I talked about how we can set some limits so the containers don't use the entire resources, right
1:40
Such as CPU and memory or storage. So, we have the resource requests that are the minimum amount of resources that we can specify for a container, right
1:56
And then I explain resource limits that specify the maximum amount of resources that a container can consume
2:06
So, actually, that was the last session. and today I'm going to talk about multi-container pods
2:14
So most of the time in a Kubernetes application, we want to run a single container in a pod
2:24
in a single pod in an isolated fashion. Why? Because there's a clear separation of concerns
2:31
in that particular design pattern. it's not a good idea to deploy all your containers in a single pod just for the sake of it, right
2:44
Just because you can't, because otherwise you won't get the separation of concerns benefits
2:51
that we can get, okay? So we have the multi-container pods option, and this is when
3:00
And multiple containers need to work together, right? Sometimes we need to do that
3:09
And I'm going to talk about DAPR as a framework for creating distributed applications
3:15
And I'm going to talk about some of its building blocks. I think that's a great example of a technology that uses a multi-container pod deployment
3:28
deployment. Anyways, when you do this, it's because you want to provide a single cohesive
3:35
unit of functionality, okay? For instance, maybe you are deploying this pod that has
3:42
I don't know, maybe you're deploying a web server, or maybe you're deploying this
3:47
microservice that needs another one. So both can be working together, right? So one of the main
4:02
traits about this is that container share does a network space. So in other words, both containers
4:11
They can ping each other, right? At the end of the day, they can see each other because they're running on the same network namespace
4:21
And they can communicate between each other just by pinging the local host address, okay
4:32
They can communicate with each other. That's one of the most important things about this kind of deployment
4:37
So there are different multi-containers deployments and options that we can use
4:45
And one of them is init containers. I think I mentioned this like eight sessions ago
4:56
When I first talked about pods, I don't remember the exact session number
5:05
Anyways, in one of them, I spoke about pods and I spoke about init containers
5:13
I think it was related with, yeah, environment variables. No, no, no, no
5:24
I can't remember. I'm sorry about that. There are so many sessions that I've done
5:29
Anyways, I mentioned before init containers. So, in it containers, this is a way for using multi-containers pods, okay
5:41
With in it containers, you have your main application, right? You specify your manifest with your application
5:49
and there is another place in the same manifest that we can use to specify in it containers
5:55
What in the world are those in containers? they allowed you to execute code before your main application does
6:06
before your main application runs. So this is great for initialization purposes
6:15
such as creating a specific file structure, creating some, I don't know
6:21
maybe a kind of structure inside the data, inside your containers, or just, I don't know
6:28
maybe running some kind of command or script or whatnot, okay? This is just for initialization logic
6:37
And one of its main traits is that this kind of container
6:42
this init container, it can start before the main application, as I mentioned before
6:48
So in this diagram, as you can see here, I have this pod with an init container, right
6:54
And also, you can have a number of init containers. You can have multiple init containers on the same pod, okay
7:07
And so, actually, in this diagram, as you can see here, I have two, and then the main application
7:16
You can see in this diagram, the purpose of this drawing is to show you that you can run an init container
7:24
and then run another one, and then run another one if you want to, right
7:29
Most of the time, you're going to have just a single init container
7:33
Of course, you can have multiple init containers. They meant to be short okay Be careful about that They not meant to run all the time right To be running over a period of time No no no no They are meant to be short
7:56
Remember when we had back in the day, back in the day, I mean like 25 years ago, we had
8:07
MS-DOS, right? And the autoexec.bat file, remember that? The autoexec.bat file, which was this batch file
8:21
And that's where we, I don't know, specify a lot of different configurations for the operating system
8:30
And there was this other file, which was config.sys. And you remember that, right
8:37
Device equals highmem.sys and those things for configuring your Sound Blaster sound card
8:45
So, auto-exec-bat is similar to init containers in that matter, okay? So, maybe you want to run your auto-exec-bat in this particular containers
8:59
Anyways, you specify this in a structure, in a field inside the manifest, which is init containers, okay
9:09
So, actually, here's an example about this. you can see that I'm specifying a pod
9:17
Its name is init container example, right? Very easy thing to grasp
9:23
And then I have this init containers field, okay? So you can see that init containers is part of the spec field
9:36
So it's very similar to the containers one, right? You specify the name of the container
9:43
and then you specify the image name, and optionally, you can specify a command
9:50
In this case, it's just running this bash command for echoing this particular string
9:59
that says initContainer has completed its task, and then it's sleeping for five seconds, right
10:08
So, very easy thing to do. And then the main application will run
10:15
The main application is implemented in this fictitious myApp colon latest image name
10:23
Make sense? And the other one is based on the busybox container image
10:31
So, yeah. This is a common thing when you want to execute something beforehand
10:42
And you don't want to mess with your application, right? You don't want to mess with the code of your main application
10:50
You don't want to change that. You just want to do that initialization thing in other container, right
11:00
And then you can verify if you execute kubectl get pods, you can query for those pods
11:10
and then you will see in the status column those init kind of containers, okay
11:18
So in this case, I took a screenshot of this command, and then I pasted the code here
11:24
And as you can see, if we query for those pods by using kubectl get pod init blah, blah, blah
11:33
the name of the pod, then we can see the status of those init containers
11:39
Okay? So that's one reason to use multi-container pods. I think that's a compelling reason to do this
11:52
And sidecar containers is another compelling reason for using multi-container pods. Okay. So in this other case, sidecar containers, those sidecar containers are helper logic for the main application. The sidecar container is running alongside your main application in the same pod
12:18
Okay? So, those are different between, I mean, the difference between sidecar containers and
12:27
init containers is that init containers are meant to be short-lived and sidecar containers
12:35
are running all the time. Right? So, that's the main difference. They provide additional functionality
12:43
to the main application or they enhance its features. Okay? Another trait is that they're not involved in the public API
12:57
It's not that you can, most of the time, of course, you won't be messing with the sidecar container itself
13:07
Of course, sometimes you do, sometimes you can actually, with Dapper. I'm going to show you the example of Dapper
13:18
Yeah, the sidecar is the one that you use for communicating to the main application
13:25
I believe Dapper is some kind of sidecar and also the ambassador
13:31
that I'm going to talk about in a few minutes. Some examples about sidecar containers
13:39
are reverse proxies, right? So log management. In other words, maybe your main application
13:50
is creating a lot of logging, right? And then you want this other sidecar
13:56
to be processing those logs or managing the logs, maybe using them for storing the logs in other place
14:05
in other, I don't know, sending the logs to, I don't know
14:11
maybe Elasticsearch or something. Another example is FileSync and monitoring in metrics
14:20
and some things that you don't want to do on your main application, okay
14:28
So you can delegate those cross-cutting concerns to this other application, which makes sense, right
14:39
If you want to follow the separation of concerns design principle, then it's a great idea to separate those cross-cutting concerns
14:52
to another place and let this other sidecar container to do its stuff, right
14:59
to do the work that you don't want to do in your main application
15:06
Security, of course. Managing authentication or authorization and those kind of things, okay
15:16
So here's the example. Here's just a diagram, of course, because otherwise I would need maybe additional two hours for explaining DAPR Of course you can go to the DAPR official website Actually I just copied and pasted this diagram
15:37
from the official DAPR documentation. This is the diagram of the service-to-service
15:48
communication building block. Actually, you know what? Let me open up the DAPR website, which is dapper.io
16:00
And actually, this is the place where I found this diagram. DAPR is a great technology for creating distributed applications
16:11
It's not a Microsoft thing. Even though Microsoft initially created DAPR, then DAPR was taken by the Cloud Native Computing Foundation
16:24
So it's part of the Linux Foundation right now. And you can use DAPR with any programming language, with any framework, and any technology in any operating system today
16:35
OK, so Dapper, actually, it's a great idea and it's a great technology because it allows you to inject that sidecar alongside your applications so you don't mess with those particular cross-cutting concerns and logic that most of the time you want in your distributed applications, such as, I don't know, maybe service-to-service communication
17:04
is a great example of a sidecar. So in this case, as you can see
17:10
service A is your code, is your application, and maybe this is another application
17:16
Maybe this is another microservice, right? Microservice A, microservice B. Because if you think about it
17:26
it makes sense, right? If you don't have something like this, then you would need something like
17:34
I don't know, maybe you're hard coding your strings, right? You're hard coding a lot of things
17:39
Of course, there are many ways to solve this. However, with a sidecar, your microservice A uses the sidecar
17:50
These two are running on the same pod. Okay, this is a pod and this is another pod
17:56
Of course, this is not expressed in this diagram, okay? Service A has its own sidecar and service B has its own sidecar as well
18:09
Okay. So at the end of the day, if microservice A wants to communicate to microservice B, it uses the sidecar
18:21
And the sidecar communicates to another sidecar, to the sidecar of the microservice that you want to communicate to, which is fantastic
18:30
if you think about it, okay? So a lot of things related to networking and communication
18:36
and authorization and authentication and the transport of those bits between those microservices
18:45
are solved by Doppler itself. So this is a fantastic technology, and it's a great example of a sidecar design pattern
18:56
in the real world, okay? Okay, so another example of a sidecar container is when you, I don't know, maybe you're writing
19:09
in your main application, you're writing a lot of things. You're writing a lot of logging
19:14
Maybe you're writing a text file. Maybe you're just spitting out a lot of bytes somehow, and you're writing that in the file system
19:24
Of course, you need a volume. And we're going to talk about volumes in one of the following sessions, okay
19:33
Anyways, maybe your main application is spitting out a lot of text files or data
19:40
Anyways, the sidecar could be reading that particular, I don't know, a directory or file or something
19:49
and the sidecar will take care of that particular data to send it out to somewhere else
19:57
I don't know, maybe Elasticsearch or, I don't know, Application Insights or Jager, whatnot, okay
20:08
So this is another example of how a sidecar could be doing the work
20:15
that your main application is not doing, okay? So this is a great example
20:21
So how in the world we create those sidecar containers? Actually, there is no specific field for sidecar containers
20:35
You just create a regular container in the containers field, okay? So, for instance, this is just creating the main container application
20:47
and then you specify this other container. It could be Dopper. It could be another sidecar
20:53
Maybe you just want to do something like this, right? Like this example that I have here
21:00
So, you don't need to use Dopper to implement the sidecar pattern in your own applications
21:09
So, yeah, at the end of the day, you specify all the containers
21:15
that you want in the particular pod inside the containers field, right
21:22
Okay, so next one is another design pattern, which is the adapter pattern
21:30
This kind of containers, adapter containers, they are useful when you want to make two incompatible interfaces compatible
21:45
So, for instance, let me give you a real-world example. Maybe you are a developer in the healthcare space
21:56
Then you should know there are so many different protocols and standards for communication and for electronic healthcare records and so on
22:09
such as HL7 and those kind of things, DICOM for imaging or something
22:15
So those protocols are very specific, right? So if you want to make your data compatible
22:26
and comply with those structures and interfaces, then you need something like this, okay
22:36
So, an adapter container transforms the output or interface of the main application container
22:44
So, that's actually the goal of this kind of containers, okay? So, that it conforms to a specific format or protocol
22:56
HL7 or DICOM and those kind of things is a great example of when we want to do this
23:01
I believe there are other verticals and other markets that they use particular protocols and structures
23:10
So I just mentioning healthcare because I happen to be very related to that Anyways so adapter containers are useful when integrating with external systems right
23:27
An HL7 server or a DICOM server or monitoring tools so that they can conform to a specific format, protocol, or requirement
23:37
So, yeah, if you think about it, adapter containers are, I think it's just a different behavior of the sidecar pattern
23:52
I could be mistaken, but actually I believe those are quite the same, quite similar
23:59
Of course, adapters are just for transforming the data, okay? Okay, specific examples of an adapter container usage could be metric format adaptation, right
24:13
For sending out metric data to, I don't know, I don't know
24:19
There are so many metrics, platforms, and technologies that we can use or log format adaptation
24:29
Again, Elasticsearch and, I don't know, many different technologies that we can use, okay
24:41
So, that's the adapter pattern. That's other scenario where you want to create those multi-container pods
24:53
And ambassador containers, this is another design pattern. And ambassador containers are meant to be proxies between the main application and external systems
25:11
Again, I think this is another, I don't know, maybe another way of using the same sidecar
25:22
I could be mistaken as well. Anyways, ambassador containers, you use them for communication to and integration to external systems, okay
25:37
Another scenarios are service discovery, connection management, and load balancing. I believe Doppler is another example of the ambassador pattern because let me show you this
25:51
So, yeah, bindings, bindings overview, output bindings, tryout bindings, blah, blah, blah
26:07
I just want to show you the list of different output bindings that we have in DAPR
26:14
Anyways, let me search for this. Dapper building blocks or maybe I'll put bindings
26:23
It's fine. I just want to show you the diagram. Okay. Let me see if I, yeah, I think this is fine
26:36
So as you can see here, open image in new tab. So Dapper, again, this is an application that is running as a sidecar
26:49
However, in this particular case, Dapper is behaving as an ambassador as well
26:57
So in this case, Dapper is able to communicate to Redis, Kafka, Event Hubs, Twitter, and so on and so on
27:07
There are many, there are dozens of different concrete implementations of those bindings that I'm talking about. So this is a great example of the ambassador design pattern, because if we return to the presentation, the ambassador is a proxy or intermediary between the main application container and external services or systems
27:33
Yeah, I believe Doppler somehow is just an ambassador as well, and it's a sidecar too, okay
27:45
Anyways, yeah, I'm talking about, and I'm talking a lot about Dapper because I truly believe
27:58
that if you want to understand multi-container pods, you should have a great scenario for doing
28:07
that. Okay. And DAPR has a framework for building distributed applications. It's a great
28:15
concrete implementation of those design patterns that I'm mentioning right now. Okay
28:25
So more information about DAPR. Remember that the website is DAPR.io and there are many
28:34
quick starts, and there are many examples about this. So, there's another example here in this diagram when we want to use the ambassador design pattern
28:54
in our multi-container pods, and it's when you want to expose your ambassador container
29:01
as the proxy, okay? So in this case, your external application, your external system is communicating
29:11
to your pod via the ambassador, okay? The ambassador is the public API
29:19
in this particular example. And of course, I think there is a narrow
29:27
that is missing between the ambassador and the main application. I believe there is something missing in this particular diagram
29:36
Anyways, it doesn't matter. Just take into account that the external system is communicating to the ambassador
29:44
instead of the main application in this particular design pattern. All right
29:52
So, great stuff. a lot of theory when talking about multi-container pods
30:04
And for me, that's all I had for today. And I don't have
30:13
the next session's title. Anyways, see you all, friends, in the next session
30:21
of the Kubernetes Fundamentals series, okay? See you next week. Thank you