What you'll learn
- Explain how containers use layered images and a shared OS kernel compared with virtual machines
- Install Docker and the Windows Containers feature on a container host using PowerShell
- Configure Docker startup options in daemon.json, including data-root, hosts, and group settings
- Run, stop, start, attach to, inspect, and remove Windows Server containers with the Docker CLI
- Build a custom container image with a Dockerfile using LABEL, RUN, COPY, and CMD instructions
- Map a host directory into a container and create shared data volumes with the -v parameter
Free 79-minute video lesson with a full transcript and knowledge checks. No account needed to watch.
Overview
Note: The lab component has been removed from this Skill. However, this skill still retains value as a training resource.
Container Installation Requirements and Scenarios
This Nugget covers the basics of containers and how they work in Windows Server.
Knowledge Check
Hyper-V containers share the container host's operating system kernel. True or false?
Installing and Configuring a Windows Container Host
Learn how to stand up a Windows container host by enabling container support and installing Docker.
Knowledge Check
Installing Docker through PowerShell automatically installs the Windows Containers feature. True or false?
Configuring Docker Startup Options
In this Nugget, you'll learn how to configure Docker startup options using a configuration file.
Knowledge Check
Which configuration file is used to define Docker startup options?
Installing a Base Container Image
This Nugget will show you how to pull base operating system container images from Microsoft's Docker repository.
Knowledge Check
To download and install a container operating system image, which Docker command is used?
Creating Windows Server Containers
In this Nugget, you'll learn how to start, stop, attach, inspect, and remove containers.
Knowledge Check
To create and run a new windows server container, which Docker command is used?
Creating Hyper-V Containers
In this Nugget, you'll learn how to create Hyper-V containers and see how they differ from Windows Server containers.
Knowledge Check
To create and run a new Hyper-V container, which Docker command is used?
Deploying Windows Containers Lab
This hands-on lab Nugget gives you access to our virtual lab environment and challenges you to complete many of the tasks Garth performed in the Deploy Windows Containers section of the 70-743 exam.
Knowledge Check
To run Hyper-V containers on Windows Server, which of the following is required?
Managing Windows Containers using Docker
This Nugget will show you how to create, tag, manage and work with Docker images.
Knowledge Check
To create an image from a container, which Docker command is used?
Creating New Container Images using Dockerfile
In this Nugget, you'll learn how to automate the process of building container images using a dockerfile.
Knowledge Check
To create and automate images from a dockerfile, which Docker command is used?
Managing Container Networking
This Nugget will cover the basics of container networking and show you how to create custom container networks and attach containers to them.
Knowledge Check
A _____ container network allows containers to join the physical network.
This interactive assessment is available in the full learning experience.
Managing Container Data Volumes
In this Nugget, you'll learn how to share data between hosts and containers using data volumes.
Knowledge Check
Which Docker command allows multiple containers to share a data volume?
Managing Resource Control
In this Nugget, you'll learn how to place resource limits on containers.
Knowledge Check
Which of the following limits can be placed on containers?
Managing Container Images using DockerHub Repository
This Nugget covers the purpose of DockerHub and shows you how to push images to and pull images from a DockerHub repository.
Knowledge Check
To push and pull images from a DockerHub repository, which command must you run in Docker?
Managing Container Images using Microsoft Azure
This Nugget shows you how to use Microsoft Azure's Container Registry service to store and manage images in the cloud.
Knowledge Check
To push and pull images to and from an Azure Container Registry repository, which command must you run?
Managing Windows Containers Lab
This hands-on lab Nugget gives you access to our virtual lab environment and challenges you to complete many of the tasks Garth performed in the Manage Windows Containers section of the 70-743 exam.
Knowledge Check
To automate Docker image builds, which file must you create?
Conclusion
I hope this has been informative for you and I would like to thank you for consuming.
View Transcript
Container Installation Requirements and Scenarios
0:00Containers are the next logical step in the world of virtualization. In this Nugget, we're going to talk about what they are, who uses them, their intended workloads, and the requirements for running them. To understand the need for containers, we need to go all the way back to the beginning. The beginning being physical machines. Prior to virtual machines, we would load up our data centers, server rooms, and server closets with physical hardware-- towers and racks to support our workloads. We'd have some machines dedicated to a specific workloads, other machines containing multiple workloads.
0:31But the point is, everything was physical. Eventually, we realized that this isn't a very efficient way of doing things. It's a waste of resources, a waste of power, a waste of time and energy, and, on top of that, these workloads weren't very portable, so it was difficult to move things around. So along came virtual machines, which solved many of the challenges that we had with physical machines, specifically around resource utilization and power consumption. We could pack VMs onto a physical server to make better use of the resources within.
1:02However, there are still some challenges that virtual machines didn't solve. And that's because they're thick. We still need to install an operating system, configure it, manage it, get our workloads on it, and they're still not very portable due to their size. That's where containers come in. So it's easy to think of containers as operating system virtualization. Containers themselves provide an isolated environment for the workloads we need to support. Those workloads primarily being applications and services along with all of their dependencies. Hosting a website being a prime example of that.
1:35We could install IIS into a container, add in our application and all of its requirements and dependencies, and we now have a box containing all of those components that we can easily move around from server to server, data center to data center, and even cloud to cloud. Now, containers are made up of images layered on top of each other, very much like an onion. So you begin at the center with a base operating system image. We fire up a container based on this image, we get into it, we make changes to it, and create our own layer on top of it. Say, for example we installed IIS.
2:06Then we do it again. Add another layer containing our application and all of its dependencies. These image layers function very much like differencing disks. When we spin up a container based on an image, any changes we make within that container are isolated into the sandbox, which is then used to create new images from. Here's the really neat thing about containers. We could be creating hundreds or even thousands of containers on a single machine all containing different workloads, but all of those containers still share that operating system layer. In fact, the operating system kernel is actually projected into these containers.
2:40And that's the operating system virtualization part. These containers essentially have their own copy of that OS with their own file system and everything. And again, all those changes we make within are isolated to the layers above. Now, we have two flavors of containers in Windows Server, Windows containers and Hyper-V containers. Windows containers are what we were just talking about here, where the operating system is shared, or the kernel of that operating system is projected into all of these containers. In fact, on your container host, if you were to run Task Manager, you would actually see all the processes that these containers expose, because that kernel is shared amongst them.
3:19So the downside here is, if the kernel was ever compromised by a container or otherwise, all of our containers on our container host would be affected. Hyper-V containers take that a step further by providing our containers with their own copy of the kernel. This results in the best security and isolation possible, but it does, of course, require Hyper-V installed on your container host. Now, there are a couple of requirements for standing up a container host. One of them is the containers feature in Windows Server. The other one, the big one here, is Docker.
3:51Docker consists of two components, a daemon which runs as a Windows service, and a client in the form of a command line interface that we use to interact with that service. Both of these requirements are easily installed in just a few lines of PowerShell code, which is what we'll be doing in the next Nugget. In this CBT Nugget, we covered the purpose and benefits of containers, and talked about the requirements for standing up a container host. I hope this has been informative for you, and I'd like to thank you for viewing.
Installing and Configuring a Windows Container Host
0:00In this Nugget, we're going to look at how to transform a Windows Server into a container host by enabling the containers feature and installing Docker. Here we are on CN-NUG, which is going to act as our container host. Our first mission is to get these requirements installed. Those requirements are, again, the containers feature built into Windows as well as Docker. Now, let me show you that feature first. Let's head into Server Manager, dropdown the Manage menu, choose Add Roles and Features. And I'll just fly through this until we get to features. One more, there it is, and you'll see containers right here.
0:32Now you don't actually need to do this, because if you install Docker through PowerShell, it will automatically install this feature for us. But the only reason you'll need to do this right here either through the GUI or through the install Windows feature chameleon PowerShell is if you're installing this on a machine that doesn't have internet access. So you would download Docker manually, and then install both Docker as well as this container features separately. All right, so we're actually going to skip this. Because we're going to do all of this through PowerShell, so let's get the Integrated Scripting Environment up here.
1:03And to install Docker through PowerShell, it's a couple of simple commands here. One, to install the Docker Microsoft provider from the PS gallery repository. Once we have that installed, we can pull the Docker package from that repository. So we're going to run these both in one shot. The second one, I added the verbose flag onto it, so we can actually see what it's doing. And you'll see that it's going to install that containers feature for us automatically, so I'm going to run both of these. We'll get a little message here just verifying that we indeed want to install Docker.
1:34I can tell that the first command already completed here, because the second command is outputting all of its step via the verbose flag there. So I'm going to hit yes to all here, and now it's going to finish installing. And check that out, installing containers. That is the step that it's doing right now in the background. It is installing the containers feature. A few minutes later, and that install finished up. If we scroll back up to take a look at the output, we can see that it finished installing containers. And then it downloaded and installed Docker. In fact, we can look in this directory just to verify that here. If we head into File Explorer, I'll head into the C drive here.
2:05And from here, Program Files, and there is that Docker directory. And here it is. So you've got Docker D, which is the Damon. This runs as a Windows service. It does all the heavy lifting, and then Dr. Docker.exe, which is our CLI command line interface for managing all things containers. Now before we go any further, we should respect this message here. The head of restart is required to enable the containers feature. So I'm just going to force a quick restart and come right back. And we're back with our new container host.
2:35Let's jump back into the ISE. A couple of commands here we can use to verify the install. We can run the Docker client here passing the version flag. This will give us the current version, which is also useful when you want to perform, and update, and compare versions with what's out there in the Docker repository versus what you have installed locally. You can see we're on version 18.09.2. We can also run and get service to verify that the service is successfully up and running. And it is. There it is. And by the way, if you look at that in the UI here, let's head into the services applet. Locate Docker in here.
3:06There it is, Docker engine. And if we take a peek at this, you'll see that it's just calling the daemon here with the run service flag. Again, this is what does all the heavy lifting. We just send commands through it with the Docker CLI. Now another fun test you can do to make sure all of these components installed properly is to run a container out of microsofts.net samples repository. Now we don't have anything on this machine at all, no images, nothing. In fact, we can verify that by running a Docker images, and we should see that we have nothing in our local repository.
3:37So by running this command, it's going to download the base operating system image, which in this case will be nano server, along with the application, and all of its requirements, and all the other images that lay on top of that base image for this container. And by the way, this container just has a really simple little app inside of it that will print out some Ascii art to the screen. Now I'm not going to run this inside of the ISE, because the output looks a little funky. So I'm actually going to copy this, and let's run this through the command prompt here. So I'll paste this in here and execute it.
4:08And this will take a little while to run, because the nano server base image is a couple hundred megabytes. And some of these other images are a little large as well, so I think the total size is a little over a gig. So I'll let this download and come back when it's done. We're almost there. It downloaded all of those layers. Now it's extracting them. One of the beautiful things about containers is since we've already gone through this process, they're all stored in our local repository. If Microsoft were to release an update to this application, and we attempted to run this container after that update took place, it wouldn't need to re download all these layers, just the ones that have changed.
4:42Now you'll see here as soon as this is done, it's going to spin up that container. The container will run its code, output this Ascii art, and then close down the container. And that's exactly what it just did. Now let's run this container again. Only this time, we'll use our command here in the ISE, and this time, it won't have to re download everything. It's just going to run that container, output its information, and closed down. Also, if we were to run a Docker images here to take a look at our local repository, we will see that image within.
5:13One more thing I want to mention here is updating Docker is a breeze. You can run a fine package against the Docker package in Microsoft's Docker repository to get the current version posted up there in that repository, and there it is. You can see where on the latest version. If we are not the latest version, and we wish to upgrade, we can just run an install package just like we did initially only with the update flag. And that will perform an update of the Docker binaries on this machine. And from there, you can fire up the Docker service and be on your way. In this CBT Nugget, we cover the process for standing up a Windows container host by installing support for containers in Windows and downloading and installing Docker.
5:51I hope this has been informative for you, and I'd like to thank you for viewing.
Configuring Docker Startup Options
0:00In this Nugget, we're going to look at how to configure startup options for the doctor daemon to ensure they persist across restarts, and look at some of the most common of these options. Here we are on our container host CN-NUG. Let's get right into the PowerShell ISE. The first thing I want to show you here is where you can find a list of all of these startup options. Now, Docker supports a massive list of startup options, but Windows only supports a small subset of them. And Microsoft, in their docs, has a page here that outlines what those options are. So I'm going to go ahead and fire up Edge here, which will take us right to that page.
0:33And if we scroll down a little bit, you'll see a section here on configuring Docker with a configuration file, which is the recommended approach. That way, these settings persist across service restarts. Now, you can configure these options on the fly against the Docker service, but, again, they will only stick around for as long as that service is running. They'll get reset back to their defaults when that services restarted. And that's why it is recommended to use a configuration file, which is what we're going to be doing here. Now, this is the relatively small list that Windows supports for startup options for Docker.
1:08You can see the complete list at this link here. Which, again, it is massive, but a lot of those do not apply to Windows. Now, some of the most common options that you'll be configuring after a Docker installation include things like the data route. We'll be configuring this one here shortly. This will change the default location, where our local image repository is on the system. The default is in the C drive. Another one is hosts. This will define the IP addresses and ports that containers will be listening on. You can also configure a log level here.
1:39Debug mode is in here as well. Where are you, debug? There it is, right above host. And then, also, group is another one. The default here is that communication will occur over named pipes when we want to interact with the Docker daemon through the CLI, and that means only local administrators will have the ability to do that. If you have a specific group that you want to give access to, you can give that group access here and define it within this configuration. So in this Nugget, we're going to configure group and data route. Those are two of the most common options you'll be configuring, again, out of the box with Docker.
2:11There are some other ones that you'll configure when you get into container management, and we'll look at those a little later on. Let's head back into the ISE. And the first thing I want to show you here is this Docker info command. This is short for Docker system info, and it'll give us some good system information here around our installation. We can see here our Docker root directory is at the default, C, ProgramData, docker. And if we scroll up a little bit here, we can see that we've executed two containers. We have one image. And as we scroll down here, we can also see some other useful information, like our default isolation level is process, which is Windows containers, as opposed to Hyper-V containers.
2:46Now, the next thing we're going to do here is essentially reset Docker by running a Docker system prune --all. This will remove that base image and give us a nice, fresh start. So we're going to run this, and this will just take a second to clear everything out. All right. That's done. And by the way, I had to do that here in the command prompt because you don't get prompted in the ISE, but that removed everything. And now, if we run a docker info again, we should see that everything has been reset. We no longer have any containers or images here within. And now we can move this-- all of this-- to the new volume.
3:18Now, before we create this configuration file, let me show you where everything is on the file system. If we open up File, Explorer here and head into the C drive, into ProgramData, you will see a directory here called docker. This is where everything Docker is stored-- our local repository, our images, and our configuration file, which you can find in the config directory. Notice there is no daemon.json file in here by default. So that's our next step. We need to create that file and then restart the service for it to pick up those changes. Let me also show you our destination is here.
3:50Over on the S volume, I created a directory called Docker, which is currently empty. So we're going to move everything over to this directory, on this volume. Let's do it. Back in the ISE, we're going to execute this command, which will send this string of text, or JSON defining our start up options, into a brand new daemon.json file inside of that config directory. So if we execute this, that'll create it. And now to pick up those changes, all we need to do is restart the Docker service. With that done, if we head back into the file system and into our Docker directory on the S volume, look at that.
4:23It moved everything over, and this is the new default location for everything Docker. We can verify that by running a docker info one more time, and we can now see our Docker root directory is over on the S volume. In this CBT Nugget, we covered how to configure Docker to startup options using a configuration file. I hope this has been informative for you, and I'd like to thank you for viewing.
Installing a Base Container Image
0:00Let's take a look at all of the base container images available to us here on Windows, and we'll go through the process of installing a base container image onto our container host. Here we are on CN-NUG, our container host, which currently contains no base container images. So we're going to fix that. Let's jump into the ISE. And where we can find these images are up in the Docker hub. So I'm going to fire up hub.docker.com inside of Edge, and this contains public and private repositories for all kinds of images. And vendors such as Microsoft have their own public repositories that we can use.
0:32I'm going to hit the Search bar here and type in Windows. In the search results here, I'm going to head into the Windows base OS images repository. This contains a reference in the description to featured repos. And these are the four repositories that contain the four container based images that we can use in Windows. Now these first two are by far the most popular. Our Server Core and Nano Server images. You'll use Server Core if you need access to the full data .NET framework. You'll use Nano Server if you can get away with .NET Core.
1:03And this is a much smaller image. The Nano Server image is a little over gig. The Server Core image is a little over nine gigs. These other two are for special use cases. IoT Core if you need to support IoT-based applications. And this Windows contains the full Windows stack and all dependencies built in. So if your application needs specific DLLs or access to GDI libraries, then you'll use this one. We're going to be using Nano Server. So let's head into this repo. You can see this is by far the most popular one-- over 10 million pulls out of this repo.
1:38You can also get the command to pull the base image. This will pull the image with the latest tag. And if we scroll down here, you can see featured tags. So if you want to pull specific images or images for older versions, you can append the tag to the end of the command, which we'll do here in a little bit. Also if you scroll down to the bottom here, you'll get a listing of these images. And if you scroll even further, you can get a full listing of all the tags available for these base images, and there's quite a few here. It's actually a huge list of JSON.
2:09So I won't actually open that up, but I will show you how we can download a specific tagged image. Now let's head back into the PowerShell ISE, and let's execute that command here to pull the latest Nano Server image, and this is going to take about 10 or 15 minutes to install. So I'll let it run through until it's done. All right, with that all set, we now have a base image installed in our container host. Notice the last line of the output here that it automatically appended the latest tag to it, which gave us the latest Nano Server image out of that repository.
2:42Now we can also pull specific images based on their tag by appending the name of that tag to the name of the container image. So in this case, we're going to pull this version of Nano Server out of that repository, and it will live side by side with our other one in our local repository. One thing to be aware of here when pulling based container images is that the operating system version must be the same as your container host OS version. So if we were to run a winver here, we can see that we're running version 1609 build 14.393.
3:15So we wouldn't be able to pull, say, build 1803 or 1809. In fact, if we were to try this out here, I'll go 1803, which by the way, if we head back to the dock repository, here it is right here. This is a more recent image of Windows. So if we attempt to pull this, we'll get an error here just letting us know that our versions don't line up. And there it is-- our 14.393 host is incompatible with that 17.1.34.1803 image. So if you want to run newer base OS container images, you'll need to make sure that your hosts match.
3:46And if you want to support older OS container images, then you can use Hyper-V containers, which have an isolated kernel. They do not share the kernel with the host. All right, let's put this back to where we were, and let's run this to download this specific version of the 14.393 base OS container image. All right, that's done, and it didn't take nearly as long as our initial poll because we already had some of the bits from Nano Server from that initial poll. So we can see one of those image layers already existed. Now if we want to take a peek at our local image repository, we can run a Docker images, and this should list both of those images.
4:21And check it out-- we can see our latest image is much newer and a little bit bigger-- probably because more features were added in-- and our older image is much older and slightly smaller. So now that we have these base images installed in our local repository. We can begin spinning up containers from them and then getting into them, installing our application, all of their dependencies, and support containerized workloads. One more thing I want to point out here is if you ever need help in Docker, you can use the help switch here, which will give us a lot of great help for all the commands and subcommands that it supports.
4:53We'll be using a few of these as we head through the next many Nuggets. In this CBT Nugget, we covered the four base container OS images available to us in Windows, as well as the differences between them, and we even installed a couple of Nano Server based OS images onto our container host. I hope this has been informative for you, and I'd like to thank you for viewing.
Creating Windows Server Containers
0:00Let's take a look at the many ways that we can create, run, and work with Windows Server containers. Here we are on the desktop of our container host, CN-NUG. Let's jump into the PowerShell ISE. Now, I just want to point out that running containers in the ISE oftentimes freezes it up. So we're going to be doing a lot of this through the PowerShell console, but I just wanted to point out that there is a script here, so when you get into our hands-on lab Nugget you have it for reference. So some of the things we'll be doing in this Nugget are looking at a couple of ways that we can run containers interactively as well as detached. We'll view running containers, stop and start containers, attached to containers, inspect containers, and then also remove them.
0:37All right, let's fire up the PowerShell console. So we'll launch this under an elevated session. And I'll get it into our screen here so we can see it. So let's begin here by just taking a look at the images in our local repository. We should have two of them, our latest nanoserver image and a versioned, tagged nanoserver image. So let's say that we wanted to fire up a container based on one of these images. Let's start here with an interactive container. We'll do a docker run -it -- for interactive-- and then the name of the image that we want to create this container of, which is right here, mcr.microsoft.co m/windows/nanoserver.
1:17And we're going to launch right into the command shell. And check it out! We are inside of that container. Much faster than firing up a VM from scratch! And now we can do things inside of here, like look at the host name. There it is, which is actually the container ID. We can run an ipconfig to look at the IP configuration, and it is connected to the default NAT network associated with containers. We'll look more at that when we get into container networking. Let's run a ping command against our default gateway. Sure enough, we can hit it. Let's ping outside.
1:48We'll ping Google's DNS servers here, 8.8.8.8. And look at that, we can hit it from inside our container. Now if we wanted to get out of this container there's a couple of things we could do. If we exit out of this container, the container will stop and it'll be done. But we can also hit Control-PQ to just exit the container and leave it running. Now let me show you the effects of this. Let's start by exiting. All right, we're outside of that container. If we want to docker ps, which will show us all of the running containers, this isn't going to return everything, because we exited out of that and the container spun down.
2:18If we recall our last command and do a -a on the end of that for all, this will show us all containers, stopped and started on the system. We can see that it exited there 13 seconds ago. Now I'm going to recall a bunch of commands ago here so we can rerun our container, once again, in interactive mode. All right, we're inside. And this time I'm going to do a Control-PQ, which will not spin down the container. That container should still be running. And if we run a docker ps here without the a switch we should see that container is running and its status is up for 11 seconds.
2:48This is also a brand new container so it got a new name. Notice the randomly generated name here, confident_ramanujan. The random names that it assigns that are sometimes just fantastic. But now if we run a docker ps with the a switch we should see two containers, one that is stopped and one that is currently running. And by the way, when you fire up new containers, you can use the name parameter to give it your own user defined name if you didn't want one of these random ones generated. And then for managing and working with containers, you can either use the ID or the name.
3:19In fact, let's stop that container that's currently running here. If we do a docker stop, all we need to do here is enter in either the ID or the name. And you only need to enter in enough to make it unique. So, for example here, all we would need is 72, part of the ID here, to stop this container. And it's done. And now if we run a docker ps one more time here we shouldn't see any containers currently running. Now we can also use that ID to start containers. Let's say we wanted to restart one of these containers. How about the first one that we've fired up, f7 there. We can do a docker start f7 and that will spin up that container once again.
3:54Now a docker ps should show us that container is running. And we can see that vigorous_newman ID f7 is back up. Now what if we wanted to get back inside of that container to do some work? This is where we can attach to them using docker exec. Here we can do another interactive session. All we need here is the name or ID, so we'll do an f7, and then we need to give it something to do so we'll launch right into the command shell. And look at that, we're back inside of that container. Now once again I'm going to Control-PQ out of this so we leave that container running.
4:28Here we go. And now it should still be running here, so if we do a docker ps, there it is. Another handy command here is docker inspect. Same thing here, pass in part of the ID or the name and this will show us all kinds of great container details. So we can see a lot of that same information that we were just looking at on the inside, only from the outside here. So we see it's network configuration, see it's connected to the default NAT network there. And as we scroll up, we get all kinds of great information. A lot of stuff here sent back as JSON about this container.
5:00Now these are Windows Server containers. And let's take a look at the effects of a Windows Server container. Remember, the only difference between a Windows Server container and a Hyper-V container is the isolation of the kernel. It's shared here with Windows Server containers and completely isolated with Hyper-V containers. And we can actually see that in action. If we head into Task Manager here, head down to all details, and then details. And we're going to add a new column in here. So we'll right click on the column headers and choose Select columns. And from here we're looking for job object ID. All right, so here it is right here.
5:30Now I can already tell you that the container that's currently running is 112. But the point here is that we can actually see these on the outside on the container host. Let's spin up a few more containers here. And this time we're going to do it in detached mode. So we'll do docker run -d the name of our image, mcr.microsoft.co m/windows/nanoserver. And by the way, if you wanted to run an old version, or a tagged version of an image, then you would just add a colon and the name of that tag.
6:00But here we're going to run it like so. We're also going to give it a workload to run here so it doesn't just spin down automatically. So we'll do a ping -t here so it just runs continuously and we'll ping our default gateway. There we go. And you'll notice as soon as I hit enter there, I saw a Task Manager do something in the background, and it's spinning up another job here. And we should see a ping command show up once this is all done. Oh, it is spun up here. There it is, right there. Check it out. Ping 140. So we can see here, if we start by our job ID, 140 is that new container.
6:30112 is that other container. The difference here is we've got a ping command running in this new one. Let's spin up another container. I'll recall my last command and do it again. And you can now kind of see the power and scale of containers. Imagine if this was a web service or a website. We could spin up many containers, put load balancing on top of them, and that is scale with containers. Now that we ran another container we should see another process in here. Look at that, job ID 152 is also running a ping command. So this is the effect of Windows Server containers here is that we can see all of these processes from the host because they all share that host kernel.
7:05Now let's shut all of these containers down and remove them. Let's start here with the docker ps to take a look at all of our running containers. We should have three of them, and we do. Now we could attempt to remove these containers and pass in all of the IDs, but you can't actually remove a running container, although you can use the F switch to force it. But let's do this step by step here. Let's start by doing a docker stop. We'll do 1c the first container, b2 for the second container, and f7 for the third one. And that should stop all three of those. And you could see Task Manager spin down all of those containers.
7:39Now if we do a docker ps -a, we'll see all of those containers that we started and then stopped. We've got four of them in here. And now we could just do a docker rm, and again pass in all the IDs. So there's a 1c, a b2, a 72, and an f7. And that will remove all of those containers from the system, and now if we do a docker ps -a, no more containers started or stopped. In this CBT Nugget, we looked at how to create Windows Server containers from docker images and how to manage them through the docker client.
8:11I hope this has been informative for you, and I'd like to thank you for viewing.
Creating Hyper-V Containers
0:00In this Nugget, we're going to look at how to create Hyper-V containers and see how they differ from Windows containers. Here we are once again on our container host CN-NUG. Let's start here by jumping into the ISE. Again here, the ISE will freeze up if we attempt to run containers through it. So I just want to point this out as a reference because you'll be using this in our hands on lab Nugget coming up immediately after this one. So we're going to do all of this here in the standard PowerShell console. So let's begin here by firing up a standard Windows container. We'll do a Docker run.
0:31We'll run this in detached mode. Let's also give it a name here. We'll name this CN1-NUG. Then we need to provide our image here. That's going to be mcr.microsoft.co m/windows/nanoserver. And then we'll also give it a little workload to run here. How about the ping command running infinitely against our default gateway 192.168.1.1? So that's going to fire up a standard Windows container. All right, so with that done, let's fire up another container-- only this one is going to be a Hyper-V container.
1:02So I'm just going to recall my last command here, and we'll call this one CN2-NUG. And the only other thing we need to do here is specify our isolation level, and we do that by using the isolation flag and setting that equal to Hyper-V-- so same container, just with V isolation. Now let's verify both of those containers are running by running a Docker ps, and there they are-- CN1-NUG and CN2-NUG. Now it's difficult to see with the default output which one is the Hyper-V container and which one is the Windows Server container.
1:34And that's, again, where the inspect command comes into play, so we can do a Docker inspect. Let's look at CN1-NUG first here. And now if we look into the details here, I'm going to scroll all the way up until we see host config because underneath host config, you will see isolation. And we can see its process here for CN1-NUG, our Windows Server container. Now the inspect command actually has a format switch on. In fact, if we run a Docker inspect using help, we can see the f switch will allow us to pull out specific properties from all that JSON.
2:08So for example here, we can do a docker inspect/f. And then in parentheses here, we're going to navigate through the JSON. So pass the route and inside of the second level is dot host config. And the property we're looking at within there is called isolation. We can close those brackets, and now we need to specify our machine. We'll go CN2-NUG this time, and this should return the isolation level here, which is Hyper-V. So that's cool. We can even recall that last command and change CN2-NUG to CN1-NUG, and they should say process, which is a Windows Server container.
2:43Now another thing we're going to look at here is Task Manager because if you remember in our previous Nugget with Windows Server containers, we could actually see all the processes that were running inside of that container from outside here on the host. Well, not so much with Hyper-V containers since they have their own isolated kernel. If we head into the Task Manager here, hit more details, head over the details, let's add that job ID in here. We'll select columns. We'll add job object ID, and we can sort by it. And we should be able to identify here that our Windows Server container is job object ID number 52, and then our Hyper-V container is right here-- job object ID number 80.
3:22Notice here that there's no other 80 within this list as I have it sorted here descending, meaning we cannot see all the service host, the ping command, nothing inside of that container since it's a Hyper-V container is exposed here to the host. So the bottom line here is that Hyper-V containers provide us with the ultimate in isolation because they have their own dedicated kernel In this CBT Nugget, we looked at how to create Hyper-V containers to provide our containerized workloads with the best possible level of isolation. I hope this has been informative for you, and I'd like to thank you for viewing.
Deploying Windows Containers Lab
0:00Are you ready to get hands-on with Windows containers? This hands-on lab will give you the opportunity to do just that. In this Nugget, we're going to challenge you with some common tasks around standing up a container host. This lab consists of just a couple of machines and you'll be spending all of your time here on CN-NUG, which will play the role of our container host. And that's your very first task here, is to install Docker and container support. Keep in mind, installing Docker through PowerShell will also add the container feature in Windows. So we can do this all in one shot through PowerShell.
0:32And I'll show you where those scripts are when we get into the virtual lab. Once that's all set, your next task here will be to configure Docker startup options using a configuration file. The big option you'll want to set is the data root directory the name of the option is data dash route. And what you want to do there is move it from the default installation, which is on the C volume over to the S volume, where I created a directory that is empty called Docker. So configure the startup option to point to this directory, and then restart the service. And that will move Docker's repository and everything over to that S volume.
1:06Another option you can configure is the group option. There is a DevOps group, an active directory, so you can reference that group to give them the ability to run CLI commands on our container host. Moving on, your next task is to install some base OS container images. You can use Microsoft's public Docker hub repository to download a nanoserver base OS image, and you can download multiple OS images based on their tag if you want to reference a specific version. But download and install those onto our container host. Next up is where the fun begins.
1:37Create containers! Create Windows Server containers based on those OS images, and also create Hyper-V containers based on those OS images, and then use Task Manager to view the differences between them. All right, let's jump into the virtual lab that you'll be working in, so I can give you a quick tour of where things are. Here we are on CN-NUG. This is the machine that you'll have access to, and that you'll be transforming into a container host. About the only thing you need to know for this lab is all of these scripts reside in the Nugget Lab directory. And also use these as a reference. I would actually run the code within these scripts, either through a PowerShell session or through the command shell.
2:13Be careful running these inside of the ISE, because oftentimes they'll freeze it up. One more thing I want to show you here, if we head down to the S volume, is the Docker directory. Notice here that it's empty. So when you configure your Docker start up options you'll create a daemon.json file, plant that in the config directory on the C drive, which, by the way, the default installation is inside a program data. There will be a Docker directory inside of here when you install Docker. So you'll create a daemon.json file, place it in the config directory, restart the service, and that will move everything over to that S volume.
2:46And that's about it! As always, good luck, and if you need any assistance, refer to the container Nuggets in this section. In this CBT Nugget, we provided you with access to our virtual lab environment so you can get hands-on with deploying Windows containers. I hope this has been informative for you, and I'd like to thank you for viewing.
Managing Windows Containers using Docker
0:00We're going to have some fun in this Nugget by looking at some common management tasks around containers and images. Let's do it. From the desktop of our container host CN-NUG. I'm going to jump right into the Integrated Scripting Environment. Let's start here by taking a look at images and image management. The first thing I'm going to do here in the ISE is run Docker images. This will show us our images. We've done this many times before. But what I wanted to point out here is I downloaded the Server Core base operating system onto our container hosts. And that's what we're going to be working with here in this Nugget.
0:30Now let's say that we wanted to rename these images or create new images based on these images with a new name. This is where the Docker tag command comes into play. Here we're going to rename these because we want to type all that out every time. So rename mcr.microsoft.co m/windows/servercore to just microsoft/servercore and we'll do the same thing here for Nano Server. So we'll run this, and that will change both of those. It won't change them. It'll actually just make new ones because if we run Docker images again, now we'll have four images inside of our local repository.
1:00So here's where if we want to get rid of these older images, we can use the Docker RMI, Remove Image command. So we'll get rid of these longer image names here by executing this command. And if we run docker images one more time here, we should just have these two images-- pretty simple stuff there. Now the next thing we're going to do is a little more exciting. What we're going to do is run a container in interactive mode, install IIS into it, and then create a new image using Docker commit. And we'll do some other things along the way here. We're going to take this the rest of the way though in the PowerShell console because, again, spinning up containers in the ISE just usually doesn't work very well.
1:37So if we head into the PowerShell console here. The first thing we're going to need to do is spin up a new container based on that image. So we'll do a Docker run. This will be an interactive session. Let's also give it the name here. How about CN-dev? This will be our development container and then the name of the image, which was microsoft/servercore. And we'll get into a PowerShell session within. A few minutes later and we are inside of that container, working in our base OS Server Core image. So let's install IIS here. We'll do an install Windows feature web server and give this a second to go.
2:13And there it is-- success. We've installed IIS inside of our container. Now our next step is to create a new image based on this container. What we're going to do is just exit out of the container here. If we were to do a control pq, that would leave the container running, and then you would need to stop it manually with the Docker stop before you can create an image. So I'm just going to exit out of that, which will spin down the container. And we can verify that here with the Docker ps. We can see that there should be no containers running-- perfect. But that container is still out there because if we were to add a slash a on the end of that, it's there, and that's good because we're going to need to get back into that in a little bit to do some more things to it.
2:48Plus we want to create our own image based on the current state of that container. And we do that using Docker commit. So if we run a Docker commit, specify our container name here, and then our image name-- let's call this Nuggetlab/iis-- that's all there is to it. This will take just a second to create that image and add it to our local repository. Now with that done, we can run a Docker images once again here. And we should now see that new image in our repository. And there it is right there. And we know that this image is the Server Core image plus IIS that we just installed on it.
3:23Now let's say that we wanted to create a another image-- only an image that contains Server Core, IIS, plus our custom website. Well, if we head into the Nugget Lab directory on this machine, I have a directory in here called mysite, which contains an HTML page and just an image-- just basically a static page here. So what we're going to do is copy this site into that container-- our dev container-- and then create another new image that is tagged with mysite. So we can do Nuggetlab/iis witg the tag of mysite.
3:54So the first thing we need to do here is fire up our development container. So we'll do a Docker start, not just start-- Docker start cn-dev to fire that container back up. So it's kind of our development workspace here. We could easily fire up a new container based on that image we just created, and it'll have the same effect. But since we already have a container out there ready to go, we'll just continue using that as our workspace. So that container has now started. Our next step is to use as a Docker cp command to copy that mysite directory into the container.
4:25First thing I'm to do here is just switch our directory-- our working directory here-- to Nugget Lab. And now we're going to run a Docker cp. We'll specify our source here as my site, and our destination will be the container colon and then the path to the destination, which is going to be inetpub wwwroot just like so, except that I have the wrong container name, not cpdev. That would be cndev. Here we go. This time, it should work, and it did.
4:57Now in order to create a new image based on the state of that container, once again, we need to spin that container down. So here we'll do a Docker stop cn-dev. And one more time here, we'll do a Docker commit, specify our container name, cndev, and our image name, which is going to be Nugget lab IIS, and then we'll do a colon to tag this as mysite. All right, with that done, let me clear the screen here of all the clutter. And now if we run a Docker images, we should see both of our images.
5:27There's our image with just IIS installed, and here's our tagged Image that also contains our site. Now comes the fun part I promised you. We're going to fire up a new container based on this image with the mysite tag and see if we could browse to it. So here we're going to do a Docker run. This will be an interactive session. We're going to map port 80 of the host to port 80% of the container-- more on that here when we get into container networking. I forget the dash there-- there we go. And then we're also going to name this here. Let's give the name Web-NUG, and then all we need to do here is pass in our image, which is going to be a Nugget lab/IIS:mysite, and we'll launch into a PowerShell session.
6:04There we go. All right, we're in the container one thing we're going to need here is the IP address of the container. There it is. We'll run an IP config. I'm just going to copy this here, copy it, and now let's bring up Internet Explorer. And the reason we need to browse to the IP address of the container is because we are on the container host. So if we were outside of the container host, which we'll do here in a second, we should be able to browse to the IP of the host or the DNS name. There is NAt on this machine, Network Address Translation. That is the default network, and everything flows through. So that's why we need to use the IP address of the container when we're directly on our container host-- again, more on that when we get into container networking.
6:40But you can see here this is the default site associated with IIS. Let's try to navigate to the site that we copied into there, which is mysite default.html. And look at that-- there it is-- served up from inside of that container. Now let's head over to our domain controller and see if we can hit this website from outside of our container host. So here we are on DC-NUG. I'm going to fire up Edge here. And let's start by browsing right over using the DNS name to CN-NUG. This should display the default IIS website. And now let's see if we can hit the site that we copied over there, mysite default.html.
7:14And voila, it works. That site was served up through that container living on our container host-- pretty cool stuff. Containers are just like mini virtual machines. We spin them up, install stuff on them, spin them down, and snapshot the image. In this CBT Nugget, we looked at some common management tasks around containers and images using the Docker client. I hope this has been informative for you, and I'd like to thank you for viewing.
Creating New Container Images using Dockerfile
0:00We saw in our previous Nugget how creating container images using the Docker commit command is quite a bit of manual labor. Well, in this Nugget, we're going to take a look at how to use a Docker file and the Docker build command to automate the process of building container images. Let's take a look. Here we are on our container host CN-NUG. Let's jump right into the PowerShell ISE where I have a couple of files opened up here. One is a Docker file, and the other is just a PowerShell script containing a bunch of Docker commands. If we look at this Docker file, really all this is a set of instructions for building an image-- a great way to automate the process.
0:36So a common workflow is to begin by spinning up a container from your base OS image. Then configure the environment, get your work load on it, and all the while documenting the commands that got you to that point, once you've tested everything and have it exactly how you want it, you can then stuff all those commands inside of a Docker file. And now you have a repeatable build process for those images. Now a Docker file itself is actually pretty straightforward to use. There's only a handful of instructions that we can add inside of here. You'll always start with a from.
1:06This is how we reference the base image that the new build image will be based on. We can also add in metadata here. Here we're adding a key value pair of maintainer equals this individual. There used to be a maintainer instruction, but that's been deprecated. And now we have the general label instruction, which allows us to add all kinds of metadata into our Docker files. Next up, we have the run instruction, which allows us to run commands. Here we're going to execute powershell.exe and pass the command install Windows feature to install IIS into the image.
1:36We're also going use the copy command here to copy the contents of the My Site directory to the WW root directory inside of the image. And finally, here we can use the command instruction to fire a PowerShell whenever a container is ran based on this image. There's a handful of other instructions as well. , I'll give you the link to the documentation if you feel like exploring that. Now that we have a Docker file created, we can run Docker command-- specifically the Docker build command-- to run that Docker file to automatically build the image.
2:06Let's start here by running a Docker images, just to take a peek at what we have in our repository. And you'll see here that we just have a couple of images within-- there we go. Both of our base OS container images and our Docker file is referencing the first one here, Server Core. So now we can use the Docker build command to run the build process to generate an image based on a Docker file. The t flag here is really just the name flag. It stands for tag, but it allows us to provide a user defined name and optionally a tag, which we are providing here for this image.
2:37And the final parameter here is the path to your Docker file, which lives in the root of our Nugget lab directory, which is why we just put a dot there referencing that it lives inside of that directory. So if we execute this, it's going to step through and output each one of those steps as it goes to build this image. So I got bit by the ISE here. It froze right after it installed IIS. So I actually had that the Stop button and then re-execute this command inside of the PowerShell console-- so a good lesson here as to why we should stick to either the PowerShell console or the legacy command line shell for running Docker commands because it froze right after IIS.
3:16But thankfully, everything is cached here in Docker. So when I reran this command, it picked up right where it left off here and used the cache. It didn't need to reinstall IIS, picked up here with the copy instruction and the command instruction. And now we have our image. In fact, we can take a peek at this if we run Docker images. We should have our new build image ready to go and there it is. Let's finish this up by creating a container from that new image and testing it out. I'm going to copy this command here, which is just our typical Docker run command.
3:46We'll head into an interactive session, map port 80 of the container to the host. We'll give it a name. And notice here we're referencing that image. So back into the PowerShell console here, I'll just paste that in here and hit execute. All right, we're inside of that container. Now we need the internal IP of that container. We can do that on the inside with an IP config or on the outside here by doing a Docker inspect, specifying our container name web NUG. There is the IP address right there. So we'll copy this, fire up a browser, and we'll paste that IP in there.
4:18That should get us to the default website hosted in that container for IIS. There it is. And if we just add default.html to the end of this, that should be our customer site-- awesome. In this CBT Nugget, we saw how to automate the process of building container images by using a Docker file. I hope this has been informative for you, and I'd like to thank you for viewing.
Managing Container Networking
0:00Container networking works very much like Hyper-V and virtual machine networking. Our containers come equipped with a virtual NIC, and container networks are essentially virtual switches. So in this Nugget, we're going to look at some container networking management tasks. We'll look at how to create our own custom networks and hook our containers up to those networks. Here we are in our container host, Hyper-V. Now the first thing I want to point out is that when you install Docker, a container network is created by default. And it is a NAT network. Now we can actually see the effects of this. If we were to look at the network connections here on this container host, you'll notice here that there's essentially a virtual switch automatically created called V-Ethernet.
0:39HNS here stands for Host Networking Service. And this is essentially an internal virtual switch. And the reason our containers can get outside is due to NAT, Network Address Translation. Let's jump into the PowerShell see here and take a look at how to control and work with and even create our own custom networks here using the Docker CLI. Let's start here by running a Docker network ls. This will show us all of the container networks on the system, and there's really only one here-- that default NAT network. We can further drill into the details of this network by running a Docker network inspect, passing in the name of that network.
1:14This will show us all kinds of great details here. We can see if any containers are attached to it. We currently have no containers running. That's why this containers block is empty. If we scroll up, we can see the address space and the gateway here, and we can also see the driver that is used. This is essentially the mode. And we have four modes here that we can work with in Windows containers. In fact, let's cover those four types of networks real quick here. I'll do this in the PowerShell console. And by the way, there are a handful of PowerShell commands also for working with containers and container networking.
1:46Let's do a get container network. This is going to show us that one NAT network and a lot of the same information there we saw inside of Docker. But what I really want to show you here is help on new container network. Notice the mode parameter here has four options. These options determine the type of container network it is. NAT which is again here the default when you install Docker is Network Address Translation. This means our containers, when going outside, assume the IP address of the host. This creates essentially an internal virtual switch that they are connected to.
2:18The downside with NAT, of course, is we need to use port forwarding/port mapping in order to route traffic to our containers. And the real downside there is that it's a one to one thing. So you can only have one container attached or mapped to one port. The next one here transparent is by far the most popular kind of container network because it allows our containers to get onto the physical network very much like our VM is attached to an external virtual switch. Our containers can receive IP addresses automatically from a DHCP server on the network, and we can also statically assign them.
2:51Together, NAT and transparent make up 99% of the container networks you'll see out there in the wild. These next two L2 bridge and L2 tunnel are primarily used for private and public cloud scenarios L2 bridge will force your containers to use the same network as your container host. An L2 tunnel is specifically used with Microsoft's cloud stack. Now while we're in the console here, let's remove this default network, and then we'll let Docker recreate it-- only we'll specify our own custom address space here. So we're going to do a get container network, and then we'll pipe this over to remove container network, just like so.
3:29We'll choose Yes, and now we can head back into the ISE. Here we can use the fixed-cider startup option, specifying our own custom address space, and we'll store that inside of a brand new daemon.json file stored in Docker's configuration directory. There is, by the way, another option called bridge, and you can set that equal to none if you didn't want the default NAT network created for you automatically. But let's go ahead and run this to create their file, and then we can restart the Docker service to pick up those changes. Now if we rerun a Docker network inspect, we should see our own custom address space within and look at that-- 10.0.0/24.
4:07Now we can fire up a Docker container and verify that it will receive an IP from the 10.0.0/24 network. So we'll run this container back inside of here. And notice here that we're using import mapping here to map port 80 of the host to port 80 of the container. The first block is your source. The second block is your destination. And if 80 was already in use on your host, you could do something like this-- 80.80 of the host to 80.80 of the container. And you can, by the way, specify this more than once, so we could do another P parameter here.
4:38And say, we wanted to map 443 of the host to 443 of the container. We could do something like that. All right, we are inside of the container. I'm going to run an IP config just so we can verify here that it did indeed receive an IP from that custom address space that we defined. Let's also verify that NAT is still working here. Let's ping our default gateway. That looks great, and let's see if we can get outside and hit Google's DNS servers. Indeed, we can. All right, I'm going to exit out of this container, which will spin it down. And let's take a look at transparent networks.
5:10The first thing I want to show you here is just a couple of help commands. Docker network help will show us those top level network commands that we can work with. So we've already looked at Docker network LS and Docker network inspect. We can also use connect and disconnect to attach and remove containers from networks. And you could also use the create command to create a network, which is what we're going to look at next here. Let's also take a look at the help for Docker network create. The big parameter within here is D, driver. Driver is the equivalent of mode that we looked at in PowerShell. And if we want to create a transparent network, we're going to set driver equal to transparent.
5:44Couple other things I want to point out here is if you want to assign static IPs to your containers, then you will need to specify the subnet and the gateway. And then when we spin up our container, we can attach an IP to it from the outside here when we're running it, or of course, you can statically assign them on the inside as well. If we had a DHCP server on the network, we would not need to provide any of that information. But since we don't have one in our lab environment here, we are going to provide that, so we can statically assign our containers with an IP.
6:15So let's create this transparent container network here. Again, the D switch is set to transparent. We're defining our subnet and gateway, and we're giving it the name transnet. All right, that's done, and we can see the effects of that on our host, by the way-- check it out. We have a new virtual switch that is essentially acting as an external switch. Now let's fire up a container on that network. Notice here that we're setting the network equal to transnet to place this container onto that network, and we're also going to statically assign it an IP address.
6:46So I'm going to copy this take it into the PowerShell console, paste it in, and run it. So inside of the container, let's run an IP config to verify all that IP information-- looks good. And this container is just like another host on our physical network. In fact, let's see if we can ping our container host here, CN-NUG. We can. Let's even see if we can ping our domain controller, DC-NUG. Notice here we're using DNS, and it's resolving to their IPv6 addresses successfully. So we can easily spin up more containers, attach them to this network.
7:18They'll all be able to talk to each other along with anything else on the physical network. In this CBT Nugget, we covered container networking management and even how to create your own custom container networks and attach containers to them. I hope this has been informative for you, and I'd like to thank you for viewing.
Managing Container Data Volumes
0:00Container data volumes give us a couple of ways to share data between our hosts and our containers and between our containers themselves. Let's take a look at how they work. Let's begin by looking at how to map a directory on our host directly into a container. Here on our container host, I've got a directory inside of another lab directory called mydata that contains a couple of files. Now what we're going to do is fire up a container and use the v parameter to map this directory into whatever directory we would like within the container. So in the PowerShell console here, we're going to do a Docker run.
0:31We'll run this as an interactive session. We're going to use the v parameter here and specify first our source directory here on the host, which is C colon backslash nuggetlabs backslash mydata. Then we add a colon. And now we specify our destination inside of the container, and this can be anything. I'll just map this to a directory called data within the container. Now all we need to do is specify our container image. We'll do Microsoft/nanoserver and we'll launch right into a PowerShell session.
1:02So inside of the container, if we do an ls or dir, we should now see a data directory. And if we look inside of there, we should see those files available to us. We could also create a file here, and we'll see it out on the host. Let's do a new item. We'll specify our type here as file, and we'll specify the path here. And it's C colon backslash data backslash new file.txt. And we'll just put a value in there of hello. That looks good. So if we create that, it's now on the system.
1:34So if we do an ls data, we should see that new file there. And back on the host, we should also see that new file with the value hello within. So that's a nice easy way to map a directory on the host to a container. But what if we wanted to share data between containers? What I'm going to do here is exit out of this container, which will spin it down and we'll clear the screen. Now I'm going to recall a few commands ago. And what we're going to do is just modify the syntax a little bit. We're going to remove the path to this directory, and we're just going to specify a label here.
2:04This is going to be the label of the data volume. So we'll hit Enter to fire up this container. Now inside of this container, let's do another ls, and we mapped it to the same directory within. But it's not mapped anything on the outside. It's a data volume controlled and contained within Docker. Now currently, there is no data within there. So let's make another file here. We'll do a new item. The type here will be file. The path will be to that local path here, C colon backslash data. We'll call this new file.txt, and the value we'll put in here once again will be hello.
2:38Now let's leave this container running. I'm going to control pq out of it. And let's recall it last run command, and let's run it again. This will fire up another container. So we'll have two running. And both of these containers are referencing that mydata data volume there, so they'll both be able to see that storage. So if we do an ls here, we should see that data volume. And if we do an ls pointing at that data volume, we should see that new file from another container. And if I control pq out of this, we can do a Docker ps, and we should see both of those running containers.
3:11There they are-- dazzling_bardeen and zen_feisten-- both of them pointing to that same data volume. Let's take this the rest of the way in the ISE. These are all of the commands that we just went through. But we can also manage these volumes here using Docker volume. So if we execute this, it should list that one data volume here called mydata. There it is. We can also inspect this data volume here by running a Docker volume inspect to get more details about it, and of course, you can remove these as well with a docker volume rm.
3:43In this CBT Nugget, we covered container data volumes. We looked at how to share data between hosting containers, as well as sharing data between containers. I hope this has been informative for you, and I'd like to thank you for viewing.
Managing Resource Control
0:00Placing resource controls in our containers will ensure that they do not compromise the resources of our host. Those resources are things like memory, CPU, and storage. This is very similar to what we do with virtual machines to ensure that they do not suck down all the resources of our Hyper-V host. Let's take a look at how this works with containers. From the desktop of our container host, let's jump right into the PowerShell ISE. Now we place resource controls on containers when we create them, so this is all done through the Docker run command. And let's take a look at the help for this command.
0:32We'll go full view here. And starting from the top, you can see we have a good amount of CPU controls available to us. Some of the big ones here are going to be CPU count-- the number of CPUs that our containers can utilize, as well as CPU percentage. We can control the overall utilization across all of our CPUs expressed as a percentage. Another good one is CPU shares, which allows us to setup a relative weight amongst other containers, so we can give our more critical workloads priority access to our CPUs. You can also use CPU set-CPUs here to control the number of cores that our containers are allowed to access.
1:07And as we scroll down here, we can also see we've got some storage-related controls I/O max bandwidth and I/O max ops. These work just like they do with virtual machines in Hyper-V to limit bandwidth and iApps down on the disk subsystem. As we scroll further down here, we also have a handful of memory controls. The big ones here are the first two-- memory and memory reservation. Memory is a hard limit, meaning that our containers will never be able to consume more than what we define here, and memory reservation is a soft limit, which means it can go above that to complete its tasks.
1:41And those are big three-- CPU, disk, and memory. Now, if we head back here to code view, here's how we can utilize it-- dock or run, specify your option. And just a quick note here, G is for gigabytes. M is for megabytes. B is for bytes. So those are the abbreviations you can use. Our first one here is going to limit memory to 1 gigabyte and CPU utilization to 20%. Our second one here will limit storage utilization I/O max bandwidth to 50 megabytes and max IOPS to 100 megabytes.
2:12Another important note here is that these values are not allocated upon container creation. These are just limits the-- ceiling in fact, we can prove that if we fire up Task Manager. We'll go to More Details here over to performance, and what we're going to do here is let's run this first command here. So I'm just going to copy this to the clipboard if I can hit it. There we go. And now we'll head into the PowerShell console, paste that in there, and execute. Now you'll notice here that our utilization is going to go up a little bit here while it creates the container, but it's not going to allocate that full gig of memory.
2:47And there you go. It took a second, but we're inside of the container. And you can see that memory barely went up. It went up like 100 megs at most. One more thing-- a bit of useful information here as I Control-PQ out of that is you can use a docker inspect against that container to view those settings. In fact, here first, we actually need to do a docker PS since we didn't name it. And now we can do a docker inspect 9F-- the first couple of characters there of that container ID. And as you just scroll up here, you can see all of these controls within.
3:19There's our CPU percent set to 20%. And if we scroll a little higher here, we can see memory set at a gigabyte. In this CBT Nugget, we covered how to control resource utilization at the container level through the docker run command. I hope this has been informative for you, and I'd like to thank you for viewing.
Managing Container Images using DockerHub Repository
0:00One of Docker's greatest assets is the Docker Hub. This allows us to create public and private repositories where we can centrally store our images and access them from anywhere. In this Nugget, we're going to look at how to create a Docker Hub repository, and then push images to it and pull images from it. Here we are in the Docker Hub. I fired up a browser, navigated to Hub.Docker.com and logged in. I also wiped my account here. So I currently have no repositories within. If we had the repositories link at the top, we can create one from scratch here. I'm going to Create Repository.
0:32Here we can give it a name. I'm going to call this Nugget Lab. That's important, because we'll need to have that in the name of our image. We can also give it a description here. And then we can specify our visibility. I'll create a private repository. Once that done, we'll head down to the bottom here and choose Create. And now we have a bucket to store our images. Also notice on the right, it provides us with an example for pushing images into this repo. Let's head over to our container host and do just that. Here we are on CN Nug. Let's get right into the PowerShell ISE.
1:03The first thing we're going to do here is take a peek at our local image repository. We have a couple of images to work with here, both of our Nugget Lab ISIS images. But again, we are going to need to rename these or create new images with new names to line up with that repo name. So we're going to run a couple of Docker tags here, and rename our IIS image to the name of the repository colon IIS. And then our image with my site on it, we'll rename that to Latest. With that done, we can rerun a Docker images here, just to verify that indeed, this looks good.
1:33So we've got our latest image with our site on it, and our image with just IIS installed. Now it's time to log into the Docker Hub. And this is another one of those camp commands here that doesn't work in the ISE. It freezes up. So let's take this into the PowerShell console, and run a Docker log in. Now I've already done this before, so my credentials were cached. If this is your first time doing it, it will prompt you for a username and password. You enter those in, log in succeeded. And we're back at the command prompt. So now that we're logged in, we can push our images into that repository using a Docker push, and the name of our local image here, which is CBT Schulte Nugget Lab colon.
2:10We'll push our latest one up there. And that's it. And you can see here, this will just take a minute, as it is a little over 300 megs. With that done, let's do one more. I'm going to recall my last command here. And we'll change latest to IIS. Now that push finished up, and we're back here in our repository in the Docker Hub. And I refreshed the page, and check it out. We've got two images up here. There's our latest, and there's our IIS image. So that's all there is to pushing images up there, pretty straightforward process. What about pulling them down?
2:42Well, let's head back into our container host here. And let's start by removing those local images that we just uploaded. And then we'll re-download them. There it is. That's gone. If we look at our local image repository here, we should see those are gone. And let's just pull the latest image from that repository. Here, we just do a Docker pull rather than a Docker push, targeting our specific image tag there in that repo. And now it's pulling it down. And it's done already. Didn't take long at all. If we do a Docker images one more time, we should now see it's in.
3:13So as you can see, the Docker Hub is just a fantastic feature that's incredibly easy to work with here, using Docker push and pull. And we can access that repository from anywhere. Our container hosts running in our data center in the cloud. As long as we have internet access, we can access these babies from anywhere. In this CBT Nugget, we covered the purpose of Docker Hub, as well as how to create a repository, push images to it and pull images from it. I hope this has been informative for you. And I'd like to thank you for viewing.
Managing Container Images using Microsoft Azure
0:00Microsoft Azure gives us yet another method for storing our container images in the cloud. That service is known as container registries. In this Nugget, we're going to look at how to create our own repository using the Azure web portal and then push and pull images to and from it. Here we are in our container host, CN-NUG, and our first task here is to create a Container Registry using the Azure web portal. I've got a browser opened up, and I've already logged into portal.azure.com. We're at the home page here. And what we need to do is hit create a resource, and we can just search here for containers.
0:32And there's a lot of other great container services up here. The big one here is Container Instances, by the way, which we'll host and automatically run your containers for you so you don't have to worry about spinning up and managing a container host. We're interested in this one right here, Container Registry. Here we get a nice overview of what this service provides. Its primary use is for storing and managing container images. We're going to head down here and choose Create. Here we provide it a name. I'm going to call this one Nugget lab. And then you can choose your subscription, your resource group. I've already got a resource group in here. So I'll just reuse that one.
1:03Choose your location here-- I'm in east US. And then you can also set up an admin user and specify your SKU here. We'll go with standard. So this looks great. This will create our container where we can store all of these images. A minute or so later and check it out, deployment succeeded. We can hit this link to go directly to that resource, or we can come down here to all resources. It's the only resource I have in here, currently, and there it is. We can head into here. And this will take us right to the overview page. The most important data point on the Overview page is the login server right here. We're going to need to tag our images accordingly, so they land in the appropriate registry here.
1:37So we'll just make a mental note of this, and that's all we need to do here in the Azure web portal. Now we can come to our local machine and into the PowerShell ISE. Now at this point, you will need the Azure CLI installed on your container host, and I've already walked through that. It's a very simple installation. That'll give us access to all of the command line utilities for interacting with Azure. So the first thing we're going to do here is run an AZ log in. This will fire up another browser window here that we can use to log in to the Azure web portal and all those services.
2:09There we go. I'm already signed in, so I'll just choose this. And look at that-- we have logged in to Microsoft Azure through the command line. Now next up, we're also going to need to log into the actual Container Registry that we created. Again, I named my Nugget lab here. So we'll do AZ, which is Azure Container Registry log in and then pass to the name parameter here the name of that registry. And this will log us in. And what this will allow us to do then is use Docker commands locally to push and pull our images to that repository. So that's a really nice touch that we can use our existing tools and knowledge of Docker to manage images in the Azure Container Registry service.
2:46All right, let's push an image up there. Let's take a peek at our local image repository where we have a Nugget lab IIS image ready to go. Now we are going to need to rename that using that log in server here, which is again the name of your Container Registry.azurecr.io. So we're going to retag this image right here-- essentially copy and paste it with a new name into our local repository that we can then upload to that cloud-based repository. So we'll run a Docker tag there. That's done. And now we can take another peek at our local repository, and we can see that it is named and tagged correctly.
3:20Now they're all set up. We can use a Docker push to push that image up there to that Azure Container Registry. And there it is-- Docker doing its thing. All right, and that push completed successfully. Now if we head back into the portal, we can give this a refresh here. And now if we scroll down, we can take a look at some of these metrics here, and we should have one image pushed. And there it is right there. We can also head down here to repositories. That's the technical name here for images. And there is that image.
3:51We can head into it and get the details here of this image, tag latest. Now let's head back to the ISE and pull that image down-- pretty simple process here. First, we'll remove our local repo image there. All right, that's gone. And now we can pull it from Azure, just like we would pull it from anywhere else-- a Docker pull there referencing that image up in that container repository. So I'll run this, and this will just take a second to pull it back down. And that's all there is to it-- a very simple service to use. So for those organizations that have an Azure implementation in place, you can just use this rather than Docker hub for storing container images in this CBT Nugget, we covered how to manage container images using Microsoft Azure's Container Registry service.
4:32I hope this has been informative for you, and I'd like to thank you for viewing.
Managing Windows Containers Lab
0:00It's time for another virtual lab where you'll have the opportunity to get hands-on with managing Windows containers. Let's take a look at some of the tasks we'll challenge you to accomplish in this lab. We have another small virtual lab environment here containing just a couple of machines where you'll be spending all of your time on our container host, CN-NUG, creating and managing images, as well as containers. Your first task will be to create container images manually using the Docker commit command. We have to base operating system images already installed in the local repository and ready to go.
0:32You have a Server Core in a Nano Server image, so you can fire up the Server Core image, install IIS into it, and then you use Docker commit to save that image in the local repository. Your first task will be to create container images manually. Now CN-NUG already has two base operating system container images installed on it-- Server Core and Nano Server-- both ready to go in that local repo. So fire up a development container based on that Server Core image, install IIS into it, and then create your own custom image using Docker commit.
1:03Then you could spin that container back up, copy a website into it, and create and save another image using Docker commit that's tagged with my site. So you'll get some experience there creating and tagging images manually. From there, you can take all of those tasks you performed, wrap them into a Docker file, and automate the process of building these images using Docker build. From there, you have a handful of container management tasks-- work with container networking by creating your own custom transparent network and even modifying the default NAT network. You can also work with data volumes by mapping a directory from the host into a container, as well as creating shared data volumes to share them between containers and finally, spin up containers by placing resource limits on them for memory, CPU, and storage.
1:48With that, let's jump into our virtual lab environment, so I can give you a quick tour, show you where to find things, and get you started with this lab . Here we are in our container host, CN-NUG and inside of the Nugget lab directory is where you can find all of these scripts to perform many of these tasks. Another thing I want to point out here is that you can launch these in the ISE and copy and paste them into the PowerShell console. You want to stick with this for running commands just to avoid potentially the ISE freezing up on you. And I also want to show you here if we run a Docker images, we have just a couple of base OS images ready to go.
2:20There's Server Core, and there is Nano Server. So that's your starting point. And as always, good luck. If you need any assistance, refer to the Nuggets in the Manage Windows container section. In this CBT Nugget, we've provided you with access to our virtual lab environment, so you can get hands on with managing Windows containers. I hope this has been informative for you, and I'd like to thank you for viewing.
Frequently asked questions
What does the Implement Windows Containers lesson cover?
The lesson explains how containers use layered images and a shared OS kernel compared with virtual machines, then walks through installing Docker and the Windows Containers feature on a container host with PowerShell. Learners also configure Docker startup options in daemon.json, manage Windows Server containers with the Docker CLI, build a custom image with a Dockerfile, and map host directories and shared data volumes with the -v parameter.
How are Windows containers different from virtual machines?
The lesson describes virtual machines as thick, because each one needs its own installed and managed operating system and is less portable due to its size. Containers are built from image layers that work much like differencing disks, and many containers on a single host share the same operating system layer, with the kernel projected into each container.
How long is this lesson, and how does it fit the 70-740 course?
The lesson runs 1 hour 19 minutes and is one part of the intermediate Microsoft Windows Server 2016 Installation, Storage, and Compute (70-740) course, which takes about 18 hours per learner. The course is designed for teams with baseline Microsoft server experience, including newer admins with roughly a year of exposure, and also covers Hyper-V, storage, high availability, Windows Admin Center, and maintenance.
Which Docker startup options in daemon.json does the lesson configure?
The lesson covers data-root to move the local image repository off the default C drive location, hosts to define the IP addresses and ports containers listen on, and log level and debug settings. It also shows the group option, which lets a designated Active Directory group such as DevOps run Docker CLI commands instead of limiting access to local administrators over named pipes.
Does the lesson include hands-on lab work with Windows containers?
Yes. In the virtual labs, the team member works on a container host named CN-NUG to install Docker and container support, configure startup options, and handle management tasks such as creating a custom transparent network, modifying the default NAT network, working with data volumes, and placing memory, CPU, and storage limits on containers, with reference scripts in the Nugget Lab directory.
How can a Training Manager assign this lesson and track team completion?
Team Leads can assign the course before virtualization projects or server refresh work so admins share the same approach to containers and Windows Server 2016 compute. Training Managers can use CBT Nuggets Playlists to sequence the content and Team Reporting to view per-learner progress and completion, including completion exports for audit evidence.
Team training path
Turn this skill into assignable team training
This free skill is a preview of the courses your team can assign, track, and report on with CBT Nuggets.
Free training library
More free lessons from CBT Nuggets
Microsoft Windows Server
Microsoft PowerShell 4 Foundations
Free lesson from PowerShell · 7h 57m
Microsoft Windows Server
Administer Active Directory Domain Services
Free lesson from Microsoft Server 2019 Essentials · 1h 21m
DevOps
Docker (v18.06.3)
Free lesson from Docker · 2h 6m
Networking
Border Gateway Protocol (BGP): Basic Operations
Free lesson from Border Gateway Protocol (BGP) · 60m
Networking
Define Wireless Network Architectures
Free lesson from Wireless Design Professional Training · 55m
Python
Introduction to Programming and Python
Free lesson from Certified Associate in Python Programming (PCAP) · 57m
$59
seat / mo, billed annually
