 Thank you for coming to the container networking update talk. My name's Amelia Downs and I'm the anchor of the container networking team. And I'm Christian Ng, software engineer on the container networking team. And so today I'm going to give you a quick team introduction who we are, what we do. We're going to talk about two features that the container networking team has been working on over the past year, that's service discovery and dynamic egress policies. We'll go over where both of those features are now, where they're going in the future, and we're going to demo both of them live. And we'll talk about what's on the horizon in the future, what are we thinking about and planning for the next year or so. So just to give you an introduction to the container networking team, we have two PMs and five engineers. And if you ever want to get in contact with us, the best way is probably via the Cloud Foundry Slack, and you can find us on the container networking channel. So just to give you an introduction to our team and what we do, historically our container networking team has been in charge of enabling dynamic container to container networking between Cloud Foundry apps on Linux machines, enforcing policy between them and providing service discovery. And as you'll see in this talk, some of those things are changing and are growing as our team grows and our responsibilities grow. But first, I'll let Christian talk about the state of service discovery. All right. Thanks, Amelia. I guess we'll start here. So before I jump straight into service discovery, I kind of want to give some context on why we build service discovery and the state of the world before it. So you can imagine you have a front end app and a back end app, and you want your front end app to talk to your back end app. So the naive solution to this would be to provide your front end app with the IP of the back end app. And an easy way to do this would be to use some environment variable and pass it the IP. So here I'm providing my front end with the IP of the back end, 10, C5, 5, 1, 2. And then my front end starts curling the back end and life's good. But with Cloud Foundry, if your back end app were to restart, it would get a new IP because they're ephemeral, and you're not guaranteed to get the same IP every time. So then your curl stops working and your front end can no longer talk to your back end, which isn't great. So at this point, you would have to bring your own service discovery. A common one for Java applications would be Eureka. So you would CF push Eureka, give it some public route, and you would create a user-provided service. And at this point, you'd provide Eureka to your front end and your back end, restart the apps, and then your front end and your back end would start registering their IPs with Eureka, and then a little bit later, your front end and your back end would discover each other through Eureka. And your front end at that point could use Eureka's registry to start curling the back end. And if your back end were to restart and get a new IP, the back end would be registered with Eureka, it would get rediscovered by your front ends, and the curl would continue working. So basic service discovery, you're happy that it works. What's not great is that you have to maintain this whole extra application to provide service discovery for you. So we've built it into Cloud Foundry so that you don't have to maintain this extra app. So now at this point, if you had your front end and your back end, the workflow would be to CF map route, an internal route for your back end. So what this would look like is you would provide the application, an internal domain, which in our case would be apps.internal, and a host name. So now my back end has a back end.apps.internal route. And then I would provide my front end with the new internal route, back end.apps.internal, through my same environment variable. And my front end would start curling back end.apps.internal, which would resolve to that 10, 2, 5, 1, 3 address. And what's great about this solution is that it's DNS-based. So it's like a polyglot solution that would work for any language. And if your app were to restart and get a new IP, service discovery would see that and update the back end.apps.internal records to point to 10, 2, 5, 1, 4. And if you were to map multiple applications to back end.apps.internal or scale up your back end, the back end.apps.internal records would reflect that. And it would point to every IP, and it would shuffle between them to give you rudimentary load balancing. And now I'll try to demo this. So we'll see where this goes. So first thing I'll do is to push a front end. And let's copy this route, and we'll give it a minute. And if you want to try this yourself, I'm just using the CF Networking Examples repo on GitHub. So if you want to try it yourself, you can go find that. And I didn't scroll down, so that's my fault. So let's try to go front end, slouch, cdccfapp.com. So what you'll see here is a couple boxes. We're going to focus on the top one. So it's a pretty basic app. It's just going to let me type in a route to hit, which in my case, I'll want it to be back end.apps.internal. I'm going to use port 7,007. So you see, if I try to hit that right now, it doesn't exist. So you could see it's trying to look up back end.apps.internal, and I'm getting a no such host. So at this point, I'll probably want to push my back end up. So let's see how I push back end. And I don't actually want to expose it on the internet, so I'm going to specify no route. I'm making sure to scroll this time. All right, so I got my back end app up. You can see right now it has no route. So let me CF map route, specify back end, the app name, and apps.internal, and host name, which I'll call back end. So if I call CF apps again, you could see it now has a back end.apps.internal route. And if I were to refresh this page, so it still doesn't work, but it's no longer getting the no such host. It's getting a connection refused. So it's able to look up the application IP, but it's not able to connect to it. And that's because I haven't added a policy. So let me do that. CF network add policy. And this is going to be front end. And I want it to talk to my back end. And it's going to be protocol on TCP, port 7,007. And if I were to refresh this, you could see I'm now getting a catgif. So it's able to talk to my back end app, and it's sending me this picture of a cat. So that's service discovery in a nutshell. And if you want to deploy CF with service discovery, just know that it's generally available in CF deployment 3.4. And it's within an ops file in CF deployment, so you could add operations, enable service discovery.aml, and that will, by default, give you and apps on internal domain and provide you service discovery. OK, so sorry, I didn't quite catch that. Yeah, you'll get back any container IP for any application that's mapped to that route. Right, OK, so what's next for service discovery? So we want to start sending any traffic that's heading to an internal route through an Envoy sidecar. And if you were at the last talk, this will allow us to provide some client side enhancements, such as sophisticated load balancing, like weighted routing, retries, timeouts, and automatic TLS. And what this would kind of look like is if I were to open up these containers, right now you would only have application processes inside of the containers. We would be adding Envoy processes within those containers too. And if you were to curl back in dot apps on internal, it would get redirected to the Envoy, and then the Envoy would send that to whatever application it was heading to. And at this point, what this allows us is to do those retries, the load balancing, and the TLS at those Envoys. And now I'm going to hand it back to Amelia to talk about egress policies. Great, so before I talk too much about egress policies, I just want to define what they are. So egress policies enable networking from your app to outside of Cloud Foundry, so saying whether your app can access the whole internet, some part of the internet, or not. So by default in CF, there are no egress policies set, so your app is isolated and cannot access the internet. Currently, network admins can create egress policies through application security groups, or usually we call them ASGs, and they're on a per IP range basis. So for example, when you're staging your app, if it was a Ruby app, you might want access to RubyGems to bundle install, and so you could create your ASG that gives you access to RubyGems only, but not the rest of the internet. So if you've used ASGs, you might know that one of the big issues with them is that apps need to be restarted in order for these policies to apply. It's annoying and a hassle, and sometimes you can forget to do it, and so the policies that you see aren't actually applied on your apps. So this workflow would usually go something like this with ASGs. So first, the app dev pushes their app, app A, to a space. Then the app dev has to send this request to a security team asking for their space to access, let's say, for example, an external DB, and then they have to provide an IP, a port, and a protocol. The security team has to approve this request, and then the platform operator creates the ASG and binds it to the space, but like I said earlier, this isn't enough. The app dev actually has to restart their app in order for this ASG to actually apply. So this workflow can take a long time. It's a security workflow that differs based on companies, but what I want to focus on is the restarting, which is completely unnecessary, and is what we are planning on improving, or what we've been working on improving. So I would like to introduce dynamic egress policies. So dynamic egress policies are a new way to define egress policies for your CF apps. So they're built into the same policy system as the container-to-container policies. And crucially, no app restarts are required for new or updated policies to apply. So you might be saying, why are you building this new thing? And why not just improve ASGs? So this is a decision that we didn't take lightly. We eventually decided that the ASG system was not set up for automatic updates. Our engineering team decided it would take a long time to improve the ASGs to get it to the state rather than building it into the C2C policy program. And when we brought egress policies into the same C2C container-to-container policy system, now all of the networking policies are under one umbrella. So when we update one, we'll be able to update them both. And the idea is that we'll be able to iterate faster. So I wanted to talk about how ASGs and dynamic egress policies will interact. Crucially, we have no intention of deprecating ASGs anytime soon. They're not going away yet, maybe in the future. But we have no roadmap for that. And right now, the union of both policies will apply. So you can still set ASGs while you set dynamic egress policies. And they're both white-listing type policy systems. So the combination of the two is what your app will be allowed to talk to. OK. Now time for a live demo. And you get to see my VIM skills. Let's see. Yeah. OK, let's make. I need two windows. OK. And I hope they're big enough. I hate not being able to see. OK. So we have two CF apps from Christian's demo. So I'm going to do this example. I'm just going to CF SSH into the front-end app. And then I'm going to curl things from there to simulate calling something from your app. So right now, the way I have the ASGs and the dynamic policies set up, all my app can access is DNS. And it can't access anything else on the internet. So if I try to curl this, BBC RSS feed. Forgot an H. Thank you. We'll see that it doesn't work. The connection is refused here. So I want to make a dynamic egress policy to talk to BBC. So first, I'm going to dig BBC to get the IP address. I missed it. And it did change, so I'm glad I dug. OK. I'll put that into my paste buffer so I don't lose it. Great. And right now, while I do this, I'm going to add a watch here if I can spell. That's going to update every 0.2 seconds. And I'm going to curl BBC. So hopefully, while I add the policy on the bottom, you'll eventually be able to see this watch succeed. Thank you. You're a very helpful audience. That looks better. OK. So I have a script here that is going to create a destination. Right now, we only have APIs and no CLIs. So I named my destination BBS feed. I named it the wrong thing. But whatever, I'm not going to change it now. BBS is our internal whatever. OK. Don't worry. OK. So I'm going to change the start and the end IPs. Here we go. Let's paste in the correct IP. Did I pass it? It's open on a range of ports, and it's over TCP. Great. So I'm going to run this and create my destination. It was created. Now I'm going to grab this GUID from the destination. And first, you create a destination, and then you create the policy. So here on the policies, you say either an app or a space, and you pass it the GUID you want. We are going to have to replace that with a new app GUID and the destination, and you pass the GUID. So I'm going to paste in that GUID, and then let me control C, get my app GUID. So if I do CF front, oh, CF app, front end, GUID. Great. OK. The idea is now when I run this, the screen on the top should start curling successfully. Let's see. Oh, Christian. Don't know how to say it. Maybe the IP changed. No. I swear it worked earlier this morning. Let's try digging it again. No. I heard that. No, the IP changed on me. OK. One more time, Abilia. You got this. Destination. I need to name it something different because it needs to be unique. This is what happens. Create destination. Oh my god, it's going to be good. I promise. So I go into egress policy. All I have to do is change the destination GUID. C, E, T. OK. Need a curl again. Oh, I'm getting XML. Yay! OK. Now, if I take the same GUID for the policy and I run a delete command, the policy will be deleted. And you'll see here, now connections refused. It automatically applied. No restarts needed. OK. So if you would like to try these dynamics, let's just make this thing away. If you'd like to try dynamic egress policies, they're experimentally available in CF Networking Release 217, which should be available in CF deployment soon. You'll need to use this ops file to enable it. And we have docs on GitHub that you can find out how to use these APIs. So what's next for dynamic egress? We're working with teams in New York for Windows support. We're going to work on creating CLI command so you don't have to do all that GUID pasting that I was just doing. And of course, we're going to work on some performance testing so that we can get it out of experimental and into production. OK. So I'm quickly going to talk about what we're thinking about and what's on the horizon for container networking. So these are very fuzzy ideas at the moment. But I just wanted to bring them up to keep it in your mind. So first is declarative policies. So the idea is being able to specify policy within your app manifest so you could enact policy when you CF push and you don't have to CF push and then run some CLI commands to add policy. And the other thing we're thinking about is FQDN-based policy. So being able to use a fully qualified domain name as the destination of a policy. So just to give you an idea of what this possibly might look like, you would have your app manifest. There would be a new policies section. And you would possibly add the apps that you want to have talk to your application that you're pushing. But again, this is all fuzzy. We're still thinking about it. And what is the best way to do this? If you have any ideas, we'd love to hear it. And second is FQDN-based policy. And the idea here is that once we have envoys in the data path, since envoys work on layer seven and they have more context as to where routes are coming from, we'd be able to enforce policy at this level. Again, we'd love to hear your feedback on any of these features, new and old. And you could reach us on the Container Networking Channel and Slack on the CF Networking Release GitHub repository in person after this talk. And at the routing and networking office hours, that's happening in 10 minutes. And that's it. Thank you. Seems like he has a question. About the routing that you showed initially, and is it the internal routing? Is that something configurable by a manifest rather than actually having to map the route manually on an instance? I don't know if I caught the complete question, but were you asking if you could configure like the internal domain? Yeah, so to add the internal domain via manifest rather than having to actually call the CLI, use the CLI to map it onto your instance. Yeah, so that is configurable in CF deployment by default. We set it to apps on internal within the ops file, but you could either change that ops file to use some other internal domain or create a new ops file to change those properties. But you could change it via the manifest. So you're talking in terms of when you're deploying open-source CF. I'm talking in terms of when your CF push environment manifest for the app manifest itself. If you can create internal routes? Not necessarily create them, but map them onto your application. Yeah, perfect. Oh, sorry, yeah. You could do that, too. We built internal routes to use the exact same mechanisms as normal routes. So internal domains just have an extra flag on it, but they're treated just like normal domains in the CLIs and APIs. Yeah, and in the manifest. Yeah, in the manifest. Any other questions? Which Cloud 100 role do you need to give access to one of the apps when you were connecting the front end to the back end? So do you have to be admin? Yeah, so if your, I guess, CF operator enables app developers who are within the correct spaces to create policy, then the app developer can create the policies between apps. Otherwise, if that's off, then you would need network-right privileges. I also have one question. So this first lookout that you gave about being able to apply policies on CF push, isn't that a pure CLI topic? Well, they're working on features that the CLI is not going to read the manifest anymore. They're just going to send the manifest as a YAML file to the Cloud Controller, and then the Cloud Controller is going to do things with it. So it's not CLI anymore, and now we will probably be working with the CAPI team to work on this. Thank you. We'll be here in the office hours. Thank you. Thank you, Chris, Trinana.