Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windows docs updates for 1.14 #13279

Merged
merged 36 commits into from
Mar 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a71d41f
Delete sample-l2bridge-wincni-config.json
michmike Mar 19, 2019
2576ae8
Update _index.md
michmike Mar 19, 2019
c403a50
Update _index.md
michmike Mar 19, 2019
5b50e4b
Update _index.md
michmike Mar 19, 2019
bdb5583
Update _index.md
michmike Mar 19, 2019
8867487
Update _index.md
michmike Mar 19, 2019
6b2673d
Rename content/en/docs/getting-started-guides/windows/_index.md to co…
michmike Mar 19, 2019
1dde76c
Delete flannel-master-kubectl-get-ds.png
michmike Mar 19, 2019
71e5693
Delete flannel-master-kubeclt-get-pods.png
michmike Mar 19, 2019
d91dc6a
Delete windows-docker-error.png
michmike Mar 19, 2019
8c5f324
Add files via upload
michmike Mar 19, 2019
19e6fdd
Rename _index.md to add-windows-nodes.md
michmike Mar 19, 2019
c762ce4
Create _index.md
michmike Mar 19, 2019
4c7e2b0
Update _index.md
michmike Mar 19, 2019
19524ad
Update add-windows-nodes.md
michmike Mar 19, 2019
c821392
Update add-windows-nodes.md
michmike Mar 19, 2019
00123c1
Create user-guide-windows-nodes.md
michmike Mar 19, 2019
6252648
Create user-guide-windows-containers.md
michmike Mar 19, 2019
9a47332
Update and rename add-windows-nodes.md to intro-windows-nodes.md
michmike Mar 19, 2019
934bc06
Update user-guide-windows-containers.md
michmike Mar 19, 2019
37439e1
Rename intro-windows-nodes.md to intro-windows-in-kubernetes.md
michmike Mar 19, 2019
6c12d22
Update user-guide-windows-nodes.md
michmike Mar 19, 2019
4ca9968
Update user-guide-windows-containers.md
michmike Mar 19, 2019
d767057
Update user-guide-windows-containers.md
michmike Mar 19, 2019
15fee1a
Update user-guide-windows-nodes.md
michmike Mar 19, 2019
1970103
Update user-guide-windows-containers.md
michmike Mar 19, 2019
e1df6ae
Update _index.md
michmike Mar 19, 2019
34a7357
Update intro-windows-in-kubernetes.md
michmike Mar 19, 2019
b43de50
Update intro-windows-in-kubernetes.md
michmike Mar 19, 2019
9a73548
Update intro-windows-in-kubernetes.md
michmike Mar 20, 2019
f33f380
Update user-guide-windows-nodes.md
michmike Mar 20, 2019
5f4d324
Update intro-windows-in-kubernetes.md
michmike Mar 20, 2019
506b52b
Update user-guide-windows-nodes.md
michmike Mar 20, 2019
d069225
Update user-guide-windows-nodes.md
michmike Mar 20, 2019
2592693
Update user-guide-windows-nodes.md
michmike Mar 20, 2019
9f3e9bc
Update user-guide-windows-nodes.md
michmike Mar 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

4 changes: 4 additions & 0 deletions content/en/docs/setup/windows/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: "Windows in Kubernetes"
weight: 65
---

Large diffs are not rendered by default.

140 changes: 140 additions & 0 deletions content/en/docs/setup/windows/user-guide-windows-containers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
reviewers:
- michmike
- patricklang
title: Guide for scheduling Windows containers in Kubernetes
content_template: templates/concept
weight: 75
---

{{% capture overview %}}

Windows applications constitute a large portion of the services and applications that run in many organizations. This guide walks you through the steps to configure and deploy a Windows container in Kubernetes.

{{% /capture %}}

{{% capture body %}}

## Objectives

* Configure an example deployment to run Windows containers on the Windows node
* (Optional) Configure an Active Directory Identity for your Pod using Group Managed Service Accounts (GMSA)

## Before you begin

* Create a Kubernetes cluster that includes a [master and a worker node running Windows Server](../user-guide-windows-nodes)
* It is important to note that creating and deploying services and workloads on Kubernetes behaves in much the same way for Linux and Windows containers. [Kubectl commands](/docs/reference/kubectl/overview/) to interface with the cluster are identical. The example in the section below is provided simply to jumpstart your experience with Windows containers.

## Getting Started: Deploying a Windows container

To deploy a Windows container on Kubernetes, you must first create an example application. The example YAML file below creates a simple webserver application. Create a service spec named `win-webserver.yaml` with the contents below:

