 I'm Kiru. I work for ThoughtWorks. So I think most of you know we are a technology consulting company. And it's like the topic for today is like kind of, we're going to discuss in a delivering, how do we deliver microservices using Docker? So just a quick bingo scorecard for us, like a bingo for every bus word, like you're going to talk about continuous delivery, and microservices, containers, Docker. Of course, a lot of stuff. So because of that, just in a duration of 90 minutes, we'll just touch upon the surface of a lot of things. We won't have much time to get into the details of any particular tool or a topic. So the layout is going to be 60 minutes kind of talk in a presentation mode of concept discussion. And then we'll have 20, 25 minutes for a quick demo of these concepts. And then we'll have some time for questions at the end. Can I just do a quick check? Like how many of you here are like devs? Okay, any folks from operation side? Okay, there are a few hands. And anyone who has never done any dev work, like something like a PM or agile coaches, any other roles? Okay, there are a few. Okay, this is kind of more towards technical side, but like of course we'll start with like, what is microservices and why you want to do it and what are the different challenges? And then slowly, the second half of this may be more towards the technical content. Okay, maybe we'll start with a simple question, like just try to answer yourself, like what's your feedback cycle? So it's a feedback between your organization and your customers. So it's like, how comfortable are you and your teams, if you have to react to really dynamically changing demands? So in the changes I'm talking about, like need not be really big, so it need not be like a totally new set of features you want to add, something groundbreaking. It could be something really small. So for example, something like T20 is around, right? So if you're an e-commerce company or if you're a telco company, so you just want to try and promote different kinds of goods. So maybe you want to promote sports related, cricket related goods, or maybe you want to sell different bundles with more data, of course you know that a lot of people will watch matches, not matches, at least they'll come back and see the highlights. And what happens, say for example, somebody's favorite team, and for some reason, they lost. And you have been promoting the goods related to that particular team for a day or two. You have dedicated to how a sale coming up in 30 minutes, but unfortunately the team lost, so they are totally out of the match. So of course you don't want to go and put it up in front of them, right? That's going to, they're going to kick you out. So things like that. So in this example, I kind of, these products are not something new for you. So it's exactly the same set of products you're selling. So nothing has changed fundamentally in your business, but all that you want to do is like, okay, I have an idea, I just want to do something. Something is trending. So I just want to, you know, make a use of it. So I just want to do something really quick, put it out in the customer hands, and then see what happens there. And then if required, I want to roll it back really quick or change it. Okay, so whatever we have been talking about, like kind of yearly to market, put things in customer hands. So these are not something new. So like kind of, you know, right from the days of agile and automation and stuff, like kind of that's our, you know, basic fundamental goal, right? So we have been doing this for so many years. That's a very simple thing. Okay, you started automating. And automating could be in different aspects. So, you know, automating your tests so that you'll have a quality built in your product. So you'll have confidence to deploy whenever you need to, or, you know, automating your bills and test. You know, nowadays, you know, you automate your infrastructure provisioning. So as you can see here, you know, initially when you would have started here, so as you get better with the automation, you can see that that has a direct impact on your speed to deliver. And after some point of time, sooner or later, you're going to reach a point where irrespective of how much ever you automate, that's not going to have a direct impact on your speed of delivery. Probably that could make things more stable, more repeatable, but that's not going to have an impact on the speed to deliver things. So, how can I go much faster than this? Like, what is stopping this basically, you know, from going further than this? So if you, you know, if you imagine your path to prediction, right? Like, of course, this is a much simplified view. Of course, you'll have a lot of other, you know, things in place, but this is my application. So I did something, you know, checked in, it's there in the CI server, and I do a build. And I have a path to prediction. So of course, I have to go through this path. It doesn't matter, you know, what the changes. So if I do a very small change, so this particular change may not be a feature. Say for example, like, you know, just a lock statement. So it doesn't change anything in my feature. So fundamentally nothing has changed, but this is single, you know, line of lock statement. So if I add this change, this change is part of my application. So if I have to see this lock statement today in my prediction, the only way for me to do it is take my entire application, go through this path of testing, whatever has been there, and it has to get to this prediction. So just, you know, go and, you know, consider this time taken from, you know, moving your system from your CI server up to your prediction. That's your kind of fixed delay. So even if this change is very small, even if there's no feature change, of course you know that if you add a lock statement, you don't have to do all testing, but like kind of you don't want to deploy anything without testing, right? So though you know that, okay, it's not going to have an impact, but still you have to go through this path. So the path, you know, the time it takes for you to move from build to production is your fixed delay. So no matter whatever you do, you know, you cannot go faster than this. So this, you know, time could be in minutes if everything is good, automated and stuff. It could be in few hours, in few organization, or it could be in weeks or months. So if you take a quick, you know, a closer look at that application, whatever you were talking about, right? Even if you see in the picture, kind of, you know, you get an idea that you're trying to solve too many things. So it's like, you know, nine different things, nine different business capabilities, probably they could be related, end of the day for you to run your business. Of course you need all these things, but everything is sitting as a part of your one single application, right? So if you just think about some of these constraints, you know, if I have something like this, right? First thing comes to mind is a single technology. So you know, I'm a consultant, so I get to go to different, you know, places and work. So most of the enterprise organizations like wherever I go, right? So it's mostly, you know, they choose a particular language or a framework and they just stick to it. So it could be either a JVM or it could be a Node.js doesn't matter. So they just choose something and you know, fundamentally, they become really good in that. So it's not a bad thing. So it's like, it's good to have some standardization, but it's getting to a point where it's kind of, it's stopping me from, you know, trying something new. Say for example, you know, very simple thing like, you know, you're trying a, you know, new functional language in a pet project. You really like it. You come back to work tomorrow and you see a screen and it's just a single block of code, you know, in a complete screen. It's just a cascading, you know, you sort of switch cases or whatever and you just want to try out something new. You just want a newer language. I just want to try in that, you know, I just want to see how it works. But the problem is with this setup, so if I have to try a new language, probably you can get to a point where you can implement that in a new language. But if you have to go beyond it and take it to prediction, put it in a new language, test along with this, you know, it has to coexist and put it on a server. That's really difficult if it's like a one single app. And other things like complex code base, right? That gets complex over time. You can help it. Even very simple things like, you know, the style of your code, whatever it has, you know, you have will have a great influence on how you write your new code. Very, you know, at least for me, I have a very bad habit of copy pasting the lock statement. So if you go to a new project, so it's already some code isn't there, something is working, so I want to add a lot. Sometimes I don't consciously think about, okay, I should write it, you know, by myself. So I just go, oh, there's a lock statement, just copy and put it here. It doesn't matter whether it's the best, you know, it was written the best thing, something could be improved. So it doesn't, you know, come to your mind consciously. And it's not easy to isolate problems. Something goes wrong. Of course, it's difficult. And scaling is difficult. Maybe instead of even saying it difficult, we can say expensive. Say, you know, one thing we forget is, you know, the load on the system is going to be different. So say if it's a ticket booking system, right? Say in that car. So just before, you know, there's a time, right, when the ticket booking opens. So just before that, all of us want to do, you know, go search for trains. Of course, you may not get a ticket in one single train. So search for different journeys, save all that, you know, have everything in place. So probably there could be a part of the system, you know, which does that. So there's no more load on that particular part of your system. And when the Tharkal booking opens, the time clicks, everybody wants to book the ticket, you know, do their payments. So probably there could be different parts of the system, you know, where the load is really high. So if you have one single application, which caters to different business capabilities, the only way for you to, you know, you know, to do that load is like run multiple instances of your entire application. Does this sound similar to any of your problems, some of these, most of these options? Yeah, or is it something not related to what you have been facing? So the whole point is going towards, okay, don't think, you know, monolith, like don't think in one single large system, but think about, you know, a small fine grained architecture. So like, you know, some question might come to your mind, like, okay, I already have a system, everything is working, everything is good. And if a change comes, I have a standard procedure. If I do a change in one part of my system, I know what is the impact on the other parts of my system, so I'm better off. But the thing is like, kind of, it reminds me of what Nicola was saying in the morning in the keynote at this, like kind of, you know, IT doesn't matter, that's what people thought, but actually now IT does matter. So as a business, you know, previously it was more like being online was just being an avenue there, but now, like, if you don't have a digital footprint, if not you, somebody else is going to do it. Could be a competitor, it could be a startup, like whoever it is, somebody else is going to, you know, eat your cake, okay. So what kind of, you're coming towards more fine-grained and microservices and architecture, so if you have to ask, you know, how do you define microservices, like, there are lots of definitions, so different ways, you know, different people, you know, different terms, but if you look at it, you know, end of the day, fundamentally everything, you know, delivers the same, you know, fundamental logic. So one thing I like the most is like how Sam Newman describes it, small, autonomous services that really work together. So we'll just do a quick deep dive and understand, you know, what it means exactly. So what is small? It's pretty straightforward, right? Something small, not big, but in this case, technically, what is small? Okay, I don't want to think as one single system, I want to break it down. So where do I start? How do I break it down? So whenever someone says break it down, layer, probably one thing we are very familiar with is MVC pattern, right? So none of us, like, could have escaped from that MVC pattern. So a layer for database and an application and a model view and all that. So maybe that's one way of thinking about it. But actually what happens if you do that way, right? Like, you have a layer and you do a lot of, you know, responsibilities for every layer. So if you have to do one small change, get it to production, you have to change in all three layers. Probably these three layers might be owned by different teams. Basically, all that you're doing is cutting across everything. Again, you know, test everything together and deploy everything together. So actually it doesn't, you know, deliver all that you want to do is get things into customer hands really quick, but that doesn't really help. And everything moves together, right? Any change you do, anything you do, everything like moves together and you have to deploy it together. And so where do I start? How do I draw those boundaries? So one way to think about is like, what's the domain? So basically what is the problem I'm trying to solve? So in case of microservices, it's not a cookie cutter technology. It's nothing like, if you're a bank, these are the services you should be having. If you are a real estate company, okay, these are the 10 set of services you should be doing. There's nothing like that. Even if you're a bank, even if you're a real estate, whatever business you are doing, right? Probably your goal might be totally different from the other person's goal. So just don't go buy a cookie cutter thing as, okay, these are the things I need. But rather look at your domain, basically go and talk to the business people. Basically it's more like a common thing. So what is that I want to do in the near term, long term? What's my business? So think about that domain term and try and identify probably, these are the services you should be doing. If you're trying to solve this one in one way, and this is clearly a good topic. So if I go down this path, if I change 10 different services, since I asked those fundamental questions, I'm trying to map it back related to your domain. So that will help you to give an idea about where do I start. Okay, maybe the one, anti-pattern I want to talk about microservices when you actually think about this boundaries is, just don't go buy reuse. You know reuse eventually will come, reuse eventually will happen. But actually when you start thinking about a new solution in terms of services, or if you have a monolith application and you're thinking about, can I break it down into more fine-grained services, just don't go buy reuse. Probably that, at least in my experience, it made things much more worse. So just go buy what is that I want to solve and then eventually reuse will happen. And then the other thing we spoke already heads to different language. So it's much easier to try out different language, things like, and the other common thing is, if you have two different services talking to one single data store, again, that's kind of tight coupling. A general good practice is identify what the data is, which service should eventually own the data, and if somebody else needs that data, actually talk through the service. So don't have multiple services going and talking to one single data store. Eventually what you're doing is you're exposing, data store internally is how things are implemented. So when you expose that to five different services, basically you're exposing your internal details. So tomorrow if there's a change, it's going to be really difficult to get it into place. And one thing I really like is go. Nice language, really fast and efficient. And it gives an opportunity to try out different models of working. I'll not go too much into this, but things like ITN business, working together, kind of Spotify models, and the thought process more like, think in terms of product, like you build it and you own it, not more like a project where you start and you end it once you deploy it to prediction. That's more like, it's a product. So until you have a life in business for that particular idea, you also have a life for that in IT. So it's where I just want to talk about reuse, that's one thing I want to highlight it. So if we come back here, okay, this is our definition we spoke. Small, autonomous services that really work well together. So in this case, when we say small, so it doesn't go by a measure, it doesn't go by lines of core, but the small, all that it means is more lightweight. So just one service solving one single business capability. And autonomous services, so it's ability to live on its own. So it's basically an ability to evolve independently. So right from conception to prediction. So if I have an idea, okay, I'll go and talk about it. Okay, so feasible, what are the things I need? Okay, I get into implementation, test it, and then go ahead and deploy it. So you should be able to do this flow end to end by itself without much disruption in your other components in your ecosystem. And this last part, right, that works well together. So actually that sounds very simple. It sounds as if, okay, everything should work well together, but actually that's where the end to your complexity comes in. So we'll have an idea, start something small. You know, we have been doing, you know, S-O-A kind of, S-O-A and microservices are like, kind of similar, it depends on, you know, what you define S-O-A as. But the complexity comes in when you say, okay, that has to work well together. So, you know, most of our, you know, the next 60 minutes kind of, you're going to focus on, you know, how to make it, you know, work well together. What are the different options? What are the different challenges there? If you have read, like, Sam has written a book on microservices, like building microservices. That's really all, you know, good books. If you've, you know, read his book or if you've listened to any of his talks, like kind of, he'll never have missed this in a hexagon-shaped representation. He's a big fan of, you know, showing a service as a hexagon. So, at the very first glance, it looks as if everything, you know, fits really nice together. So if I have to do a change, it's really easy to do and, you know, it's nice and everything. But actually, you know, all these are the attributes of a monolith in our application. So if you have one single application, it's easy to do a change, it's easy to get it into production. But actually, if you have multiple moving paths, if you have to do a small change, actually, it gets more complex. Okay, so now we have an idea. Okay, I may go and do it in terms of services. So the next thing I want to do is deploy it. But even before I go ahead to deploy, I should have a confidence to deploy it. So what are the things, like, what does really change in testing perspective compared to a single application and having multiple services? So I have multiple things. So if I have to test, if I have to tell my system is working, so everything should work fine. So end-of-grade comes to how my services are integrated. So there are multiple ways to do it. So one of the most common patterns we see, at least in large enterprises is having an ESB or an integration layer enterprise service spot. Nothing wrong in doing it, like till the point if we keep it only for the sake of communication. So if I use the bus only for the services to talk to each other, then it's pretty straightforward. Everything else is there in my service. But the moment I start adding more intelligence into this integration layer, like, kind of intelligent forwarding, you know, a lot of data transformation, you know, and things like that, so that's where it gets more complex. So the moment we add it, without having this ESB in place, I'll not be able to test any of these components. So general good practices kind of have all the intelligence, everything, whatever you want to do, logic, filtering, checking, whatever it is, retain all that within your service and then ensure whenever you talk between your services, that's more like just dumb, very simple, maybe like pretty basic HTTP protocols. That's more than enough for, you know, majority of our needs. And in this case, even in this case, I'd say, if I have to test it, so one thing comes to mind is, okay, if I have to test my system, I need nine different services. Okay, I'll spin up all nine different services. I'll identify your integration test environment. I'll identify, okay, this is the version of each of the services. I'll spin up all my services and I'll ensure I get all the tests that are in there and I'll get my very first pass of integration testing. So whenever I did that, right, so whenever I see a green build on my pipeline in the integration test, like, okay, I'll feel so happy because it's not so easy to, you know, get that in place. But, you know, this happiness will not, you know, last forever, you know, it's not, it's not go for long because it's very difficult to keep your integration test up to date. Ensure all the services you have the required version in place and all that. So what can I do? Can I really test my entire system, my services without, you know, running everything? So one way of doing it is like using consumer driven contract. So what do we do if we talk to, you know, a third party application or external component, right? How do we test it? What do we, like simple thing, in unit testing, it's an external call, what do we do? Submit, mock it. So we assume that, you know, the other entity is not there. So even in this case, start of similar, can I test one service, you know, without having the other servers in place? So it's, you know, the way mock works is like, basically you have some assumptions in place. Okay, this is how I'll talk to you. And if I talk to you in this manner, this is what I expect you to give me. So it's basically a set of assumptions, you know, between two components. So it's something similar here. If you have a service which is a provider is giving you some information, an API, a contract. And you have a service which talks to this and consumes that information. So you have some, you know, assumptions between these two. And if you see that, the assumption will be there somewhere hidden inside the code in your service which consumes it. Okay, I get an XML, I get an JSON, this is the format, this is how I pass it, this is what, I know, these are the attributes feels I'll get it. The kinds of it, it's hidden somewhere inside the code in your consumer, right? So what if we take it out of the code and expose it? So have it like a contract. So I have a mock. Instead of talking to the service directly, I'll have a mock. I'll just talk to the mock. Hey, if I go, okay, I'll ask, okay, tell me your name. If that's a service, okay, what's the name? Okay, so instead of going and talking to the service directly and asking it, right, probably I'll have a mock. And I'll say, okay, if I go and ask this question, this is the answer I expect. So go and do your testing against your mock and then you record your expectations and then you do your testing, you know, against your mock and you are done there. And at a later point in time, even when the other service is not working. So it's a part of maybe, you know, build pipeline of the server, their service. You take those recorded expectations and then you basically, you know, go and replay them again and say, okay, this is the, you know, request I give and this is the response I'll be expecting. So me going and talking to you face directly and checking it, probably I'll have a mock service. I'll tell, okay, this is my request and response. This is my expectation and let the mock and go and do it when the service is available. And again, you have a service and you have 10 different consumers. Probably different consumers will have different expectations. The first one will read on 10, all 10 fields. The second one, I don't really bother about 10. I just want two fields. The third one will be very specific about ID. Okay, ID should be numeric because I do some numeric calculation based on the field you give me. So a lot of different expectations from different consumers, right? So basically how all this recorded and then come back and play it again when the service is available. So basically, you know, when you, whenever you build your service, you know, test this and then check your, verify your expectations. There are a lot of, there are a few open source tools which will help us to do this, you know, consumer driven contract testing. The one thing I've used a lot is PAC. It's an open source and has very good support for, you know, it's like to basically start with Ruby, but it has good support for, you know, JVM languages.net and I think for some extent JavaScript. Even when we say contract, how many of you have used SOAP or WSDL? A lot of us, yeah. Say one, that is more like a contract, right? So you say, okay, this is my contract, but the only difference we see is there. You'll have the contract always defined by the provider. Always I'll give you this. It doesn't matter whether you read it or not read it, whether you need it. Okay, this is my contract. Okay, you know, stick to it. So just slightly, you know, shift in that. Instead of, you know, telling a provider saying this is my contract, but as a consumer say, okay, this is what I need. I mean, even if we see practically right, it's a consumer which knows better about what data I need. Provider is just a means of, you know, getting it out of some data store or whatever it is. Okay, we started with a large monolith system and we know, okay, probably going fine-grained might be, you know, a better option. Okay, so if I go fine-grained, testing will be challenging. Okay, I have some idea about what are the additional things I need to do. And the next thing I want to do is going ahead and deploying it. So deploying it, it's not going to be a one single component. You take it and put it somewhere, but you're going to have multiple components. Okay, for having this services, right? Like, you know, even two years back, we used to have dedicated servers. So now we have VMs on cloud. So even if you go down this path, if you have one single application, say you're going to have a dedicated, isolated, operating environment for that application. So previously, you know, I still remember even the server name from my very first project, like 497, 498, used to be our production service. Whatever happens, we'll get deployed only there. But at least it's not the case anymore. So it has an isolated operating environment. So you have at least a VM or a server for database, a server for, you know, web app. So you're dedicated environments. So what happens if I try and deploy multiple components there? So I have microservices. I cannot afford to have a server, you know, for every service, maybe. So I have to deploy multiple things in there. So what happens if we go down this way of deployment? So the dependencies, they get into one single host, probably that could be conflicting. So if everything is Java, probably you know, you have a different minor version. Someone might be still in Java 6 for some reason, and somebody else wants to move ahead on Java 8. And say something goes wrong in my server. So if I get an alert, how do I know who cost it? There are three different components here. So how do I know how easy or difficult it is to diagnose? You know, what's the root cross of my problem? Or even if something goes wrong in my server, so how do I know what will be the impact of that on all the components inside that? That's always better. It's much easier to have an isolated operating environment for a service. And in an ideal world, like kind of, you know, if you talk to, you know, operation folks who are completely responsible for the deployment, right? So one thing they would love to have is, whatever unit you deploy, that unit to be considered like a black box. It doesn't matter what you implement inside that, what language you use, how you do it. But whenever you give me something to deploy, I just want to take it and deploy it. So if you get to that state, probably that will make their life much easier. And all that I want to, you know, bother is what is being exposed. From there, how do I talk to this unit? Kind of whenever you say isolated environment, does that like sound familiar to something? Like how many of you are using VMs here? For some, you know, there were, yeah. A lot of us are using, right? Like, so what does VM give us? So we wanted to have, so why did you start using VMs? Yeah. So it's like easy to deploy, so repeatable standard environment. Yeah, it doesn't have a dependency on, you know, where you run it, your hardware. And even things like, if I want, yeah, much faster. Yeah, yeah, it's a lot of things. So kind of fundamentally, those are the things, you know, we want whenever you go down in a deploying multiple units. So one thing is like having VMs. So what happens if you don't have a VM? If I try and say, I have, say, mission hardware and I have an OS, just a piece of software specialized. And I deploy two different things. I get all my dependencies here. Everything is conflicting in one single environment, right? So what if I go down this path? So I have a VM. So I just have a layer of Hypervisor here. So Hypervisor, it's nothing but just, you know, a piece of, another piece of software there, depending on which vendor you're using. And it will just abstract your hardware from your operating system, right? And here I can run multiple VMs on a single hardware. I get that isolation. So here if I run my applications, so I have the isolated environment for my service one, and I have two different environments for service two. So even if I use Java, so I use Java six and Java eight. So six gets here, eight gets here, it doesn't matter, everything, you know, these two will coexist. But the only difference is like, problems is like, how many VMs can you run on a server, on your dev mission? Depends on memory, yeah? So if it's like a typical mission, say 16 GB RAM and, you know, fightability, like, how many can we run? Three or four, max, thousand. So I was like doing my demo as a VM, so like, hardly I can run three or four. If I go beyond that, like, everything counts. So the main reason is because of this layer of hypervisor. So everything has to go through this and that every call inside my application, any process inside this, you know, VM, has to go through this layer of hypervisor and this hypervisor is like really expensive and it's very slow. So for that reason, it's limited. I can run only, you know, limited number of, you know, VMs on a given hardware resource and it's, again, like, it's going to be slow. If you have to spin up a VM, of course, it takes a couple of minutes, right? So what's the other option? Is there anyone here who has never heard about Docker? Okay, we have few. So like, so the other way of thinking about it is like kind of running things as a container. So it's similar to VMs, so it's like another different way of, you know, running things is like running it as a container. Maybe you'll understand more about it, you know, in the next few slides. And here again, you start with a mission, you have some hardware where you're going to run it and you're going to have, you know, particularly we need a Linux based operating system. So we'll see, you know, why you need a Linux based operating system if you have to run, you know, containers. And in this particular talk, we're just going to pick Docker. So Docker doesn't mean container, Docker is just one way of doing it. So just keep that in mind, but that's the most popular way of doing it. So you run Docker in this and if you have a Docker running, you'll be able to spin up containers, very similar to VMs. You can spin up multiple containers on a given hardware resource and these containers are going to have isolated operating environment. In the sense, if I run something here or if I copy something here, that will not be visible to, you know, any other containers even running on the same mission. And again, similar to, you know, VMs, it's portable, again a set of files, you have means to kind of, you know, if you create a container on your dev mission, you'll be able to create something similar on your higher environment. So how does it work? So VMs, we know, we have an idea. We have been using it for a few years. We know how we get that isolation. So how do we get that level of isolation in case of containers? So these are the three, you know, basic fundamental logic it uses to give us that kind of isolation. So it uses, you know, combination of three group namespaces and copy on write storage. And these are the, you know, you know, things we get it from the Linux kernel. And that is the reason why we say that, okay, containers, as of now, can run only on Linux based operating system because these are the functionality which you get from the core Linux based kernel OS. So only using these fundamentals, you get that level of isolation. So what are they? How does it work? We are not going to get into, you know, depth of it. So, you know, even if you have to go back and do a spike using Docker, you know, you don't even have to know any of these things. But it's always good to know, you know, fundamentally, you know, how it works. So what is the group? So it's a feature in Linux kernel, which will help you to, you know, allocate, okay, for this particular set of process, you can use only this much amount of resources. So the resources could be, you know, things like your, you know, CPU, your process, your memory, whatever, you know, other resources you need. And how does it work? So it has a tree hierarchy structure maintained. So for every resource, say, for a memory, I have a tree hierarchy structure. For, you know, CPU, I have a tree hierarchy structure. And inside that, I have information about all my process IDs. So very first process, bit one, you know, in it, in it process. So when you start the process, by default, it will sit in the default group. So this is my group for memory. So by default, when you start my bit one, it's going to sit in the default group. So I have whatever, you know, limitations I put for this group will be applicable here. So I keep, you know, start more process. So everything falls under, you know, the default group. And here I can go ahead and create new groups. So I can say, okay, inside, I don't want, you know, whatever limitations you have here. I want new set of rules. So you go ahead and create new group and you can define your own rules. Say probably this is something very critical. So I want to allocate, you know, more, you know, CPU for this. And you know, this is something which will have a lot of IO. So probably I'll allocate, you know, more resources for that, something like that. So here I can create a new group and any process inside this will, you know, get new set of rules. So that's up to you to define, you know, how you want to do it. And the next is namespaces. So it's similar to C group. Again, you have a group of process, but in case of C group, it tells you how much resource you can use. But in case of namespaces, you say, what is all that I can see? So fundamentally it gives a very, you know, a limited view of my underlying operating system. And that is how you can have multiple containers coexisting on a single machine and also get a level of isolation between them. So it's basically whatever, you know, features we got from the layer of hypervisor. That's how we got that isolation in case of VMs. And in case of, you know, container, every time you create a new container, it creates a new namespaces for all the inner sources there. And the resources could be, you know, a process, network, mount, user. So every container will have its own namespaces. Basically a very limited view. I can see only this much if I'm inside a container, whereas in the host, in a lot of other things exist. But in a container, I can see only this particular table. Container two, I can see only what's happening in this table two, something like that. Similar to that, internally it has a representation of, you know, three hierarchy where I have a group of processes. This set of process can see only this much. So for example, if you say, you know, process, right, like this is my host mission. So I sat in my pit one, I have multiple other processes. So what happens if I go ahead and start a container? So the moment you start a container, say if you're using Docker and starting a container. So internally what it does is it creates a namespace, particularly just for that container for all the resources. So I have my own view of process. I have my own view of, you know, an amount. I have my own, you know, view of networks. So even container will have pit one. And this is pit one only within container. So the moment it escapes out of container or if someone is looking at this process outside the container, it has a different ID. So it has just privileged only within the scope of the container. And I can go ahead and create multiple containers and every container is going to have, you know, its own pit one. Have some idea, like, is it going too much over their head, just have a lunch? Yeah. Do we need a break? A minute? No? Okay. So the third thing, third concept. So we spoke about C Group and we spoke about namespaces and we told that containers are really, really fast compared to VMs. So how is it fast? How does it work? So it makes you so something called a copy on store, you know, right storage. So if you think about a container, right? So it is portable. So we said if you create a container or a dev machine you can create exactly similar in other environments. How can it create based on a template? So what's your template? The Docker image. So what's an image? Image is nothing but a layer of read-only, you know, files. So I can define, you know, how to create what's there in my image. Say for example, if you take an image it's a layer of files. So when you start creating an image either you can start it from the scratch or I can start it based on a different image. So probably you can pull, you know, if it starts based on a different image it pulls all the layers from that one. And it's like a step-by-step process. Every step corresponds to a layer here. So I can define some metadata who, you know, maintains it and I can install some software. So this is the Nginx container. So I say install Nginx. So it installs something. You can see that it occupies, you know, some space and some of the metadata I post for it and you tell how you start it. So all these layers are basically, you know, read-only layers. So what happens if you want to start 10 instances of Nginx container? They can start 10 containers based on the same image. If the image is same, underlying layers are same. It's a read-only. So it's never going to differ across 10 containers. So all 10 containers will inherently, you know, use exactly the same sort of layers. So that's how, you know, you see, I know, really, you know, big difference in the startup time between a VM and a container. So every time you add a step it just creates a new layer, writes on top of it. Even if you modify, if you add a file here say XYZ, you added a file and then you thought about something. You modify your content. What happens? It pulls that file, puts it on this layer and then puts the content here again. So every layer, once you write it, it's just a read-only. And the moment you start a container based on an image, all the containers are going to reuse all my underlying kernel. So the kernel is same. So it uses the combination of, you know, C groups and namespaces. That's how you get that isolation. So all the containers will reuse my underlying kernel. And the moment I start a container I'll get a very thin, you know, basically a writable layer on top of it. And this layer will exist only till the container is running. So I can start a container. Okay, I get a writable layer. That's my file system. So all the processes, all the files, whatever I do with the container is going to sit in here. So the moment I stop the container, you know, this is gone. And there's something tricky, just keep in mind it will come back again, you know, later. Okay. So we know about copy and write storage. This is a typical, you know, slide. If you go to any Docker or no one intro, you know, you'll not miss this. They've had to run multiple copies of VM, exactly the same application. The only way I can do this, okay, copy the whole thing. So the libraries are exactly the same. Nothing has changed here. But even then I need to copy everything because everything is within that VM. But in case of containers, so everything is exactly same. All the layers are reused. If something has changed, just a layer, you know, I have five layers, only the six layers changed. You know, for this one, you get only the six layers. So everything else is basically reused. Quick recap. So it uses the functionality whatever we get from the Linux kernel. So combination of C group, namespaces and copy and write storage. That's how you get that isolation, you know, between containers. Okay. So I had a large system. I can think in terms of services. I'll have more challenges around testing. I need to take care of all that before I can put things in production. Okay. I need to have a better means of deploying things. So one way of thinking about this, one option is thinking in terms of containers. So what's the workflow? So if I go with Docker, so what's going to be my Dev workflow? So you write something, do a check-in. So you have a CI server. So what do I do from there? So every server, you know, needs to have something called a Docker file or you need to have some means of defining how do you create that image? And based on the instructions from the Docker file, you're going to create an image and you're going to do all your testing. So you'll run a container based on that image, run your test and you know, do whatever you, you know, unit test or integration or whatever it is. And end of that, what's going to be your deployment, you know, unit artifact is going to be a Docker image. So in your case, like what's the artifact you create? Like it could be a jar file, AR file, you know, RPMs, something like that. So in this case, you're going to create a Docker image. And of course, you need to store it because only then you can run similar ones somewhere else. So either you can, you know, use it in registry or you know, some artifact storage somewhere. And then the moment you want to run it, okay, deploy it in QA, deploy it in prediction, you go ahead and pull that image based on the image, start how many of our containers you need. Okay, so one guiding principle of Docker, if you talk to anyone who's like a core active contributor in Docker, it's an open source project, right? So if you talk to anyone, like one thing they'll emphasis again and again, developers and operations are equally important. So if you look at that, like VMs, right? Kind of why, you know, why the VM started, it's mostly, you know, I want to optimize my hardware. So it basically started from the other end of the spectrum. It's mostly driven by the, you know, ops guys. Maybe that's why we don't have, you know, very good tooling around it. If I have to create a VM, right? To create that image, it's not that easy. But in this case, kind of, you know, dev and operations are equally important. The thing is like, kind of, that's the fundamental for them. The kind of, you know, you should have that message when you do it. So it's like, whenever you want to do a do a spike, you want to go down this path, ensure you involve both devs and ops, you know, in your decision before you take any decision. Okay, going down this container path, it makes life easier a bit for both. Kind of, I get more freedom. So I can use whatever language I need, whatever crap I need inside this box, because the crap is not going to get on, you know, the same host mission. And then, as an ops guy, okay, all your crap is inside. Okay, now let me take care of my, you know, headache. So what are the things I need? So something goes wrong. What are, what is all that I need? So I need logging, I need monitoring. How do I get to it? How do I put things? How do I deploy things? Stuff like that. So basically, you know, trade off a balance of freedom plus a balance of few things to be standardized. And other thing usually they say is like, kind of, it's good to have like one process per container. Maybe that's, you know, in an ideal world, at least the way I read it, I understand is like one service per container. So try not to put too many things in one container, like don't put your database, you know, your app, everything in one container. Again, you'll end up with the same sort of problems what you had before. So it's like, think in terms of like one service per container. Okay. So now I have an idea about Docker. I mean container and Docker. Okay, maybe I'll go and do a spike. Okay, I'll have my app up and running as a container. Next thing I want to deploy in prediction. So is there something else I have to do before I deploy in prediction? So service discovery. So once you have multiple moving things here and there, right? Of course, there are somebody else, you know, who are dependent on it. Say how multiple services. Previously you had like a client server architecture. So you had a client, you had a server, service or server, like all that you wanted to know was the client should know where the service is. So it's pretty simple, just one thing you need to figure out. But once you have multiple services, okay, I need to talk to X, X needs to talk to Y, Y needs to talk to Z. So you see that chain of movements. So basically you need to have some means to, you know, how do I know where that particular service is running? So simple things like say shipping service. So you have a pool of VMs or you start something in, you know, a cloud. So it's just start somewhere. The mission will get some identity, basically some IP address. And I have, you know, intelligent logic. So something happens immediately, that's moved to a different server. And we spoke about, you know, sales, T20, let's not forget it, it's coming. So I have three and okay, it's a peak. I have five different services running. So someone wants to talk to shipping service at this point in time. I need to know the identity of all these five instances. So it could be IP address or port or whatever I need to communicate with this service. And again, of course I'm going to scale down and I come back to one service. And this is a server I had shipping service running before. So it has an IP address. But now I have something else running here. So how do I ensure, you know, it's more dynamic. So it cannot be a static configuration file somewhere. I write, okay, this is a server, this is a service. But it's going to change, you know, more rapidly, more dynamic, right? So if you have three instances, I need to ensure the load is balanced across all three. How many of you remember your, you know, production server name? Quite a few years now, okay. Maybe we, you know, probably if I ask this question next year, probably, you know, the number of hands might go down, hopefully. So we used to have, right? You know, you treat it like a pet, you know, you remember your static server. But now kind of, okay, we are going more dynamic. So it makes your discovery, you know, even more difficult. And again, if you go down that path, probably, you know, you'll be doing more of an immutable deployment. So you do a change, you want to deploy it, okay? You just spin up a new instance of it. How does internet work? Just the end of the slide, nothing else. You don't know the magic in that. So the whole internet is working using DNS. You're just talking about some services, you know, six, seven, eight services. You know, can you not just use DNS and, you know, make it working? DNS, right, the main problem is like, it has invented when, I don't know, maybe 70s, 80s, that they're for many years. So then, like, kind of, it was more static. Even if you take the port right, like we used to have a port number. If someone tells me my SQL server, I never, you know, ask them what port. I just know, okay, this is the default port. But now if someone is telling me, you know, it's a shipping service, someone is giving me IP address, okay, what's the port? They ask that question, right? So it's like more dynamic. So it's like, if you're just having DNS records, you know, just A records, especially you're just going to get IP address. And if you need to think, tell things like, you know, what's the life of it, how it's going to change, you have to define TTLs. Probably there are mainstream and defined TTLs, but you don't have a lot of things which will actually, you know, respect that TTL. So I feel this is something which is still evolving. I don't know if we have a real good solution for this. Though we have a lot of tools, maybe we've just started to, you know, solve this problem. Maybe we'll have, you know, even better tools in the near future. So it's like a lot of open source combination. So okay, what's there in DNS? It's like an entry. So you tell, this is my service and this is my identity. So I need to have something similar to that. So I need to have something like a registry. So I mean, just go, don't go by this list. This is not very exhaustive. I just picked based on, you know, what I used or what's my favorite. So it's like a lot of options. So you need to have some kind of registry. So a lot of, you know, key value pair tools, more, you know, highly available, you know, reliable, which in turn will run as a cluster and all that. So you need to have some kind of registry where you can store, you know, just a key value, you know, key value pair. This is my service. This is the identity for that service. And based on that, probably, you know, you'll have some means to generate some configuration and that configuration may be, you know, given as input to some kind of reverse proxy. I really like having reverse proxy for a lot of different reasons. Like you can do a lot of different things with reverse proxy, right? Do I or is this a termination, you know, but a load balancing, you know? Yeah. Yeah, like a lot of us are using it. So it's like not something new. So it's like, yeah, something like this or something changes. It's easy to, you know, generate the configuration for your, you know, reverse proxy, right? Okay. I must put the wrong button. Yeah, so you have a registry. So you, we started with having a registry. I need to have a key value pair. I need that information in there. So if I run as a container, if I start a new container, the container is going to get an IP address. If we start a container, probably it might get a different IP address. So who will feed in that information to my registry? How will I get all that information to my registry? So you can, you know, have some tools which will actually listen to, you know, events from Docker. So when I was something like this happens, Docker, you know, basically tells, hey, something like this happens, like, you know, emits an event. So basically you can, you know, make use of this event and then, you know, build on top of it. So you have a lot of tools, you know, which will actually keep listening to this event and if something happens, say, you start a new container, you get an event. So based on that event, you can go back and say, hey, I know that you started a new container. Okay, give me more information about the container. So this is a container, this is the IP address and this is the port. These are the different ports being exposed from this container and whatever method that you added to it. So more labels, health checks, so whatever you needed, whatever you say, okay, these are the additional information. So you get all that here and then you can go back and, you know, write it in wherever you store it. So there are different tools to do that. So the one is Registrator, which will help you to go back and, you know, put that information in these, you know, key value two, you know, tools we spoke about and the other one is Interlock. I think Interlock, you know, you can even directly generate the configuration, you know, from there and you have some place where you store it and you can have templates, like console templates, like a lot of options today. Keep listening to it. Whenever something changes, you come back and update my configuration, right? So there's like one way of doing it. So this is not the only solution. So I have n number of tools, even if you go back and look at that set of tools, right? There's no one single, you know, thing that's okay, these are the subsets. They can use a different combination of those tools. Personally, I feel like it will be even much better if you have, you know, enter your service, you know, discoverability or thing, you know, when you actually, you know, orchestrate your services, you tell where you deploy it. The one who deploys it will know much better about where it has deployed. How will that be? How can I communicate with that service? Okay, so it looks something like this. I had one single large box. I just had to carry heavy lifted, take it up and put it somewhere. But now it's more like multiple things, every small, small containers, but I'll have multiple containers. So you'll have, you know, need, you know, better logic to say, you know, where, you know, that you get deployed. So it might be something like this, like six AM, not many users. At least I don't get up so early. So I just have one instance of each. And then you have some sale period, something, you know, automatically, you see that your load is going up. Automatically, your system, you know, ensures that more instances are up and running and it might, you know, come down again. So these components might have to be deployed somewhere. So someone has to manage your cluster. Someone has to define, okay, where we'll get deployed. It cannot happen. Like if you scale it to three instances, you cannot deploy all three in a single mission. That's again a single point of failure. The lots of tools here, I, I don't, if you are just starting with services, you just want to playing with the Docker. You just want to put one service. Probably you may not need it on day one. And eventually, once you start scaling your services, you go beyond a point. Because you need, you know, something or other, you know, from this line. So a lot of choices here, like Docker spam, that's the default one you get from Docker. So it, you know, talks the basic Docker API. And I don't know, personally, I feel it's both good and bad. And you have like, you know, Mesos and that's your scheduler platform. And you can use that along with, you know, other, you know, layers for orchestration. It supports spam as well. So you can use a combination of Mesos and spam. Or you can use, you know, Mesos and Marathon or Kubernetes. Kubernetes is again, it's like a very big giant for me. Running Kubernetes itself is a big thing. So if you really don't have scale of, you know, that high level, probably going down this path might be an overkill. Okay. How fun it will be. Okay. Hey, I have something working in Docker. Okay. You get super excited, put in prediction. Everything is going fine. And you go tell your friend, you know, your teammates, okay, somebody else does something similar. So, you know, in a very short period of time, you have three different services running as, you know, three different services running in prediction. But you never really thought about much about logging. This gets much tricky, you know, when you are running something as a Docker container. So if you remember, you know, the way Docker, you know, container works, say it has a read-only layer and the file system comes into place only when you start a container and say, assume that everything is running fine and something happened, something is screwed up, something is buggy. And your container is gone. And you want to debug that particular container. You go, you're familiar. Oh, you have Docker logs. Okay. You go and say, Docker logs, nothing will come up because the container is already gone and the logs are also gone along with it. So if you don't take care of your logging, if you don't do anything, then it's going to be a nightmare. And please keep in mind logging is not something which will kick in after you put things in prediction. This is something which you have to do before you get anything to prediction. So typical, this is something very common, right? This is not even very specific to Docker or container. So when there are multiple things, of course, you don't want everyone to have access to production boxes. You don't want to go and look at the logs there. You need some kind of, you know, aggregation of your logs. And, you know, some means to, you know, ship them to a central place. And maybe logs are for two different reasons again, according to me, for both systems and humans. So ensure you cater to both. Again, lots of tools in here. And plunk is something where you get everything. If you have a lot of money, you can use it. So 20 log stash, basically something which will help you to collect all the logs, aggregate it and ship it somewhere. And especially with the Docker container, right? The way Docker does is like, it captures all the information from your standard out, you know, standard error, and it just writes to a file. And that file sits in the Docker container file system. And Docker container file system is a premural. It lives only till the life of that container. The moment you lose that container, the file system is gone, file system is gone, your logs are gone. So ensure you get it out of your containers. How can I get it out? So put some, you know, magic logic, nice logic in your application, which will help you get it out. Probably there's not something you want to do. You don't want to go and do that in every application. Run a file container, collector inside a container, maybe okay to start, but again, remember, one service per container, basically, you know, one logic, one thing per container. So of course you don't want to run a collector in every container. So other thing you can do is run a collector as a container. So you have a collector, actively it will go and collect all the logs and get you. It's very similar to how you did that registration, right? You know when a new container was started. So very similar to that. You know when the new containers are started. Okay, I'll go collect all the logs from all the new ones and ship it to a central point. And you can even run a log collector as a container and write it somewhere forward. Like lots of different options. You can even, you know, use your existing option like kind of, most of your applications will write to log files, right? So you can, you know, even continue the same style. Just ensure that file is exposed as a volume. Just ensure it's outside your containers, you know, available somewhere. Is that enough? Is that enough talking about logging? Is there something else coming to mind? Especially if you have services, if you have multiple calls, yeah? Probably say if you have like a hundred different users using your app within five minutes for one user it went wrong. And Christian, yeah, like a lot of things you can do but maybe the one I was thinking about is correlation IDs. Is there something you're familiar? Have you heard about correlation IDs? Yeah? So it's like, it's a very simple thing. It's nothing new, nothing, you know, fundamentally different. So I need some unique way of tracking my transaction end to end. If you have one single system, you'll have one single entry point. So user A, B, C came in. This is what happened to that user. But once you have multiple services, so I have 10 different calls. So the user came here and it went through a long flow. So what happened across this journey? So I need some easy means of tracking it. So one way of doing it is like a very simple user ID, some unique ID. It could be your own, I mean, if you have a transaction, you have a unique ID, just put that ID, log it, if it is okay, or just generate a unique UID and just put it there. And if you have to be a really good sophisticated, you can even add every ID for, you know, every part of your cascading calls. And if you look at this log, especially with multiple services, right, it'll never be a single, you know, flat line. That's like, if you do a mental map, I call here, I go from here, you know, it happens here, you know, two calls from here and all that. It's basically, you know, hierarchy of things. So there are tools that will actually help you to visualize this. But only thing is like, only tool I have played with is like Zipkin, that's Scala-based one. And this is something that Dapper has saw from Google. It's just a concept which will tell you, you know, how it works in a distributed system. It works really well, especially for the synchronous calls. So it's like, if someone is aware of any language, agnostic tools, just let me know. And probably one thing I want to do it is like, monitoring, right? So you've heard about, you build it, you own it. You know, your thing, you take care of it. You have your own, you know, it's more towards like having an end-to-end functional, you know, a team which will take care of a product rather than you build something and put it across the wall. It's somebody else's problem. So if you have to, you know, make your life easier, you should have some things to monitor it. And this gets even, you know, if you have one single application, I have a binary state. I can say that my application is up or I can say my app is down. But in services, right? So what happens? I have, say, nine different services. I, one is gone. So I have eight different services working in perfect conditions. And still I'm able to serve my users. So now do I say my app is up or down? It's actually up. Again, that depends on your business. Say, you know, a conference, you go to your website. So there are different things in Agilent website now. I can go back and see, you know, what's the, you know, photos from 2015, schedule for 2015. That's not working now. That's not really that big thing. You know, until unless you get scheduled for today, you are more than happy, something like that. So you decide what, you know, critical, what you want for your business. And the moment you might get a point where you can say, okay, beyond this point, you know, I don't have any sensible service, so I can say my system is down. And again, similar to logging and sure, you know, you collect whatever metrics you need. So that could be something like a health check-in point. So we have to say our service is up or down. It doesn't go by just whether the service is running or not. It's more like, you know, can I serve that functionality or not? So give that, you know, basically, you know, functionality to the service. So let the service define, you know, whether it's healthy or not, how to find out whether I'm working or not. And it doesn't matter whether you run a container or a VM, however you run it, ensure you get some stats, basic stats out of it. So Docker, you can say Docker stat, pretty much you get most of the, you know, information you need. And some monitoring tool on, you know, maybe some alert on the counter. Okay, so maybe just do a quick demo. We'll go to our application and then come back to this. One second, just putting my browser in the back row. Yeah, okay. I just want to do a, you know, take a simple app and show you some of the concept. You're not getting to the details of how you break it down, you know, which I learned over different projects. Something slightly different in terms of, you know, the world of services compared to having one single app. So whatever we spoke in monitoring, right, like where you'd be told, or for particular services down, you know, my entire system may not be down. So like, you know, serve some functionality to the users. That doesn't come for free. So if you design your application in a similar way, like how you did in terms of, you know, monolith or single application, probably you may not get it for free. So you need to ensure that your logic, your design is put in place, which will identify what's critical. When do I say I'm down? When do I say I'm up? And there are a lot of different patterns there, like, you know, have you heard about circuit breaker patterns? Where you say that, okay, you know, you have a cascading service calls and you call a service and by measure, you know that this is going to be the average response time for my service. It takes about 10 seconds. For some reason it's taking 15 seconds, 20 seconds. So consequently for few number of calls, so consequently for few calls, you know, it takes more than 20 seconds. Then I know that probably something is wrong. So I should not send more requests to it and bombard it and, you know, totally, you know, collapse it down. Probably I'll, you know, break my circuit. I'll not send any more for the, you know, calls to that particular service. Let it recover. Probably, you know, it might recover on its own if your system is really good or probably something went wrong and your, you know, orchestration, you know, it got a red alert, the health check went red. So automatically, you know, it started a new instance and it's up and running. Then everything is good. You get a green health check and then you start sending your traffic to care. So at least for the end user, right? Like, okay, if I'm doing, so if I'm trying to book it to care, okay, something went wrong at the last, you know, downstream. So if we have to go there, you may have a timeout. Say you may have a timeout of, say, 60 seconds. Say something went wrong. I didn't know that something is not working, but if you don't break this flow, if you keep sending more requests, probably as an end user, I need to wait for 60 seconds for me to know that your system is not working. Rather, I would be more than happy if you tell me, it's not working, come back again. I'll be, you know, it's more irritating, you know, like, you have to wait for a long and then know that it's not working. Okay, simple things like, you can see here, just a list of, you know, say albums, I have some information in here and then I see that, some ratings in here and, okay, maybe for some particular reason, I don't see the ratings for two different albums. So it's like, okay, I can live with it. So at least my business, like, I'm serving something. But you need to ensure that, you know, you take care of these functionalities when you actually design your services. And coming to the pipelines. So in this example, I have an application, like I have a shop app. So and this shop, say, application is talking to two different services. So it's talking to, you know, review service for me to get the review ratings. And it is talking to catalog service for me to get, you know, the catalog information. So basically the list of albums, right? So the moment someone is telling you that they're doing SVA or they're doing microservices, first thing is have a look at the pipeline. So you need to have a linear flow of your services. So end to end. So for any service I pick, I should be able to independently get it from a single source of truth, a single source code only for this particular service. And I should be able to build it independently, test it, package, however you packaging it. Go ahead, I should be able to deploy it up to production and on its own. If you see anything like a funnel, shape things right where you start with multiple services, but the moment you want to deploy it, everything comes together. Everybody has to coordinate. Everything goes together and as a one single bundle. For me, that's not microservices. Basically you don't get any value there. Because all that you wanted to do is, if you remember the very first thing, okay, ability for us to deploy more frequently, do things more faster. So if you have everything as a one single funnel, deploy everything together, that actually defeats the purpose of, you know, why have to invest so much and do it. Shop app is consuming my review service, right? So I have shop app application and I have my review. Review provides me all the review ratings. So shop app basically, you know, runtime it comes to talk to my review service, get the review ratings. So how do I test this? So I have a contract between these two services. So I'm using fact here and I'm doing a CDC testing. And you can see here if I see, they open this stage. So here I say, is that readable? Should I increase it a little bit? More space, yeah. So this is my review service and I have different stages. So I have a source code particularly only for my review service. So I build it, I do some unit testing and I do some consumer testing. Probably this is, you know, slightly before my, you know, end-to-end or integration test in case if you have it. So what does it look like? So if you look at that particular, you know, the locks for that stage, if you just read this bit, which I'm going to highlight there. Okay, I'll read it out. So here it says that, okay, I'm testing something and that's basically I'm doing a request. I'm doing a get for star ratings for this particular album and I get a response and the status is 200 and I get some JSON output and it has a matching body. So when it says matching body, it is up to you to define, you know, how things are going to work. So you can say, I need 10 different fields. You can say, I need my very first, you know, field to be an ID and you can say, okay, very first field and the value should be numeric and in a second field should be name. It has to be a string. So you as a consumer, what you expect from the provider, put that into a contract. So if you have multiple different consumers, if they have different expectations, let them define their own expectations so that will be totally different and this is a part of the pipeline, you know, of my provider service. So every time I do a change, so I run this test, so I know that if I change something, I'm not going to break any of my consumers. So that gives a better confidence for me to deploy my changes. So in case if something goes down, so I give something, I'll have a contract. So something breaks down. So because each consumer has its own contract, I know which consumer broke down and whenever something like this breaks down in, you know, integration, just don't jump on fixing it. Just that's more like a point of collaboration. So you go and check with them why it broke. So if it happens like every time you change a particular consumer is breaking, then probably your boundaries are wrong. See, I remember we spoke about service boundaries. Where do I start? What is my service? So what's, you know, how do I say my service is too small or too big? So what's the correct fit size? So things like this when you start doing it, so that will give you kind of clues and guidelines as whether your boundaries are correct or not. So if something is, if a consumer is breaking every time you change it, it means more tight couple. So probably it should live as one service rather than as two different entities. And if you look at this contract, right? This is a simple JSON file. I'm using, in this example, I'm using pack. And if you look at this like, okay, I define my expectation. So here I say HTTP get. This is the endpoint I want to test. And, you know, some input, say I'm passing an ID, correlation ID in my header. And this is the album ID I want to test. And what are the things I need to verify? I am expecting a HTTP response status 200. And then I'm expecting an output of JSON. And probably it returns a large JSON, but I'm interested in only this part where I need an ID and I need a link. And I'm expecting a star rating and a numeric value. So that's one thing. And then we spoke a lot about service discovery. So in this example, I'm using console. So I'm using a combination of, you know, Registrator plus console and Nginx as the reverse proxy. So every time I start a new container, say I start a new review service, I start a new catalog service. So the Registrator is already running as a container. So it knows that a new service has started. Automatically it will get that information and put it on console. So console also has a nice UI interface where you can just see, you know, the different information. It could also be used as, you know, a pre-value pair tool, you know, not necessarily only for, you know, discovery. Okay, here I see a big list of, you know, services already running. And, okay, this is my service name. And if I look at this service, I can see, you know, health check and points. So I have a particular, in a specific health check implemented for a service. So I define, you know, how do I say, when do I say, how do I say review is good? You know, how do I say, you know, catalog service is good. So I have my own health check and points I know to find. So you can see, you can also tell, you know, put that health check endpoint to console. So it keeps polling that, you know, endpoint. The moment it goes down, automatically it removes the entry from console. So if some client or some service is trying to talk, it will not get an endpoint where it's not working. And for logging, so using, you know, lockstash and cabana dashboard. So it's good to have, you know, both, you know, some user interface where you can go to body locks and look at it and also ensure, you know, your system is, you know, the longest of all. Logists like, at least I've seen few examples where they don't use logs only for the sake of debugging. So it locks could be used for different purposes. Like you have like a lot of, you know, animated it a lot of, you know, valuable information on that. Probably that can act like, you know, a feedback to your monitoring tools. Probably that can act like a feedback for your, you know, new features, A-B testing, you know, how many users are actually using it? What's the trend? Like a lot of stuff you can do with it. Yeah. So like, you know, response time, like you can do a lot of fun things in this. So just using a cabana dashboard. So I get a nice interface, you know, get a, I can do inner queries. It's a losing base query. So it's like, you know, more flexible. So there we saw that in our app, right? We didn't have the ratings for two different albums. So if you just look at this log in the log stack, it's just a heap of information. So at least for me, you know, with my eyesight, I can't read anything of that. Like I can't make, you know, any sensible information in that. Like, so how do I do, where do I start? So in case if you have a correlation ID, say, you know that, you know, that this particular transaction did not work for this user or in this particular use case, and you pick that ID and you see that, you know, end to end what happened. From your interface, you see that in my shop app, application, I don't see a rating. So you go and look at the logs for the shop app application. All that it will tell us, I'm talking to review and I didn't get the ID. That's it. You're not get any more information as to why exactly you did not get that ID. So if you have a correlation ID, just makes it more easier to trace the transaction and see, you know, what exactly happened, you know, in the entire call. So in this case, you can see that, okay. The log from shop app tells you, you know, exception while fetching star ratings. So nothing else is useful. But if you look at the log information from review, you see that, okay, invalid star rating, it's giving a negative number. So it doesn't know how to put stars for negative numbers. So that's how it broke. So just like basic fundamentals, like I feel like things like logging, you know, monitoring, it's something which has to be thought upfront. You know, it's more intrusive. So you need to have an idea about how am I going to do it? So it's like just not about your application, right? It's about your entire ecosystem. So how am I going to get logs for my domain or for a suit of applications? It's never about one single app. So it's like, you know, just keep in mind, like these are all to be, you know, thought upfront before you start your first one in product. And monitoring, just using Prometheus. So Prometheus, like it's again an open source tool. It's from SoundCloud. So especially it fits well and world of containers. So it gets a lot of exporters. So you can get export your, you know, statistics and information from your host mission and from the containers and also from your specific to your application. So it's like you have a set of exporters. You decide like, what are the information I need to monitor? Get all that information, have some kind of a dashboard. It did not be super cool. Just start with something really simple, but you know, easier to use so that, you know, if I think about something useful, it could be a metric for, it could be an operation metric or it could be a business metric, right? So it could be a business, you know, thing like you put a new feature or you want to see your trend that's going up or down. So it's like, you know, simple things. Just ensure whatever tools you use, it's like easier for your teams to use it. And it was saying like kind of having alerts in place. Again, it's really good if you have these alerts tied up to the, you know, health checks of that particular service. So in this example, like running in a mini cluster, somebody is using two VMs and, you know, running these services between these two VMs using Docker spam and a certain, you know, alert like, okay, at the minimum, I should be running three instances of services. So the moment it goes down, you know, below three automatically, you know, creates an alert and that, you know, gets a notification. So it's like simple example, like, just think what you need, you know, for your systems to work, what kind of feedback you need, you know, from your system, just ensure you get it up there, you know, more proactive. And maybe alert dashboard. Just want to like close with, you know, just two minutes on, you know, basic principles. So once you go down this microservices path, you'll have multiple teams who own services. You may not have a one single architecture, you know, one single team who will take all the, you know, technical decisions on then, you know, spread it out to all the teams. You have your own teams, they own their things. You know, a lot of, you have more decision points. So what are the, you know, guiding factors, like few simple things to keep in mind, you know, things like model it around your business domain, so that, you know, if you have that in mind, you'll get more stable APIs and a culture of automation, that's pretty straightforward. So if you don't have an automation in place, if you don't have pipelines in place, please don't go down the services path. And hiding implementation details, like how tightly coupled are they, even things like talking to the same data store, how do I talk, you know, it's like what's the protocol I use and decentralized things, like things like, you know, having an ESB, so nothing wrong in having an ESB, like even if you have a message, it's like just use it for the right purpose, ability to deploy independently. So it should not happen like a one single, you know, correlation and then you, I mean, aggregate and deploy as one single unit. Customer first, that's an interesting one. So for the services, right? So customer is just not the business. So customers are also other services, other teams who are going to use your services, who are going to consume your services. So ensure, you know, you know, if I take this decision, will it make life, you know, easier for them or more difficult for them, even things like having a simple documentation, tell what are the different APIs available, isolating failure and highly observable, like something, if you read it, you see it, you understand. So that should be the guiding side for your service. Especially if you have documentation, that kind of in one of my recent projects, like kind of, we have been doing the services style for almost two, more than two years. And then we thought, okay, why not expose a set of public APIs? Probably, you know, other can integrate towards maybe, just not for monetization, but maybe, you know, get more people interested in this, like giving some information. But like then we realize, okay, I have no idea about these services I have in my domain. So where do I start? So maybe having, you know, even a lot of tools like Swagger, which help you to, you know, do it more easily. And very strong foundation on C. So if your team is not agile, if you're not working on iterations, if you're not delivering more frequently, if you don't have CD, if you don't have pipeline, don't go down Microsoft's path, that's a waste of investment, if you don't have these things in place. And again, some people might think, oh, it's only for Netflix, it's only for Amazon, it's only for large enterprises. They are technology company. I'm a bank, you know, I'm a real estate, I'm an insurance company, but actually it's not. So whatever we write today, it's going to get absolute. You know, actually happening more frequently, right? Even if you take Docker, it's like you get a major release every two months. So if I do a hands-on workshop, if we do something today, I cannot go and run it, you know, three months down the line, things are going to change. So if you don't do it, somebody else is going to do it. Which I like personally, building microservices and Docker in production. I quite like this. This doesn't tell you how you run the containers, doesn't tell you the commands. That's something easy to learn. Once you know Docker, go and search Docker 101, you will get a lot of examples. You'll get a container up and running in five minutes. Like that's something really simple. But things like this understanding, your cases, where do I use? You know, what are the things I need to take care of? You know, how is it going to have an impact on my underlying architecture? Should I think something different, operation concerns? So it talks a lot about that. And of course, domain driven design. I think this is like kind of an evergreen. And maybe other interesting, like just a small thing. ThoughtWorks, we also publish our technology radar. So we do it like once every few months. So every time I read it, I learn something new. Or I see something contradictory or something useful. Maybe if you're technically interested, that's another source of information. I think we have a few minutes. Yeah, maybe questions? Yeah. So if you're not getting any dock, then you'll not get lost. That's more like an server-infra-oriented error. But like kind of, if you have anything like, you know, 200 and you know, other than 500, like you'll, okay, yeah. You know, a few things like having some aggregated lock. So at least you know that, okay, if you have three, four different service calls, you know that it was fine until the third service. And something went wrong, only the fourth one. So at least you'll narrow down the problem and you can focus only on the fourth one. So the problem could be both infrastructure-related. Yeah, the problem could be two things, right? Either it could be related to infrastructure or it could be something to do with your application logic. So, I mean, this debugging actually doesn't change really so much between a single system and services. The only thing is like, okay, the two different modes of failure. Either my communications can go wrong. So here if you are able to isolate your problems to a particular service, instead of looking at, I have 10 different services, I know where it went wrong. If you can narrow it down to, okay, it went wrong in my six servers. So again, it's like a one single application. So it's very similar to having a monolith. So you narrow it down to six applications and you can focus only on that. And then you can go on to three major, usually, you know, three broad reasons, either your communications file. So when you make a call to fix the communications file or something went wrong in your infrastructure or something went wrong with your service. It changed something in one service. So how do you know until you deploy it? How do you know that something has been changed? So it's like, you will obviously find it somewhere. Of course, you cannot find it in your compile time. You cannot find it if it is sitting on your dev mission. But the moment you check in, the moment it's running on your CI server, so you basically generate a new contract. So now you're, so if you mean to say you're public APIs, you're talking to public APIs. So you'll have more control over contracts at the border point, only if you own border services. But if something is like going wrong with your, I mean, if you're talking to completely a third party application, the only way to test is have an integration test between these two components. So contract, you can do it only both the components are under your control. So it's like the example is more like a public API. Say I'm talking to, you know, AWS API, something changed within it. You own both the services. You can test it using contracts. But if you're talking to an external third party thing, which you do not have control, then you need to have some integration test in place. Yeah, so if your integration test is filing, then you know that, okay, something is broken, something has changed. That means you come to know about the problems before you go and deploy it. That will be the set of problem, right? The problem will still be same, even if you don't have a services, even if it's a single app, if you're talking to a third party API, it'll still be the same. It's more like a Yolli feedback. Yes. Yeah. Yeah. That way, I don't have to change the subject. Yeah. If it's a set of requirements, then we're going to do, you know, virtual and then. So it's too much overwhelming. Where do I start? Is there some, you know, so we spoke about a lot of things, but if you're doing your very first service, very first application or services, or very first thing as a Docker container, you don't need to deploy just one, two, three and leave it there. Rather, depending on the load, I want it to go up or down. Only then you need, you know, all these things in place. Only then you need some kind of process. Yes. Okay. Only for the learning experience. I see that. So, because in this case, you're trying to stop your tech, having to be proud of your company, but then, as well as the products, it takes a week and a half of your time to do something that I can't see. Yes. There's no concept of switching out. Yeah. So now, if you, not that important, you are on a big environment, then the same opportunities to come, so you have the answer. Blocking now and I don't have the voice again and again, so I, or all the block it can do as well as block the same ways. Yeah. So, this came in the future, how do we switch on it? Which I want you to do the next step, come up with this, which is like, blogging can be done, it can be done with the companies that have come back, I know I know, maybe it's the way it's going to be done. What is the best thing about this game? I don't know. This... Because you're doing it as a container. So, even if you deploy directly your application on a Linux VM, so whatever capabilities you get, from that OS, you'll get exactly the same set of capabilities, even if you run as a container. Yes. Yeah. You get an entire, only thing is like, you don't have a complete, you still have an OS, even within a container. So I can, on a Red Heart, I can run Fedora, so you still have OS, but the underlying, when you make a system call, so when you try to use a driver, when you try to use your CPU, so instead of going through hypervisor, it just goes through my same kernel. Yeah, it has a kernel. Thank you.