 Deep below the surface of the cloud, there is a hidden world. One where applications run without fear of vendor longing. Roam freely. Logregators lurk. And Diego Moon Supreme. This is the journey to the center of the cloud foundry. Be yourself as Ed King and Alex Lay. Take you to the deepest, darkest corner. So yeah, thank you very much for joining us this morning. So my name is Alex Lay. I'm a product manager for Pivotal in London. I'm going to be one of the guides on your journey. And I'm Ed King. I work on the garden team also in London. So just to set expectations, that was our entire production budget for this talk completely gone. So, you know, stay if you want to. So this all started when we found this map. We're in the National History Museum in London. And we were just going through some old books. And it turned out we found a map that takes you right around the cloud foundry, going through the center of the cloud foundry. So you can see that we're going to be starting up in the top left at the CLI beach. And then we're going to be going past the UAA through the cloud controller across the CC bridge. We're going to check out Diego Island. Here there's a nice garden there. We're going to check also look at the router, the logator and the blob store. That will take us right back to the beach. So to start off our journey, we're going to be using the CLI. So what is the CLI? The command line interface. So this is the primary way that you interact with cloud foundry. And so it has the commands for both users and operators. And we're going to use this to guide our journey. And so you can see here that the CLI has a plugin interface as well. So you can extend the CLI with plugins. There's quite a good marketplace for these with community and cloud foundry repositories. So what do we first need to do on our journey? We first need to log in and authenticate with the system. And so you're going to see a lot of this from our talk. We're jumping up to the CLI to see what the user would be seeing as we're going through our journey. And so you can see here that we need to target our selected platform. And here we're just going to Pivotal's public cloud foundry. And then you need to authenticate. So there's two ways that you can do this, the username and password as usual, or you can use SSO. So we do this through a component called the user authentication, user account authentication service. And so this is the primary authentication system you'll see used across most cloud foundries. And the CLI receives the UA information from a component called the cloud controller, which we're going to take a look at next. And this performs kind of an OAuth dance. And so it's based on OAuth 2. And it came back on to LDAP, SCIM and OpenID. And this is actually built as a Spring MVC scalable web app. It's one of the only Java components left in Cloud Foundry at the moment. Quite rare. So let's just take a look at this workflow. It's quite straightforward. So we'll send a login request from the CLI to the cloud controller. We get back the UAA details of where to authenticate against. Then we can send an authorization request to the UAA. And we get back an access token. Right. So now we're authenticated. We really need an application. So we're going to be using a Spring music example app. And so you can see here it's a groovy application. We specify a manifest. It's pretty straightforward. And so we're going to be using this to guide us through our journey. So let's take a look. We want to have a manifest to describe what the application needs to look like when it's running in Cloud Foundry. So you can see we give it a name. We give it how much memory we need. And we also specify how many instances we want running. So in this case, we're saying we want three instances of our app running. And we're using this feature as well to have a random route so that we avoid collisions. Because we need a way to access our application. And so this is going to allow Cloud Foundry to find a unique name to run our app has. So now we need to get ready to push this into Cloud Foundry. So I guess everyone here must have run CF push, right? Yeah. Good. OK. So you're very familiar with this command. And so what we're going to be doing is when we run CF push, it creates a record in the Cloud Controller database. And the Cloud Controller will then keep track of your application and record the desired state. So let's take a look back at the map. So you can see we've gone through, got past the UAA. We're onto Cloud Controller, which is on Cappy Land. And so let's take a look at a bit more detail about the Cloud Controller. Cloud Controller. So this component is the core entry point. And it provides a set of RESTful APIs. These APIs are used by app developers and operators. And it's really a huge amount of endpoints. You can see that it's going under a big rewrite at the moment, going to a v3 API. The Cloud Controller also interfaces with your external services. And it uses a broker API specification to do this. So, right, next we need to get a way to access the application. So we need a route. So you can see here that Cloud Foundries Generators are nicely named random route. And so how does your application then get messages to it? So we use a Routing Release. This Routing Release contains a collection of components. You can see here we've got a Go Router and a TCP Router. So this supports HTTP and TCP Routing. And you can see on the right hand side we've got the route emitters. And these will be sending information to the routers to make them aware of your application. Go Router. Okay, so this component uses its... It offers HTTP routine for Cloud Foundry effectively. And it uses a component that you can see in the middle called NATs to advertise its availability. And so consumers have to put messages onto NATs to register with the Go Router periodically. Otherwise, the Go Router will prune it from its routing tables and then assume that your application is offline. And this stops people from getting errors when trying to reach your application. And it uses simple round robin load balancing. So next up we've got the TCP Router. So this is for TCP-based apps. You've given a reserved port and route on a shared domain. You can see that it actually uses HA proxy inside. And so this offers us a way to kind of move away from the NATs message bus and move towards a routine API. So the routine API is currently an experimental stage. And you can check it out. There's lots of good docs on the repo as well. But this uses the public subscribe model but over HTTP. So this allows us, like I said, to move away from NATs but works in the same way where stale routes are pruned from the routing tables. And so you can get started really easily by using this RTR client. You can see the link there at the bottom. So now we have our application registered with Cloud Foundry. We've got our route. But next we need to upload the files. So you can see here that we're uploading all of the files in the directory. And we're going to be passing these through to the Cloud Controller. So the Cloud Controller obviously needs somewhere to store these files. So in Cloud Foundry we normally attach a blob store. Dare you enter the blob store caverns. So yeah, this effectively is where we store all of your application files. And so it has three main concepts. You've got resources, app packages, and droplets. Resources are files that are uploaded to the Cloud Controller. And we track a unique SHA. You then have app packages. And these are unstage files that represent an application. And finally you have droplets. And this is a result of taking all of those files and getting them ready to run on Cloud Foundry. And so you might have seen a talk yesterday about the bit service. And so this is underway to kind of extract the blob store logic from the Cloud Controller. So let's take a look at what the kind of workflow is for uploading an app. So you can see to start with from the CLI, we will send a resource match request to the Cloud Controller. This will then go to the blob store and check for this unique SHAs. So what you're saying is you're sending a list of all the SHAs for your files and you get back your matches. And then based on the difference, you're going to be uploading the changed or new files to Cloud Controller. And this puts it into the blob store. So it's quite straightforward. So next up we need to start looking at how we're going to get our application because we've just pushed a raw source code. And so we need a way to turn this into something that runs in Cloud Foundry. And so you can see here from the CLI's perspective, you'll be seeing an output of this build packs, downloading build packs, downloading build packs. And so what is this you might think? So this is how we take your application code and build it into something that can run on the platform. So you can see here build packs really allow you to have a repeatable process for compiling and running your code on Cloud Foundry. It means the platform can worry about the operational concerns, especially on the underlying operating system, and you just get to focus on your code. So again, we have a three-step process for build packs. To start with, you have the detect phase. So Cloud Foundry will run every build pack's detect script until it finds a match. When it's found a matching build pack, it will then go through a compile phase where it grabs your dependencies, compiles them into an artifact and then the release phase is when it gets it ready to be extracted into a droplet, which we'll go into a bit more later. So here's an example of how we've, you know, running a Java app. And so you can see that we've been detected as Java and then we've downloaded the dependencies and packaged it up ready for extraction to run on Cloud Foundry. All right, thank you very much, Alex. Okay, so let's just briefly recap our journey so far. So far, we have created an app. We have created a route for that app, and we've also uploaded all of the source code into Cloud Foundry. So what happens next? Well, in order to answer that question, let's just take a step back and think about exactly what it is that Cloud Foundry is going to do when it receives our application pushes. And really, Cloud Foundry has two key responsibilities. The first responsibility is to take our application source code and compile that down into some artifact that can then be scheduled to run on the platform. And that's exactly the second responsibility. We need to take the output of that build, compile process, and actually schedule it to run and ensure that it continues to run until we tell it to stop. And then, of course, there are also all of the supplementary responsibilities, such as logging, metrics, et cetera, et cetera. So what exactly does this look like inside Cloud Foundry? Well, the first process, that compile process, is known as staging. And staging looks like this. First of all, we take our application source code. We then combine that together with a build pack, which, as Alex said, provides the runtime dependencies. And we compile that together into some artifact. But in order to actually do this, we need to have somewhere to actually run that compile step. We need to have a root file system or an operating system. And in Cloud Foundry terminology, this root file system is known as a stack. And every deployment of Cloud Foundry will come with a default stack. Typically, this tends to be Ubuntu, but it could just as easily as be something else as well. And so what happens is we create a container using that default stack as the root file system for this process. Once we've got these three components together, we then run the compile step and we output a droplet. So this is the immutable artifact that we can actually schedule to run on our Cloud Foundry platform. So what does that actually look like? Well, next up, we create ourselves another container. And this container is based on the exact same stack that we used to actually compile the artifact in the first place. This is how we can guarantee that it's going to run successfully and how it has all of its dependencies available. So we create a new container, and we simply copy the droplet into the container. And we say, start, start running. And this is really, really nice because we've got a very, very clear separation here between the developers who are responsible for creating the source code and the droplet and the operators who are responsible for the underlying file system. It's a very clear contract. And this approach to running your applications is really nice because it means that things like scaling is also very, very easy. Here is a typical scale command in Cloud Foundry. The minus i there means scale it up to eight instances. What does this look like? Well, rather than creating one container, we create eight. And then all we need to do is copy our droplet onto each of those containers and tell them all to start. Very, very nice and simple model there. And I think that's one of the reasons that Cloud Foundry is really excelling at this, in the running the applications here. Okay, so we've got an idea of what exactly Cloud Foundry is trying to do when we push our applications. How exactly does it do this? And in order to answer that, we are going to need to cross over the CC bridge and into Diego Island. All hail Diego. Just making sure you're all still awake. Okay, so what is Diego? Well, Diego is the component of Cloud Foundry that actually provides that staging and runtime support. At its core, Diego is a scheduler. And it's able to schedule two types of workload, tasks and LRPs. And I'm going to touch on those in just a moment. But one of the other features Diego provides is it can take all of the incoming workload and optimally distribute it across a cluster of cell components. So a Diego task, this is a workload that is guaranteed to be run at most once. So this is perfectly suited to the staging process as we only really ever want that to happen once, or at least once per push of your code. Another example there might be a one-off database migration, for example. A Diego LRP, on the other hand, these stand for long-running processes. And this is what your applications are actually going to end up running as under in the Diego cluster. So Diego provides some additional features here. It is able to distribute the LRP instances across your cluster of cells. And this is nice because it means if we lose one of the cells for whatever reason, perhaps the virtual machine crashes or goes away, your application can still continue to run as other instances of the LRP will be distributed to other cells. And it also provides us with some fairly nice health checking. So if your application instance crashes for whatever reason, perhaps it runs out of memory, Diego can detect that and automatically restart it. Okay, so we now know what staging is and we know what Diego is. How exactly does Diego stage our applications? Well, first off, the Cloud Controller sends a request into the Stager. And the Stager sits there, listens for these requests and converts them into a Diego task. In this case, it's going to be a staging task. It then sends that off to a component called the BBS. The BBS stands for the Billet in Board Service. And this is really Diego's core orchestrator and sort of the central data store of our cluster. So the BBS receives this staging task and it persists it to its database. This is currently backed by EtsyD. So at this point, Diego knows that there is a staging task that it needs to perform. But it doesn't know where it can actually perform that. So we have an entire cluster of cells available to us at the moment, any one of which might be suitable for running this workload. How do we determine which cells to send it to? Well, in order to solve this, Diego kicks off an auction process. So the BBS will go and send out a request to the auctioneer. And the auctioneer is in constant communication with the cluster of cells via a component called the Rep, which I think is the representative of this cell. And so the auctioneer says, okay, we have this staging task, one of you needs to go and perform it. And it asks all of the cells to make a bid on that workload. And the one with the highest bid is then assigned that workload. So once we've decided, the BBS sends off the request to the appropriate cell, at which point the executor will create us a garden container. And this is where the actual process gets executed. And I'm going to talk a little bit about garden in just a moment. But also worth mentioning here that the executor will also be streaming the standard out and the standard error of that process into a component called Metron, which Alex is going to talk about in just a moment as well. Okay. So at this point, the staging task is now complete. As I mentioned earlier, the output of that process is the droplet. So we now need to take that droplet and put it back in the Cloud Controller so that we can schedule it to run. And this is fairly simple. The executor simply sends off a request to the CC uploader, which is responsible for mediating that upload. Great. So that's responsibility number one done. We have now completed the staging process and we have this droplet, which we want to schedule to run in our cluster. How do we do that? Well, there is another component here called NSync. And NSync sits there listening for the desired app requests. And it will convert those into LRPs, which it will then send off to the BBS. So obviously we don't want our apps to run as a task because we want them to continue running until we tell them to stop. And then again, a very similar process happens where the BBS persists to the database, kicks off an auction, finds the cells it's actually going to run that application on, streams all the logs off to Metron. Another component worth mentioning here is the TPS. And this is responsible for providing the Cloud Controller with information about the currently running LRP instances. And it will also be monitoring activity for any crashes and reporting that information back to the Cloud Controller. Finally here, there's one last component, the Converger. And the Converger is responsible for ensuring that everything becomes eventually consistent. And it will take action to ensure that that is the case. So for example, if it detects that one of our LRP instances is missing, it can go and kick off another auction to ensure that we bring that back into focus. So that the desired state is always equal to the actual state. All right, perfect. So hopefully now I've described both of those processes, the staging and the running, and shown you how that actually works inside Diego. There's one other component that I'd like to talk about. And that is Garden. So full disclosure, I do work on the Garden team, so I'm going to be speaking very favorably about it. But I think with good reason, let me show you why. Welcome to the Garden. That's the last one, I promise. Okay, so Garden. Garden is Cloud Foundry's container technology. And the first question people tend to ask with regards to containers and Cloud Foundry is, can I run my Docker image in Cloud Foundry? And the answer is yes, absolutely you can. But as well as that, it allows us to run the build pack-based applications as I've just described. So what exactly does Garden look like? Well, at the top level, we have the Garden API. And the API provides the functions such as create container, destroy container, et cetera, et cetera. And that API is implemented by multiple and pluggable backends. And there are currently three main backends. Let's take a look at those. The first one is Garden Linux. As the name suggests, this is the Linux implementation of the Garden API. And this was essentially a rewrite of the Warden container technology, which was in use in previous versions of Cloud Foundry prior to Diego. And that's actually where the name Garden sort of originated, as we rewrote Warden in Go, and then it was Go Warden, which kind of sounds like Garden, I guess. Anyway, this is what's currently running in most production Cloud Foundry deployments. Next up, we have Garden Windows. So this brings along .NET and Windows support into Cloud Foundry. But perhaps most excitingly of all, we have Garden Run C. What is Run C? Run C is a project that's being worked on by the Open Container Initiative. So the Open Container Initiative is a body who are looking at defining standards around containers. And this is really, really exciting for a number of reasons. So first off, it means that the containers running inside Cloud Foundry are going to be running according to standards set by some independent body. The body is part of the Linux foundation, and so that's fairly nice. We have those standards there. It also means that the containers running in Cloud Foundry will be using the exact same code base as containers running with Docker. And this is great because it means that things like compatibility is going to be much better. And also with a lot more eyes on the code base, things like security issues are going to surface much quicker and be easier to fix as well. And so this is nearly ready. I think it's currently going through the Diego CI pipelines. Hopefully we will be able to ship it fairly soon. And once we do, this is going to replace Garden Linux as sort of the default backend for Cloud Foundry. Okay, so we've seen now our application is running in Cloud Foundry. And so from the outside, we need to access the application. So let's take a look at the workflow here. So we first send a request in, and that will end up hitting the Go router. While the Go router is working out what to do is continually being updated by the router meter of where to find that application. So you can see here we've got two Diego cells. And then so the router needs to know where to forward this request onto. So once it gets the information from the router meter continually, it will be looking to forward this request first. The first request will go to cell one. The second request will go to cell two. So this is just a nice straightforward workflow, very similar for TCP routing as well. So awesome apps running, but we want to really see what's happening because Cloud Foundry can be a bit of a black box. You know, you've just pushed your code, and now you've got your app running in a container, you know, deep nested inside Diego. So to do this from the outside, we can use CF logs. So you can see here we've issued a logs command and we're connected and tailing any logs that get emitted from our application. So this is awesome. It's almost like a live stream of information coming from your app, really useful for debugging. And so how is this being achieved? So Ed mentioned earlier, we have a component called Loggigator. And this is comprised of two main concepts. So we've got Dopplers, and Dopplers are there for collecting all of this information, and then we have the traffic controller, which is used to push this information. So there's a few concepts in here that you might have seen throughout the presentation. So the sources, in this case, will be your application. The Metron agents are what is going to be connecting to Doppler and sending your logs and metrics and events. You then have the traffic controller, which kind of collects this information and produces what's called a fire hose. This fire hose can then be connected to and it's a massive information that's coming out of Cloud Foundry. And so this is one of the components that's under the most stress in the system, because you can imagine you have thousands of applications running, and loads of system components all emitting information to this one component set. So you can see this has some real scalability challenges. So let's take a look at how do we collect these logs. So you have the Diego cells running the Metron agents. So you could be emitting out logs or metrics. Metrics are normally from the system components. These are then collected and pushed into traffic controller, and then traffic controller creates the fire hose. So now from the CLI, how do we see these logs? Because the logs have flowed through the system and they ended up at traffic controller. So we send a request for application details and we get back everything we need to be able to connect to the traffic controller. So we send off a request to the traffic controller, which is using web sockets. So you can see here we hit up an endpoint that's like slash tail and then you pass your app good. And then so you establish your web socket connection. And then you get back at logs. Okay, so that kind of concludes our journey. We just recap. We've touched on UAA, Cloud Controller. We visited Caffeyland, crossed the CC bridge, kind of looked at the staging and running processes in Cloud Foundry. Had a walk through the garden. And then we came back out looking at the router and logigator. So I guess thanks for joining us. Cheers.