25,19 €
Build and deploy scalable cloud applications using Windows containers and Kubernetes
With the adoption of Windows containers in Kubernetes, you can now fully leverage the flexibility and robustness of the Kubernetes container orchestration system in the Windows ecosystem. This support will enable you to create new Windows applications and migrate existing ones to the cloud-native stack with the same ease as for Linux-oriented cloud applications.
This practical guide takes you through the key concepts involved in packaging Windows-distributed applications into containers and orchestrating these using Kubernetes. You'll also understand the current limitations of Windows support in Kubernetes. As you advance, you'll gain hands-on experience deploying a fully functional hybrid Linux/Windows Kubernetes cluster for development, and explore production scenarios in on-premises and cloud environments, such as Microsoft Azure Kubernetes Service.
By the end of this book, you'll be well-versed with containerization, microservices architecture, and the critical considerations for running Kubernetes in production environments successfully.
This book is for software developers, system administrators, DevOps engineers, and architects working with Kubernetes on Windows, Windows Server 2019, and Windows containers. Knowledge of Kubernetes as well as the Linux environment will help you get the most out of this book.
Piotr Tylenda is an experienced DevOps and software engineer with a passion for Kubernetes and Azure technologies. In his projects, he has focused on the adoption of microservices architecture for monolithic applications, developing big data pipelines for e-commerce, and architecting solutions for scalable log and telemetry analytics for hardware. His most notable contribution to Kubernetes' open source ecosystem is the development of Ansible automation for provisioning and deploying hybrid Windows/Linux Kubernetes clusters. Currently, he works at Microsoft Development Center Copenhagen in Denmark in a team developing a Microsoft Dynamics 365 Business Central SaaS offering.Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 614
Veröffentlichungsjahr: 2020
Copyright © 2020 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Vijin BorichaAcquisition Editor:Shrilekha InaniContent Development Editor:Ronn KurienSenior Editor: Richard Brookes-BlandTechnical Editor: Dinesh PawarCopy Editor: Safis EditingProject Coordinator:Neil DmelloProofreader: Safis EditingIndexer:Manju ArasanProduction Designer:Deepika Naik
First published: March 2020
Production reference: 1300320
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-83882-156-2
www.packt.com
Packt.com
Subscribe to our online digital library for full access to over 7,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Fully searchable for easy access to vital information
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Piotr Tylenda is an experienced DevOps and software engineer with a passion for Kubernetes and Azure technologies. In his projects, he has focused on the adoption of microservices architecture for monolithic applications, developing big data pipelines for e-commerce, and architecting solutions for scalable log and telemetry analytics for hardware. His most notable contribution to Kubernetes' open source ecosystem is the development of Ansible automation for provisioning and deploying hybrid Windows/Linux Kubernetes clusters. Currently, he works at Microsoft Development Center Copenhagen in Denmark in a team developing a Microsoft Dynamics 365 Business Central SaaS offering.
Amit Malik is an IT enthusiast and technology evangelist focused on cloud and emerging technologies. He is currently employed by Spektra Systems as the director of technology, where he helps Microsoft partners grow their cloud businesses by using effective tools and strategies. He specializes in the cloud, DevOps, software-defined infrastructure, application modernization, data platforms, and emerging technologies around AI. Amit holds various industry-admired certifications from all major OEMs in the cloud and data space, including Azure Solutions Architect Expert. He is also a Microsoft Certified Trainer (MCT). Amit is also an active community member for various technology groups and is a regular speaker at industry conferences and events.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Hands-On Kubernetes on Windows
About Packt
Why subscribe?
Contributors
About the author
About the reviewer
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Get in touch
Reviews
Section 1: Creating and Working with Containers
Creating Containers
Technical requirements
Linux versus Windows containers
Docker containerization on Linux
Docker containerization on Windows
Key differences between containers on Linux and Windows
Understanding Windows container variants
Process isolation
Hyper-V isolation
Linux containers on Windows
LinuxKit and MobyLinuxVM
LinuxKit LCOW and Hyper-V isolation
Installing Docker Desktop for Windows tooling
Stable and Edge channels
Installation
Verifying the installation
Running process-isolated containers
Running LCOW containers
Building your first container
Preparing a Visual Studio Code workspace
Creating a sample HTML web page
Creating a Dockerfile
Building a Docker image
Running Windows containers
Inspecting container logs
Exec into a running container
Summary
Questions
Further reading
Managing State in Containers
 Technical requirements
