.NET Containers advancements in .NET 8 | .NET Conf 2023

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] okay so we just heard about like cost savings and maybe they wanted to know about security hardening hardening so that's like basically what this talk is about so this is about container advancements and done at 8 I'm rich Lander I work on done at runtime and our d at container images and this is Chad husk hi I'm Chad husk I'm the PM for the net SDK and Ms build and this cool containers Fe that we're going to learn more about today yeah definitely and so um this talk is uh uh focused on a repo that we already created called container Workshop so almost everything we're going to talk about is in this repo so if you like take your you know your phone um that's a QR code and you can actually get to the repo on GitHub okay so let's uh we just got a few slides before we move to demos um so we've been producing container images now for almost 10 years um and uh so we've heard feedback from you know customers and users throughout that whole time and the things that they've been asking us for basically you know this six or seven points they want images to be as small as possible because registry pull is often part of startup they want the images to be as secure as possible that can include nonroot no shell no package manager uh we get a lot of feedback about compliance so that's like scanning cves that kind of thing um some of our when we ship our images they only have a specific set of dependencies in them customers want it to be easy to add new dependencies um we've shipped Alpine for many years that's kind of our small uh offering that uses the muel libc library which doesn't work for all code um so if you need GBC then you've had to use our larger container images and then last um customers often want to know that they're working with a supported operating system uh so we kind of got this provocative statement here which is that um we think the general purpose container images are not the future of cloud apps so up until now that's actually what we've been shipping is general purpose container images that really have a lot of components into them in them and so we're going to one of the things we're going to talk about today is what uh more constrained more sort of chiseled uh container images would look like okay so back to the size conversation um and and we're using auntu as the example here um and these are all compressed image sizes so if you sort of do nothing um you'll get the the image size on the left so this is for you know relatively small application uh so you do Docker build you'll get the image on the left and as you kind of like progressively move down um you get all the way to the image on the right and you can see that it's like 90% smaller than than the the largest one there this is actually all the same app and it's just little little configuration changes you can make and we're actually going to show this in the demo so these are the kind of quote unquote normal container images that we ship and you can see that continuing to use auntu as the example and these are all compressed sizes um we start with a buntu as 28 megabytes and then we kind of add all these layers on top um and then certainly for asp.net then you get about 90 megabytes compressed before you build your app on STK is kind of a different thing because you don't host that in prod um oh and the the thing I forgot to show on that slide is the user uh unless you do something special is the root user so that root user can do anything in that container image uh we've been talking about this chiseled offering that we've um developed with our friends at canonical um and so this is actually quite different so here we've stripped um the Linux image to be as small as possible in fact there is no auntu layer anymore the the um we basically have a small set of Linux components that's what's in those runtime depths that's what's in those the runtime depths layer or image we're down to like 5.6 megabytes if you look at the previous slide that was 46 megabytes we've reduced a ton of size um and there's basically nothing extra here so you don't have to worry about getting cves in components you're not even using so and you see here that we ship with another user called app and so all of these images are rootless last um before we get to the demos um you can see here that we also have a native aot offering uh you've probably heard about that in a bunch of other talks and we actually have some um aot specific runtime depths image you can see that those are pretty small the runtime depths image on the left at 5.6 megabytes and then we have an actual app native aot app this is and so that container image in total is under 20 megabytes is really impressive we also have customers that care a ton about globalization so like ICU TZ data um and so we actually have produced another image uh for those users that want that so it's as small as possible while still giving you all those globalization libraries um so we hope people enjoy using that okay enough about the theory so let's move on to some demos yeah so Chad you know I just kind of you know showed all these fancy charts and everything I think you should you know show show the people what this actually looks like let's walk through it I'm I'm really excited for this so uh one of the big uh themes you were trying to drive home there I think was was size so let's interactively start with sort of the default for net applications and work our way down definitely what I've got here is a very simple uh C program um that just emits to to the output the current operating system we're on and the current architecture we're on this is a very standard CSR here uh we've got all of the same normal um standard net 8 Flags here implicit usings nullable uh enhancements All That Jazz we're targeting net 8 and we've added one piece of customization here we've got this package reference to the net build containers package so I've got this app I think this app is awesome I want to go deploy it somewhere that uh uses containers as the unit of deployment right and I just saw the package reference version there was 8.0.1 100 so that means that package actually just shipped yesterday yeah hot off the presses okay wow so let's containerize this thing yeah so we're going to need that to make that a little bit we are going to need that bigger how about that so um we can actually containerize an application just with the net CLI uh for those of you that have some experience uh containerizing applications you may be familiar with Docker files and the docker CLI that's not necessary forn net we can we can help get some of that boiler plate out of the way and it's super fast right so there's no Docker file you know peel underneath the covers there's no there's no Docker file there I can't show you something because it's not there right so I'm guessing what happened is you downloaded that that image there that's that's listed runtime 80 yeah um you brought it to this local machine and then you built the app put that on top shoved it on top of that thing and then we basically have a new container image and that's it that's exactly right um there are a couple sort of key points to to dig into there and one of those is what base image you should run with this is where the SDK can really help out uh the SDK knows information about your project it knows if you're a web application or a console application or if you've opted into some of our new deployment mechanisms like trimming or aot and based on all of that information it can choose the best image for you in this case because we're a console application we've chosen the runtime image and because we're targeting net 8 we've chosen the 8.0 tag for that so this is our sort of default framework dependent deployment I expect this image to be pretty big let's go take a look at it this is hello. net latest oh that's the wrong one want list and you want Docker image yeah yeah it's been a long day already yeah so this is 193 megabytes so not not crazy but also a bit big yeah and it's not exactly the kind of thing you'd want to to be doing a lot of in production where you're often build on like Network IO for this so let's let's see if we can shrink that down a little bit let's start with our app first because that's the thing we can control uh most easily uh We've invested inet in this concept of trimming your application right which is a process by which the tooling can inspect the code that you wrote and find all the code that it references and remove everything else right so by doing that we've now switched to self-contained exactly yeah so we should see a couple things happen as a result of this publish here with the same command based on the changes we made to our project we should see it optimizing our assemblies for size and we should see it um becoming architecture and Os specific as a result we also see it the SDK choosing a different base image for us whereas before we were based on top of the runtime image which includes all of the runtime bits and their entirety now we just need those same pieces you were talking about earlier that include things like TZ data and ICU right because if we were still using the runtime we'd actually have two copies of the runtime and in this image which would not be all that helpful yeah it defeats the purpose a little bit so let's take a look at this image instead and I've called it latest still so we can look at it again we went from 196 Megs to 144 megabytes so basically 50 meg reduction yeah and that's just all the pieces of the runtime that we didn't use okay so that's all focused in our application let's see if we can Target maybe the b os yeah it's like oh can we do better um so you mentioned these chiseled images before yeah I'm very I'm very enthusiastic about those let's see what it takes so you can actually opt into these very easily with the net SDK tooling we have this concept called container family which is a single property you can set that tells the SDK sure detect the runtime depths image detect the runtime image but use this chiseled variant of it instead right so Jammy here means um auntu 2204 which was its code name is Jamie jellyfish um so you're basically saying give me a particular version of auntu 2204 and I would like the chiseled variant yep and I'm going to build now with that I'm going to also do us all a favor and give this one a slightly different name using the container image tag property so that we can do a little compar and contrast right so every time we're making this CH this time we're um downloading a different base image and then still putting the app on top yeah so you can see how that container family prop fed into the base image selection here so the SDK kind of knows the scheme it's like you know interpolated string blah blah blah exactly probably literally is using interpolated strings why wouldn't you so with just that change from the full Ubuntu Jammy image to the chiseled one we went from what was it I think 144 megabytes to 36.3 okay so I'm I'm hearing here chiseled provides quite a bit of value it does but there are tradeoffs right we should talk about those for for a second so when you've got a a sort of standard um dockerized application that uses our runtime images or another full featured OS as its base image you can actually hop into those images and general purpose right that's what we started with at the at the top yeah general purpose um so what that means is you can do things like this ENT point in bash you can jump into that container and poke around right you can look at the files that were deployed you can do things like install Diagnostics tools you can mess around with that Con well let's let's let's actually run the command sure oh right we can't which because of another aspect of the SDK containers that we'll talk about in a second Yeah we actually forgot about this again when we practicing so these um these general purpose containers have um shells on them if we try this same flow oh you you missed you missed the key part so go back into it you forgot one thing oh wrong thing um right here type who am I oh yeah why did that all happen why could we not touch the file it's because we're not root we're app right so how did that happen well uh this was in a partnership with the runtime team the base images changed to sort of allow operating in a rootless mode of execution that means the user that your application runs as by default does not have a whole slew of permissions that you may expect you can't create files in the application's directory as we saw you can't run commands like app update because permission is denied and depending on the image that you choose like applications like apt or pseudo may not even exist on the image right right so if you had built this with Docker build for example doing the default thing and definitely with done in six or seven M this image would have been root and you would have basically been able to do literally anything you wanted in that image exactly now you uh you're in the driver seat with all this just because the SDK defaults to using that new app user with limited permissions doesn't mean you're stuck in that mode you can always tell your container execution tool whether that's Docker kubernetes or anything else that you want to operate as root and if you do then you can pretty easily do whatever you want you can make files you can do apt updates whatever you need so um this isn't a one-way uh operation we've got the mechanisms in place to keep you in control with that particular change yep um yeah so let's try that same exact flow with chiseled and just sort of Drive the point home about uh that we were trying to make there so on a chiseled application we're going to try and hop in there with a shell because we need to debug our application and we can't bash does not exist on this image and that the reason it's not there is to reduce the size of the image so all of these things sort of work together to reduce the uh attack surface area of your uh deployed applications yeah okay so what uh what are we going to see next so can can we do better I guess is absolutely can yeah um what what's the thing from the Olympics it's like better faster higher those are the things smaller we can actually try this new aot thing that we've been talking about so with this we are going to go even one step further than trimming and what's going to happen here is we should see a size reduction even further because we are compiling directly to native code which I think typically means we don't have component it's like the jit we do not have the jit at all anymore so we do have the GC still yeah are you going to change the tag I uh yeah I am going to change the tag so we can uh differentiate so this one we will call aot yeah and by the way you don't have to use this container image tag we're just we're just doing that yeah we're showing all the fun little features yeah right so generating native code this is I think the first time we've seen that Yep this is a difference um this is uh the Step Beyond trimming here so um yeah so you still have to trim but then the stuff that is trimmed then becomes natively generated yeah and I think one thing to take home is we are in no way trying to say which one of these options is best for you like we're not trying to say everyone should move to Native aot that that's not the message it's really just um we have a lot more options than we had before and it's like wow what what did we just see there we just went from 36 Megs to 17.4 right and this is is this is uncompressed right so in terms of um pulling a container image from a registry to a container service you wouldn't be pulling 17 Megs over the network it would be more like 10 Megs y um because that's that's compressed um payload at that point and like we sort of touched on before that matters for two primary reasons one is billing uh Network IO you don't do can't cost you and the second is startup speed smaller payloads are easier to download and faster to start up okay so what else can you show me there is one further step so if we think about our OS and our application we've gone I think as far as we can with our application now there's one more step we can do with Ros and that is uh using a version of our base image that uh is ruthlessly optimized for I heard I heard a rumor that this was available so this is bleeding stuff here so every other image we've been using has been under the sort of fully like fully stable net uh bucket but this is under nightly this is the runtime depths image and we're going to choose the aot variant of the Jammy chisled image that we've been playing with up until now right because our aot runtime doesn't have the same dependencies just fewer than uh the Corr run the yeah runtime jet one okay so let let's let's try this outly so just a quick note we're using this container base image property here because this lets us exactly specify the base image man mode so as always the story is helping you do did you save that oh that was a great saw I did not thank you okay we saved a couple minutes there yeah the story as always is um uh deps yeah uh giving you lots of tools here but making the sort of default pathway easy and correct right so we're literally generating the exact same app this time there's zero changes to the app only the operating system yeah so drum roll please a DS so before we go it was 17. like six before okay we are at 15.1 we saved two two more Megabytes yeah okay awesome I'm I'm pretty happy with that okay so um you know one of the things that you and I just can't seem to agree on is um you have an x64 laptop and I have an arm64 laptop and um yeah so your x64 you know I just I just couldn't do it I wanted to use this arm one so how can you kind of help me out with that sure yeah so uh net developers are used to publishing applications for different architectures and different operating systems they should expect the same okay so it works with uh container publish yep there's a couple caveats um the aot capabilities here are uh fairly restrictive on the platform that you can aot natively for um so we're just going to back that step out for a second right so so can be made to work we're just not going to demo it at the moment yeah we've got samples it takes a little bit of set up but it can be done it's actually in the workshop how you do that um yeah so this should be good we still are fine with trimmed we're still fine using Jammy chiseled we are just going to add one more flag that most net developers should be uh familiar with we're going to tell the application to Target arm 64 instead and I'm just going to call this one instead arm 64 so identify it just like specifying a runtime identifier with D or an operating system with D- the system understands what you mean here and it will help you make an image for that correct architecture so let's run this one locally real quick and even though I'm on an x64 architecture machine Docker supports emulation you can see it saying here that we're running on uh arm 64 emulated and we do fact get that output so let's push this to somewhere that rich can get it yeah so I heard that your oci published stuff can actually push to a registry as well it absolutely can as if everything we showed today wasn't enough yeah so we've been pushing to a local Docker Damon that I've got going right here you could also push to podman or to a file if you want but the most common way people interact with containers is external Registries so we 100% support that uh we're going to push to an Azure container registry that I have set up right now uh aure cr. and we're just going to get that push going and because we've told the system which registry to push to instead of pushing to Docker it will push up to ACR so this will look very similar except it won't uh see husk container testing because I forgot to log in again yeah okay so yeah I was going to ask you that so clearly the the container registry is a protected resource so you need credentials passwords you know all that kind of stuff so it would also help if I typed it correctly yeah okay right so I think um we're we're we're um taking advantage of the same underlying mechanism as Docker login I think exactly any system that can correctly authenticate to Docker should also work for our system and it looks like it did some slight VIs ual differences in the tool tell us that so all of this is what we've been seeing before we're building this image with this tag on top of this base image but this next bit that you see is saying that we've uploaded layers the actual Docker file system items to the Azure CR that I specified and finally we've pushed hello. net arm64 to my destination okay so now here's the big test um so now we're going to go to look at my machine um and uh uh I'm going to run docka run uh as soon as the machine flips in the in the video and see if I can pull this from the registry don't forget to zoom in a little bit yeah I did zoom in um maybe maybe I'll open up actually a different um since we seem to have a little bit of time um I will open up a different um terminal I actually always have trouble with this um okay maybe that's not going to work cuz I'm still seeing that there so what we could do while we're waiting um is uh well actually you could pull it yeah absolutely yeah you could pull it won't it won't quite do the exact same thing because you we're going to rely on emulation again but um we could just at least demonstrate yeah you're absolutely so this will work for me because I'm authenticated it would work for Rich because I previously set up my Azure container registry to allow uh Anonymous pull um so if we pull this and we go hello. net arm64 this is a normal Docker pull the base images for the runtime depths and all already exist we pulled the new layer and now we can just run it we're just going to run it okay same emulation message as before same emulated result as before that was the round trip right so the only thing that would have been different on my machine is we wouldn't have had that warranty message yeah exactly so we've just got slightly less than a minute left um I think the cool thing to do would be to show the workshop oh yeah yeah just to you know give people an idea of what's there sure you want to see it online or you want to see it no no online okay yeah we got in the web browser um yeah yeah so rich has got this Workshop that we worked on together yeah uh under his name here you want to walk us through what we're seeing here yeah so we can zoom that in a little bit basically um what we did is we thought of everything that you would really need to know to get started it's mostly about publishing occi images but it's got a ton of just open up one of the files um doesn't matter which one sure uh and it's got um this one has all the properties that you would need to use and um it's got a ton of instructions to to get you started okay well thanks everyone for listening to the talk you know Chad and I and a bunch of other people worked a ton on this stuff and we're really glad to see you start to use it oh yeah thank you
Info
Channel: dotnet
Views: 11,509
Rating: undefined out of 5
Keywords: .NET
Id: scIAwLrruMY
Channel Id: undefined
Length: 25min 38sec (1538 seconds)
Published: Fri Nov 17 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.