```yaml
apiVersion: v1
kind: Service
metadata:
name: win-webserver
labels:
app: win-webserver
spec:
ports:
# the port that this service should serve on
- port: 80
targetPort: 80
selector:
app: win-webserver
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: win-webserver
name: win-webserver
spec:
replicas: 2
template:
metadata:
labels:
app: win-webserver
name: win-webserver
spec:
containers:
- name: windowswebserver
image: mcr.microsoft.com/windows/servercore:ltsc2019
command:
- powershell.exe
- -command
- "<#code used from https://gist.github.com/wagnerandrade/5424431#> ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add('http://*:80/') ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host('Listening at http://*:80/') ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host '' ;Write-Host('> {0}' -f $$requestUrl) ; ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$ip=(Get-NetAdapter | Get-NetIpAddress); $$header='<html><body><H1>Windows Container Web Server</H1>' ;$$callerCountsString='' ;$$callerCounts.Keys | % { $$callerCountsString+='<p>IP {0} callerCount {1} ' -f $$ip[1].IPAddress,$$callerCounts.Item($$_) } ;$$footer='</body></html>' ;$$content='{0}{1}{2}' -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = [System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host('< {0}' -f $$responseStatus) } ; "
nodeSelector:
beta.kubernetes.io/os: windows
```

{{< note >}}
Port mapping is also supported, but for simplicity in this example the container port 80 is exposed directly to the service.
{{< /note >}}

1. Check that all nodes are healthy:

```bash
kubectl get nodes
```

1. Deploy the service and watch for pod updates:

```bash
kubectl apply -f win-webserver.yaml
kubectl get pods -o wide -w
```

When the service is deployed correctly both Pods will be marked as Ready. To exit the watch command, press Ctrl+C.

1. Check that the deployment succeeded. To verify:

* Two containers per pod on the Windows node, use `docker ps`
* Two pods listed from the Linux master, use `kubectl get pods`
* Node-to-pod communication across the network, `curl` port 80 of your pod IPs from the Linux master to check for a web server response
* Pod-to-pod communication, ping between pods (and across hosts, if you have more than one Windows node) using docker exec or kubectl exec
* Service-to-pod communication, `curl` the virtual service IP (seen under `kubectl get services`) from the Linux master and from individual pods
* Service discovery, `curl` the service name with the Kubernetes [default DNS suffix](/docs/concepts/services-networking/dns-pod-service/#services)
* Inbound connectivity, `curl` the NodePort from the Linux master or machines outside of the cluster
* Outbound connectivity, `curl` external IPs from inside the pod using kubectl exec

{{< note >}}
Windows container hosts are not able to access the IP of services scheduled on them due to current platform limitations of the Windows networking stack. Only Windows pods are able to access service IPs.
{{< /note >}}

## Managing Workload Identity with Group Managed Service Accounts

Starting with Kubernetes v1.14, Windows container workloads can be configured to use Group Managed Service Accounts (GMSA). Group Managed Service Accounts are a specific type of Active Directory account that provides automatic password management, simplified service principal name (SPN) management, and the ability to delegate the management to other administrators across multiple servers. Containers configured with a GMSA can access external Active Directory Domain resources while carrying the identity configured with the GMSA. Learn more about configuring and using GMSA for Windows containers [here](/docs/tasks/configure-pod-container/configure-gmsa/).

## Taints and Tolerations

Users today will need to use some combination of taints and node selectors in order to keep Linux and Windows workloads on their respective OS-specific nodes. This will likely impose a burden only on Windows users. The recommended approach is outlined below, with one of its main goals being that this approach should not break compatibility for existing Linux workloads.

### Ensuring OS-specific workloads land on the appropriate container host

Users can ensure Windows containers can be scheduled on the appropriate host using Taints and Tolerations. All Kubernetes nodes today have the following default labels:

* beta.kubernetes.io/os = [windows|linux]
* beta.kubernetes.io/arch = [amd64|arm64|...]

If a Pod specification does not specify a nodeSelector like `"beta.kubernetes.io/os": windows`, it is possible the Pod can be scheduled on any host, Windows or Linux. This can be problematic since a Windows container can only run on Windows and a Linux container can only run on Linux. The best practice is to use a nodeSelector.

However, we understand that in many cases users have a pre-existing large number of deployments for Linux containers, as well as an ecosystem of off-the-shelf configurations, such as community Helm charts, and programmatic Pod generation cases, such as with Operators. In those situations, you may be hesitant to make the configuration change to add nodeSelectors. The alternative is to use Taints. Because the kubelet can set Taints during registration, it could easily be modified to automatically add a taint when running on Windows only.

For example: `--register-with-taints='os=Win1809:NoSchedule'`

By adding a taint to all Windows nodes, nothing will be scheduled on them (that includes existing Linux Pods). In order for a Windows Pod to be scheduled on a Windows node, it would need both the nodeSelector to choose Windows, and the appropriate matching toleration.

```yaml
nodeSelector:
"beta.kubernetes.io/os": windows
tolerations:
- key: "os"
operator: "Equal"
value: "Win1809"
effect: "NoSchedule"
```

{{% /capture %}}
Loading