Mounting local volumes for stateful applications
Volumes and bind mount
Creating and mounting volumes
Removing volumes
Mounting a local container host directory using bind mounts
Using remote/cloud storage for container storage
Installing the Azure CLI and Azure PowerShell module
Creating Azure Files SMB share
Mounting Azure Files SMB share in a container
Running clustered solutions inside containers
Creating a MongoDB ReplicaSet
Writing and reading test data
Summary
Questions
Further reading
Working with Container Images
Technical requirements
Storing and sharing container images
Pushing an image to the Docker registry
Using a custom local registry
Using cloud container builders
Creating a GitHub repository
Creating a Docker Hub repository with autobuild
Triggering the Docker Hub autobuild
Creating Azure Container Registry
Building a Docker image using Azure Container Registry
Automatic builds for Azure Container Registry
Image tagging and versioning
Using the latest tag
Semantic versioning 
Ensuring the integrity of the image supply chain
Signing an image
Enabling DCT for the client
Summary
Questions
Further reading
Section 2: Understanding Kubernetes Fundamentals
Kubernetes Concepts and Windows Support
Technical requirements
Kubernetes high-level architecture
What is Kubernetes?
Kubernetes master – control plane
kube-apiserver
etcd cluster
kube-scheduler
kube-controller-manager
cloud-controller-manager
Kubernetes nodes – data plane
kubelet
Container runtime
kube-proxy
DNS
Kubernetes objects
Pods
ReplicaSets
Deployments
StatefulSets
DaemonSets
Services
Storage-related objects
The Windows and Kubernetes ecosystem
Kubernetes limitations on Windows
Creating your own development cluster from scratch
minikube
Docker Desktop for Windows
Production cluster deployment strategies
kubeadm
kops
kubespray
AKS Engine
Managed Kubernetes providers
Creating AKS cluster with Windows nodes
Summary
Questions
Further reading
Kubernetes Networking
Technical requirements
Kubernetes networking principles
L2 network
Overlay network
Other solutions
Services
ClusterIP
NodePort
LoadBalancer
ExternalName
Ingress
Kubernetes CNI network plugins
Understanding the CNI project
CoreOS Flannel
Windows Server networking in Kubernetes
Limitations
Choosing Kubernetes network modes
L2Bridge
L2Tunnel
Overlay
Transparent
Summary
Questions
Further reading
Interacting with Kubernetes Clusters
Technical requirements
Installing Kubernetes command-line tooling
Accessing Kubernetes clusters
Working with development clusters
Looking at common kubectl commands
Creating resources
Deleting resources
Describing and listing resources
Editing resources
Running an ad hoc Pod
Accessing Pod container logs
Execcing into a Pod container
Copying Pod container files
Port forwarding and proxying traffic
Summary
Questions
Further reading
Section 3: Creating Windows Kubernetes Clusters
Deploying a Hybrid On-Premises Kubernetes Cluster
Technical requirements
Preparing the Hyper-V environment
Enabling Hyper-V
Creating an internal NAT Hyper-V vSwitch
Creating an external Hyper-V vSwitch
Creating a Kubernetes master node using kubeadm
Creating a VM and installing Ubuntu Server
Creating the VM
Installing Ubuntu Server
Configuring the network
Installing additional packages for integration with Hyper-V
Setting up a passwordless SSH login
Installing and configuring Kubernetes prerequisites
Planning the cluster
Initializing the cluster
Installing the Kubernetes network
Preparing VMs for Windows nodes
Creating the VM
Installing Windows Server 2019
Configuring the network
Installing the SSH server
Installing and configuring Kubernetes prerequisites
Joining Windows nodes using kubeadm
Deploying and inspecting your first application
Summary
Questions
Further reading
Deploying a Hybrid Azure Kubernetes Service Engine Cluster
Technical requirements
Installing AKS Engine
Creating an Azure resource group and a service principal
Using apimodel and generating an Azure resource manager template
Deploying the cluster
Deploying and inspecting your first application
Basic operations
Connecting to virtual machines
Enabling Azure Log Analytics and Azure Monitor for containers
Summary
Questions
Further reading
Section 4: Orchestrating Windows Containers Using Kubernetes
Deploying Your First Application
Technical requirements
Imperatively deploying an application
Using Kubernetes manifest files
Scheduling Pods on Windows nodes
Accessing your application
Scaling the application
Summary
Questions
Further reading
Deploying Microsoft SQL Server 2019 and a ASP.NET MVC Application
Technical requirements
Creating and publishing an ASP.NET MVC application to Docker Hub
Injecting the configuration using environment variables
Configuring logging for Windows containers log monitor
Creating a Dockerfile
Building and pushing the Docker image
Preparing the AKS Engine
Deploying a failover Microsoft SQL Server 2019
Deploying the ASP.NET MVC application
Accessing the application
Scaling the application
Debugging the application
Creating a debug Dockerfile and publishing a debug image
Updating the Kubernetes Deployment
Attaching the Visual Studio remote debugger
Summary
Questions
Further reading
Configuring Applications to Use Kubernetes Features
Technical requirements
Using namespaces to isolate applications
Creating namespaces
kubectl commands and namespaces
Deleting namespaces
Health monitoring using liveness and readiness probes
Readiness probes
Liveness probes
Startup probes
Specifying resource limits and configuring autoscaling
Resource requests and limits
HPA
Managing application configuration using ConfigMaps and Secrets
Managing persistent data storage on Windows nodes
Configuring rolling updates for Deployments
Role-Based Access Control
Summary
Questions
Further reading
Development Workflow with Kubernetes
Technical requirements
Using developer tooling with Kubernetes
Visual Studio 2019
Visual Studio Code
Packaging applications using Helm
Installing Helm
Deploying Microsoft SQL Server using Helm
Creating a Helm chart for our Voting application
Debugging a containerized application using Azure Application Insights
Enabling Azure Application Insights
Snapshot debugger
Using Kubernetes Dashboard
Deploying Kubernetes Dashboard
Accessing pod container logs
Executing commands in a pod container
Working on microservices in a team using Azure Dev Spaces
Summary
Questions
Further reading
Securing Kubernetes Clusters and Applications
Technical requirements
Securing Kubernetes clusters
Using built-in RBAC for authorization 
Using an external authentication provider
Bootstrapping the cluster using kubeadm
Disabling public API access
Disabling the public Dashboard
Running containers in nonprivileged mode
Encrypting data at rest
Using network policies
Securing the image supply chain and scan images
Rotating infrastructure credentials and certificates
Enabling audit logging
Integrating AAD with AKS Engine
Securing container runtime in Windows
Deploying secure applications using network policies
Network policy support
Configuring network policy
Kubernetes secrets on Windows machines
Summary
Questions
Further reading
Monitoring Kubernetes Applications Using Prometheus
Technical requirements
Available monitoring solutions
Prometheus and monitoring Windows nodes
Provisioning observable Windows nodes
Installing WMI Exporter and enabling Metrics Server in Docker
Using extensions for AKS Engine
Deploying Prometheus using a Helm chart
Installing Helm charts
Verifying the Deployment
Windows Performance Counters
Extending a Docker image with the Telegraf service
Deploying an observable version of the voting application
Monitoring .NET applications using prometheus-net
Installing the NuGet package and adding metrics
Deploying the new version of the voting application
Configuring dashboards and alerts in Grafana
Adding visualizations
Configuring alerting
Summary
Questions
Further reading
Disaster Recovery
Technical requirements
Kubernetes cluster backup strategy
Backing up an etcd cluster
Restoring the etcd cluster backup
Automating backup
Replacing a failed etcd cluster member
Summary
Questions
Further reading
Production Considerations for Running Kubernetes
Technical requirements
Provisioning clusters reproducibly
Infrastructure as code for clusters
GitOps for application workloads
Kubeadm limitations
Upgrading clusters
OS patching
Configuring a network proxy for the Docker daemon and Kubernetes
Summary
Questions
Further reading
Assessments
Chapter 1: Creating Containers
Chapter 2: Managing State in Containers
Chapter 3: Working with Container Images
Chapter 4: Kubernetes Concepts and Windows Support
Chapter 5: Kubernetes Networking
Chapter 6: Interacting with Kubernetes Clusters
Chapter 7: Deploying a Hybrid On-Premises Kubernetes Cluster
Chapter 8: Deploying a Hybrid Azure Kubernetes Service Engine Cluster
Chapter 9: Deploying Your First Application
Chapter 10: Deploying Microsoft SQL Server 2019 and ASP.NET MVC Applications
Chapter 11: Configuring Applications to Use Kubernetes Features
Chapter 12: Development Workflow with Kubernetes
Chapter 13: Securing Kubernetes Clusters and Applications
Chapter 14: Monitoring Kubernetes Applications Using Prometheus
Chapter 15: Disaster Recovery
Chapter 16: Production Considerations for Running Kubernetes
Other Books You May Enjoy
Leave a review - let other readers know what you think
Starting with version 1.14, Kubernetes has brought the most anticipated feature of the year 2019: production-level support for Windows Server container workloads. This is a huge milestone that enables migration to cloud-native technologies for all enterprises that rely heavily on Windows technologies at their core. Developers and system operators can now leverage the same tools and pipelines to deploy both Windows and Linux workloads, scale them in a similar way, and undertake efficient monitoring. From a business perspective, container adoption for Windows means lower operational costs and better hardware utilization than plain VMs.
You are holding in your hands a book that will guide you in terms of how to use Kubernetes and Docker containers in the Microsoft Windows ecosystem – it covers both hybrid Windows/Linux Kubernetes cluster deployment and handles cluster operations using a Windows client machine. Since support for Windows in Kubernetes is a fairly new concept, you can expect the official documentation and guides to still be scarce. In this book, we aim to systematize your knowledge regarding Kubernetes scenarios that involve Windows. Our aim was to create the ultimate guide for Kubernetes on Windows.
The primary audience for this book is Kubernetes DevOps architects and engineers who need to integrate Windows container workloads into their Kubernetes clusters. If you are a Windows application (especially .NET Framework) developer and you haven't used Kubernetes yet, this book is also for you! In addition to the strategies regarding the deployment of hybrid Windows/Linux Kubernetes clusters, we cover the fundamental concepts behind Kubernetes and how they map to the Windows environment. And if you are interested in migrating existing .NET Framework applications to Windows Server containers running on Kubernetes, you will definitely find guidance in terms of how to approach this problem.
Chapter 1, Creating Containers, describes different container types that are currently used, in particular, across the Linux and Windows operating systems. The main objective of this chapter is demonstrating how to build a sample Windows container, run it, and perform basic operations.
Chapter 2, Managing State in Containers, discusses the possible approaches for managing and persisting state in containerized applications and explains how to mount local and cloud storage volumes (Azure Files SMB share) on containers in order to run clustered database engines such as MongoDB using Windows containers.
Chapter 3, Working with Container Images, focuses on container images, which are the standard way of distributing containerized applications. The objective of this chapter is to demonstrate how to use Docker Hub and Azure Container Registry and how to deliver container images safely in deployment pipelines.
Chapter 4, Kubernetes Concepts and Windows Support, familiarizes you with core Kubernetes services such as kubelet, kube-proxy, and kube-apiserver, as well as the most commonly used Kubernetes objects, such as Pod, Service, Deployment, and DaemonSet. You will learn why Windows support in Kubernetes is important and what the current limitations are as regards Windows containers and Windows nodes. We will also focus on creating simple development Kubernetes clusters for different use cases.
Chapter 5, Kubernetes Networking, describes the networking model of Kubernetes and available Pod network solutions. You will learn how to choose the most suitable networking mode for Kubernetes clusters with Windows nodes.
Chapter 6, Interacting with Kubernetes Clusters, shows how to interact and access Kubernetes clusters from a Windows machine using kubectl. As an example, we will show how to work with local development clusters and what the most common and useful kubectl commands are.
Chapter 7, Deploying Hybrid On-Premises Kubernetes Clusters, demonstrates how to approach the provisioning of VMs and the deployment of hybrid Windows/Linux Kubernetes clusters with Linux master/nodes and Windows nodes. On-premises deployment is the most universal type of deployment as it can be performed using any cloud service provider or in a private data center.
Chapter 8, Deploying Hybrid Azure Kubernetes Service Engine Clusters, provides an overview of how to approach the deployment of a hybrid Windows/Linux Kubernetes cluster using AKS Engine and demonstrates an example deployment of a sample Microsoft IIS application.
Chapter 9, Deploying Your First Application, demonstrates how to deploy a simple web application to Kubernetes imperatively and declaratively and discusses the recommended way to manage applications running in Kubernetes. We will also cover scheduling Pods on Windows nodes exclusively and how to scale Windows applications running on Kubernetes.
Chapter 10, Deploying a Microsoft SQL Server 2019 and ASP.NET MVC Application, describes how to deploy a sample voting application implemented in ASP.NET MVC (running in Windows containers) to an AKS Engine cluster, together with Microsoft SQL Server 2019 (running in Linux containers). You will also learn how you can debug .NET applications running in Kubernetes using Visual Studio Remote Debugger.
Chapter 11, Configuring Applications to Use Kubernetes Features, describes how to implement and configure more advanced features of Kubernetes, including namespaces, ConfigMaps and Secrets, persistent storage, health and readiness checking, autoscaling, and rolling deployments. This chapter also shows how role-based access control (RBAC) works in Kubernetes.
Chapter 12, Development Workflow with Kubernetes, shows how to use Kubernetes as a platform for microservices development. You will learn how to package applications using Helm and how to improve your development experience using Azure Dev Spaces. Additionally, the chapter describes how to use Azure Application Insights and Snapshot Debugger for your containerized application running in Kubernetes.
Chapter 13, Securing Kubernetes Clusters and Applications, covers the security of Kubernetes clusters and containerized applications. We will discuss the general recommended security practices for Kubernetes and Windows-specific considerations.
Chapter 14, Monitoring Kubernetes Applications Using Prometheus, focuses on how to approach the monitoring of Kubernetes clusters, especially Windows nodes and .NET applications running on Windows nodes. You will learn how to deploy a full monitoring solution using a Prometheus Helm chart and how to configure it to monitor your applications.
Chapter 15, Disaster Recovery, discusses backing up a Kubernetes cluster and disaster recovery strategies. The main focus is to show what components require backups in order to restore the cluster safely and how to automate this process.
Chapter 16, Production Considerations for Running Kubernetes, is a set of general recommendations for running Kubernetes in production environments.
Having some general knowledge of Docker and Kubernetes is advised but not required. We are going to cover the fundamental concepts of containerization on Windows and Kubernetes itself in dedicated chapters. For those chapters that focus on the deployment of Windows applications to Kubernetes, it is recommended that you have basic experience with .NET Framework, C#, and ASP.NET MVC. Please note that for each guide and example in this book, there is a counterpart available in the official GitHub repository: https://github.com/PacktPublishing/Hands-On-Kubernetes-on-Windows
Throughout the book, you will require your own Azure subscription. You can read more about how to obtain a limited free account for personal use here: https://azure.microsoft.com/en-us/free/.
Software/Hardware covered in the book
OS Requirements
Visual Studio Code, Docker Desktop, Kubectl, Azure CLI with 16 GB RAM
Windows 10 Pro, Enterprise, or Education (version 1903 or later; 64-bit), Windows Server 2019, Ubuntu Server 18.04
If you are using the digital version of this book, we advise you to type the code yourself or access the code via the GitHub repository (link available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packt.com
.
Select the
Support
tab.
Click on
Code Downloads
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Hands-On-Kubernetes-on-Windows. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: http://www.packtpub.com/sites/default/files/downloads/9781838821562_ColorImages.pdf.
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "Mount the downloaded WebStorm-10*.dmg disk image file as another disk in your system."
A block of code is set as follows:
html, body, #map { height: 100%; margin: 0; padding: 0}
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
[default]exten => s,1,Dial(Zap/1|30)exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
Any command-line input or output is written as follows:
$ mkdir css
$ cd css
Bold: Indicates a new term, an important word, or words that you see on screen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "Select System info from the Administration panel."
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in, and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
The objective of this section is to present different containerization technologies and the benefits of choosing one variant over another. You will see how to containerize an application on Windows and understand the key steps involved in creating and maintaining the images.
This section contains the following chapters:
Chapter 1
,
Creating Containers
Chapter 2
,
Managing State in Containers
Chapter 3
,
Working with Container Images
The concepts of containers and OS-level virtualization have their roots in the chroot system call in Unix V7 operating systems (OSes), which date back to the late 1970s. Starting with a simple concept of process isolation and chroot jails, where the process is running in an apparently isolated root directory, containerization has undergone rapid evolution and became a mainstream technology in the 2010s with the advent of Linux Containers (LXC) and Docker. In 2014, Microsoft announced support for Docker Engine in the incoming release of Windows Server 2016. This is where the story of Windows containers and Kubernetes on Windows begins.
In this chapter, we will provide you with a better understanding of containers for the Windows OS by highlighting important differences between containerization on Linux and Windows and container runtime types on Windows, namely Windows Server Containers (or process isolation) and Hyper-V isolation. We will also learn how to install Docker Desktop for Windows 10 for development scenarios and create our first example container running on your machine.
This chapter will cover the following topics:
Linux versus Windows containers
Understanding Windows container variants
Installing Docker Desktop for Windows tooling
Building your first container
The requirements for this chapter are as follows:
Intel Virtualization Technology
(
Intel VT
) or
AMD Virtualization
(
AMD-V
) technology
features enabled in the BIOS
A minimum of 4 GB of RAM
Windows 10
Pro, Enterprise, or Education
(version 1903 or later, 64-bit) installed
Visual Studio Code
For more information regarding the hardware requirements for running Docker and containers on Windows, please refer to https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/system-requirements.
Windows 10 versions starting with Anniversary Update (version 1607, build 14393) are supported, but version 1903 is recommended for the best experience since it comes with all the necessary features. For more details regarding Windows 10 versions and container runtimes compatibility, please refer to https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility.
Visual Studio Code can be downloaded for free from the official web page at: https://code.visualstudio.com/.
You can download the latest code samples for this chapter from this book's official GitHub repository at: https://github.com/PacktPublishing/Hands-On-Kubernetes-on-Windows/tree/master/Chapter01.
Containerization on both Linux and Windows aims to achieve the same goal – creating predictable and lightweight environments that are isolated from other applications. For Linux, a classic example of container usage can be running a Python RESTful API written in Flask, without worrying about conflicts between Python modules that are required by other applications. Similarly, for Windows, the containers can be used to host an Internet Information Services (IIS) web server that's entirely isolated from other workloads running on the same machine.
Compared to traditional hardware virtualization, containerization comes at the cost of being tightly coupled with the host OS since it uses the same kernel to provide multiple isolated user spaces. This means that running Windows containers on the Linux OS or running Linux containers on the Windows OS is not possible natively without the additional help of traditional hardware virtualization techniques.
In this book, we will focus on the Docker container platform, which is required for running containers on Windows. Now, let's summarize the current state of containerization support on Linux and Windows that's provided by Docker Engine and what the possible solutions are when it comes to development and production scenarios.
Originally, Docker Engine was developed primarily for the Linux OS, which provides the following kernel features for the Docker runtime:
Kernel namespaces
: This is the core concept for containers and makes it possible to create isolated process workspaces. Namespaces partition kernel resources (such as network stacks, mount points, and so on) so that each process workspace can access its own set of resources and ensures they can't be accessed by processes from other workspaces. This is what ensures the isolation of containers.
Control groups
: Resource usage limits and isolation is a secondary core concept in containerization. On Linux, this feature is provided by
cgroups
, which enables resource limiting (CPU usage, RAM usage, and so on) and priority access to resources for one process or a group of processes.
Layer filesystem capabilities
: On Linux,
UnionFS
is one of the many implementations of
union mount
–
a file system service that allows files and directories coming from separate filesystems to be unified into one transparent, coherent filesystem. This feature is crucial for Docker container images that consist of immutable layers. During the container runtime, the read-only layers are transparently overlaid together with a writable container layer.
Docker Engine is responsible for providing a basic runtime for containers, abstracting container management, and exposing functionalities using the REST API to the client layer, such as the Docker CLI. The architecture of Docker on Linux can be summarized with the following diagram:
From a Linux OS perspective, the container runtime architecture is presented in the following diagram. This architecture applies to container engines on Linux in general, not only Docker:
Next, we will look at Docker containerization on Windows.
In 2014, when Microsoft announced support for Docker Engine in the incoming release of Windows Server 2016, the Docker container engine had already matured on Linux and was proven to be an industry standard for container management. This fact has driven design decisions for Docker and containerization support for Windows, which eventually received a similar architecture for running process-isolated Windows Server containers. The Windows kernel features that are used by Docker Engine roughly map to the following:
Kernel namespaces
: This functionality is provided by, among others, Object Namespaces and the Process Table in the Windows kernel.
Control groups
: Windows has its own concept of
Job Objects
, which allows a group of processes to be managed as a single unit. Essentially, this feature provides similar functionality to
cgroups
on Linux.
Layer filesystem capabilities
: The
Windows Container Isolation File System
is a filesystem driver that provides a virtual filesystem view for processes that are executed in Windows containers. T
his is analogous to
UnionFS
or other implementations of
union mount
for the Linux OS.
On top of these low-level functionalities, the services layer, which consists of a Host Compute Service (HCS) and a Host Network Service (HNS), abstracts a public interface for running and managing containers with language bindings available for C# and Go (hcsshim). For more information about the current container platform tools, please refer to the official documentation at: https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/containerd#hcs.
It is important to know that there are two types of Windows containers: process-isolated and Hyper-V-isolated. The difference between them will be explained in the next section – isolation is a runtime property of the containers and you can expect them to, in general, behave similarly and differ only from a security and compatibility perspective.
The following diagram summarizes the containerization architecture and Docker support for Windows:
For comparison with the high-level architecture of containerization on Linux, the following diagram presents the multi-container runtime architecture for Windows. At this point, we are only considering process-isolated Windows Server containers, which closely resemble containers on Linux, but in the next section, we will also cover the architecture of Hyper-V isolation for containers on Windows:
Next, let's look at the some differences between containers on Linux and Windows.
Docker containers on Linux and Windows aim to solve the same problems in principle and currently, the container management experience is starting to converge on these platforms. Nevertheless, if you come from the Linux ecosystem and have used Docker extensively there, you may be surprised by some differences that you can find. Let's briefly summarize them.
The largest and the most apparent limitation is the Windows host OS and Windows container OS compatibility requirements. In the case of Linux, you can safely assume that if the host OS kernel is running the minimum required version of 3.10, any Linux container will run without any problems, no matter which distribution it is based on. For Windows, it is possible to run containers with base OS versions that are exactly the same as the host OS version that's supported without any limitations. Running a newer container OS version on an old host OS is not supported, and what's more, running older container OS versions on a newer host OS comes with the requirement of using Hyper-V isolation. For example, a host running Windows Server version 1803 build 17134 can use containers with base image version Windows Server version 1803 build 17134 natively, but running containers with Windows Server version 1709 build 16299 will require Hyper-V isolation, and starting a container with Windows Server 2019 build 17763 is not possible at all. The following table visualizes this principle:
Host OS version
Container base image OS version
Compatibility
Windows Server, version 1803 b
uild 17134
Windows Server, version 1803 b
uild 17134
Process
or
Hyper-V
isolation
Windows Server, version 1803 b
uild 17134
Windows Server, version 1709 build 16299
Hyper-V
isolation
Windows Server, version 1803 b
uild 17134
Windows Server 2019 b
uild 17763
Not supported
Windows Server 2019 build 17763
Windows Server 2019 build 17763
Process
or H
yper-V
isolation
For a more detailed compatibility matrix, please refer to the official Microsoft documentation at: https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility#choose-which-container-OS-version-to-use.
It is worth mentioning that the requirements for Hyper-V isolation may be a significant limitation in cloud environments or when running Docker on virtual machines (VMs). In such cases, Hyper-V isolation requires the nested virtualization feature to be enabled by the hypervisor. We will cover Hyper-V isolation in detail in the next section.
Another important aspect you may notice is the difference in sizes between the base images for Linux and Windows containers. Currently, the minimal Windows Server image, mcr.microsoft.com/windows/nanoserver:1809, is 98 MB in size, whereas, for example, the minimalistic image for Alpine Linux, alpine:3.7, is only 5 MB in size. The full Windows Server image, mcr.microsoft.com/windows/servercore:ltsc2019, is over 1.5 GB, while the base image for Windows, mcr.microsoft.com/windows:1809, is 3.5 GB. But it is worth mentioning that since the first release of Windows Server 2016 Core image, when the image size was 6 GB, these numbers constantly go down.
These differences can be seen more as the limitations of Docker containers on Windows. However, there is one aspect where Windows provides more flexibility than Linux – support for running Linux containers on Windows. Docker Desktop for Windows 10 supports such a scenario out of the box. Although this feature is still in development, it is possible to host Linux containers alongside Windows containers on Windows 10 with the help of Hyper-V isolation. We will cover this feature in more detail in the next section. The opposite scenario with Windows containers running on Linux has no native solution and requires manually hosting additional Windows VM on a Linux host.
In the next section, we will focus on the differences between different Windows container runtime variants.
Windows containers come in two distinct levels of isolation: process and Hyper-V. Process isolation is also known as Windows Server Containers (WSC). Initially, process isolation was available on the Windows Server OS only, whereas on desktop versions of the Windows OS, you could run containers using Hyper-V isolation. Starting with Windows 10, version 1809 (October 2018 Update) and Docker Engine 18.09.1, process isolation is also available on Windows 10.
Now, let's take a look at how these isolation levels differ, what the use cases for them are, and how to create containers by specifying the desired isolation type.
Process-isolated containers, also known as WSC, is the default isolation mode provided for containers on Windows Server. The architecture of process isolation is similar to what you have when running containers on the Linux OS:
Containers use the same shared kernel.
Isolation is provided at the kernel level using features such as process tables, object namespaces, and job objects. More information can be found in the
Docker containerization on Windows
section
.
This is summarized in the following diagram:
Process isolation provides a lightweight runtime for containers (compared to Hyper-V isolation) and offers a greater density of deployment, better performance, and lower spin-up time. However, there are a few points you should consider when using this type of isolation:
The Docker container base image has to match the version of the container host OS. For example, if you are running Windows 10, version 1903, you can only run containers that have used base image version 1903 of Windows 10 or Windows Server. This means you have to rebuild the image for each version of Windows that is being released (only major
feature updates
).
This should be only for the execution of trusted code. In order to execute untrusted code, Hyper-V isolation is advised.
With Windows 10, version 1809 and later, it is possible to use process isolation for the container runtime, provided that you are running Docker Desktop for Windows 2.0.1.0 (Edge release channel) or later and Docker Engine 18.09.1+. For Windows 10, the default isolation level for containers is Hyper-V and in order to use process isolation, it has to be specified explicitly while creating a container using the --isolation=process argument:
docker run -d --isolation=process mcr.microsoft.com/windows/nanoserver:1903 cmd /c ping localhost -n 100
This option can be also specified as a parameter to the Docker daemon using the --exec-opt parameter. For more details, please see the official Docker documentation at the: https://docs.docker.com/engine/reference/commandline/run/#specify-isolation-technology-for-container---isolation.
Hyper-V isolation is the second type of isolation available for Windows containers. In this type of isolation, each container is running inside a dedicated, minimal Hyper-V virtual machine and can be briefly summarized as follows:
Containers do not share the kernel with host OS. Each container has its own Windows kernel.
Isolation is provided at the virtual machine hypervisor level (requires Hyper-V role to be installed).
There are no compatibility limitations between the host OS version and container base OS version.
This is recommended for the execution of untrusted code and multi-tenant deployments as it provides better security and isolation.
The details of the Hyper-V isolation architecture can be seen in the following diagram:
This type of isolation comes at a cost that you have to take into account when choosing the isolation level:
Hyper-V isolation involves virtualization overhead, higher memory, and CPU usage footprint compared to process isolation, but still provides much better performance than running a full VM with Windows Nano Server. You can check the memory requirements for running containers with different isolation levels in the following table.
Container spin-up time is slower compared to process isolation.
Requires nested virtualization when used for containers running on a VM. This may be a limitation for some hypervisors and cloud deployments. The following table shows the memory requirements for Windows Server 1709 containers:
Container base image
Process isolation (WSC)
Hyper-V isolation
Nano Server
30 MB
110 MB + 1 GB pagefile
Server Core
45 MB
360 MB + 1 GB pagefile
The container images remain unchanged compared to process isolation; you only need to specify a different isolation level when creating the actual container. You can do this using the --isolation=hyperv parameter:
Note that in this case, even if you are running Windows 10, version 1903, you can use the container base image version 1809 without any limitations.
In April 2017, Docker announced LinuxKit, a solution for running Linux containers on platforms that are not shipped with the Linux kernel, namely Windows and macOS. LinuxKit is a toolkit for building portable and lightweight Linux subsystems that contain only the bare minimum for running Linux containers on a given platform. Although Docker, since the first release in 2016, was able to run Linux containers on Windows to some limited extent, the announcement of LinuxKit was the milestone that started the story of Linux Containers on Windows (LCOW) as we know them today.
Docker for Windows (which was the initial name of Docker Desktop for Windows at that time) eventually came with a dedicated Hyper-V virtual machine based on LinuxKit named MobyLinuxVM. The purpose of this virtual machine is to provide a minimal runtime for Linux containers that can technically be run side by side with Windows containers.
In this solution, MobyLinuxVM runs its own Docker daemon and technically acts as a separate container host enclosed inside a virtual machine. Similarly, Windows has its own Docker Daemon that's responsible for Windows containers and also provides the Docker Client (CLI), which communicates with both Docker Daemons. This architecture can be seen in the following diagram:
Now, let's take a look at a more up-to-date approach for running Linux containers on Windows: LinuxKit LCOW.
Contrary to the MobyLinuxVM approach, Linux Containers on Windows (LCOW) uses Hyper-V isolated containers to achieve similar results. LCOW is available for Windows 10, which comes with Docker for Windows 17.10, and for Windows Server, version 1709, which comes with a preview release of Docker Enterprise Edition.
The main difference compared to MobyLinuxVM is the possibility to natively run Linux and Windows containers side by side using the same Docker Daemon. This solution is the current strategy for supporting Linux containers running on Windows but as the long-term solution, in June 2019, Docker and Microsoft started a collaboration to integrate the Windows Subsystem for Linux version 2 as the primary Linux container runtime on Windows. Eventually, both LinuxKit LCOW and MobyLinuxVM with Docker Desktop for Windows will be retired.
The following diagram shows LCOW:
In order to enable LCOW support in Docker Desktop (version 18.02 or later), you have to enable the Experimental features option in Docker Settings > Daemon. Creating an LCOW container requires specifying the --platform linux parameter (if platform selection is unambiguous, that is, the image only exists in Linux, then it can be omitted in newer versions of Docker Desktop):
docker run -it --platform linux busybox /bin/sh
The preceding command will create a busybox Linux container and enter the interactive Bourne shell (sh).
In this section, you learned how containers are currently supported on the Windows platform and the key differences between the provided runtimes. Now, we can start installing Docker Desktop for Windows.
Creating applications for Kubernetes on Windows requires an environment for developing and testing Docker containers. In this section, you will learn how to install Docker Desktop for Windows, which is the recommended tooling environment for development, building, shipping, and running Linux and Windows containers on Windows 10. First, let's recap on the prerequisites and Docker's minimum requirements before continuing with the installation process:
A minimum of 4 GB of RAM.
The
Intel Virtualization Technology
(
Intel VT
) or
AMD Virtualization
(
AMD-V
) technology
features enabled in the BIOS. Note that if you are using a VM as your development machine, Docker Desktop for Windows does not guarantee support for nested virtualization. If you want to find out more about this scenario, please refer to
https://docs.docker.com/docker-for-windows/troubleshoot/#running-docker-desktop-for-windows-in-nested-virtualization-scenarios
.
Windows 10
Pro, Enterprise, or Education
(version 1903 or later, 64-bit) installed. The current Docker Desktop supports version 1703 or later, but for the best experience when going through the examples in this book, it is recommended that you upgrade it to version 1903 or later. You can check your version of Windows by opening the
Start
menu, selecting the
Settings
icon, and navigating to
System > About
. You will find the necessary details under
Windows Specifications
.
Depending on your requirements, you can choose from two release channels for Docker Desktop for Windows: Stable and Edge. You should consider using a Stable channel if you are OK with the following:
You want the recommended and reliable platform to work with containers. Releases in a Stable channel follow the release cycle of Docker platform stable releases. You can expect releases in the Stable channel to be performed once per quarter.
You want to have a choice of whether to send usage statistics.
You should consider using an Edge channel if you are OK with the following:
You want to get the experimental features as soon as possible. This may come at a cost of some instability and bugs. You can expect releases in the Edge channel to be performed once per month.
You are OK with usage statistics being collected.
Now, let's proceed with the installation itself.
The installation process described in this section follows the recommendations from the official Docker documentation. Let's begin:
In order to download Docker Desktop for Windows, navigate to
https://hub.docker.com/editions/community/docker-ce-desktop-windows
. Downloading it requires registering for the service. You can also choose direct links for downloading the Stable channel release (
https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe
) or the Edge channel release (
https://download.docker.com/win/edge/Docker%20Desktop%20Installer.exe
).
Navigate to the directory where the installer has been downloaded to and double-click on it.
Enable Windows container support by default by selecting the
Use Windows containers instead of Linux containers
option:
Proceed with the installation:
You may be prompted to restart your machine if the Hyper-V role was enabled by the installer.
Launch the
Docker Desktop
application.
Wait until Docker is fully initialized. You will see the following prompt:
After installation, we need to verify whether Docker has been installed properly and can run a simple hello world container image.
Now, let's verify whether the installation was successful:
Confirm that the Docker Client is working properly by opening Powershell and executing the following command:
docker version
You should see an output similar to the following:
Client: Docker Engine - Community
Version: 18.09.2
API version: 1.39
Go version: go1.10.8
Git commit: 6247962
Built: Sun Feb 10 04:12:31 2019
OS/Arch: windows/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.2
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit: 6247962
Built: Sun Feb 10 04:13:06 2019
OS/Arch: linux/amd64
Experimental: false
Run a simple container based on the official Powershell image:
docker run -it --rm mcr.microsoft.com/powershell pwsh -c 'Write-Host "Hello, World!"'
During the first run of this command, the missing container image layers will be downloaded. After some time, you will see
Hello, World!
written to the console output by Powershell:
Congratulations! You have successfully installed Docker Desktop for Windows and run your first container.
In the next subsection, you will learn how to enable process isolation for containers.
On Windows 10, in order to run process-isolated containers, you have to explicitly specify the --isolation=process parameter while creating the container. As we mentioned previously, it is also necessary to specify the container image version that matches your OS. Let's get started:
Assuming you are running Windows 10, version
1903
, let's execute the following command, which attempts to create a process-isolated container in detached (background) mode. Run a ping command stating the number of echo requests to be sent to your localhost machine, that is,
100
:
docker run -d --rm --isolation=process mcr.microsoft.com/windows/nanoserver:1809 cmd /c ping localhost -n 100
The selected version of the mcr.microsoft.com/windows/nanoserver image is 1809, which does not match your OS version. Therefore, it will fail with an error informing you that the container's base image OS version does not match the host OS:
Now, let's execute a similar command but now specify the proper, matching version (1903) of the container base image:
docker run -d --rm --isolation=process mcr.microsoft.com/windows/nanoserver:1903 cmd /c ping localhost -n 100
In this case, the container has started successfully, which can be verified by using the docker ps command:
Now, let's check how process isolation differs in practice from Hyper-V isolation. We will compare the visibility of the container processes in the host OS between these two isolation types.
First, get the container ID of your newly created process-isolated container. This container should run for a few minutes as it performs 100 echo requests to localhost before it terminates and is removed automatically. In our example, the container ID is
a627beadb1297f492ec1f73a3b74c95dbebef2cfaf8f9d6a03e326a1997ec2c1
. Using the
docker top <containerId>
command, it is possible to list all the processes running inside the container, including their
process IDs
(
PID
):
docker top a627beadb1297f492ec1f73a3b74c95dbebef2cfaf8f9d6a03e326a1997ec2c1
The following screenshot shows the output of the preceding command:
In the preceding screenshot, the PID of the ping.exe process inside the container is 6420. In order to list ping.exe processes running in the context of the host OS, use the Get-Process cmdlet in Powershell:
Get-Process -Name ping
The following screenshot shows the output of the preceding command:
The preceding output reveals that the ping.exe process running inside the container is also visible from the host and has exactly the same PID: 6420.
For comparison, we will create a similar container, but this time specify the --isolation=hyperv parameter in order to enforce Hyper-V isolation. On Windows 10, when running a default Docker configuration, you can omit the --isolation parameter altogether since the default isolation level is Hyper-V. We can create the container (with a different base image OS version than the host) using the following command:
docker run -d --rm --isolation=hyperv mcr.microsoft.com/windows/nanoserver:1809 cmd /c ping localhost -n 100
The following screenshot shows the output of the preceding command:
The container has started successfully. In this case, the container ID is c62f82f54cbce3a7673f5722e29629c1ab3d8a4645af9c519c0e60675730b66f. Inspecting the processes running inside the container reveals that ping.exe has a PID of 1268:
When inspecting the processes running on the host, you will see that there is no ping.exe process with a PID of 1268 (and nor is there a cmd.exe process with a PID of 1216, which is the main process in the container):
The reason for this is that the processes running in the Hyper-V container are not sharing the kernel with host as they are executed in separate, lightweight Hyper-V VM with their own kernel matching the container base image OS version.
Now, it's time to run your first Linux container on Windows using LCOW!
By default, Docker Desktop for Windows hosts Linux containers using MobyLinuxVM, which provides a minimal, fully-functional environment for hosting Linux containers. This approach is meant only for development and testing purposes as it is not available on Windows Server. Windows Server currently has experimental support for LCOW and it is also possible to enable this feature in Docker Desktop.
To enable LCOW support in Docker Desktop, you have to enable experimental features in the Docker Daemon. Let's take a look:
Open the Docker Desktop tray icon and select
Settings
.
Navigate to the
Daemon
tab.
Enable the
Experimental features
checkbox:
Apply
the changes. Docker Desktop will restart.
Open PowerShell and create a container that uses Linux as the base image by providing the --platform=linux parameter to docker run. In this example, we're creating a busybox container in interactive mode and starting a Bourne shell:
docker run --rm -it --platform=linux busybox /bin/sh
After the container is started, the Bourne shell prompt will appear (/ #). Now, you can verify that you are indeed running inside a Linux container by using the uname command, which prints Linux kernel information:
uname -a
The following screenshot shows the output of the preceding command:
In a separate Powershell window, without closing the Bourne shell in the container, execute the docker inspect <containerId> command in order to verify that the container is indeed running using LCOW using Hyper-V isolation:
In this section, you learned how to install Docker Desktop for Windows tooling and how to verify its functionality, including running Linux containers on Windows. In the next section, you will learn how to approach building your first Windows container image with the help of Visual Studio Code.
In the previous section, you have learned how to install Docker Desktop for Windows and how to run simple Windows and Linux containers. This section will demonstrate how to build a custom Docker image using Dockerfile and how to perform the most common actions on running containers, such as accessing logs and perform exec into a container.
As an example, we will prepare a Dockerfile that creates a Windows container image of Microsoft IIS hosting a demonstration HTML web page. The image definition won't be complicated in order to demonstrate operation principles.
The first step is preparing the Visual Studio Code workspace. Visual Studio Code requires you to install an additional extension for managing Docker. Let's get started:
In order to do that, open the
Extensions
view by pressing
Ctrl
+
Shift
+
X
.
In
Extensions: Marketplace
, search for
docker
and install the official Docker extension from Microsoft:
After the installation is complete, Docker Explorer will become available:
You can also leverage new Docker-oriented commands from the
Command Palette
after pressing
Ctrl
+
Shift
+ P and typing
docker
into the search bar:
Now, initialize the workspace by opening the desired folder using the
Ctrl
+
K
,
Ctrl
+
O
shortcut or navigating to
File | Open Folder...
.
In the next subsection, we will create a demonstration HTML web page that will be hosted inside the Windows container.
