From ba8258a3ed6b8a06769fe2b7407b48c94f15f1b3 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Thu, 19 Oct 2017 13:01:01 -0700 Subject: [PATCH 01/35] Updated for WSv1709 and K8s v1.8 --- docs/getting-started-guides/windows/index.md | 108 +++++++++++-------- 1 file changed, 65 insertions(+), 43 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 4b7eee0141e5b..4e8c9ebc0474a 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -1,62 +1,101 @@ --- title: Windows Server Containers --- +**Note:** These instructions were recently updated based on Windows Server platform enhancements -Kubernetes version 1.5 introduces support for Windows Server Containers. In version 1.5, the Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) continue to run on Linux, while the kubelet and kube-proxy can be run on Windows Server. +Kubernetes version 1.5 introduced support for Windows Server Containers based on the Windows Server 2016 OS. With the release of Windows Server version 1709 and using Kubernetes v1.8 users are able to deploy a K8s cluster either on-premises or in a private/public cloud using a number of different network toplogies and CNI plugins. Platform improvements include: +- Improved support for Pods! Shared network namespace (compartment) with multiple Windows Server containers (shared kernel) +- Reduced network complexity by using a single network endpoint per Pod +- Kernel-Based load-balancing using the Virtual Filtering Platform (VFP) Hyper-v Switch Extension (analogous to Linux iptables) -**Note:** Windows Server Containers on Kubernetes is an Alpha feature in Kubernetes 1.5. + The Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) continue to run on Linux, while the kubelet and kube-proxy can be run on Windows Server version 1709. + +**Note:** Windows Server Containers on Kubernetes is an Alpha feature in Kubernetes 1.8. + +**Note:** There is one outstanding PR ([51063 Fixes to enable Windows CNI](https://github.com/kubernetes/kubernetes/pull/51063))which has not been merged into v1.8 and is required for Windows CNI to work with kubelet. Users will need to build a private kubelet binary to consume this change. Please refer to instructions here [TODO - George's guide] ## Prerequisites -In Kubernetes version 1.5, Windows Server Containers for Kubernetes is supported using the following: +In Kubernetes version 1.8, Windows Server Containers for Kubernetes is supported using the following: -1. Kubernetes control plane running on existing Linux infrastructure (version 1.5 or later). +1. Kubernetes control plane running on existing Linux infrastructure (version 1.8 or later). 2. Kubenet network plugin setup on the Linux nodes. -3. Windows Server 2016 (RTM version 10.0.14393 or later). -4. Docker Version 1.12.2-cs2-ws-beta or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version). +3. Windows Server version 1709 (RTM version 10.0.16299.15 or later). +4. Docker Version 17.06.1-ee-2 or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version). ## Networking -Network is achieved using L3 routing. Because third-party networking plugins (e.g. flannel, calico, etc) don't natively work on Windows Server, existing technology that is built into the Windows and Linux operating systems is relied on. In this L3 networking approach, a /16 subnet is chosen for the cluster nodes, and a /24 subnet is assigned to each worker node. All pods on a given worker node will be connected to the /24 subnet. This allows pods on the same node to communicate with each other. In order to enable networking between pods running on different nodes, routing features that are built into Windows Server 2016 and Linux are used. +There are several supported network configurations with Windows Server version 1709 and K8s v1.8 including both Layer-3 routed and overlay topologies using third-party network plugins. +1. Upstream L3 Routing - IP routes configured in upstream ToR +2. Host-Gateway - IP routes configured on each host +3. OVN & OVS with Overlay - OVS switch extension and OVN controller creates VXLAN overlay network +4. [Future] Overlay - VXLAN or IP-in-IP encapsulation using Flannel +5. [Future] Layer-3 Routing with BGP (Calico) + +The selection of which network configuration and topology to deploy depends on the physical network topolgy and a user's ability to configure routes, performance concerns with encapsulation, and requirement to integrate with third-party network plugins. ### Linux The above networking approach is already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. ### Windows +Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the **_Windows Host Setup_** section below. + +#### Upstream L3 Routing Topology +In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a Pod CIDR assigned. All pods on a given worker node will be connected to the POD CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes. The upstream router has static routes configured with POD CIDR prefix => Host IP. + Each Window Server node should have the following configuration: -1. Two NICs (virtual networking adapters) are required on each Windows Server node - The two Windows container networking modes of interest (transparent and L2 bridge) use an external Hyper-V virtual switch. This means that one of the NICs is entirely allocated to the bridge, creating the need for the second NIC. -2. Transparent container network created - This is a manual configuration step and is shown in **_Route Setup_** section below. -3. RRAS (Routing) Windows feature enabled - Allows routing between NICs on the box, and also "captures" packets that have the destination IP of a POD running on the node. To enable, open "Server Manager". Click on "Roles", "Add Roles". Click "Next". Select "Network Policy and Access Services". Click on "Routing and Remote Access Service" and the underlying checkboxes. -4. Routes defined pointing to the other pod CIDRs via the "public" NIC - These routes are added to the built-in routing table as shown in **_Route Setup_** section below. +TODO: Add diagram + +#### Host-Gateway Topology +This topology is similar to the Upstream L3 Routing topology with the only difference being that static IP routes are configured directly on each cluster node and not in the upstream ToR. Each node uses a local 'l2bridge' network with a Pod CIDR assigned as before and has routing table entries for all other Pod CIDR subnets assigned to the remote cluster nodes. + +TODO: Add diagram + +#### Overlay using OVN controller and OVS Switch Extension + +TODO + The following diagram illustrates the Windows Server networking setup for Kubernetes Setup: ![Windows Setup](windows-setup.png) ## Setting up Windows Server Containers on Kubernetes -To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and setup Routes for Pod communication on different nodes. +To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and depending on your network topology, setup Routes for Pod communication on different nodes. ### Host Setup -**Windows Host Setup** - -1. Windows Server container host running Windows Server 2016 and Docker v1.12. Follow the setup instructions outlined by this blog post: https://msdn.microsoft.com/en-us/virtualization/windowscontainers/quick_start/quick_start_windows_server. -2. DNS support for Windows recently got merged to docker master and is currently not supported in a stable docker release. To use DNS build docker from master or download the binary from [Docker master](https://master.dockerproject.org/). -3. Pull the `apprenda/pause` image from `https://hub.docker.com/r/apprenda/pause`. -4. RRAS (Routing) Windows feature enabled. -5. Install a VMSwitch of type `Internal`, by running `New-VMSwitch -Name KubeProxySwitch -SwitchType Internal` command in *PowerShell* window. This will create a new Network Interface with name `vEthernet (KubeProxySwitch)`. This interface will be used by kube-proxy to add Service IPs. **Linux Host Setup** 1. Linux hosts should be setup according to their respective distro documentation and the requirements of the Kubernetes version you will be using. -2. CNI network plugin installed. +2. Configure Linux Master node using steps here [TODO - Add link to George's page] +3. [Optional] CNI network plugin installed. + +**Windows Host Setup** + +1. Windows Server container host running Windows Server version 1709 and Docker v17.06 or later. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. +2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found here [TODO - George's guide] +3. Copy Node spec file (config) from Linux master node with X.509 keys + -- TODO: Create node-specific keys +4. Create HNS Network +5. Ensure correct CNI network config +5. Start kubelet.exe using script [TODO - Add link to George's script] +6. Start kube-proxy using script [TODO - Add link to George's script] +7. [Optional] Add static routes on Windows host ### Component Setup +TODO - Add link to George's documentation + Requirements +TODO - George Check * Git * Go 1.7.1+ * make (if using Linux or MacOS) * Important notes and other dependencies are listed [here](https://git.k8s.io/community/contributors/devel/development.md#building-kubernetes-on-a-local-osshell-environment) +Remove if it makes sense and info is in George's documentation + + **kubelet** To build the *kubelet*, run: @@ -91,34 +130,19 @@ ip route add 192.168.1.0/24 via ip route add 192.168.2.0/24 via ``` -**Win01** - -``` -docker network create -d transparent --gateway 192.168.1.1 --subnet 192.168.1.0/24 -# A bridge is created with Adapter name "vEthernet (HNSTransparent)". Set its IP address to transparent network gateway -netsh interface ipv4 set address "vEthernet (HNSTransparent)" addr=192.168.1.1 -route add 192.168.0.0 mask 255.255.255.0 192.168.0.1 if -p -route add 192.168.2.0 mask 255.255.255.0 192.168.2.1 if -p -``` - -**Win02** - -``` -docker network create -d transparent --gateway 192.168.2.1 --subnet 192.168.2.0/24 -# A bridge is created with Adapter name "vEthernet (HNSTransparent)". Set its IP address to transparent network gateway -netsh interface ipv4 set address "vEthernet (HNSTransparent)" addr=192.168.2.1 -route add 192.168.0.0 mask 255.255.255.0 192.168.0.1 if -p -route add 192.168.1.0 mask 255.255.255.0 192.168.1.1 if -p -``` ## Starting the Cluster To start your cluster, you'll need to start both the Linux-based Kubernetes control plane, and the Windows Server-based Kubernetes node components. + ## Starting the Linux-based Control Plane Use your preferred method to start Kubernetes cluster on Linux. Please note that Cluster CIDR might need to be updated. + ## Starting the Windows Node Components To start kubelet on your Windows node: Run the following in a PowerShell window. Be aware that if the node reboots or the process exits, you will have to rerun the commands below to restart the kubelet. +TODO - Either link to George's doc or update in-line below + 1. Set environment variable *CONTAINER_NETWORK* value to the docker container network to use `$env:CONTAINER_NETWORK = ""` @@ -168,7 +192,5 @@ Because your cluster has both Linux and Windows nodes, you must explicitly set t ``` ## Known Limitations: -1. There is no network namespace in Windows and as a result currently only one container per pod is supported. -2. Secrets currently do not work because of a bug in Windows Server Containers described [here](https://github.com/docker/docker/issues/28401). -3. ConfigMaps have not been implemented yet. -4. `kube-proxy` implementation uses `netsh portproxy` and as it only supports TCP, DNS currently works only if the client retries DNS query using TCP. +1. Secrets currently do not work because of a bug in Windows Server Containers described [here](https://github.com/docker/docker/issues/28401). +2. ConfigMaps have not been implemented yet. \ No newline at end of file From b41b9d26a09abfbd9fea38359260af9f4b86ff51 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Thu, 19 Oct 2017 15:10:41 -0700 Subject: [PATCH 02/35] Updated picture and CNI config --- .../windows/UpstreamRouting.png | Bin 0 -> 88719 bytes docs/getting-started-guides/windows/index.md | 62 ++++++++++++++++-- .../windows/sample-cniconfig.json | 49 ++++++++++++++ 3 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 docs/getting-started-guides/windows/UpstreamRouting.png create mode 100644 docs/getting-started-guides/windows/sample-cniconfig.json diff --git a/docs/getting-started-guides/windows/UpstreamRouting.png b/docs/getting-started-guides/windows/UpstreamRouting.png new file mode 100644 index 0000000000000000000000000000000000000000..91189c36af3baf0dafefaad5c3be201a350a1a75 GIT binary patch literal 88719 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 z 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 4e8c9ebc0474a..a7f501f8e2ab5 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -43,7 +43,8 @@ In this topology, networking is achieved using L3 routing with static IP routes Each Window Server node should have the following configuration: -TODO: Add diagram +The following diagram illustrates the Windows Server networking setup for Kubernetes using Upstream L3 Routing Setup: +![K8s Cluster using L3 Routing with ToR](UpstreamRouting.png) #### Host-Gateway Topology This topology is similar to the Upstream L3 Routing topology with the only difference being that static IP routes are configured directly on each cluster node and not in the upstream ToR. Each node uses a local 'l2bridge' network with a Pod CIDR assigned as before and has routing table entries for all other Pod CIDR subnets assigned to the remote cluster nodes. @@ -55,8 +56,6 @@ TODO: Add diagram TODO -The following diagram illustrates the Windows Server networking setup for Kubernetes Setup: -![Windows Setup](windows-setup.png) ## Setting up Windows Server Containers on Kubernetes To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and depending on your network topology, setup Routes for Pod communication on different nodes. @@ -74,16 +73,66 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your 1. Windows Server container host running Windows Server version 1709 and Docker v17.06 or later. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. 2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found here [TODO - George's guide] 3. Copy Node spec file (config) from Linux master node with X.509 keys - -- TODO: Create node-specific keys 4. Create HNS Network 5. Ensure correct CNI network config 5. Start kubelet.exe using script [TODO - Add link to George's script] 6. Start kube-proxy using script [TODO - Add link to George's script] 7. [Optional] Add static routes on Windows host +*** Windows CNI Config Example *** +{ + "cniVersion": "0.2.0", + "name": "l2bridge", + "type": "wincni.exe", + "master": "Ethernet", + "ipam": { + "environment": "azure", + "subnet": "10.10.187.64/26", + "routes": [ + { + "GW": "10.10.187.66" + } + ] + }, + "dns": { + "Nameservers": [ + "11.0.0.10" + ] + }, + "AdditionalArgs": [ + { + "Name": "EndpointPolicy", + "Value": { + "Type": "OutBoundNAT", + "ExceptionList": [ + "11.0.0.0/8", + "10.10.0.0/16", + "10.127.132.128/25" + ] + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "11.0.0.0/8", + "NeedEncap": true + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "10.127.132.213/32", + "NeedEncap": true + } + } + ] +} + ### Component Setup -TODO - Add link to George's documentation +!Note: TODO - Add link to George's documentation Requirements @@ -93,8 +142,7 @@ TODO - George Check * make (if using Linux or MacOS) * Important notes and other dependencies are listed [here](https://git.k8s.io/community/contributors/devel/development.md#building-kubernetes-on-a-local-osshell-environment) -Remove if it makes sense and info is in George's documentation - +!Note: Remove if it makes sense and info is in George's documentation **kubelet** diff --git a/docs/getting-started-guides/windows/sample-cniconfig.json b/docs/getting-started-guides/windows/sample-cniconfig.json new file mode 100644 index 0000000000000..f3842026ce28c --- /dev/null +++ b/docs/getting-started-guides/windows/sample-cniconfig.json @@ -0,0 +1,49 @@ +{ + "cniVersion": "0.2.0", + "name": "l2bridge", + "type": "wincni.exe", + "master": "Ethernet", + "ipam": { + "environment": "azure", + "subnet": "10.10.187.64/26", + "routes": [ + { + "GW": "10.10.187.66" + } + ] + }, + "dns": { + "Nameservers": [ + "11.0.0.10" + ] + }, + "AdditionalArgs": [ + { + "Name": "EndpointPolicy", + "Value": { + "Type": "OutBoundNAT", + "ExceptionList": [ + "11.0.0.0/8", + "10.10.0.0/16", + "10.127.132.128/25" + ] + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "11.0.0.0/8", + "NeedEncap": true + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "10.127.132.213/32", + "NeedEncap": true + } + } + ] +} From 44bb863778315810a3d10f7541be3850f3c181be Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Thu, 19 Oct 2017 15:12:32 -0700 Subject: [PATCH 03/35] Fixed formatting on CNI Config --- docs/getting-started-guides/windows/index.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index a7f501f8e2ab5..1f957fe66f4d4 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -79,7 +79,9 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your 6. Start kube-proxy using script [TODO - Add link to George's script] 7. [Optional] Add static routes on Windows host -*** Windows CNI Config Example *** +**Windows CNI Config Example** + +``` { "cniVersion": "0.2.0", "name": "l2bridge", @@ -129,7 +131,7 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your } ] } - +``` ### Component Setup !Note: TODO - Add link to George's documentation From 6a6922c6c6d6ea5cc97ed48e78c492b89fbf42f8 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Fri, 3 Nov 2017 13:33:05 -0700 Subject: [PATCH 04/35] Updated docs to reference Microsoft/SDN GitHub docs --- docs/getting-started-guides/windows/index.md | 97 +++----------------- 1 file changed, 12 insertions(+), 85 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 1f957fe66f4d4..0087688803610 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -12,7 +12,7 @@ Kubernetes version 1.5 introduced support for Windows Server Containers based on **Note:** Windows Server Containers on Kubernetes is an Alpha feature in Kubernetes 1.8. -**Note:** There is one outstanding PR ([51063 Fixes to enable Windows CNI](https://github.com/kubernetes/kubernetes/pull/51063))which has not been merged into v1.8 and is required for Windows CNI to work with kubelet. Users will need to build a private kubelet binary to consume this change. Please refer to instructions here [TODO - George's guide] +**Note:** There is one outstanding PR ([51063 Fixes to enable Windows CNI](https://github.com/kubernetes/kubernetes/pull/51063))which has not been merged into v1.8 and is required for Windows CNI to work with kubelet. Users will need to build a private kubelet binary to consume this change. Please refer to these [instructions](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) for build ## Prerequisites In Kubernetes version 1.8, Windows Server Containers for Kubernetes is supported using the following: @@ -30,6 +30,9 @@ There are several supported network configurations with Windows Server version 1 4. [Future] Overlay - VXLAN or IP-in-IP encapsulation using Flannel 5. [Future] Layer-3 Routing with BGP (Calico) +## CNI Plugins +Microsoft plans to publish code for two CNI plugins - win-l2bridge (host-gateway) and win-overlay (vxlan)) - per this [issue](https://github.com/containernetworking/plugins/issues/80). These two CNI plugins can either be used directly by WinCNI.exe or with Flannel [PR 832](https://github.com/coreos/flannel/pull/832). We have an [outstanding informational PR](https://github.com/containernetworking/plugins/pull/85) needed to complete this work. Windows Server platform work is complete. + The selection of which network configuration and topology to deploy depends on the physical network topolgy and a user's ability to configure routes, performance concerns with encapsulation, and requirement to integrate with third-party network plugins. ### Linux @@ -49,14 +52,10 @@ The following diagram illustrates the Windows Server networking setup for Kubern #### Host-Gateway Topology This topology is similar to the Upstream L3 Routing topology with the only difference being that static IP routes are configured directly on each cluster node and not in the upstream ToR. Each node uses a local 'l2bridge' network with a Pod CIDR assigned as before and has routing table entries for all other Pod CIDR subnets assigned to the remote cluster nodes. -TODO: Add diagram - #### Overlay using OVN controller and OVS Switch Extension TODO - - ## Setting up Windows Server Containers on Kubernetes To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and depending on your network topology, setup Routes for Pod communication on different nodes. @@ -65,22 +64,24 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your **Linux Host Setup** 1. Linux hosts should be setup according to their respective distro documentation and the requirements of the Kubernetes version you will be using. -2. Configure Linux Master node using steps here [TODO - Add link to George's page] +2. Configure Linux Master node using steps [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) 3. [Optional] CNI network plugin installed. **Windows Host Setup** 1. Windows Server container host running Windows Server version 1709 and Docker v17.06 or later. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. -2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found here [TODO - George's guide] +2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) 3. Copy Node spec file (config) from Linux master node with X.509 keys 4. Create HNS Network 5. Ensure correct CNI network config -5. Start kubelet.exe using script [TODO - Add link to George's script] -6. Start kube-proxy using script [TODO - Add link to George's script] +5. Start kubelet.exe using this script [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) +6. Start kube-proxy using this script[start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) 7. [Optional] Add static routes on Windows host **Windows CNI Config Example** +Today, Windows CNI plugin is based on wincni.exe code with the following example, configuration file. +Note: this file assumes that a user previous created 'l2bridge' host networks on each Windows node using -HNSNetwork cmdlets as shown in the start-kublet.ps1 and start-kubeproxy.ps1 scripts linked above ``` { "cniVersion": "0.2.0", @@ -132,82 +133,12 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your ] } ``` -### Component Setup - -!Note: TODO - Add link to George's documentation - -Requirements - -TODO - George Check -* Git -* Go 1.7.1+ -* make (if using Linux or MacOS) -* Important notes and other dependencies are listed [here](https://git.k8s.io/community/contributors/devel/development.md#building-kubernetes-on-a-local-osshell-environment) - -!Note: Remove if it makes sense and info is in George's documentation - -**kubelet** - -To build the *kubelet*, run: - -1. `cd $GOPATH/src/k8s.io/kubernetes` -2. Build *kubelet* - 1. Linux/MacOS: `KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kubelet` - 2. Windows: `go build cmd/kubelet/kubelet.go` - -**kube-proxy** - -To build *kube-proxy*, run: - -1. `cd $GOPATH/src/k8s.io/kubernetes` -2. Build *kube-proxy* - 1. Linux/MacOS: `KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy` - 2. Windows: `go build cmd/kube-proxy/proxy.go` - -### Route Setup -The below example setup assumes one Linux and two Windows Server 2016 nodes and a cluster CIDR 192.168.0.0/16 - -| Hostname | Routable IP address | Pod CIDR | -| --- | --- | --- | -| Lin01 | `` | 192.168.0.0/24 | -| Win01 | `` | 192.168.1.0/24 | -| Win02 | `` | 192.168.2.0/24 | - -**Lin01** - -``` -ip route add 192.168.1.0/24 via -ip route add 192.168.2.0/24 via -``` - ## Starting the Cluster -To start your cluster, you'll need to start both the Linux-based Kubernetes control plane, and the Windows Server-based Kubernetes node components. +To start your cluster, you'll need to start both the Linux-based Kubernetes control plane, and the Windows Server-based Kubernetes node components (kubelet and kube-proxy). ## Starting the Linux-based Control Plane -Use your preferred method to start Kubernetes cluster on Linux. Please note that Cluster CIDR might need to be updated. - -## Starting the Windows Node Components -To start kubelet on your Windows node: -Run the following in a PowerShell window. Be aware that if the node reboots or the process exits, you will have to rerun the commands below to restart the kubelet. - -TODO - Either link to George's doc or update in-line below - -1. Set environment variable *CONTAINER_NETWORK* value to the docker container network to use -`$env:CONTAINER_NETWORK = ""` - -2. Run *kubelet* executable using the below command -`kubelet.exe --hostname-override= --pod-infra-container-image="apprenda/pause" --resolv-conf="" --api_servers=` - -To start kube-proxy on your Windows node: - -Run the following in a PowerShell window with administrative privileges. Be aware that if the node reboots or the process exits, you will have to rerun the commands below to restart the kube-proxy. - -1. Set environment variable *INTERFACE_TO_ADD_SERVICE_IP* value to `vEthernet (KubeProxySwitch)` which we created in **_Windows Host Setup_** above -`$env:INTERFACE_TO_ADD_SERVICE_IP = "vEthernet (KubeProxySwitch)"` - -2. Run *kube-proxy* executable using the below command -`.\proxy.exe --v=3 --proxy-mode=userspace --hostname-override= --master= --bind-address=` +Use your preferred method to setup and start Kubernetes cluster on Linux or follow the directions given in this [link](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md). Please note that Cluster CIDR might need to be updated. ## Scheduling Pods on Windows Because your cluster has both Linux and Windows nodes, you must explicitly set the nodeSelector constraint to be able to schedule Pods to Windows nodes. You must set nodeSelector with the label beta.kubernetes.io/os to the value windows; see the following example: @@ -240,7 +171,3 @@ Because your cluster has both Linux and Windows nodes, you must explicitly set t } } ``` - -## Known Limitations: -1. Secrets currently do not work because of a bug in Windows Server Containers described [here](https://github.com/docker/docker/issues/28401). -2. ConfigMaps have not been implemented yet. \ No newline at end of file From c05678752d3b481e2907bc53d3971bb49eab6609 Mon Sep 17 00:00:00 2001 From: runzexia Date: Thu, 30 Nov 2017 17:08:01 +0800 Subject: [PATCH 05/35] fix typo --- docs/getting-started-guides/scratch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-guides/scratch.md b/docs/getting-started-guides/scratch.md index b177f4a24b2db..8d1cb7b3f24e8 100644 --- a/docs/getting-started-guides/scratch.md +++ b/docs/getting-started-guides/scratch.md @@ -705,7 +705,7 @@ Complete this template for the scheduler pod: "containers": [ { "name": "kube-scheduler", - "image": "$HYBERKUBE_IMAGE", + "image": "$HYPERKUBE_IMAGE", "command": [ "/hyperkube", "scheduler", From b84ac59624b625e6534ccd97bb4ba65e51b441e4 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Thu, 30 Nov 2017 17:18:18 +0800 Subject: [PATCH 06/35] Workaround for Jekyllr frontmatter --- cn/docs/tutorials/stateful-application/web.yaml | 1 - cn/docs/tutorials/stateful-application/webp.yaml | 3 +-- cn/docs/user-guide/multi-pod.yaml | 1 - docs/tasks/access-application-cluster/frontend.yaml | 2 +- docs/tutorials/stateful-application/web.yaml | 1 - docs/tutorials/stateful-application/webp.yaml | 3 +-- docs/tutorials/stateful-application/zookeeper.yaml | 1 - docs/user-guide/environment-guide/backend-rc.yaml | 1 - docs/user-guide/environment-guide/backend-srv.yaml | 1 - docs/user-guide/environment-guide/show-rc.yaml | 1 - docs/user-guide/environment-guide/show-srv.yaml | 1 - docs/user-guide/multi-pod.yaml | 1 - test/examples_test.go | 9 ++++++++- 13 files changed, 11 insertions(+), 15 deletions(-) diff --git a/cn/docs/tutorials/stateful-application/web.yaml b/cn/docs/tutorials/stateful-application/web.yaml index f5f246c47f7e9..6c2770082bc8c 100644 --- a/cn/docs/tutorials/stateful-application/web.yaml +++ b/cn/docs/tutorials/stateful-application/web.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Service metadata: diff --git a/cn/docs/tutorials/stateful-application/webp.yaml b/cn/docs/tutorials/stateful-application/webp.yaml index 0a56f234e0cfc..74a71c90ac7b7 100644 --- a/cn/docs/tutorials/stateful-application/webp.yaml +++ b/cn/docs/tutorials/stateful-application/webp.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Service metadata: @@ -42,4 +41,4 @@ spec: accessModes: [ "ReadWriteOnce" ] resources: requests: - storage: 1Gi \ No newline at end of file + storage: 1Gi diff --git a/cn/docs/user-guide/multi-pod.yaml b/cn/docs/user-guide/multi-pod.yaml index 7f7d0a5745711..2ace060d89eff 100644 --- a/cn/docs/user-guide/multi-pod.yaml +++ b/cn/docs/user-guide/multi-pod.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Pod metadata: diff --git a/docs/tasks/access-application-cluster/frontend.yaml b/docs/tasks/access-application-cluster/frontend.yaml index 382c3786e5f8f..63631c0d05ede 100644 --- a/docs/tasks/access-application-cluster/frontend.yaml +++ b/docs/tasks/access-application-cluster/frontend.yaml @@ -1,5 +1,5 @@ -kind: Service apiVersion: v1 +kind: Service metadata: name: frontend spec: diff --git a/docs/tutorials/stateful-application/web.yaml b/docs/tutorials/stateful-application/web.yaml index 9f0ba1a343f5a..9b34869298905 100644 --- a/docs/tutorials/stateful-application/web.yaml +++ b/docs/tutorials/stateful-application/web.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Service metadata: diff --git a/docs/tutorials/stateful-application/webp.yaml b/docs/tutorials/stateful-application/webp.yaml index 231883742718d..705d1207cb13d 100644 --- a/docs/tutorials/stateful-application/webp.yaml +++ b/docs/tutorials/stateful-application/webp.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Service metadata: @@ -45,4 +44,4 @@ spec: accessModes: [ "ReadWriteOnce" ] resources: requests: - storage: 1Gi \ No newline at end of file + storage: 1Gi diff --git a/docs/tutorials/stateful-application/zookeeper.yaml b/docs/tutorials/stateful-application/zookeeper.yaml index f07708c398b93..952e5b45c5798 100644 --- a/docs/tutorials/stateful-application/zookeeper.yaml +++ b/docs/tutorials/stateful-application/zookeeper.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Service metadata: diff --git a/docs/user-guide/environment-guide/backend-rc.yaml b/docs/user-guide/environment-guide/backend-rc.yaml index 6c57b95dac912..28c7eeb097629 100644 --- a/docs/user-guide/environment-guide/backend-rc.yaml +++ b/docs/user-guide/environment-guide/backend-rc.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: ReplicationController metadata: diff --git a/docs/user-guide/environment-guide/backend-srv.yaml b/docs/user-guide/environment-guide/backend-srv.yaml index 7083b37bf88e0..1c306bc0f60da 100644 --- a/docs/user-guide/environment-guide/backend-srv.yaml +++ b/docs/user-guide/environment-guide/backend-srv.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Service metadata: diff --git a/docs/user-guide/environment-guide/show-rc.yaml b/docs/user-guide/environment-guide/show-rc.yaml index 4de94c06ca30b..df2f03e3471c8 100644 --- a/docs/user-guide/environment-guide/show-rc.yaml +++ b/docs/user-guide/environment-guide/show-rc.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: ReplicationController metadata: diff --git a/docs/user-guide/environment-guide/show-srv.yaml b/docs/user-guide/environment-guide/show-srv.yaml index 25a2d7473e021..17613104214cb 100644 --- a/docs/user-guide/environment-guide/show-srv.yaml +++ b/docs/user-guide/environment-guide/show-srv.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Service metadata: diff --git a/docs/user-guide/multi-pod.yaml b/docs/user-guide/multi-pod.yaml index 7f7d0a5745711..2ace060d89eff 100644 --- a/docs/user-guide/multi-pod.yaml +++ b/docs/user-guide/multi-pod.yaml @@ -1,4 +1,3 @@ ---- apiVersion: v1 kind: Pod metadata: diff --git a/test/examples_test.go b/test/examples_test.go index 87b7e9a54a717..a7f837ae2c5a3 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -199,6 +199,10 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er if err != nil { return err } + // workaround for Jekyllr limit + if bytes.HasPrefix(data, []byte("---\n")) { + return fmt.Errorf("YAML file cannot start with \"---\", please remove the first line") + } name := strings.TrimSuffix(file, ext) var docs [][]byte @@ -217,7 +221,10 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er if err != nil { return fmt.Errorf("%s: %v", path, err) } - docs = append(docs, out) + // deal with "empty" document (e.g. pure comments) + if string(out) != "null" { + docs = append(docs, out) + } } } else { docs = append(docs, data) From a88e70cb5b9afa1e3f6f9f8649737a03d4693900 Mon Sep 17 00:00:00 2001 From: Bob Steciuk Date: Thu, 30 Nov 2017 09:14:27 -0500 Subject: [PATCH 07/35] Added section on features and limitations, with example yaml files. --- .../windows/configmap-pod.yaml | 31 ++++ .../windows/emptydir-pod.yaml | 20 +++ .../windows/hostpath-volume-pod.yaml | 18 +++ docs/getting-started-guides/windows/index.md | 139 ++++++++++++++++++ .../windows/secret-pod.yaml | 32 ++++ 5 files changed, 240 insertions(+) create mode 100644 docs/getting-started-guides/windows/configmap-pod.yaml create mode 100644 docs/getting-started-guides/windows/emptydir-pod.yaml create mode 100644 docs/getting-started-guides/windows/hostpath-volume-pod.yaml create mode 100644 docs/getting-started-guides/windows/secret-pod.yaml diff --git a/docs/getting-started-guides/windows/configmap-pod.yaml b/docs/getting-started-guides/windows/configmap-pod.yaml new file mode 100644 index 0000000000000..e30939b367044 --- /dev/null +++ b/docs/getting-started-guides/windows/configmap-pod.yaml @@ -0,0 +1,31 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: example-config +data: + example.property.1: hello + example.property.2: world + +--- + +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod +spec: + containers: + - name: configmap-redis + image: redis:3.0-nanoserver + env: + - name: EXAMPLE_PROPERTY_1 + valueFrom: + configMapKeyRef: + name: example-config + key: example.property.1 + - name: EXAMPLE_PROPERTY_2 + valueFrom: + configMapKeyRef: + name: example-config + key: example.property.2 + nodeSelector: + beta.kubernetes.io/os: windows \ No newline at end of file diff --git a/docs/getting-started-guides/windows/emptydir-pod.yaml b/docs/getting-started-guides/windows/emptydir-pod.yaml new file mode 100644 index 0000000000000..8a3a2133a68cb --- /dev/null +++ b/docs/getting-started-guides/windows/emptydir-pod.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: empty-dir-pod +spec: + containers: + - image: redis:3.0-nanoserver + name: empty-dir-redis + volumeMounts: + - mountPath: /cache + name: cache-volume + - mountPath: C:/scratch + name: scratch-volume + volumes: + - name: cache-volume + emptyDir: {} + - name: scratch-volume + emptyDir: {} + nodeSelector: + beta.kubernetes.io/os: windows \ No newline at end of file diff --git a/docs/getting-started-guides/windows/hostpath-volume-pod.yaml b/docs/getting-started-guides/windows/hostpath-volume-pod.yaml new file mode 100644 index 0000000000000..994b48e6f040b --- /dev/null +++ b/docs/getting-started-guides/windows/hostpath-volume-pod.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: hostpath-volume-pod +spec: + containers: + - name: hostpath-redis + image: redis:3.0-nanoserver + volumeMounts: + - name: blah + mountPath: "C:\\etc\\foo" + readOnly: true + nodeSelector: + beta.kubernetes.io/os: windows + volumes: + - name: blah + hostPath: + path: "C:\\etc\\foo" diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 0087688803610..ca9db536332d8 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -171,3 +171,142 @@ Because your cluster has both Linux and Windows nodes, you must explicitly set t } } ``` + +## Supported Features and Limitations + +### Secrets and ConfigMaps +Secrets and ConfigMaps can be utilized in Windows Server Containers, but must be used as environment variables. +Using Secrets and ConfigMaps as volume mounts is not supported in Windows Server Containers at this time. + +**Examples:** + + Windows pod with secrets mapped to environment variables + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: mysecret + type: Opaque + data: + username: YWRtaW4= + password: MWYyZDFlMmU2N2Rm + + --- + + apiVersion: v1 + kind: Pod + metadata: + name: mypod-secret + spec: + containers: + - name: mypod-secret + image: redis:3.0-nanoserver + env: + - name: USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username + - name: PASSWORD + valueFrom: + secretKeyRef: + name: mysecret + key: password + nodeSelector: + beta.kubernetes.io/os: windows +``` + + Windows pod with configMap values mapped to environment variables + +```yaml +kind: ConfigMap +apiVersion: v1 +metadata: + name: example-config +data: + example.property.1: hello + example.property.2: world + +--- + +apiVersion: v1 +kind: Pod +metadata: + name: configmap-pod +spec: + containers: + - name: configmap-redis + image: redis:3.0-nanoserver + env: + - name: EXAMPLE_PROPERTY_1 + valueFrom: + configMapKeyRef: + name: example-config + key: example.property.1 + - name: EXAMPLE_PROPERTY_2 + valueFrom: + configMapKeyRef: + name: example-config + key: example.property.2 + nodeSelector: + beta.kubernetes.io/os: windows +``` + +### Volumes +Some supported Volume Mounts are local, emptyDir, hostPath. One thing to remember is paths must either be escaped, or use forward slashes, for example `mountPath: "C:\\etc\\foo"` or `mountPath: "C:/etc/foo"`. + +Persistent Volume Claims are supported for supported volume types. + +**Examples:** + + Windows pod with a hostPath volume + ```yaml + apiVersion: v1 + kind: Pod + metadata: + name: hostpath-volume-pod + spec: + containers: + - name: hostpath-redis + image: redis:3.0-nanoserver + volumeMounts: + - name: blah + mountPath: "C:\\etc\\foo" + readOnly: true + nodeSelector: + beta.kubernetes.io/os: windows + volumes: + - name: blah + hostPath: + path: "C:\\etc\\foo" + ``` + + Windows pod with multiple emptyDir volumes + + ```yaml + apiVersion: v1 + kind: Pod + metadata: + name: empty-dir-pod + spec: + containers: + - image: redis:3.0-nanoserver + name: empty-dir-redis + volumeMounts: + - mountPath: /cache + name: cache-volume + - mountPath: C:/scratch + name: scratch-volume + volumes: + - name: cache-volume + emptyDir: {} + - name: scratch-volume + emptyDir: {} + nodeSelector: + beta.kubernetes.io/os: windows + ``` + +### Metrics + +Windows Stats use a hybrid model: pod and container level stats come from CRI (via dockershim), while node level stats come from the "winstats" package that exports cadvisor like datastructures using windows specific perf counters from the node. + diff --git a/docs/getting-started-guides/windows/secret-pod.yaml b/docs/getting-started-guides/windows/secret-pod.yaml new file mode 100644 index 0000000000000..4bbfb671b280a --- /dev/null +++ b/docs/getting-started-guides/windows/secret-pod.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Secret +metadata: + name: mysecret +type: Opaque +data: + username: YWRtaW4= + password: MWYyZDFlMmU2N2Rm + +--- + +apiVersion: v1 +kind: Pod +metadata: + name: mypod-secret +spec: + containers: + - name: mypod-secret + image: redis:3.0-nanoserver + env: + - name: USERNAME + valueFrom: + secretKeyRef: + name: mysecret + key: username + - name: PASSWORD + valueFrom: + secretKeyRef: + name: mysecret + key: password + nodeSelector: + beta.kubernetes.io/os: windows \ No newline at end of file From 4468bda9553bd01c1184562369c70fed4ede88fc Mon Sep 17 00:00:00 2001 From: Michael Michael Date: Fri, 1 Dec 2017 08:17:25 -0600 Subject: [PATCH 08/35] Update index.md --- docs/getting-started-guides/windows/index.md | 66 +++++++++++--------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index ca9db536332d8..2b9eb7feebf57 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -1,42 +1,45 @@ --- -title: Windows Server Containers +title: Using Windows Server Containers in Kubernetes --- -**Note:** These instructions were recently updated based on Windows Server platform enhancements +**Note:** These instructions were recently updated based on Windows Server platform enhancements and the Kubernetes v1.9 release -Kubernetes version 1.5 introduced support for Windows Server Containers based on the Windows Server 2016 OS. With the release of Windows Server version 1709 and using Kubernetes v1.8 users are able to deploy a K8s cluster either on-premises or in a private/public cloud using a number of different network toplogies and CNI plugins. Platform improvements include: -- Improved support for Pods! Shared network namespace (compartment) with multiple Windows Server containers (shared kernel) -- Reduced network complexity by using a single network endpoint per Pod +Kubernetes version 1.5 introduced Alpha support for Windows Server Containers based on the Windows Server 2016 operating system. With the release of Windows Server version 1709 and using Kubernetes v1.9 users are able to deploy a Kubernetes cluster either on-premises or in a private/public cloud using a number of different network topologies and CNI plugins. Some key feature improvements for Windows Server Containers on Kubernetes include: +- Improved support for pods! Shared network namespace (compartment) with multiple Windows Server containers (shared kernel) +- Reduced network complexity by using a single network endpoint per pod - Kernel-Based load-balancing using the Virtual Filtering Platform (VFP) Hyper-v Switch Extension (analogous to Linux iptables) +- Container Runtime Interface (CRI) pod and node level statistics +- Support for kubeadm commands to add Windows Server nodes to a Kubernetes environment - The Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) continue to run on Linux, while the kubelet and kube-proxy can be run on Windows Server version 1709. +The Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) continue to run on Linux, while the kubelet and kube-proxy can be run on Windows Server 2016 or later -**Note:** Windows Server Containers on Kubernetes is an Alpha feature in Kubernetes 1.8. +**Note:** Windows Server Containers on Kubernetes is an Beta feature in Kubernetes v1.9 -**Note:** There is one outstanding PR ([51063 Fixes to enable Windows CNI](https://github.com/kubernetes/kubernetes/pull/51063))which has not been merged into v1.8 and is required for Windows CNI to work with kubelet. Users will need to build a private kubelet binary to consume this change. Please refer to these [instructions](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) for build +## Build +If you wish to build the code yourself, please refer to these [instructions](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) ## Prerequisites -In Kubernetes version 1.8, Windows Server Containers for Kubernetes is supported using the following: +In Kubernetes version 1.9 or later, Windows Server Containers for Kubernetes are supported using the following: -1. Kubernetes control plane running on existing Linux infrastructure (version 1.8 or later). +1. Kubernetes control plane running on existing Linux infrastructure (version 1.9 or later). 2. Kubenet network plugin setup on the Linux nodes. -3. Windows Server version 1709 (RTM version 10.0.16299.15 or later). +3. Windows Server 2016 RTM or later. Windows Server version 1709 or later is preferred; unlocks key capabilities like shared network namespace 4. Docker Version 17.06.1-ee-2 or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version). ## Networking -There are several supported network configurations with Windows Server version 1709 and K8s v1.8 including both Layer-3 routed and overlay topologies using third-party network plugins. +There are several supported network configurations with Kubernetes v1.9 on Windows, including both Layer-3 routed and overlay topologies using third-party network plugins. 1. Upstream L3 Routing - IP routes configured in upstream ToR 2. Host-Gateway - IP routes configured on each host -3. OVN & OVS with Overlay - OVS switch extension and OVN controller creates VXLAN overlay network -4. [Future] Overlay - VXLAN or IP-in-IP encapsulation using Flannel -5. [Future] Layer-3 Routing with BGP (Calico) - -## CNI Plugins -Microsoft plans to publish code for two CNI plugins - win-l2bridge (host-gateway) and win-overlay (vxlan)) - per this [issue](https://github.com/containernetworking/plugins/issues/80). These two CNI plugins can either be used directly by WinCNI.exe or with Flannel [PR 832](https://github.com/coreos/flannel/pull/832). We have an [outstanding informational PR](https://github.com/containernetworking/plugins/pull/85) needed to complete this work. Windows Server platform work is complete. +3. Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay - OVS switch extension and OVN controller creates VXLAN overlay network +4. [Future Release] Overlay - VXLAN or IP-in-IP encapsulation using Flannel +5. [Future Release] Layer-3 Routing with BGP (Calico) The selection of which network configuration and topology to deploy depends on the physical network topolgy and a user's ability to configure routes, performance concerns with encapsulation, and requirement to integrate with third-party network plugins. +## Future CNI Plugins +An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxlan)] will be published in a future release. These two CNI plugins can either be used directly by WinCNI.exe or with Flannel + ### Linux -The above networking approach is already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. +The above networking approaches are already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. ### Windows Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the **_Windows Host Setup_** section below. @@ -52,12 +55,11 @@ The following diagram illustrates the Windows Server networking setup for Kubern #### Host-Gateway Topology This topology is similar to the Upstream L3 Routing topology with the only difference being that static IP routes are configured directly on each cluster node and not in the upstream ToR. Each node uses a local 'l2bridge' network with a Pod CIDR assigned as before and has routing table entries for all other Pod CIDR subnets assigned to the remote cluster nodes. -#### Overlay using OVN controller and OVS Switch Extension - -TODO +#### Overlay using OVN controller and OVS Switch Extension Topology +_Documentation is pending..._ ## Setting up Windows Server Containers on Kubernetes -To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and depending on your network topology, setup Routes for Pod communication on different nodes. +To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and depending on your network topology, set up Routes for pod communication on different nodes. ### Host Setup @@ -69,13 +71,13 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your **Windows Host Setup** -1. Windows Server container host running Windows Server version 1709 and Docker v17.06 or later. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. +1. Windows Server container host running the required Windows Server and Docker versions. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. 2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) 3. Copy Node spec file (config) from Linux master node with X.509 keys 4. Create HNS Network 5. Ensure correct CNI network config 5. Start kubelet.exe using this script [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) -6. Start kube-proxy using this script[start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) +6. Start kube-proxy using this script [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) 7. [Optional] Add static routes on Windows host **Windows CNI Config Example** @@ -172,11 +174,10 @@ Because your cluster has both Linux and Windows nodes, you must explicitly set t } ``` -## Supported Features and Limitations +## Supported Features ### Secrets and ConfigMaps -Secrets and ConfigMaps can be utilized in Windows Server Containers, but must be used as environment variables. -Using Secrets and ConfigMaps as volume mounts is not supported in Windows Server Containers at this time. +Secrets and ConfigMaps can be utilized in Windows Server Containers, but must be used as environment variables. See limitations section below for additional details. **Examples:** @@ -253,7 +254,7 @@ spec: ``` ### Volumes -Some supported Volume Mounts are local, emptyDir, hostPath. One thing to remember is paths must either be escaped, or use forward slashes, for example `mountPath: "C:\\etc\\foo"` or `mountPath: "C:/etc/foo"`. +Some supported Volume Mounts are local, emptyDir, hostPath. One thing to remember is that paths must either be escaped, or use forward slashes, for example `mountPath: "C:\\etc\\foo"` or `mountPath: "C:/etc/foo"`. Persistent Volume Claims are supported for supported volume types. @@ -310,3 +311,10 @@ Persistent Volume Claims are supported for supported volume types. Windows Stats use a hybrid model: pod and container level stats come from CRI (via dockershim), while node level stats come from the "winstats" package that exports cadvisor like datastructures using windows specific perf counters from the node. +## Known Limitations for Windows Server Containers with v1.9 +Some of these limitations will be addressed by the community in future releases of Kubernetes +- Shared network namespace (compartment) with multiple Windows Server containers (shared kernel) per pod is only supported on Windows Server 1709 or later +- Using Secrets and ConfigMaps as volume mounts is not supported +- The StatefulSet functionality for stateful applications is not supported +- Horizontal Pod Autoscaling for Windows Server Container pods has not been verified to work end-to-end +- Hyper-V Containers are not supported From ffd6057e3514bd270f28fd87b6cbe70c26fd8222 Mon Sep 17 00:00:00 2001 From: Bob Steciuk Date: Fri, 1 Dec 2017 13:23:24 -0500 Subject: [PATCH 09/35] Added kubeadm section, few other small fixes --- docs/getting-started-guides/windows/index.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 2b9eb7feebf57..34f148bda5031 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -15,7 +15,7 @@ The Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) co **Note:** Windows Server Containers on Kubernetes is an Beta feature in Kubernetes v1.9 ## Build -If you wish to build the code yourself, please refer to these [instructions](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) +If you wish to build the code yourself, please refer to these [instructions](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md), otherwise the release binaries can be found at [https://github.com/kubernetes/kubernetes/releases](https://github.com/kubernetes/kubernetes/releases). ## Prerequisites In Kubernetes version 1.9 or later, Windows Server Containers for Kubernetes are supported using the following: @@ -33,7 +33,7 @@ There are several supported network configurations with Kubernetes v1.9 on Windo 4. [Future Release] Overlay - VXLAN or IP-in-IP encapsulation using Flannel 5. [Future Release] Layer-3 Routing with BGP (Calico) -The selection of which network configuration and topology to deploy depends on the physical network topolgy and a user's ability to configure routes, performance concerns with encapsulation, and requirement to integrate with third-party network plugins. +The selection of which network configuration and topology to deploy depends on the physical network topology and a user's ability to configure routes, performance concerns with encapsulation, and requirement to integrate with third-party network plugins. ## Future CNI Plugins An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxlan)] will be published in a future release. These two CNI plugins can either be used directly by WinCNI.exe or with Flannel @@ -173,6 +173,17 @@ Because your cluster has both Linux and Windows nodes, you must explicitly set t } } ``` +## Support for kubeadm join + +If your cluster has been created by [kubeadm](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/), +and your networking is setup correctly using one of the methods listed above (networking is setup outside of kubeadm), you can use kubeadm to add a Windows node to your cluster. + +The kubeadm binary can be found at [Kubernetes Releases](https://github.com/kubernetes/kubernetes/releases), inside the node binaries archive. Adding a Windows node +is not any different than adding a Linux node: + +`kubeadm.exe join --token : --discovery-token-ca-cert-hash sha256:` + +See [joining-your-nodes](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#44-joining-your-nodes) for more details. ## Supported Features From 3e5c06d1c02c2f3bcef62fddf5501790646a34b2 Mon Sep 17 00:00:00 2001 From: Bob Steciuk Date: Fri, 1 Dec 2017 15:22:13 -0500 Subject: [PATCH 10/35] Few minor grammar fixes --- docs/getting-started-guides/windows/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 34f148bda5031..e6de4841df69e 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -12,7 +12,7 @@ Kubernetes version 1.5 introduced Alpha support for Windows Server Containers ba The Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) continue to run on Linux, while the kubelet and kube-proxy can be run on Windows Server 2016 or later -**Note:** Windows Server Containers on Kubernetes is an Beta feature in Kubernetes v1.9 +**Note:** Windows Server Containers on Kubernetes is a Beta feature in Kubernetes v1.9 ## Build If you wish to build the code yourself, please refer to these [instructions](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md), otherwise the release binaries can be found at [https://github.com/kubernetes/kubernetes/releases](https://github.com/kubernetes/kubernetes/releases). @@ -45,7 +45,7 @@ The above networking approaches are already supported on Linux using a bridge in Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the **_Windows Host Setup_** section below. #### Upstream L3 Routing Topology -In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a Pod CIDR assigned. All pods on a given worker node will be connected to the POD CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes. The upstream router has static routes configured with POD CIDR prefix => Host IP. +In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a Pod CIDR assigned. All pods on a given worker node will be connected to the POD CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes, the upstream router has static routes configured with POD CIDR prefix => Host IP. Each Window Server node should have the following configuration: From 31e4dbdc25a60e4584ce01a6b1915e13ac63bc67 Mon Sep 17 00:00:00 2001 From: Robert Pothier Date: Fri, 1 Dec 2017 16:10:29 -0500 Subject: [PATCH 11/35] Update access-cluster.md with a comment that for IPv6 the user should use [::1] for the localhost --- docs/tasks/access-application-cluster/access-cluster.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tasks/access-application-cluster/access-cluster.md b/docs/tasks/access-application-cluster/access-cluster.md index 0ae68442b5373..8993067de5b17 100644 --- a/docs/tasks/access-application-cluster/access-cluster.md +++ b/docs/tasks/access-application-cluster/access-cluster.md @@ -55,7 +55,8 @@ $ kubectl proxy --port=8080 & See [kubectl proxy](/docs/user-guide/kubectl/{{page.version}}/#proxy) for more details. -Then you can explore the API with curl, wget, or a browser, like so: +Then you can explore the API with curl, wget, or a browser, replacing localhost +with [::1] for IPv6, like so: ```shell $ curl http://localhost:8080/api/ From 330873585f3b4c28ea88f147a6a0700a927714ab Mon Sep 17 00:00:00 2001 From: Bob Steciuk Date: Fri, 1 Dec 2017 16:52:55 -0500 Subject: [PATCH 12/35] Addressed a number of issues brought up against the base PR --- docs/getting-started-guides/windows/index.md | 129 +++++++++---------- 1 file changed, 63 insertions(+), 66 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index e6de4841df69e..b8ddc7f1dedf2 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -26,10 +26,11 @@ In Kubernetes version 1.9 or later, Windows Server Containers for Kubernetes are 4. Docker Version 17.06.1-ee-2 or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version). ## Networking -There are several supported network configurations with Kubernetes v1.9 on Windows, including both Layer-3 routed and overlay topologies using third-party network plugins. -1. Upstream L3 Routing - IP routes configured in upstream ToR -2. Host-Gateway - IP routes configured on each host -3. Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay - OVS switch extension and OVN controller creates VXLAN overlay network +There are several supported network configurations with Kubernetes v1.9 on Windows, including both Layer-3 routed and overlay topologies using third-party network plugins. + +1. [Upstream L3 Routing](#upstream-l3-routing-topology) - IP routes configured in upstream ToR +2. [Host-Gateway](#host-gateway-topology) - IP routes configured on each host +3. [Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay](#overlay-using-ovn-controller-and-ovs-switch-extension-topology) - OVS switch extension and OVN controller creates VXLAN overlay network 4. [Future Release] Overlay - VXLAN or IP-in-IP encapsulation using Flannel 5. [Future Release] Layer-3 Routing with BGP (Calico) @@ -42,10 +43,10 @@ An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxla The above networking approaches are already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. ### Windows -Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the **_Windows Host Setup_** section below. +Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows) section below. #### Upstream L3 Routing Topology -In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a Pod CIDR assigned. All pods on a given worker node will be connected to the POD CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes, the upstream router has static routes configured with POD CIDR prefix => Host IP. +In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a pod CIDR assigned. All pods on a given worker node will be connected to the pod CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes, the upstream router has static routes configured with pod CIDR prefix => Host IP. Each Window Server node should have the following configuration: @@ -53,86 +54,82 @@ The following diagram illustrates the Windows Server networking setup for Kubern ![K8s Cluster using L3 Routing with ToR](UpstreamRouting.png) #### Host-Gateway Topology -This topology is similar to the Upstream L3 Routing topology with the only difference being that static IP routes are configured directly on each cluster node and not in the upstream ToR. Each node uses a local 'l2bridge' network with a Pod CIDR assigned as before and has routing table entries for all other Pod CIDR subnets assigned to the remote cluster nodes. +This topology is similar to the Upstream L3 Routing topology with the only difference being that static IP routes are configured directly on each cluster node and not in the upstream ToR. Each node uses a local 'l2bridge' network with a pod CIDR assigned as before and has routing table entries for all other pod CIDR subnets assigned to the remote cluster nodes. #### Overlay using OVN controller and OVS Switch Extension Topology _Documentation is pending..._ ## Setting up Windows Server Containers on Kubernetes -To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows and depending on your network topology, set up Routes for pod communication on different nodes. +To run Windows Server Containers on Kubernetes, you'll need to set up both your host machines and the Kubernetes node components for Windows. Depending on your network topology, routes may need to be set up for pod communication on different nodes. ### Host Setup **Linux Host Setup** 1. Linux hosts should be setup according to their respective distro documentation and the requirements of the Kubernetes version you will be using. -2. Configure Linux Master node using steps [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) +2. Configure Linux Master node using steps [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md#prepare-the-master) 3. [Optional] CNI network plugin installed. **Windows Host Setup** 1. Windows Server container host running the required Windows Server and Docker versions. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. -2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md) +2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md#building-kubernetes) 3. Copy Node spec file (config) from Linux master node with X.509 keys -4. Create HNS Network -5. Ensure correct CNI network config -5. Start kubelet.exe using this script [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) -6. Start kube-proxy using this script [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) -7. [Optional] Add static routes on Windows host +4. Create the HNS Network, ensure the correct CNI network config, and start kubelet.exe using this script [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) +5. Start kube-proxy using this script [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) +6. [Optional] Add static routes on Windows host **Windows CNI Config Example** Today, Windows CNI plugin is based on wincni.exe code with the following example, configuration file. -Note: this file assumes that a user previous created 'l2bridge' host networks on each Windows node using -HNSNetwork cmdlets as shown in the start-kublet.ps1 and start-kubeproxy.ps1 scripts linked above -``` +Note: this file assumes that a user previous created 'l2bridge' host networks on each Windows node using `-HNSNetwork` cmdlets as shown in the `start-kubelet.ps1` and `start-kubeproxy.ps1` scripts linked above + +```json { - "cniVersion": "0.2.0", - "name": "l2bridge", - "type": "wincni.exe", - "master": "Ethernet", - "ipam": { - "environment": "azure", - "subnet": "10.10.187.64/26", - "routes": [ - { - "GW": "10.10.187.66" - } - ] - }, - "dns": { - "Nameservers": [ - "11.0.0.10" - ] - }, - "AdditionalArgs": [ - { - "Name": "EndpointPolicy", - "Value": { - "Type": "OutBoundNAT", - "ExceptionList": [ - "11.0.0.0/8", - "10.10.0.0/16", - "10.127.132.128/25" - ] - } - }, - { - "Name": "EndpointPolicy", - "Value": { - "Type": "ROUTE", - "DestinationPrefix": "11.0.0.0/8", - "NeedEncap": true - } - }, - { - "Name": "EndpointPolicy", - "Value": { - "Type": "ROUTE", - "DestinationPrefix": "10.127.132.213/32", - "NeedEncap": true - } - } - ] + "cniVersion": "0.2.0", + "name": "l2bridge", + "type": "wincni.exe", + "master": "Ethernet", + "ipam": { + "environment": "azure", + "subnet": "10.10.187.64/26", + "routes": [{ + "GW": "10.10.187.66" + }] + }, + "dns": { + "Nameservers": [ + "11.0.0.10" + ] + }, + "AdditionalArgs": [{ + "Name": "EndpointPolicy", + "Value": { + "Type": "OutBoundNAT", + "ExceptionList": [ + "11.0.0.0/8", + "10.10.0.0/16", + "10.127.132.128/25" + ] + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "11.0.0.0/8", + "NeedEncap": true + } + }, + { + "Name": "EndpointPolicy", + "Value": { + "Type": "ROUTE", + "DestinationPrefix": "10.127.132.213/32", + "NeedEncap": true + } + } + ] } ``` @@ -143,9 +140,9 @@ To start your cluster, you'll need to start both the Linux-based Kubernetes cont Use your preferred method to setup and start Kubernetes cluster on Linux or follow the directions given in this [link](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md). Please note that Cluster CIDR might need to be updated. ## Scheduling Pods on Windows -Because your cluster has both Linux and Windows nodes, you must explicitly set the nodeSelector constraint to be able to schedule Pods to Windows nodes. You must set nodeSelector with the label beta.kubernetes.io/os to the value windows; see the following example: +Because your cluster has both Linux and Windows nodes, you must explicitly set the nodeSelector constraint to be able to schedule pods to Windows nodes. You must set nodeSelector with the label beta.kubernetes.io/os to the value windows; see the following example: -``` +```yaml { "apiVersion": "v1", "kind": "Pod", From 5d89b14cfdb1d7150c90a983e7cfe15bafcdd6fb Mon Sep 17 00:00:00 2001 From: Bob Steciuk Date: Fri, 1 Dec 2017 16:56:18 -0500 Subject: [PATCH 13/35] Fixed windows-host-setup link --- docs/getting-started-guides/windows/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index b8ddc7f1dedf2..b3fde00c03497 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -43,7 +43,7 @@ An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxla The above networking approaches are already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. ### Windows -Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows) section below. +Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows-host-setup) section below. #### Upstream L3 Routing Topology In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a pod CIDR assigned. All pods on a given worker node will be connected to the pod CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes, the upstream router has static routes configured with pod CIDR prefix => Host IP. @@ -64,13 +64,13 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your ### Host Setup -**Linux Host Setup** +#### Linux Host Setup 1. Linux hosts should be setup according to their respective distro documentation and the requirements of the Kubernetes version you will be using. 2. Configure Linux Master node using steps [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md#prepare-the-master) 3. [Optional] CNI network plugin installed. -**Windows Host Setup** +#### Windows Host Setup 1. Windows Server container host running the required Windows Server and Docker versions. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. 2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md#building-kubernetes) From 5d39cfeae41b3237a5e1247bc1c1f98e0727c5fd Mon Sep 17 00:00:00 2001 From: Tim Allclair Date: Sun, 19 Nov 2017 17:52:31 -0800 Subject: [PATCH 14/35] Rewrite PodSecurityPolicy guide --- .../policy/{psp.yaml => example-psp.yaml} | 9 +- docs/concepts/policy/pod-security-policy.md | 656 ++++++++++++------ docs/concepts/policy/privileged-psp.yaml | 27 + docs/concepts/policy/restricted-psp.yaml | 48 ++ test/examples_test.go | 4 +- 5 files changed, 538 insertions(+), 206 deletions(-) rename docs/concepts/policy/{psp.yaml => example-psp.yaml} (66%) create mode 100644 docs/concepts/policy/privileged-psp.yaml create mode 100644 docs/concepts/policy/restricted-psp.yaml diff --git a/docs/concepts/policy/psp.yaml b/docs/concepts/policy/example-psp.yaml similarity index 66% rename from docs/concepts/policy/psp.yaml rename to docs/concepts/policy/example-psp.yaml index f82f7a856f1a8..d8359220e42b5 100644 --- a/docs/concepts/policy/psp.yaml +++ b/docs/concepts/policy/example-psp.yaml @@ -1,8 +1,10 @@ apiVersion: extensions/v1beta1 kind: PodSecurityPolicy metadata: - name: permissive + name: example spec: + privileged: false # Don't allow privileged pods! + # The rest fills in some required fields. seLinux: rule: RunAsAny supplementalGroups: @@ -11,10 +13,5 @@ spec: rule: RunAsAny fsGroup: rule: RunAsAny - hostPorts: - - min: 8000 - max: 8080 volumes: - '*' - allowedCapabilities: - - '*' diff --git a/docs/concepts/policy/pod-security-policy.md b/docs/concepts/policy/pod-security-policy.md index a1e219c146126..f1373a71302f8 100644 --- a/docs/concepts/policy/pod-security-policy.md +++ b/docs/concepts/policy/pod-security-policy.md @@ -1,265 +1,523 @@ --- approvers: - pweil- +- tallclair title: Pod Security Policies --- -Objects of type `PodSecurityPolicy` govern the ability -to make requests on a pod that affect the `SecurityContext` that will be -applied to a pod and container. +{% include feature-state-beta.md %} -See [PodSecurityPolicy proposal](https://git.k8s.io/community/contributors/design-proposals/auth/pod-security-policy.md) for more information. +Pod Security Policies enable fine-grained authorization of pod creation and +updates. * TOC {:toc} ## What is a Pod Security Policy? -A _Pod Security Policy_ is a cluster-level resource that controls the -actions that a pod can perform and what it has the ability to access. The -`PodSecurityPolicy` objects define a set of conditions that a pod must -run with in order to be accepted into the system. They allow an +A _Pod Security Policy_ is a cluster-level resource that controls security +sensitive aspects of the pod specification. The `PodSecurityPolicy` objects +define a set of conditions that a pod must run with in order to be accepted into +the system, as well as defaults for the related fields. They allow an administrator to control the following: -| Control Aspect | Field Name | -| ---------------------------------------------------------------------- | ------------------------------------------- | -| Running of privileged containers | `privileged` | -| Default set of capabilities that will be added to a container | `defaultAddCapabilities` | -| Capabilities that will be dropped from a container | `requiredDropCapabilities` | -| Capabilities a container can request to be added | `allowedCapabilities` | -| Controlling the usage of volume types | [`volumes`](#controlling-volumes) | -| The use of host networking | [`hostNetwork`](#host-network) | -| The use of host ports | `hostPorts` | -| The use of host's PID namespace | `hostPID` | -| The use of host's IPC namespace | `hostIPC` | -| The SELinux context of the container | [`seLinux`](#selinux) | -| The user ID | [`runAsUser`](#runasuser) | -| Configuring allowable supplemental groups | [`supplementalGroups`](#supplementalgroups) | -| Allocating an FSGroup that owns the pod's volumes | [`fsGroup`](#fsgroup) | -| Requiring the use of a read only root file system | `readOnlyRootFilesystem` | -| Running of a container that allow privilege escalation from its parent | [`allowPrivilegeEscalation`](#allowprivilegeescalation) | -| Control whether a process can gain more privileges than its parent process | [`defaultAllowPrivilegeEscalation`](#defaultallowprivilegeescalation) | -| Whitelist of allowed host paths | [`allowedHostPaths`](#allowedhostpaths) | - -_Pod Security Policies_ are comprised of settings and strategies that -control the security features a pod has access to. These settings fall -into three categories: - -- *Controlled by a Boolean*: Fields of this type default to the most -restrictive value. -- *Controlled by an allowable set*: Fields of this type are checked -against the set to ensure their values are allowed. -- *Controlled by a strategy*: Items that have a strategy to provide -a mechanism to generate the value and a mechanism to ensure that a -specified value falls into the set of allowable values. - - -## Strategies - -### RunAsUser - -- *MustRunAs* - Requires a `range` to be configured. Uses the first value -of the range as the default. Validates against the configured range. -- *MustRunAsNonRoot* - Requires that the pod be submitted with a non-zero -`runAsUser` or have the `USER` directive defined in the image. No default -provided. -- *RunAsAny* - No default provided. Allows any `runAsUser` to be specified. +| Control Aspect | Field Names | +| ----------------------------------------------------| ------------------------------------------- | +| Running of privileged containers | `privileged` | +| Usage of the root namespaces | [`hostPID`, `hostIPC`](#host-namespaces) | +| Usage of host networking and ports | [`hostNetwork`, `hostPorts`](#host-namespaces) | +| Usage of volume types | [`volumes`](#volumes-and-file-systems) | +| Usage of the host filesystem | [`allowedHostPaths`](#volumes-and-file-systems) | +| Allocating an FSGroup that owns the pod's volumes | [`fsGroup`](#volumes-and-file-systems) | +| Requiring the use of a read only root file system | [`readOnlyRootFilesystem`](#volumes-and-file-systems) | +| The user and group IDs of the container | [`runAsUser`, `supplementalGroups`](#users-and-groups) | +| Restricting escalation to root privileges | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) | +| Linux capabilities | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) | +| The SELinux context of the container | [`seLinux`](#selinux) | +| The AppArmor profile used by containers | [annotations](#apparmor) | +| The seccomp profile used by containers | [annotations](#seccomp) | -### SELinux -- *MustRunAs* - Requires `seLinuxOptions` to be configured if not using -pre-allocated values. Uses `seLinuxOptions` as the default. Validates against -`seLinuxOptions`. -- *RunAsAny* - No default provided. Allows any `seLinuxOptions` to be -specified. +## Enabling Pod Security Policies -### SupplementalGroups +Pod security policy control is implemented as an optional (but recommended) +[admission +controller](/docs/admin/admission-controllers/#podsecuritypolicy). PodSecurityPolicies +are enforced by [enabling the admission +controller](/docs/admin/admission-controllers/#how-do-i-turn-on-an-admission-control-plug-in), +but doing so without authorizing any policies **will prevent any pods from being +created** in the cluster. -- *MustRunAs* - Requires at least one range to be specified. Uses the -minimum value of the first range as the default. Validates against all ranges. -- *RunAsAny* - No default provided. Allows any `supplementalGroups` to be -specified. +Since the pod security policy API (`extensions/v1beta1/podsecuritypolicy`) is +enabled independently of the admission controller, for existing clusters it is +recommended that policies are added and authorized before enabling the admission +controller. -### FSGroup +## Authorizing Policies -- *MustRunAs* - Requires at least one range to be specified. Uses the -minimum value of the first range as the default. Validates against the -first ID in the first range. -- *RunAsAny* - No default provided. Allows any `fsGroup` ID to be specified. +When a PodSecurityPolicy resource is created, it does nothing. In order to use +it, the requesting user or target pod's [service +account](/docs/tasks/configure-pod-container/configure-service-account/) must be +authorized to use the policy, by allowing the `use` verb on the policy. + +Most Kubernetes pods are not created directly by users. Instead, they are +typically created indirectly as part of a +[Deployment](/docs/concepts/workloads/controllers/deployment/), +[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/), or other +templated controller via the controller manager. Granting the controller access +to the policy would grant access for *all* pods created by that the controller, +so the preferred method for authorizing policies is to grant access to the +pod's service account (see [example](#run-another-pod)). + +### Via RBAC + +[RBAC](/docs/admin/authorization/rbac/) is a standard Kubernetes authorization +mode, and can easily be used to authorize use of policies. -### Controlling Volumes - -The usage of specific volume types can be controlled by setting the -volumes field of the PSP. The allowable values of this field correspond -to the volume sources that are defined when creating a volume: - -1. azureFile -1. azureDisk -1. flocker -1. flexVolume -1. hostPath -1. emptyDir -1. gcePersistentDisk -1. awsElasticBlockStore -1. gitRepo -1. secret -1. nfs -1. iscsi -1. glusterfs -1. persistentVolumeClaim -1. rbd -1. cinder -1. cephFS -1. downwardAPI -1. fc -1. configMap -1. vsphereVolume -1. quobyte -1. photonPersistentDisk -1. projected -1. portworxVolume -1. scaleIO -1. storageos -1. \* (allow all volumes) - -The recommended minimum set of allowed volumes for new PSPs are -configMap, downwardAPI, emptyDir, persistentVolumeClaim, secret, and projected. - -### Host Network - - *HostPorts*, default `empty`. List of `HostPortRange`, defined by `min`(inclusive) and `max`(inclusive), which define the allowed host ports. - -### AllowPrivilegeEscalation - -Gates whether or not a user is allowed to set the security context of a container -to `allowPrivilegeEscalation=true`. This field defaults to `false`. - -### DefaultAllowPrivilegeEscalation - -Sets the default for the security context `AllowPrivilegeEscalation` of a container. -This bool directly controls whether the `no_new_privs` flag gets set on the -container process. It defaults to `nil`. The default behavior of `nil` -allows privilege escalation so as to not break setuid binaries. Setting it to `false` -ensures that no child process of a container can gain more privileges than -its parent. - -### AllowedHostPaths - -This specifies a whitelist of host paths that are allowed to be used by Pods. -An empty list means there is no restriction on host paths used. -Each item in the list must specify a string value named `pathPrefix` that -defines a host path to match. The value cannot be "`*`" though. -An example is shown below: +First, a `Role` or `ClusterRole` needs to grant access to `use` the desired +policies. The rules to grant access look like this: ```yaml -apiVersion: extensions/v1beta1 -kind: PodSecurityPolicy +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: custom-paths + name: +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - +``` + +Then the `(Cluster)Role` is bound to the authorized user(s): + +```yaml +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: +roleRef: + kind: ClusterRole + name: + apiGroup: rbac.authorization.k8s.io +subjects: +# Authorize specific service accounts: +- kind: ServiceAccount + name: + namespace: +# Authorize specific users (not recommended): +- kind: User + apiGroup: rbac.authorization.k8s.io + name: +``` + +If a `RoleBinding` (not a `ClusterRoleBinding`) is used, it will only grant +usage for pods being run in the same namespace as the binding. This can be +paired with system groups to grant access to all pods run in the namespace: +```yaml +# Authorize all service accounts in a namespace: +- kind: Group + apiGroup: rbac.authorization.k8s.io + name: system:serviceaccounts +# Or equivalently, all authenticated users in a namespace: +- kind: Group + apiGroup: rbac.authorization.k8s.io + name: system:authenticated +``` + +For more examples of RBAC bindings, see [Role Binding +Examples](docs/admin/authorization/rbac/#role-binding-examples). For a complete +example of authorizing a PodSecurityPolicy, see +[below](#example). + + +### Troubleshooting + +- The [Controller Manager](/docs/admin/kube-controller-manager/) must be run +against [the secured API port](/docs/admin/accessing-the-api/), and must not +have superuser permissions. Otherwise requests would bypass authentication and +authorization modules, all PodSecurityPolicy objects would be allowed, and users +would be able to create privileged containers. For more details on configuring +Controller Manager authorization, see [Controller +Roles](docs/admin/authorization/rbac/#controller-roles). + +## Policy Order + +In addition to restricting pod creation and update, pod security policies can +also be used to provide default values for many of the fields that it +controls. When multiple policies are available, the pod security policy +controller selects policies in the following order: + +1. If any policies successfully validate the pod without altering it, they are + used. +2. Otherwise, the first valid policy in alphabetical order is used. + +## Example + +_This example assumes you have a running cluster with the PodSecurityPolicy +admission controller enabled and you have cluster admin privileges._ + +### Set up + +Set up a namespace and a service account to act as for this example. We'll use +this service account to mock a non-admin user. + +```shell +$ kubectl create namespace psp-example +$ kubectl create serviceaccount -n psp-example fake-user +$ kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user +``` + +To make it clear which user we're acting as and save some typing, create 2 +aliases: + +```shell +$ alias kubectl-admin='kubectl -n psp-example' +$ alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example' +``` + +### Create a policy and a pod + +Define the example PodSecurityPolicy object in a file. This is a policy that +simply prevents the creation of privileged pods. + +{% include code.html language="yaml" file="example-psp.yaml" ghlink="/docs/concepts/policy/example-psp.yaml" %} + +And create it with kubectl: + +```shell +$ kubectl-admin create -f example-psp.yaml +``` + +Now, as the unprivileged user, try to create a simple pod: + +```shell +$ kubectl-user create -f- <` - Specify a profile as a file on the node located at + `/`, where `` is defined via the + `--seccomp-profile-root` flag on the Kubelet. -For more details, see the -[PodSecurityPolicy RBAC example](https://git.k8s.io/examples/staging/podsecuritypolicy/rbac/README.md) -of applying PodSecurityPolicy to control access to privileged containers based -on role and groups when deploying Pods directly. +**seccomp.security.alpha.kubernetes.io/allowedProfileNames** - Annotation that +specifies which values are allowed for the pod seccomp annotations. Specified as +a comma-delimited list of allowed values. Possible values are those listed +above, plus `*` to allow all profiles. Absence of this annotation means that the +default cannot be changed. diff --git a/docs/concepts/policy/privileged-psp.yaml b/docs/concepts/policy/privileged-psp.yaml new file mode 100644 index 0000000000000..6b6ec6687831d --- /dev/null +++ b/docs/concepts/policy/privileged-psp.yaml @@ -0,0 +1,27 @@ +apiVersion: extensions/v1beta1 +kind: PodSecurityPolicy +metadata: + name: privileged + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: + - '*' + volumes: + - '*' + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' diff --git a/docs/concepts/policy/restricted-psp.yaml b/docs/concepts/policy/restricted-psp.yaml new file mode 100644 index 0000000000000..fe1c1d90fe33d --- /dev/null +++ b/docs/concepts/policy/restricted-psp.yaml @@ -0,0 +1,48 @@ +apiVersion: extensions/v1beta1 +kind: PodSecurityPolicy +metadata: + name: restricted + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # This is redundant with non-root + disallow privilege escalation, + # but we can provide it for defense in depth. + requiredDropCapabilities: + - ALL + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + # Assume that persistentVolumes set up by the cluster admin are safe to use. + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'MustRunAsNonRoot' + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false diff --git a/test/examples_test.go b/test/examples_test.go index a7f837ae2c5a3..1999d1f1581f4 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -288,7 +288,9 @@ func TestExampleObjectSchemas(t *testing.T) { "nginx-deployment": {&extensions.Deployment{}}, }, "../docs/concepts/policy": { - "psp": {&extensions.PodSecurityPolicy{}}, + "privileged-psp": {&extensions.PodSecurityPolicy{}}, + "restricted-psp": {&extensions.PodSecurityPolicy{}}, + "example-psp": {&extensions.PodSecurityPolicy{}}, }, "../docs/concepts/services-networking": { "curlpod": {&extensions.Deployment{}}, From ee8801d376e4682c4c4c948ef8aa781757ac4389 Mon Sep 17 00:00:00 2001 From: Alin Balutoiu Date: Sat, 2 Dec 2017 02:32:54 +0100 Subject: [PATCH 15/35] Update index.md Signed-off-by: Alin Balutoiu Signed-off-by: Alin Gabriel Serdean --- .../windows/OVN_OVS_Windows_Installer.png | Bin 0 -> 42455 bytes docs/getting-started-guides/windows/index.md | 126 ++++++++++++++++-- .../windows/ovn_kubernetes.png | Bin 0 -> 106577 bytes 3 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 docs/getting-started-guides/windows/OVN_OVS_Windows_Installer.png create mode 100644 docs/getting-started-guides/windows/ovn_kubernetes.png diff --git a/docs/getting-started-guides/windows/OVN_OVS_Windows_Installer.png b/docs/getting-started-guides/windows/OVN_OVS_Windows_Installer.png new file mode 100644 index 0000000000000000000000000000000000000000..520f6ae9e6c54b752ef6b60df6d4b11a17741cd0 GIT binary patch literal 42455 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 vgj|*rqxpV7NDO(&Jeq=wLm z5(7vI2t)Jk0X^q_&N*wnAD^`zKHRs%T-Vi~k$R3PxD6y>hO_mu)B|@r_scJ@}8m*xk z{sKIGoda>QT3@|x6XlhJOZo?~WIC$kRzz?PHi7meb^=21^&`d8U2?qBP~k5#uY`z8F=CQ%RlhZ0_Kapevp0cNtFJ zPk@V{BDfTvka;FhoO>=$zvKm7(v!9tzQ>CqH|IyappUKEv-lale@G}4cfrg!%HV92 zU39F`T|o~gY|mj*kC*Xb2O+%M9y2Kx54b8Pi=!3%e|(b^UTPlTX)$RcdS$w9xY#(6 zPxpy^8_jdbe3=vJ3#)sds`gVT9_t>KG*XnQwpynr(Fksf!6|a2f*-jQx2~t@?ze2S zNHrlSJBB7DalHE)_4n|`3hthyv~x5QvkK%cbcN+E&tT1o!)Dn;YCZ!qqIOBVRazlx zyY>U=Y z^rgON=;rQo1^Q7bzF|rQJsxUG^v(HD6}765U+Tm4tMt4eGpw&KqVezoQ2$~n2?@N8 z7yeL1MgM~~cjtRkc6lUab7Z_O4|O?fXc3~MFbTIADe?sV%@Bt(nMd0j`E7Qe3xb;VD_0Eu$39KL&>}YZ&VXhr-YV|0o}Ta8F{<>o zjRMU`Wbp+f9*c1|zndbhl-3FMn1qr7$;~9LA5Ov7l!Bmdh(4s8xqxFO9Rm@tU-089 zb|9@Z9WKlh&BUYi==1}<@8!Onl{axi1eK1`x z`|UUHO~EQ`Qm49z7n}iX_ANh3-7r?Ti4Mr@G27`$9uS>aHJ#TVZhY;!;bXwf`HD*i z`TjH0J$~AcnJZC@!YZ%Z!(Hj1UtpF$E!D#np~riQ@>IcICb@xIPOf+ejTXBOV0V-A z?Y@A9`ae|4i77!WE(n*Jhl&1vqKB?ZXfJ9l4X2MCYNmG23a=%(8c*z)(lIpmsh!`V zNU}`8{lP4$132{}@gKTta^>lj4PJ>ri1*yB^pI?yjrF)8B?LTqEAS>7YrQbv!$mm1 z+UVKWKJL1sgm`#4tbb&%@Q$g0f93vXp+Kz=wrkXEd5;2naj<|$l|+P%X-() z*tZ@ssfeV>C9vaTroTJJ^B{z!3{j|Xdl}^NM#akT-qMy|-JSx@R2FIfKBZTn-6E(9 znW5WIuReUphf}1*e=os=_8_}umA=oV3wc}cy#3yEQt=j%!$$sZ51E`Mp#K>yICTa; z8Ak1>@Y&~-OG_yom$Z3i45Q44&c=6I3NP7yM%Sj;C@51R;$6x6bzJ#@qYLeP2 zg<^!4e6H;#1}5vYh+b9a$RaZ6{PCqB#l9k6ifk^kX?SwJ=gvnXwxo9q-MXiLAhP9D%3qB7ot+y|$a9 z;Pv8KTk!j~Kfxh`Am=Q7^R?NH4xzzuQSgQ3A6jAfz%z79V~xj607Y__|FBXtKpe-t zH-8*k0K>Q5UXJ-RZwCiKq%w=AqI)9v_Q9>wpduF`9Ih>ht%Jz~wZE_|GrBc%*=;)jJjZM#A4Hs?xm=w$+lmfo-DNGvCE|cbcjoL$3 zD9OpOI6wCjP5Dz%QOiW)N}p}yvNt!*GUAp0Zpp)qXb-#`Oh*>cyHJ48(u*w@3ysNF z)hgh_rigsy@e#Li)IG<$(z~#r<84tf$(|^-|Mlz8oh;yEa!CGiQr!uqu5;rvjMVHM z$%C5LnV($lyjRaswWz%re2LFZ93H}aOSSg;WeG)O_1$10z#u*Of9;P=fo_K;jJ-Iz zb=&(bUBt@nB8`xFqR#Jc_w?dSG#4;gYOfhe53k}*{qMJ4DMDt%m<+T!c7@iM7jqJO zdStKQj3eXmA63c`#*o8FSR2$oGrjJVu2d`OK#pGDFb}n74juFsSYzUizzJISuPKVY zTSkTR256lZtw^-w)v}}E;o`r#67kUE{MEeOM?MK_j~`PuUqc8SP(B6%3;N>$GFlMQ z2q&^L3AqmIq*`|D8nxH=f_PAgn?;sR=Ou#fHNbcPt$F{_DV-x2_i>eh)-;!`Sxn zuuh*R@2QDBXscao*q?oETND!}SaYW(oc@YMYh?Tdp}O}D$>ww;`*PqN@anw|`{kh$ zs8uIj^}?I5ljrwWYlZqe`TnlswV0dD$r9B;qi@U}C9{`PVAg2r<>mF%T}|>tXLIV( z(pU@{{pzLm7T!94q0zr1#gdqv=7q+J{t-rS=2B6uMz`deltGYY?r9t1e}t)kmd1|FNOGP#QGutmVD;HF?^P%1?o;VLxU)OdD#P6)jZFc2FyPJ- zV2bmMA;P%V9Si=U_32%D?;?Nc~C%T2RnVkT8G z?>wPRKlCN^=Z93AhWc*l`IYgWz8o>X$lUt&Wf*(!M+t$IV1)mW#w}Nn+v$ugXmW*C z#iVagkcAp%TfxcTRKzNf7rEt}7Q!l=QWf!|#mE39gWXsS)lRP)k378R9R=JHY}0YUXt1yixupv}Dz552hAV5~NIV?yC|mAT4zZy9~m z!wR1q%gJ}Hsohf(&*d3K5GuJ?EeW2I``X$pXQD+rH%KZD@Qcecwa?*nHb>|m9FTkK z^ODjO{g&jjqewRiITrTV>RPNBw{TmdQ9qK%sQU}{Yh^`^8{yf~~@yJcK?aC_YG zdZVlkvHq`EjTX)Xb#GnF%{&W4{~hF(4l&N3&;C4M}*GA(HdSWpP{ zDR>PhYK5qy^JtV8rbtwMa0|KJnzFuOQY30e)Hc zFeYt|_K*_%3#l?_P^7=Fg;4WBVlMW;TEq+P%Pg;xP%Z1R=Kc75+0>)U!XlaPYE|rK z8C|41WJXjy>G+A`0IcQWk4&oSLC<@bo%-WW)l(}Wl&5zD>q4Dp?;u62BY$JDYA!Bi z;Y{MO4}eMbiOSRKnw2~Ye;LTo(0O^xl21m;&>R&$=mjv~sBKvXfi6hnkR=~rsBr0z zDqI_f&Orj*yKac7gr0pIOBU%+;g#U%U0q!jt#h5oD}WfCDDcJaD~MaJ@t4|O2EGot zeGz@`Jh75K8nS0KnV{_790*OD3On9*8Aa=@XL3%J32ZTmEH)5s-+$;QB6$^w=+NO1sS6?$k-n_=w?9m#$PCZtWP%tjC!O05n_F=wSLtZc zw`?gTQ>rYRIKH(z)_54QQqto)BRgAw^?#qab+1;sYEIL6p-pQ%1e~Fd2(awcY-Aqwwwyk;iJ21XtZi?*HFlo`hZ995$kShp8Hg~NMKI1M3iQ#r4PO#>I2e9N7tADfw48Sy zI`dANzl%?-eO4(y)Ks|{n;!iPnAlvQJ9&H5y~fPl1w6c`o-=Zdbt5ivrX$swrVA4S z`DT81{kEoW*o;>xT`uxAII_NLxN7!|-L}RJjn5}B>pzeQpQ=gBa-F$s%T+r zMXR_vbk!GkGfSTj5nHl*EF7h-lg z2R=3&n91%0F-bjDRD?e3oE+N}q4#UXW#Ty({fDs$QtKfC&ZDue&h7X-;#+ee<;NLv z{Tj8q?A5c+5MvdVskjF=5`7(iPPjs-!D}=hEZeEX4}X7$?>#+iJir+g+CC=)I_|wc z8;7m5ssDN1VWim^Q-_HCU}MoKGYrTuFst44iVm~!2G~B?JLmI~VAJy<*9NvJu+lthOx=Xg z`TJ+-0TpzHBN7$ptqb?iHWv$@ukXv$J{{1mcAof-N??`VVn>!g$jX$cAXvMk2yjL~ z9u5l5s+sM@uHs4pcyJM21!Q%;8Sl?`T0U0!#^P%>234zYWZk3q@Z|0H1IhR2Cl2p_ zVh{h|JAH%@h(`Wm#tP*U!|~Wg65QN6W`puAJ9XWi*mzj6T7)|T7h@=@vv1(T`N;+0 z5IQ5U{b-5+5JILW=3VS)IGnNkykw$ObnK^QWhKSgkDqSA*>Irf+wb0P-;FjG|Adm) z{!FmQHQoG&^7OWhk}Kv0zsAxrS*iPZK8lnlRM&0|7-3kC*I8ZNabkuH!${!U4Zbj$ z=~j;sA*P0%swHQn+Ff>T@0mihs$PsKwyhZ6V}y^9y-x(PS)w4= zJF26N#KyM$39O9g!FsE!`*|FbRr?f>-u}DZD`IcZzB(NTUz|44cb$J0WSuXbDeG#C zy`n5qxl7K(gusRnSq4wy%H=f&%Rz$TOBF#CJ+nA216=}6DSj?K+0t-nG=;(lTp_s9d9b<7D})77{o_L! zRyA&#XKEjzxq);gnVi(apqeUdma2Ncl9k#zGESq#XP@@>0SxNBZ6`hxE;8FCHrY2$ z1E|P&phX5JXBOu*^ItGn5kqx4{qE@3PBk)F`{1Iixv+>lo)1~6kejRX_Pe}S5A0cP zYkYmy3o~D0_VHVNr6zb34q_&bY*ZdQ->x*BF1rN*RASG4K5nVQw~g{FigZ!^Ms!Iq z-OtR=cF)vq*tHA9Q8v66xRG+)?70W{AciD`!OzlmY(|o#WXy-WF>DEH|N9s1zsmKerD_CD1sxt5f^s=jwMyA@WO8pskmg$22}3$l+B-?nZ5k9CQ% z?c|i={>ImUdn zZ|F27I->!=To=7}LoXQI7ubt_aCbtH@4u83E9OqDB(7-jhG*`))PZ?e->Dq4~VWodKU2@V3ZFFCU~{1hxYlg->NYpkf4{ zzU;1HRo?RcWMH1|zMU&khGf!|qNRb0I6$^~|`UgGVt6#mL z04hu2gPm8xHn;C9yX;OCZ6-!`qsnOpgQuBRN2((ipO|dEi=*PppkB1K!Xuj3XpM%? z9SHZ&lInsGF8&*9FfSlABw8W@zBtzF8<<)a zzRy=A*xd*)vs?RaQE)rQ)d!*IUY7=B)fk%hf#2jNoel5i!XvIIu1_I7AJxDy|J5>>xGCiOPKWo!~A(s2gdVSb3n#}2)C~yQP z7s_M*!gMvskQaWCbS8W-8V-cd-XnWlSBI@%>mSDzkJzq{qdL1MDlw(QjijUxi&C)V z{Ki;kC4U>HEc5%plh-sG_GU2E4a_%hLRk6PqlsD3Ir#KjumPlP+ktLY-c&_bc4$=s zKO;D4|K^u!O`6}sJ|HZ^f%#YG^{D#wxUQ}64|5bp3hs+^R6tW7qr#);N!p8KzXwYd8U3sg)6gNp%O%_SDBJ_h(cdfKkTod zi83fw+eE4Q(cKt?kX55TFprkiO~_m_vNtX}`{ifsI|2oU(f+99myBB#}t?hvHsrGmYmwHa6|Egxja%eO0-he7g`g};u z2irk(ATjmRlSoLUqz@4}c0V@ii@0q2MZJ&!3jEygn4iS8YY;(UHRq>wI+ znrG=e$I?$>RkxSuTan8?de!~7<~4)Vb9$Fl(48t|tknIz|4HK9$m=f23k+uq-5@(K7Em9{&Ph4 zruN|H$VlGTz%|yCbxWvS=D(kD>KfUYQJu_<_s#l~MHF&P_TK|9a}z?VA*2byT(IZH zXVx*X+|CRxB$2zlRV|C2;8KA)vA+46w9%HOUAsHfVFvP4-u;pOkQs8%rr*kIly(6u z$giO1gVJJ1jfdo^#%|vhcGlwwb;YE)5J&_G(GE2lCzeK4it(OJa@;}@umG;Hg+wZ0W zh5|w~%|&mTPLS8|nyN6Q55HzK?4obFDOxV;*uVB2JbWrde70B($(8FrS65H% z?xX$(dE^!4sP@q{rr3rTFRn*fNj!N1lYzeVd8Q7$f8FqL&yZvFKv&ViZh z6uIvA@Wg3%RxchlY&e20^;Q8>bKS7621NA?RN1d&r#OeMI`m}` zQ**Z+AFUlPuHw21KXMsRow$5pGBDI@f5%_wV$4P`)Z9VclYj>Vz(}@ccMW7YHsyL= zbaNwXDC(PYbF#tni)HDN*dHLI%r}>8gTp@24rIy0yG_$KWEz{RSfZDScyIjRIK|h- z@lx}ZM?W7we&6!~ZiBkuRw^UnjoenIEyx=sF^(~(SX!Dsvmy_ntB`qF{?#U0ej&l3h&@vP8wVxm5 ztU&Nk=+XRM{Z<(y&*7qM;@H*JS+u8S2jHhApoAtj@8`s5HYwZOD3xCCOJcZT*8F7=D3&KHe`aZEB^x{8XXE8-c4wO{Oj4wH~tzSegj zVQwRBWS1o!0d7QI!2eHt@2zvzQPC3xiKXuLW`7z!2Z!^{f|lnmvDI`2k7FWs#+^|= zxgQ75o=HTzA0}l)SAXZ_N=4kKkpOAfxtsGTE}W@?mOo4p9g)nEmSa^;r(V>91M%uM zpFYGzb1~>m6c=8`b)31YT+pABU$^((FZXX$w>4qpjpnf$$2l(^kETnkIm{r$~q56FLzp+%^RmHZ&__Yf{zL)<>^1R4ip+; z>eqaWfkuCb@|nG|u|IiidXkypamgbel{*JQC-;UOLuDfI0(y~??vo~a&y(INvj8}h zZZja#+6fH%nXllD=v>RN9=rJVuzSP7ays4Y-|N)LnL5vDv_`)2asPP%3IZCt0=+An z1p(i-@fDrBajab;Ji-{tw3?6_PQ)1w^Pjz08`V9&8t!6?BN1W~kTR>T-V^jAccPYk zu(`Z+exW_Ovv}y{Jzs1;tLzm*3g&j{!5Swur3TrSyWaPK;%9kcxQ(7%N!$n| zjQvOB`s%fZv`d!mlX9!Rb}Qm+)D4?C_DC=nCBlSs&!Lj?G04lnYi=RE!=#X2y*JB1 zA^<_O3t3z+ks6rs^AG9@0iJ%RYHu+g^G%txe>|e5!fnNHcc)dh=mcj3fELSjLv~c> z`;K>QPBT51L9afuQ9^l6X!WKxtzLd~JeM|ezVJmg*6H_cc&JF#x^YP@m9jzV3=>IV73{WnVx)!l;;!2Pm=cf?tom{G=kjtN?$G|n ze&V~cai?Vv7|seVFrsni!4*(J;WQRIwii7nx=DzugM(A^;FKZsJ1D+iQI152yUgA3 z_iyxBWjv1A4Zn9z#M*ye%b?6N`+h0?Fn0S^H8!zPXjhU`9Uh(wN_U^FD;^(DTo`>P zv|qpMEy>!#B$<$VPGVGx*}@)-vBebLR)Od1A+p$q-+$RK=4M)_FXE4XA0pz%g=>D- z1uK*VUHuXWMPjFm=1PkB;vqgP48We6CD-b%GzXK#y;Y7{TvZ)UzGnWsZUfDCsvcF8 zKs|!U;E{~}6-@5ydK*QI{v1oD<6ImZE_0nR7X+*1Kr7D%*O~otIjS|Qx_WrqS8RDY zf3|Af+S@NO-E~xccPrg2&LZKd)$zxSOo>_yHMWvwiy4du0x3Ef}h#T%mtf;tg8mx^CjfmlIzJie~pf$gEx=QW7SBxD= zKV676_S?mPj-yWyt}Cr)7i^A`$>IJgqin2s`i|j``J*Z$mIRFdhy&w*Iw$qla#y?f zur+V!Z}&T(0P}2e5TxCupfq3ukSH*Ycu-rta~?`NiOmF0emF18fiy=a9NW}}3uF}E zazR^K;*%=N0fd53@C;&^?y!JB_cw!d(MeH>W!ksbL9QLJalh8B@L+uMFm=^IPSK&} zCpS{mHsQ3wC>RL+_6R)g$~zXhd*O9*R%4?X z=;Abk9&pAh@oaUMZINA<<2mVU^`slC2_YEee6v{Q(15ui;h1_yR>WleMvc#!J|pJ2 zH)~J5Ajqe25EFzJhW20Z9kR{YCU4fnu5aQZ(IV}WjWOp6nlsBH0^uBjo=c~;ytoF zRF_#gWaXELcB*intdW~LyF;(vL|w$okl@|*9sFgcHrs$<-e?*aM^7~rL^4y; z(@F6cudOA@9%U(~Ef4W7RV>F!rWp%~Nmbl#xZxkYDO>8=1&~C&+ZmF zw)u8QW==IG=-Qcqc{>Cca{Dn=vs4s!{=#LPwOf9FcXwlo!vFp$5TFG>;Cdr$j!)Lq z^!GYwwrGB6Tq`nruWcyi5OcS9C0>l2v<-w=PBz+g*X8?j-VliKx=F}OTsvgq=2xL) zx8?YRh~l=bsDgq;KXybeXpDSp)^FU?Ll0efh+Q3rI*i@?hc4I2BXI@Rw^?J%_;|W^ zbsN?MtFTVUa*(HbRp{V4PM%KlGQ%Gl&9>`(VSD5(vCkAjFkfTdqR!HZ9aM3ztSvYeT_UO-o zRm-Ivvq{I?V7@++N^dWsaTTE- zQ`G4@fdvN5meE>HXrAmlW@hQ9p6W&*^vHe)u7e8%VdiwsV>@MV@R7Ha*%so`+jx9` zz+qVLx9}Of1z|+v+T+~6>%9pRjGa&S2Z%0O)bGG!xXe20Ukgs)7W_;nBOh$y6Hl7n z%in6^qc=B6Lu6He>g?@aeG^59Czp=e^VPSFfW6xQ;GTkYw@o>-tV{aouUrIN&aL22?oFAOQ$A79mww^_zCDXgw;kulG4Ja!2?Y zZTe%g-$b3kV*?|-Z@v-1dBHH@uV3p?{&n2JLL#IuE|-9$EMP<{0%nyH+ByTZ?q(Xb zIQ8zLTSR!2aGdA=EC1Q6vOJ9-Pk!qD)-n+9ThltoByt1-p%aFNhL*E!F}-7B{D+5! zxJBs2oio7<<-#fh9^3POZ2e>yp4c8r!}p&{9Dyak{1gxwh%2}u&9qgs36yknMpxW^ zqWi*;PL5|FG$5qM|7f$+ZWuZ~4xwk4D}N#dPVo2w7`#X!#K(IMx|DBDUI7iXs`uG#c* z8oYn-Y}Ek~9+v)S$^&fDcNq-i+@v7D3tSIk{a{PMwOH+Yq`Xpdd~OjG|9?zvk2)se zlH7s+xy`k-(NZ<uvfS%a*dIBdsiANk2a`!sPoF+*`}~R;0C!8{1H}uipx>5JL5U7* z_PmCdL05VFFm?Oun}pGo#{1d(l!IJ2Vj6t+XUo59eE**ZdnmnkU?sjeaDD_o-0-pW zM2#GauV2}!f>9+Piq$&J^IhHch;2=+7L}mio1hucWrG=kv79L>Iy_h?NCsj(W(P-_ z!wnySLYYAAKEYGg-Wo6wwo^45t7eHoqolvl{5NGGWTV?{9|A>`KG?DzeXtvpqb8p;la+e9_z5BsO-HXrNnx$& zMOMsLrj!vQLpBs@Gn)DxYQ-yjbDD%SINBaLIwtz>W&8I6jz0NM#fACW+uP&D2p3jw z_XBhb?`?{QdMzr9C|qQ=@9YbKgI;E7d6^LwB?qpTd~7{B+{b*T)&%Lp|5|J7GWz}p z05F$m3lQHOidF)we)ok~_CAk~T^!2uPJD|8a7X}1eNKk~FGc*PQ3Nb5t*$2Y=j$)6 z2HyjTY=JL45f_1q(i-KvtCzG^ZmIID;No#{ml->*r~bjnjkv6t^e%2)M#nm>)y88# zz)gn#;^xcH#$|7{w4LV5)%NWYxFLWP!{EoS%@gm&%(SEn08|a~v;^>x$1^p1{2@#%@PL<W{U^Zx;$~YNTal+ILJ~uQzi9vq9|Q~oQNo-egzziHXbIg zI$R1m)qws)Rl0|CR$(eolO}X8xLz@^MIU=7zA&G?mXgmi8FwAxzP9QxO=!GoLEqt0 zGtNF(v zNJCsWd$yLq_{%e991_th>ob2 z0@Cj5^wtEkf7EJ5OT`oJG2!%bJ@4vCFa`#@`6v4Hl_n%ye$_ey{0d0B&eHFIs|E6} z!Kj$lLcbrRWjYyx|iT^J#@XSed< zF{9og*$`_7tG-&!G!w(uUc$8*{n?}Q=SJ`P}&G%~?`$cZ_-h4vtp58*0<8>p)dwgfF6f-V%Q?}KlmG4>A=0{aGK!O{c^^R}u zCr~`9lc&e-mk|=LT1-tSo6FNH^b2*^8aH=WZ%6H#F8kA(AKe?H;q6|T-(Qdlo{G|} zf!e(+|+G!!4e2iu#OIXCn$`MBv3>5_V@j`*qOA%iMR-&4T;dxD`qNaw_>1~vCf4seaUVZ@yxy&WwL!AbFB~}{t zP`rS75#n}~DssDJd1fUd6z`o01I;HjeVrHAuiwz-i30;|mmYK^2tXhA zL4K~S4UWfuJ#|ePMqls3`_)2;;JOMgcpRv_?8vr1PCh-It?h0UQ;tuthEO}xRXz-UfRDyad7rpuB6wag6Ds`f5PKuK+*n^n z=Z57vLqmZH!v*FyolL9YQytF0!p|OdG#-Tcta(oY?DK~J$}`Wzyi9~3K0BoWyM}fG zl?5){3FSF2D6nL%u6%5Wb<$u}V)y~J#5XOvlkDgrFC1JZRPumTz;17`s8PT}=^OZK zr$6#C>m^w-PYdW~OdZs^kXa`f=u6O-f#%q7Vs7AL4Z22HOR?dr|LK`rv+7Xl+;lcX z8iwdPV?P6Z$oGi_19%+co6c>Y#OtD#FX-fvO!D*@awaAwP`jaPC(XQg*r@<0&zui| z29XWx-pLBL7eG_8sY7(yyi4r(bhFguwbRxb5vs^13c)lq==+t-d9gXrcqpf)naQWq;u?I1!1D>)0sQvR|d-6nb;aja-OGzVM-JaOVVgt-3D@2#zPxCv;l zKD>Ti<;l95XJUt7At~HhA<>h6jnr;qvxf*3ejYf$z%@T?t@Gj5ATS)rX%x?S1KWHR zIP30m(_3d`ERq+oKJrfVDU5&;?P)X?_qukiYhRyE*H42!YWLm-GfWqm)SMJ=p@CeM zAW71B_p34Pmkat53&Xi{&t&|g=1NpO^+tD&x*)t}@=uO@EhCNOsj3eX$0>xjqHWVq z>JO@vAuk@Wod!%fX^0WzJFYpVkEi_!vmpcvgt90k!UtFKJ_?5jlnE$9u7FEQmoN+8 z-a^fr&KXoYXRQ{U;~o8?x!v;8Ir2s4*`j0{UL?ErhC-6Z#4M>O>$9G_`NsZ*OO+I4 zv#!mzMLS{a-!*rp9$v~3T(XXQIV;0hcQu2;Fwx78d}%(~Yk@~8;73)-YT9x01~OjL z$2dL0w0P4yD$i5eZomEFb6+#YBEMbve%X*vmn# zgdPXm`?4W!UH_8|=$g5^SE{F*j!p_`>7>DKo49K4V#bO~q7>(d3>3jdPS0}!K)Pwo z_OyNR4B-CrB^yw}+K7qrQ9McZzvzn#`t^wgToMaQX?*Qg+~&5~i=ER{L4|vkeO=;? z#7tJ$dmk*;1SVH$7>A$jpC>gO{{rz7J2K(BKx$tT)brXKO83>ZqC!)CNN54$=ho3|!XY~FSjn>{0)=l33_ z`sl|IO72N~qGa29xAyt{ekpGAJdXn3jigFkkCE1OE&ZSbjh*y7AR()7>imX}c>dQ( z;PBfYFNnT~wrnC*Qc?{{bg4trpofAvI;3FtF&E;Y;s8MrHyo}wcFeYe!hN%TJFRTP zOts_-@~vVo7d1&gQTzIDvyxW>uCAFa*ErnHoe0?^c+>N_Pl?Pu^Wzst!0V|^q(K(> zxy~*8q~2I{FvA6W&q;!m7X^E_cRPZCi;$cNVoo-kcUj3*ML{RATB(tzFi3&{pYNBKZXf(r(!6mS>?ZWC9K zMgE#<#++1mXtKaQb-_>94O(n-gp}H*7o}1T{>}o3Rmx4F)W4?OFb@{GAg+6txQg!l zwd*{=1-&v%;0AD$%2f+^G9x+c4_=j%1}aDgSW2I%%_F}4nHmmKvYOgy?cOh%IS)Qt zXq#d_f1YS8b?Y+Hfk7;gnruIc!tCw*Fs0k#)J>6-td{{X{|4aze&7(q;XW4BSUDnL z1dzBdVYD5 zSGs%SrZ83RSp}re`&eQ_dAp8Y>@|gW&%#O=(ENW_AWoC5lXk;x6ZTU+AO#Fc6>&ir zDd}FcTJ-WxF0Cwk%MzBzxS%=S^De=PbffO0ySNE*nVXRSKxtfLguJJvp%eU_{ zkMM>5eBy$>dAao7Sm02C0nZE#3uaIyi!^{&jSDSN98c?FDm00{HTV@#L1QW7uJF76 zMrGpEX0;JlL;4|-i)qqgdyU6BzcX;d+)okqk%9~lL33Kvk=xqZ-c~g-0$E32{C5q> zyI$VjphkER)FXAmS;&+hT*fU@M?#fA0;jXJlDIP6N`*)g zcp`XNiSi-F{Yoe4(@-*a!BU&!q&VqoUViQ4vo*%pD!^?@rMc)h;wU_c)NmF4m|t`) z!m_f7*!h~tdDm_6yEG!;&QYchdjm5-xS#^(2~7K!PbA3H{-yaeOfo+A9qPC4;W~ks zNXgacmC;Il`_Vt4Q8@JDh^OY5xN)LL&bF_qun*FH_r7*)1?&@3f-syS3IA-=nA8LG zRBvx=xcK~DsVl_n=d|c-)*38{xOIEss_(4%oxCJUjEloeOf>rlfd&pc0wNb8U3-u`Ny3#kUvTGy`F;@&=t$=WFWgrvdsOf;baBPx7cmgMa?aAOEqpr@oo3iPhJ4mlvA435jYjy<3 z@9cUC2cvA}#+$A|Lw=N)=m(LE`+4^FClhOq&4V>A;HG3AY#JrLSwrV>C_kaLLPodp zO|C8bk>ork@sas_!)_G+F&-cST-(HC#%aWAy}jKI2tr)2{+DdNy;a6#D5vfvz^V~M zE=+=vLySwexbnl2B%c|^$>DlD{KpU!q!hc7h z8dM%J2b(>KfaZ>?vb!oOoK()B($#jby9xgiO4B<$%#$qUn1H+Cfh%$rly#SmUt$n` z80fPeW`-EAb*Db7NZN{@!yf4=O2wn4fAw5f>J+vv7}nypDHZ>Vz5*?j@)I* zvIEmY?*u|k_l2q)gSvRA5AKb%j(GXhMaFL(1{t(SB8aIW)lr3|O?S3@7VK}z=RQAM zI9)$4z2@|xaWB7d!`?d8HNjDGvs1)(6e!Wu=)~cwJ7ER5fiqqi!74jZ8Nn#lT^YeF zIZzovFVa#O!6H3Und&xT)35?U+?M^@+YuY~0C=lDkOY3iceHk5OK{SySLLc_1+~V_ zTfr2pf>+Z#-dHn&^1Zd>R3NqG&U!Qa^LjHTkXi#)F%yN`f=;-pk_`OmgGw^S8~pE? z-N&37x^^eQodMQ0FT1`Rts?U-5C^#cvtxYsw|}0-)R*tYCOj1G6`KlNpcTZ~4Gsxm zdewyD8xKbt+`L~#D4J6t|<4C|i7MGXnpITMtLv>!lpwpEc2!5>)J+<26WSYLa3 zBY^m(42!wJO)EK_UG^@w+TQ}3?Im9gsYmGwt^OAYpeMJ5d^V5sJoeXaZ2 zw!QcE^17Y0v~+|0+C+VW{bYl0!wR@m@Y@~~fEw(Nj}9AFK0d>5C@e1SsjLULQyNxQ zDkrz?K?|h8{=tKf{Vd+g!n^bSN7mvVzcL)X!ToE*%7^-K=e4+qjb`gcz85cEq^*2K zDKxAAnAEV+7IURx1)z=w+z3KL*W-ho_3E`5AQyIbdwDv1yc|%6BLdfobI!0HE-1Uu zO3Vq7JJzk=_T0rJ<~v(ZO*u&g7^28!pU+<+F6w+QZ8n<%%?g6fZ3ypgGd+90R>#); zYTWllc!sBm&zw0ACnC2g1^Nu}DSC!3!BvC46>56xwekauv3pLnbLe>R#u_6X16@O> z1Bh-QMb9y&a{&}Uvq5+HI_Qv$n*e)ijpRD9rw1>MN-bZdcuc=?ZX&+gW?-GlCA-_M zY1fl@INiFL_|2~|Q%`emsW#%QgIl~5zXpwyFi9WzVBmJbR3|juJuewM(9@hT|Hbvn zD1Fgva1%PQ7{P^T*IT}CX0dFq{w#p*b@tg+j~X?D}+rG3uXdgpG*bGpEPr;2AL z)3+r3r@K43%RXMK?=D8^6bSuDiJibU=;Lex=t<$m?uOZc$2tC@&jk-tEt3byahx&EffwNtW5PEJuk)j zkgZe`?=i{S1lz``FX-CLR6?~yPWu{yU$Nw-L}fA^82dwfJIOtxssds&R5aH*Z_*|f+& z!+hrV(Dj`#<``~L!P{pLP13W}V4h*&_Me8G*EP@r2Y(R&w2T$OUzLH)@Vcze&Hf&w%+lwfJFvsag`WDx)X1VwUOh*Ym?zwR?f*dha#1RA+&@?4|KjI}{Jt+y zq7bL5}Vn~#bkhRSc5shWY5}`$e z5LvQhXOxh2vNdEU#_l~Y<9?p!{=M&Uy!SuPbKLj1uJ3a0=jU@?6ZRIZy^%#~)THCc zmBQe}@fM4qM^!K83bpg^350)WJjR><=SV{YL5LYB*Ge@Z?~dIE9<==U{X?5`4ECPh zDs`JdPKS)W0AR^E`BA>jI)-Q)bT1zPH1o%&Gv=!>#;nFmd>aubjLTpWUg~db{GiE@ z^y<(xSs@3^7_nGD7C+OOKMbY|^(zV}S^>{Q@Hbg?yUD({wsp5eaKzX9rrB5TPU^qY5oZ)VVKuyIVl zXhFI#N*lL>+4l6)mvome$;_O3jCt!SYmRUX4{%hTW3Dkm+uh>%y}K{Bzc_iXWI@`a zVTFp>&dfiyuIlK32NWo>iy!{a3lS1r_gXZ}0Xgp${ik9yJy8@K0)XAAGDnSU{J2vc zUg~{0j}PVQW&iP$x%rX8@8|hn%#>aT07>%P ze^QH7w{E9~TCk==KdINecq{OXi{PUqdbP_X*9YltvXuuXTP(e)$tl8Ulz4(Xv(NUb8nxk?PqV z96j)MUprA#gfGvMU;q8EpWVi&S}X>8Kob2y&qje;$U?;X&i;Tm#-)Dqg#KqMYo7y5 z8j5|jQiI9sxusc+Co{6HJU(}ci2C-Agm^l9 zn^cW4dIuDwpqrW3h=f%&9pZGhoZx@xI2<@iT8wdyKdTI5ZnEri3fggOZJeaBU`z>oMD&-mJ}OT)w!6 zY%1B@U;7%r?GM8iw&71Xk~4h1I{{eV|09HYF7-6cy#tH}F-%g&vu+&C`cQ4WcHwGL ze@2%MKb-{3t{CdGI;j}+CcqS??rj(P|5@O6f7)EpLApadIc>tBx65C&ewBP(n@O7P z^4D((AAM($^m1>oNSoXeQ(^n_xZvuAF2C~v9ml@*$OYk7=G!}9v*BB^;dk%$Z-VWi zEoI$OnwOeP4ny069Og1tr;RK!moEP_v>42OVKEsXkF{Ux=h-dMo& z+H4FLK(0@Bn(9%K67IOV+IcJem4gs?c)r5|kYxXR9RJhQyyvQO@!?#JT4#F;-*B)h zrrYki(A}r0rOIUo=GJy*32$$3lh#q6l(mlHd`nH(=(&-`UT^OSc6Rohd-H#K1`+G$ z`sY&Nz!Tx2C&HP}z+Eyh5R|=(5J--|xfgNR z(^gFMUY(X(ovsYR>^_a(Mq5?1D9Up|D3UL_q3-YBkGyI4GyFQK7b4E3v$Onq*Y@^s z@af~x4WWisv1vbUd8I8d3Or|DeyVrXuHb8%7v7M!G@ftFtVOyg&+hSk(ywlU4c zndaVLv#{6LS>wTMQzdR=UB33IT`j(u%x*Om7F`{}Xmy6Isd8?4z-_fcZ%%1m!KaoU zm-Ikzhep+2zJ-0{)C)S_NAK9%JaXMuZ17I!&83JNd4GbAV+T1^W|GI|J`9|Le|6!_ zP|RiA+Sg_dx3_IK#ys)20Te?YBADXu8;xqwm9BTUy&=;0Q(ZejFib-bDkQq_q$O=V{!4 z?Tlv04Q=(n#`&&R>6)q>6c#cb&n+C!&7WN=9-8yG26RkSMy%#p(+v(fuHz4qL+s^F zkiJ|!C}F0FuIZ?#9++Efnfb&q!Qv&~s2uclW}oEyksoq~`vZ7GWgiGWJP+^MmuGx7 zEj=CQbBI7u7Fz|Cx&t&1KE7vJkQI*YkG%@`JdNDMO zKRyIROeQye@4;`l&`wqkFuKZz*36H{YD9^KIi4_MzO(v_yIyrCmUj1f(P;kY1|9kM zyAH3E9a!R*YV?ak{*bXkk=A$b8o=vK8j=WU$5Su7nbQ3Wn4b}w4a%v4KnzNJcVFl6 zeUkoe%(^PcdRM|NJ+J~C4dJdX#WzQDk_H1B8MN5A%T|ZQTo3M$(86zvy^$CDW6YJo zZoDkK&YCZgcyMheZheMPOlL*W#@3cU@=TB=E1d0}gMfPAa&E+9pMNadwIlH827jfZ zr43g@^y9GHj^PHcu&KlHcR0(Wj$K@+xeHeWGQy;R=Ia|D&v?~pr<2~w>+vlHxs?kl z2V14szqxpM6*DOZ*!@NZogIZMxqw`WsQlFNR`ZIC!bZZxm&fQzX7(P7f~eE`0x|6! z6aAK!njwC}rQ10g*eX zckfffZ{&4p69e~DsQ3&#CaRw;G`+Rfd4f6kf(WzGZy1wQb?84&i0k_+u(?z52)HCf z6hR~y(bvWoK~APU?qq>3ibh+}g186rBSs3KAKKfK=`PXZ#GUn8@m|V_i>y}tAh#9d zY{dnYj<46Su;S8kIGEj7O(yC(k+*ElGuRZB@)pUn7ZH(&ZW!e_BQg_~=-xjUcuqOd zu_=MO8UD~L5OZVEQyj&$ClGU94PSmfl&sEx%S7Ui&!PTR&0Q?MCU zsehLBfHzDrVpFx~*jG+>7{AvH*;BrG1Sw_p!#RL&$<57eOaLL@p+>zjl#VL?{@!G0 z1cULrBY$FP_4>v`{xhqC$IKTMX;TbE&Im<*SAv&3Lm~D~i4~=x!E9X}6H&C8*aqc6O9rs1GXMUM>* z4pxDT)5}pe%ypdEhEBqUdHbYG6W%EH`SBXM!|FEM&uH;Jk_~fJ(N_rtIZH%IW=Q%h zhi&RmRg_&UMnR$B^bZ_jX)4Gs_1_yjHx;chM}|XRpl(t1nmdoCRhmwU+fOV1HJ`DU zPjnxiXsW}XIUKb7$vjN|SxTt<84mBi*xpLjMg|xQ)XP~EWDZ{S zf`e|*q#iV1fN;Jn&)Hf!Mv~F-Te=vTVbgOC;x%$%l=#a#jPh1 z5nVAa4K|oqdT~#SH%2P^w@e5gGNfwyTaQ zlq1ZJi?xPe_DS}kh1gR<{)j}r4$H0n%7GCwcyIjGJRiLE{kv&)X9S*ycXk?y1}yG@}8q^AmnPA<55!_YP9(I-k1F3NhJoKZjZL*P4%U^ibi!^?sL^z4LwaXh> z83Yrh{ofSw8^vTtF$FKnnwZWOX6J>lY;L&4e_z5#b$8#w$t6H2XLzz|2g0oo1-Bjv zxt#WcOG5l%inD=}mR!FBF)bBRXW^v~M7SQ@ss0N==I=NltBQ2Odezk`z$d(EyHOMX zM}H0R)SC}T2~&=xYU&Fn>z@VN-nM5L@j`B9Z$5X#rr~N5n2?aLFx_m!A4)K3j{YKu zrUn|NdT29bcz9npx`75QxH&HInfd{{_gCs2&~(P2Uw7o2`mVreV-_%QSX$IG8V&So zu6k4;kZ3|&t@7#ah@X9qYXm!yHb&a)}x?b-bEjG97I)mj zG4o@>S2FR)IUxVSra?7MPoVNp2pr<$tuvq+(H1v&+l4oWbvKfPJIvhT$Du_td&PJD zN)E1p89CK=ZPshc^UfnL1L~24xK~}{6d|pS0~Gc@PkLY#DyPZevuH`x$QHLWyPTeb zMGKuo9|M5meP5o^6Byj>2~!xOJ*P^p)U=@9bc{7d!G-Xg!eb$hgl+w4dq<5a!Th3< zwElhGrQlT}h+zvVA}FrthHMLF6lxDB_U3_X+Z39SeXUa9;jR>_^*PB zZ;k{#fABBh%n3@nQL5X)YS2R!YRi>HHGwv!UO@CM`$AR+;?XJM5UVDF$JzYZ2b-oN z9@FK!s9{@q4pZ>yI%^F4zF0=r3SPPSjQ~{k^E&HSmxREXL4d>iug#a|;4tW@5j9fV z=FW=@-nG3l6#4W2`Ab6D8_(U^exQ~K$h^cr_J2KToA_bybv6)UQRtB+{f1uAXIEOm=J{#n>L*?yWO(3~_+)sWi;&!4Q8wD*zUZ^zPBHcOqYBWtZ(+Xok^K~=4gw{>+oMg_Ox2TPGjBSS;4 z(ipfW12H2y%8Aj=g@|Q-rYE3|FK;=@$q6ua6iSospZ7uD2CZm?$!?&~m^yuBiq(Ad ziMKxKSZix5*wGQN)z7Iij^aACbwF$-pX|dLNtAtszoI-nOW8}8-93mK%epn*Q%fTj z_5JU{EZRMGd9TcxsYEJ?l_jt6>d++971_k5fu#<%i!BP+j#5uGet$+Zx)sp^dhV?w z6*c$Hn<>kykRN$ zK}anYkU`6;<6Bbb%2Mp*+RrVvD3LLl4P_nQQ6UVeBQP|&OEWus^HQ|MIO%5g>$J~a|(~| zKI_bP3Cmdj(P3i2TmP36p01mEVSH*EN=XQ`2FWeJfNE@+>XzaBL}gK})p_Zz=%c|x z)kA+$3L6j*hNUWspc;z$*O_A^R!HFhw9X3h?)X<5B@PqW80={)r z1*Ga)Y#P)qK>fE%D1b_!oVIj=u50|M%7~r76DG@X&-@>Wy#iyCpL{zD_T4JHV)And z=Cp5X!-hvhE$d6RU(2>gkcP1t`FmB*m41b4!WQVt1HCl)Wb6 zLwC0x{2khhoZ`1b);?1?aX4Z_K9@^^FXYj5v{Zw96%UF3rXdG8;eo6Vae#kY-!*NN z*bWNFt><>k9~MP6+urL`HdqWRvp{wl-g}3JKoaw5V6YBVo*H8hJGOcJU(VNBV>Hkq zAy8?7yu-pB_+iJlq{hc&gA@3Gwpxss=8~CRv;Fo{KMrBX!><>T7dh?A_{B=T(_s|u zHb^A?VY3dzJXC{)T>bLoYjR_A^QIvVL{UYgMW5_DR%5*5%#Q*q<#|^Lw{hn1YKM3? z^Sdq`WOquDV?#rh)NlHmy@e(Q!ZhgQ#;YNh@Nca5O9<@E`MHATvj=Jc2dN?t<;*ib7=(K(nMR)1FfmIq<0Nw{w zzdsTH_JW7A_>X57Z~Yjt#JJC+vnjk+=qSfbar=IK2ZIEqxm^~HcOV<{e5f zC>8bPA@z-cUHXY#JX4?krWw)@5ZO4XnC;OiV}CcK7j*DAOOJDw^E0`n*_|H4ZFir^ zWd?JpD?O_CTYcwY2uO*s=d++$n-fMh zlRtZ11G8_Xn>xKKzOfJExUT26sU5rwIHAt!om03I7B&Zus5zxX+@#rQZ*XqTM&(wv zICr&%n$Y7t-4e9VZi zX0VqVo7TEQ28@mSi>bH?rKxH2&!nSe*@dKl2Sf^CMbh54ca6~5Jms@-E!)A|ivcHo z1`0Efo%L420Wok<1D<3IrDVTZfPY=^Ej)5QllMk+Qky1Sdqh7Co6AwEIcvu}L(UR> z7ekA?yu$J)drsIZyO3)2|x5xAurUW5&8Jc(E>D)JE)B zy{zqR8ZWCQk?{6UtfbPGzM@*vJ%>5d1t)1@YeHVXQnf-#m2H~VoZ>|KZ1t;ZkK+5u zts&tCS4XCgWOR(~(M({q_M9|$v^xkBI`=c#e?__5rBG!T(Q|Na-GgK`HAc7U)mtN5 zI@L2cx8#%KO`nNCv^GJs1$shdV<`<7cf+`LZqy}Wl{JBL_%&b26z{M_R8 zo_EpSt?ajZ3R+87{Sk$mW`!cz~A)h~*5GUY#tab&ywLgDIh@tU!}Dgq*kizQP& zVNPD{+a%*&kPc4H$doImdTr`Ld6>Odl5?@9+t{ib7S2`{0@BM}|H!#)Iw2)w z>g#k8;duPD(_aE!(hK)+dez(>FkTQ6uct8^vJk1&2ngONE&swHv7M5cU6Sud-o5XX zj|Ih3e{N+okOYaoeRQQU?~+k~;Gi6*Zp^kIFv|Zg`||FOy8f9z z#q(!!tq@Cf!S`<5;0#z&v#BPGNP%Rjv*(!Wt=?>tbFv%DxWwEJ!NER(3J>=7`QVAY z-H#TX9d|J-?pxYM>CB|$XUVz!^x<(Zp^Ln!=SAm;pD7$6+2d!%cO9D6)I#HmNmnhg z)k{s^7H#$tjt_R`YD^528RKU>i*G8bsR?r3`IwMO7G(S@|1c%Qvn=k(*wVvmVUBcn zyvrUn;hlU=Hc^5I7!DLqTYG$8D@+(^;P*fb+j$WJZ&bEA)ydo$b6g+hnCR!tEKn)zVz$0J8CCEbsvRp{ zt7n#~^*IhKS(|p8+>se3pVhg1n$X<+$UPyiVXQtfgPW1DZ+hUZ$b6((sa~ledMC#e<>N$Zl~6971qUzCMq5Kuo zj)w|bgmWgAi%Na#MS&RZiuA*BJg4}un#B@dZQ0f(apRn?Z_4E!xQrQbiZ6X>+~DLI z(`ngs=>}T=9bT!J~`9mkibPPLTGD< zm+0%27azS}D!vu8@_f;MKzL$TUTJy8Od+MT&Y+luVp8M2JzOR^%!xdpRxkIwHaq=kJ%!gV z{A#R#Bm_LH3{)$KN}k{Fx}}`MmHTIET_-BRr;p-M++qKjaGdc2@g5Od-CR`qC%5Yo z|5&Geb?=^-D{gAIiS% z7%K_@Nk_SF9l0gqfhJb+s@4`ZeAWdRf=uIA+=BO(B@KEjC)4?bYvIcUp@t=5L5unlxaC1B z=y9}1aiS~hYdk!MBCJ|=L0GBIy_ue3-nPAklKp1w*e!NtQgAAhqt^LYqH)(O5>*ENV1|cXY=*vis zVa#=!1Ej1geD-?UCl$WU6dvubX41~kZoNr>3cU~ZwZz?u#@A4-8bAIp+%h(8k{fC( zNHr5FI9LW^)`Bsk`yBC2V&gwn_f($3qcP!{1P22Fuffx&b2JTdCdoH$XoO{4ioO4} zAnQ_2x#g>f37={`7HoCwFr$3%E|gT=u(O6HB)Bxxuoh0UHBr!Ih_wD(@l%k+fv1eg zjjBtJX%bh)wLCW<#&KoJQDwh{QNMjVPUCNm(F*DV5JboIz;cfCDCGdo?2(zhf zjC7RfyG5mF;^KRq#$)vz@Jfw8}G~qY-myfB~3hlf@OfsGB7-U6IRHfEc z>97Jtf|3wq^6;Dr4LX+G_@&dP0%G@T$y~urD>+X`kF%%f{>4`NNc5cy{X*WmmwU4F zqgx) zLQbTglI`+QoH5xD33AALOKT@f1v&2a7Y6KW)ga(Tui$4$7X`-`?>4$9$4d)zhzJs6 zURWdw9>$ll$Sb+EQ1VxljQSRPb3ey?+X*$iy<6ddxCUWZixB3$Cfbz916{8>*J=G7 z^1ZPIPT#yLj$Wi?z-4$_3J9>VB*hck zmGCslawTDUT+90OKFX~3g3ISP*(Gp&^zugA{O~Qy1iwVItt6;EDe&4nt48#I(;E==& zjN>?$q(~sfSW2vM*_4k$67Rjs(4{2F9U(aAoBf#`w^}{s+nltY^f1~hr@EVaak1o} z1|jpWbp5Bqn(U8;=>)-n9gV@Tvv{Wymw$fUVY01* za`H<@+r)Q|dne9V@_1!DeKx_E3w@Q0t+Ec7jgr%ZAYxO4WcS_c>wjDJC(~WC%zie^ zW6il=sQza{w#Q7V2Y1)8<~+x@SYE;FQj=3`xQYam7yVz^Px7M6NWNoNn|_#R;%AQf zj)bIM-+vL0Jz}5E&-w3{^lA}g)|&EW=PU@ZDsp#%1s}4WUpe9Y_trF4^92hbQdIV! zdz#*tIsL=TB`n`~kCZJ44hHHnXra*#f=KDu@6&%BLQya#YiZ6G&#Aa7+?06ao*MqX zPw-AcOUaAYz%hONo;`F6{Nx8wKju0MQZN1(vC~JVlJh4qRWY?^+SiJBj+C_vw$for zzv&R_Z8<)KT}tO~R+J1ccB&|pGB?MHghnWA&Scdoq3wa$`ZiK zNyp_@Bz7;|TNO>vl3bS+vB-a6Bw*HzpP`XVTzlg+pv^1)kvQlvWs-O?z2jFex!%Kk zV`^JX;*Q5N1rMIANG`Co4(p-Eq~(KyU5r$_ohH%?Ds)$3?p8UGWY{F1LZMh;%Z>n$ zkpM+OU21Vq(QHA^K7QPFVD#z6qc*w&JOZEmf5+R z-De+3iT8_#nkoMc_e96!^CQJxgzqk&i4(rr@)59%2c?9)-a!~;$*3ceVdEsXiNTDE zi`A-HNh9?7^2M|p9V3d-ZeGpA^SISg;^1D95-oHGMf=M*M~&>7O=w}|*#MVqD8I>n z#1+Y)k%C~r`&KaR}UL;QvpJ z7o}REp>Q!x?sF}>fS2w0B^tIGA54?>)q}KeJNv_MOb zfE{#G%d`;cY}pru8c65#tT$Yl_*i!MPKGy$xy;)=1J@W;kRCGSBkrS{EiEFUcWYj^R536Mdkd6JeP@ zx9lK46~fJECUigoVk$Qti>7AG?*!%YqA)DTQJj zMTxpN;x5sXNMy(QpN5tBTx>@z%xs1Fu7no;Tg5Q}8WA zFT!sVTfpuWo$7S@00~$7qGqvrmp&`j{g!a3tWCuyvEt9_PZjEEMC`2-^9BltkmKq7 zthTaHu5&ZuqO2VHphw^EcD~NfhMS=sRxS>%huXv2?0IPxBn_8(RR$`_O7Up7INPXU zt2eH>1$guHGz9ECP545-$=30SwC*cY9r2#Vw^uG?Pac1xVNpieX58SngBmbCquIsb zo`ej6p*93hyjZD|dhozvXyh>Nfz2bDfc*?@P?~T_8*mBn#Y=3zwLsr0t93f335|(# zm{SbiS(AY#`p7ZuG5?;i6#FTLq%tY~o50WXapu!ToheDIoy>7N6RA`_IGnM+`DUV1 z%~|46tvh{Xb+Jmn_r7}S*qT9Ph4{$tYI{_0uJ5^olCT~xWp#?}#M1bC*@0zRdm40i zVyd6_Q~616>-f*}UisofrD4C2Z+@|CzR=Gy|KrD3^E0d*n+@^nS4lEo@7hK;M9(|w z6V7=S(oDhUlQnv>QkF=aA3l#6_1wX4~x)i9bxU zY)vNzOUSWC(`BT4Yu^;FPzL`juIjpAhL=nqn1|I?gse%%|7rcSGMM!6Km?107nXWk z`-@q;ZZ-%TUGZm14speHv1`g}5)SA_?zDKd5GR);zN4Hn;I(2p*-1AU{42qTKA%79 z!L|L8=;cNxtp`!TV{GDGq;$31*wvJfIj{S~{-f7kDe+dX_4t&h$C1@#i4J_nDBs;f z<4EJLKOFbiJ7}rN4u*E`rs$}Cl;8Daq(Z|qSx>=B*1~0Oy*+*(MzTdbWdT-xF>~dC zxjt{LY^YhxXhZD^I3d8Qoqe%#l{Mo1rzoupL74Z04&>vnMR$sLhO5S(v))6vGXs*R+B@Bwrm{YJ&8BT!;KGkby}1) z+q3ts$S~lRGb8eBa+Wq6_WC%M`1VC};tYR-f7b}!G=^Np<+&o(metZG)za^(XYw>P zZoja#)TFc0WbO&GXa6zk)hDsAzWDo_%f+Ta8|&(|*y!KZ^)ZLErlyO1Itq;~Ty{lH zhF$bte@s~T^w~#A9UAwrqd?bi=fX0t%*cue!$4ITNgUqxgwg%9N)OKvzB8MvdY9K| zI-PTuon+Esi?kz9PSnVf{sbu2{=NGo7wEqqum8wNN+|4)UmBoeT_3!IfHIYBW8z#w zzDgQUtY9T?rF~?&$L7s0WHb!o6MWTd95#CA$IzH8?+N?i$1LVlq?>@HrfXJ+c9hhq zPl5~h8I^2ay0;pHBzoI}r>KjmUoYKR63~wo@VXmC@luvtFqPalK|03x_yIBJUNga< z^yN1tg%(G2wZm6wg`62CJSQ{(X|*ps{j;%=w?{deK-o#ShtwipqBs zdrNFcT!&9~TLXHKu(M`7(md?qz4hN7MIK7~+8vHm(pR!(4mWHf1a!D4-|Z^BUJ^>I zX&V{EV_DwcoGPIbb=o6U(2AX$J9U2LNO8sbSq*}+^Uk8v8^cTrB?YCVqwL%L zDW;PIi9Q0Rov1;!+YxncPNd_fhnUD1lzP6bPFgJ-K%pvww(dKV|I4_{%4HuCfo0+R zcQd?^bJccolP@Pr;_Fr?#r`ahPUsjoTbpsD&#snZkNukeL~7vfzDT`Sl-Y-govlTN z6MdYT+@_BjML$@4YBt~#m%FtcVp}Q}pkC@6Q?bm`jSe$URuI1$M$1)7*j_Kk_fro= z7w~(GFA(oO@`c#?`CN9nWVWfK=P63dAKYDV(1H85EP;pEh*%?QpOMH~Aja%ORvSsM zb!`^M({8`eyg1tbsfFw&YR0^9Z&<-GePWuk>CZX0o&rr*eWY`65Zb9NyE4}d<*TA@*>E49;2iE# zNE>vvVdv3lS!CBG6`l$q>A^1{aeumX@bMJ9omkJMg%Zoa+7%qO_&4J`@+ z9zI4(Y>(cz&)w^ndy#k3_a z(`#9hpClzuyAKbyJTT9l^P1e9Bi>r-Xjy%1xAey6=s|gvjflpxkEd=jF5IKD`jp%_ zW=@gsEOLEEg+1|V4iDHYChS9fP-ORQma>g8+@G9>U%H&E*RptY=GDy4YL8Wl zI1h-$Grp~A6cvsoc@13cNBib;PE)&D+fBPN(9rqE^d&k@{(8xb>#_P9n(JY{;?fx< zX`gj_v-0)hA1uly`m!+)@~D>gGcL8hqZnN)O`Sp8%ReM>N67iTrYciMh#fxbzg&ta zU!B6fk;gK*5WLdWzyErIUPzu88?71r9nR;G4~SpS*6geYN6f~uM>s+nN*W)0D!cD; zw`B+AksM1ti)j~$Rrq_G^~=fM`uUU(piuuVKTFK6LT8fH(mL;sD<++sm zYky_mh^uCd-bP-~a7IuMLk4Fd{wo%%5CsGS6fH0xVB6xn-ud@dLL8vzPi zGrb8t7l>Mo7I4vEJ|T%ar5QiLc9zXzYE&*mwGtqmv_vXoP=pz59X)lnB>J1>Q_;D;513!B*vHTeQU3fwEs#78g#8j|ma` zb2Us_A{QN(4oaJb?f(FfcAPyJ=8fwf+43(cLdgU;kaKV)zsLk!Ll(VoSo~hUS8L?E{(zBK3YvLF3ZQuCR zhC{)EJJ_ME3vJKMa-{?njVFH3H2W)q-6`;iH0&x*#W76g#yrZI-XhpEPbv_Sb?+v4 z>^|V(08qUN@Y)M@S|T|l_LU}qWz4OiL)r7m>cZQ~A+E9L{WS-|BOSfdSHE^lMlA;` zAMA22c_H5}yMUj6!m?l-X2fkvD%I6+D65h?$^Ur8&DFuGKw@6mX^pL`)X~F1%*NT)L7wYjtF`75>j838HCWH>*Vn_!C zV?HN5GuarB>E^CxeXeeh8FBfYL0!Fibr%cn;PTm}#k0BtdIFz^7ILphmHG?}=V1Fs z^G$uOH5b|)yP4qJf zZ8IsSA1XyB5yCh;+ai>U6;;W0DtDV-qU24win=KaT-@2=@{WCPuraPlokN?GbFP5q8YunpYvSG$^Px4SNm0M z5Ui_`No?GWRU?nNFKJ<@fa2 zMTD5yzscF-r1!*bXF{8^&(+96t!9Pq^p%F(wx1I|u;YYy;@TUITQw16SXM-=zz6wh zQ<21mLd?Mc@nq5Y1_&r<9fjD%Mi9wM36Me~(Dmnd!Cdjy7vav;XUkU#+EC?e_*KqrQQ5g;!nR>=CB4;GxdG)01{{neU%t3K>I@@TaE+n;j_wZ~ z`ihOHxlENoiTN==B=;b6mJ7%0$aBzEpX>(%%?+i7=OKb~Nv7?l0weEPNTjcW%&Fr2 zWxjd}MTI zxB4_#Sfu)=qlw=WD*QIge%Ij!Z|C(J8^d*74RP^;(T;}?I^r3^&&t%Hn~db%5kIFZ z#RY)R2&aNh)p>zk2Axr)H==%@)>K1FEMvE%l2TI!A`@V%r8NkBoVH&hvmL%>^Tp=* zHvN3l(ZEbh*$!P#hoaGt>hYt4;&S9rv-WZ*+XQ~G3}6=^D$a#aC5=@m&-lHoQ^LNC zI;8KtvBT^*mF*GTFjE4KYZ*%a0%)wj9{?ttG#5Q~#GlnFy?*|^m?OSHU#d#Hn$Kj$ zHw_|o!|L%5E<>Sar{H=)TYy{k@a1LEXrRTyY2cVoZ>Pu6r=8a7?y7ur}?9^+EebNid00 z{Vq}t+dAx#f8ewCl>w}$fnLO%y$B2%@RJO7+fZM=K%4?J_>UA1^mEcm4pCE#Bi~5) zn7OE0*w4##^)Z%#GoBVvHK&IVwOM#9w^8~<(k%qTlk+AbvNEr&_!#l0#|* z-oUQeBu}=p?Sf@Q4L)`BN>PLl{ZeiARldju9JJ=%ivz*XN{1IUV~Y?CrE3y<0Y(p4 zQ_v-X9EjgF%emi8FmLNg0;fJ6eR|<%_Jux^#nK;UH-CR!?w!peNH@`A1TH>aQKuwj z+tjR@pX@fA%#gDe(00c&)L?7?fQO2Dx|xacJ;*B#2Qn0RFH_MmjzdLN5tmY$_KHUV zuL8}<3HTp=pfC>Bf*G%1zc=zyN$fH-952TWk%$}Ya<7>bs)wFMzO!z7dpT$JS@vBT zxe=M+L75YeY0(S}o$iG%t}Bqf4YEYSi#tUz#58fdg*7fAg6haSm1ptf^7Qx7Atuc&(Fr4+{%r#t(g72^`8LUt4r1kXmHZHDW;+YKAtL(XYzQ|fG{~a zY6qzFC_RBz`BH$u1N{Up23Sz<=i(5~pU&Ghp@z4|dFnMP_l6ETcS=}g7`)3{utV;2 zs_nuXK7wBLT#4BxEln4k5zKsOp8@=QbxjSZRZSxMm?At3km&5?j~Bsa`uC=*tl2HK z1StP#wL&VJ(B4L{Ts~udcn+CJ+2Z(lRD6gc0Q(=#jS(~&~?;Y3P8`$^u zAk)gVV-b1*jN@w0gpY8a#a=L%20esC{OfObOR2c@c`Hcu&-7||8{qbp`;kOBV|Ec*M!YbV~23sza+?g#qSIhUWYd5&j0SMHY)R6&CAk#wT> zB*Z<>1gTLO@0XHe=KzuoG>uQMRmL@kT|XH~8fOqQ;WBJW0CYM47}zh*3Sqhp&e{0_ zh7girQD#0_NapA)_Hg+%1461=rU)N*f~`69e8N)BA9}c{ELSxU1trf#Gz=S4_Rl4V zjNZBTx@HP6+X$1AN)%oxhgDu(^zPqh@l0hoMJ1vD22CNe@#Oxts1Lt)^nORq|NTg& z;b@pKcR+gI$jUsn5bgico31Cy*R$huA3x{H&zhlNi`8VHKzJSU@Z^B1cohwgZ4AHb>w2lbuc3SO7-AeV4a90Q6v}v`ox7s#x;BV zy1z@Yz;`7~VVEcepG!*nYg=l;85w8E+Ew%A=2AiTtTzuCCELGh%m%c0EGp#X%mrpT> z$pZTd+|>ztI2Bdj4_;{hP7o`BP6q>+?aQLa5fQ2NS(!K%91NVm?Mb7+6m->qkNdO(caVq8 zsfuA1)(_a-YoUTWRH=wfSo$$Ok%vs5z@e}=AT>3V8UU4;9-q4JE$qiy2=m&8p;m%? zA?wSIgZL@$DbN3|<$Cr52xhXoT?B3oX8+`csKeF+>7?HQ)D3nvzo6tPuF;Qm2_}-O zce;_h!KaLHoViBTm@k!^9FlC~2g32^YDC@PVi93M7(hv|iWU`sEk_`8Ir`=^-M|$2 zr6He?$(br$IkboN`fz>ZY=g!67NZ(aWAIaO)OqwQ&xT?T;J-FAv!MKzI;iiOPoqS{xp)6k#^a)_O;R=DV36?&T-w*<2+e z`FQ-f+({w$!)2hHB2b=Z)>P>pF#<*_U`i#dn(SUe_|X;TNuSe%YuSQ@rlPZRAhjdYKjy;fWH#o6 zk{ju{K@!1zE&^@Qo@2+|zu&YPfaIJ^BgeS_tS)8cYMQBaGpwB&(4dh|I$JX)CO z#`PAtVosjaj6pm7_lV&SP;}@r*16uVM~C*2*7&eCwIR-U!iyJp;5W%ln!u;bfEjh; z2m|eX!5vircCo7i<9_TejS@LdgPL1nCDMJG#casa7qD&(qMt<~$bmPWe@so~FN8^l z#vAeH(oHrf%kyK%_}ZW$4|wA;w_vqm*`OQ)!_t5oadVfQ(~G^cx#>O?H+SFK$e!_J z-@x8tr7ei*Z2>4lVA#D9Q3R$c{*OvF+(im}U=ak7FM9|<@7THR@)ezvagikpUApEg zT^*XUY@>JNBb0DH6gS^ZMyK59tLH;$aks$e56vZR6la*17$d|^pNG&2t%|S+DV*sO zHj${lb{c)F(rxT8&c6-#TF~)scOn(Jj``n9YZUk8cnGP<|EfWLme;Vb^OtSA0xel{ zV7ysfpXbzxm5G8xHm~V&=O*b6jafGAX#z6i5k76B0`s2^C@)@x|1rog}i`z}VIy z8(~e>D+?3Q=ouRcw)&4t$Mj1YMR!I@K&JbXk)0BP-EcjyUZI+ipVx)f1#GvDP>unhWGnm`e=T& z{K=C7i2rsy2sR~2*vIMjfMeoWJX%7-4~7TqhIsEE%NN)P-<9m$%Rc41vEq6#Jw;`G zP$jCP__y?XzrQf)aFhc~ovQxo001uU&~JnJ2)w|zM5KhH^DXarb*lBKHT4*dbcX1o zo;!ez2Z*_5ugIAlW8n$<8ho3BEM`s0=1syAkAmfC8FvD3r+gp^A)ABuuF?Wwz9au0 z42ko2c1^vQ&&<9pY1g;`&JoFjYKd{@(s?%~Lf>VT8ZY#^Ss<|;uaX#IWZ){nJ#hbL zWB(&Dfj?ljp(ts6p@3J#Q3cZLT9^p@t(J(`S&hfL>0vrWKVoHK(vCwC^k0!ze`%hz zNzp@WEZt!SE*NhBbqW+;r&A64FWUWkVY&I7Vv%$9T$vPn z2+b7!&*$rLt92yD*0rc@;auAh>b)%D8s_hni0PK|{&Y^(<8@$d?heua9k?iK6f?6& zXdh;9FEX>FQRFqJ<5SBUHvR;RC|E4`hrL8*quA?L#Czx8z%*!nph~ zpA|nG_kW*H9TzZZ$yXmoTD9>2=5>@WPaA((va;y(;!eWo-5`v8p=6ZU9LR3q`z%u7 zWdWi`z0>E?ddHIOyQ_)&x$gNs^EGb{RI?tPzgtgE=vZUk-f)U05T;h#MjR#(wph;M z?L?NOH|w*_9>rD$O%)*_XP-&VC- zMaFM^F*vJ~Yl<@mjq#DRX%=y4TQk_M#QWb3{Kt0&@%*2%>qq^o*(c1>+`T+E(A@Ql z$OfMF;E0dRFS(MGojWCq0`{x&`rJaT&9Cd`AD9F0I|VnCNwe(y+ZnYqbYOOa2k8CpR}o3~QY5W>FD~?wfuvS->=M zUmp1V9t3tby@ukzCcpc+q`*kb*_kHoMiuBMNKh&Uk@N+M0Ak3 z$toL5L{E2X7Z|rN9w@o5ZW%ISiQHOpZq|{u5Jh+qgoYX~kooti?{M-cYcCB?nmkVi zW}RER-)Q|$#6eXtJNgs_k--I_x@D&NCgHQ;Tg-<2g-%ILBjO_`q~E*qnVjo`@|l#= zvp+woUB1I`{$J4obg=)!3tv^O&fk@|e?qQEB8^|q;pbE^=7C;Y7r z?aLPE4_l|=x!5V@XGxNhKkP^bkYHd@zX9`N0%$-yuYgan^}eXg{0~a;LRG}uq2L1j z+xJ=@FQbBkT6ACVMj>%y?40W`;($2sMWwrRCN0lh$$5L;ETEA4uP}xXYXPKU^b8De z1P>$?ASIa>7lVPYC9!hxu(v2Vo@9vg@tRe4Mwp z7KfU;;zh0>RYEz)Ll6)N(ILhPGREaD!T9tQs@vDcR{z4_|7;A?wO_--15;DUaIG4! z3uJ?9;L6K6JHQNfC<4nsH*d1nUCEhrrg!1F-nkOn&<$$iVV87R8c)ku+t$)13buXbU4iXM3%V(`EccwSgHTNG(SK_JjtQ?T2Qnw` za1ba0rG3NRV~WEjev#0>)Def-!c7=ML8-cy=z_b#8jwdg?vmxCJ*$nktH&ou9ONvd=}Z) z{N5cX-tG^$-Kk$R-G&`RJ@x|Z2owyiy5x}R$S;|Nu5Of^w8ahojM`C_KW{heuYK56 zsXuNBhK{G!_Mr}4zq?-9=c%{emc722wLbambg!vd@-ckQeX+CR$S_LoJey%%`n+KM zGec&a^eg)W#do#AB1}?*Dk#3OMJ!Ai^@=5o`Co-qbr6BihQ=Gu?IaH%YZZronZUvG`E7=N8s`3GDQ?+WglrgHWP z*wgL8p4XUGBwRR6k%bGbu@KUG_O8{H#oD&Mnp7YGz0|Ex6w;ebVoy%jBHVIgIx9Jxgqt_FlPxK@`-H~Y^nW{xV65(N*DT3Iz8_z8l z2S@qEu~1Y8=MeUa=fZ~njNxU(s}+F>0v&q#_Z<|;

;5+pZHH^-q8EoJS2|JDTL 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 literal 0 HcmV?d00001 From 47eed4346e4491c9a63c2e0cb76bdd37bff5677c Mon Sep 17 00:00:00 2001 From: Dushyant Date: Sat, 2 Dec 2017 22:14:06 +0700 Subject: [PATCH 16/35] Spelling correction and sentence capitalization. - Corrected the spelling error for storing, was put in as 'stoing'. - Capitalized list items. - Added '.' at end of sentences in the list items. --- .../api-extension/custom-resources.md | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/concepts/api-extension/custom-resources.md b/docs/concepts/api-extension/custom-resources.md index 710a334a48d45..5ce45d4e3171b 100644 --- a/docs/concepts/api-extension/custom-resources.md +++ b/docs/concepts/api-extension/custom-resources.md @@ -48,24 +48,24 @@ When creating a new API, consider whether to [aggregate your API with the Kubern #### Declarative APIs In a Declarative API, typically: - - your API consists of a relatively small number of relatively small objects (resources). - - the objects define configuration of applications or infrastructure - - the objects are updated relatively infrequently - - humans often need to read and write the objects - - the main operations on the objects are CRUD-y (creating, reading, updating and deleting) - - transactions across objects are not required: the API represents a desired state, not an exact state. + - Your API consists of a relatively small number of relatively small objects (resources). + - The objects define configuration of applications or infrastructure. + - The objects are updated relatively infrequently. + - Humans often need to read and write the objects. + - The main operations on the objects are CRUD-y (creating, reading, updating and deleting). + - Transactions across objects are not required: the API represents a desired state, not an exact state. Imperative APIs are not declarative. Signs that your API might not be declarative include: - - the client says "do this", and then gets a synchornous response back when it is done. - - the client says "do this", and then gets an operation ID back, and has to check a separate Operation objects to determine completion of the request. - - you talk about Remote Procedure Calls (RPCs) - - directly stoing large amounts of data (e.g. > a few kB per object, or >1000s of objects) - - high bandwidth access (10s of requests per second sustained) needed - - store end-user data (such as images, PII, etc) or other large-scale data processed by applications - - the natural operations on the objects are not CRUD-y. - - the API is not easily modeled as objects. - - you chose to represent pending operations with an operation ID or operation object. + - The client says "do this", and then gets a synchornous response back when it is done. + - The client says "do this", and then gets an operation ID back, and has to check a separate Operation objects to determine completion of the request. + - You talk about Remote Procedure Calls (RPCs). + - Directly storing large amounts of data (e.g. > a few kB per object, or >1000s of objects). + - High bandwidth access (10s of requests per second sustained) needed. + - Store end-user data (such as images, PII, etc) or other large-scale data processed by applications. + - The natural operations on the objects are not CRUD-y. + - The API is not easily modeled as objects. + - You chose to represent pending operations with an operation ID or operation object. ### Should I use a configMap or a custom resource? @@ -102,7 +102,7 @@ Aggregated APIs are subordinate APIServers that sit behind the primary API serve Custom Resource Definitions (CRDS) allow users to create new types of resources without adding another APIserver. You do not need to understand API Aggregation to use CRDs. -Regardless of whether they are installed via CRDs or AA, the new resources are called Custom Resources to distinguish them from built-in Kubernetes resources (like pods) +Regardless of whether they are installed via CRDs or AA, the new resources are called Custom Resources to distinguish them from built-in Kubernetes resources (like pods). ## CustomResourceDefinitions @@ -215,9 +215,9 @@ Kubernetes [client libraries](/docs/reference/client-libraries/) can be used to When you add a custom resource, you can access it using: - kubectl - - the kubernetes dynamic client - - a REST client that you write - - a client generated using Kubernetes client generation tools (generating one is an advanced undertaking, but some projects may provide a client along with the CRD or AA). + - The kubernetes dynamic client. + - A REST client that you write. + - A client generated using Kubernetes client generation tools (generating one is an advanced undertaking, but some projects may provide a client along with the CRD or AA). {% endcapture %} From ed832e33ac356f418dc6e5ca6ced538dae5547cb Mon Sep 17 00:00:00 2001 From: Michael Michael Date: Mon, 4 Dec 2017 02:54:22 -0600 Subject: [PATCH 17/35] Update index.md --- docs/getting-started-guides/windows/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 39b52541ac537..95456078fb2a3 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -60,7 +60,7 @@ There are several supported network configurations with Kubernetes v1.9 on Windo The selection of which network configuration and topology to deploy depends on the physical network topology and a user's ability to configure routes, performance concerns with encapsulation, and requirement to integrate with third-party network plugins. -## Future CNI Plugins +### Future CNI Plugins An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxlan)] will be published in a future release. These two CNI plugins can either be used directly by WinCNI.exe or with Flannel ### Linux From ae44007bb82f107f9526d38de71703ab74591002 Mon Sep 17 00:00:00 2001 From: Michael Michael Date: Mon, 4 Dec 2017 10:03:40 -0600 Subject: [PATCH 18/35] Update index.md --- docs/getting-started-guides/windows/index.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 95456078fb2a3..d3dd891b092b3 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -15,7 +15,7 @@ The Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) co **Note:** Windows Server Containers on Kubernetes is a Beta feature in Kubernetes v1.9 ## Build -We recommend using the release binaries that can be found at [https://github.com/kubernetes/kubernetes/releases](https://github.com/kubernetes/kubernetes/releases). +We recommend using the release binaries that can be found at [https://github.com/kubernetes/kubernetes/releases](https://github.com/kubernetes/kubernetes/releases). Look for the Node Binaries section by visiting the binary downloads link. If you wish to build the code yourself, please follow the next instructions: @@ -281,10 +281,9 @@ Because your cluster has both Linux and Windows nodes, you must explicitly set t ## Support for kubeadm join If your cluster has been created by [kubeadm](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/), -and your networking is setup correctly using one of the methods listed above (networking is setup outside of kubeadm), you can use kubeadm to add a Windows node to your cluster. +and your networking is setup correctly using one of the methods listed above (networking is setup outside of kubeadm), you can use kubeadm to add a Windows node to your cluster. At a high level, you first have to initialize the master with kubeadm (Linux), then set up the CNI based networking (outside of kubeadm), and finally start joining Windows or Linux worker nodes to the cluster. For additional documentation and reference material, visit the kubeadm link above. -The kubeadm binary can be found at [Kubernetes Releases](https://github.com/kubernetes/kubernetes/releases), inside the node binaries archive. Adding a Windows node -is not any different than adding a Linux node: +The kubeadm binary can be found at [Kubernetes Releases](https://github.com/kubernetes/kubernetes/releases), inside the node binaries archive. Adding a Windows node is not any different than adding a Linux node: `kubeadm.exe join --token : --discovery-token-ca-cert-hash sha256:` From d7c1e3f618f8909f0913b53bd5371fa1a63b0c48 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 14:43:27 -0800 Subject: [PATCH 19/35] Addressed comments and rebased --- docs/getting-started-guides/windows/index.md | 24 ++++++++++++------- ...son => sample-l2bridge-wincni-config.json} | 0 2 files changed, 15 insertions(+), 9 deletions(-) rename docs/getting-started-guides/windows/{sample-cniconfig.json => sample-l2bridge-wincni-config.json} (100%) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index d3dd891b092b3..5a61d89fae712 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -40,6 +40,7 @@ KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy # You will find the output binaries under the folder _output/local/bin/windows/ ``` +More detailed build instructions will be maintained and kept up to date [here](https://github.com/microsoft/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) ## Prerequisites In Kubernetes version 1.9 or later, Windows Server Containers for Kubernetes are supported using the following: @@ -55,19 +56,19 @@ There are several supported network configurations with Kubernetes v1.9 on Windo 1. [Upstream L3 Routing](#upstream-l3-routing-topology) - IP routes configured in upstream ToR 2. [Host-Gateway](#host-gateway-topology) - IP routes configured on each host 3. [Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay](#overlay-using-ovn-controller-and-ovs-switch-extension-topology) - overlay networks (supports STT and Geneve tunneling types) -4. [Future Release] Overlay - VXLAN or IP-in-IP encapsulation using Flannel -5. [Future Release] Layer-3 Routing with BGP (Calico) +4. [Future - In Review] Overlay - VXLAN or IP-in-IP encapsulation using Flannel +5. [Future] Layer-3 Routing with BGP (Calico) The selection of which network configuration and topology to deploy depends on the physical network topology and a user's ability to configure routes, performance concerns with encapsulation, and requirement to integrate with third-party network plugins. ### Future CNI Plugins -An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxlan)] will be published in a future release. These two CNI plugins can either be used directly by WinCNI.exe or with Flannel +An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxlan)] are in [PR review](https://github.com/containernetworking/plugins/pull/85). These two CNI plugins, when ready, can either be used directly or with Flannel. ### Linux The above networking approaches are already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. ### Windows -Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows-host-setup) section below. +Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. At the time of this writing, the only publicly available CNI plugin is built from a private repo and available here [wincni.exe](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/cni/wincni.exe) which uses an l2bridge network created through the Windows Host Networking Service (HNS). An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows-host-setup) section below. Source code for the future CNI plugins will be made available publicly. #### Upstream L3 Routing Topology In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a pod CIDR assigned. All pods on a given worker node will be connected to the pod CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes, the upstream router has static routes configured with pod CIDR prefix => Host IP. @@ -85,7 +86,7 @@ The following diagram gives a general overview of the architecture and interacti ![Overlay using OVN controller and OVS Switch Extension](ovn_kubernetes.png) -(The above image is from https://github.com/openvswitch/ovn-kubernetes#overlay-mode-architecture-diagram) +(The above image is from [https://github.com/openvswitch/ovn-kubernetes#overlay-mode-architecture-diagram](https://github.com/openvswitch/ovn-kubernetes#overlay-mode-architecture-diagram)) Due to its architecture, OVN has a central component which stores your networking intent in a database. Other components i.e. kube-apiserver, kube-controller-manager, kube-scheduler etc. can be deployed on that central node as well. @@ -99,18 +100,20 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your ##### Linux Host Setup 1. Linux hosts should be setup according to their respective distro documentation and the requirements of the Kubernetes version you will be using. -2. Configure Linux Master node using steps [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md#prepare-the-master) +2. Configure Linux Master node using steps [here](https://github.com/Microsoft/virtualization/windowscontainers/kubernetes/creating-a-linux-master.md) 3. [Optional] CNI network plugin installed. ##### Windows Host Setup 1. Windows Server container host running the required Windows Server and Docker versions. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. -2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/SDN/blob/master/Kubernetes/HOWTO-on-prem.md#building-kubernetes) -3. Copy Node spec file (config) from Linux master node with X.509 keys +2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/virtualization/windowscontainers/kubernetes/HOWTO-on-prem.md#building-kubernetes) +3. Copy Node spec file (kube config) from Linux master node with X.509 keys 4. Create the HNS Network, ensure the correct CNI network config, and start kubelet.exe using this script [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) 5. Start kube-proxy using this script [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) -6. [Optional] Add static routes on Windows host +6. [Only required for #2 Host-Gateway mode] Add static routes on Windows host using this script [AddRoutes.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/AddRoutes.ps1) + +More detailed instructions can be found [here](https://github.com/Microsoft/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md) **Windows CNI Config Example** Today, Windows CNI plugin is based on wincni.exe code with the following example, configuration file. @@ -433,3 +436,6 @@ Some of these limitations will be addressed by the community in future releases - The StatefulSet functionality for stateful applications is not supported - Horizontal Pod Autoscaling for Windows Server Container pods has not been verified to work end-to-end - Hyper-V Containers are not supported + +[!Warning] +As of this writing, the Kube-proxy binary requires a pending Kubernetes [pull request](https://github.com/kubernetes/kubernetes/pull/56529) to work properly. You may need to build the binaries [manually](#Build) to work around this. \ No newline at end of file diff --git a/docs/getting-started-guides/windows/sample-cniconfig.json b/docs/getting-started-guides/windows/sample-l2bridge-wincni-config.json similarity index 100% rename from docs/getting-started-guides/windows/sample-cniconfig.json rename to docs/getting-started-guides/windows/sample-l2bridge-wincni-config.json From 551c2a81e50d9fa1bb040f9eee342cbb39ea1b4e Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 14:45:55 -0800 Subject: [PATCH 20/35] Fixed formatting --- docs/getting-started-guides/windows/index.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 5a61d89fae712..113eb62b247dd 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -20,10 +20,13 @@ We recommend using the release binaries that can be found at [https://github.com If you wish to build the code yourself, please follow the next instructions: 1. Install the pre-requisites on a Linux host: + ``` sudo apt-get install curl git build-essential docker.io conntrack ``` + 2. Run the following commands to build kubelet and kube-proxy: + ``` K8SREPO="github.com/kubernetes/kubernetes" go get -d $K8SREPO From b353c5691fbda99a876f45f253ca3e2683d37c2a Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 14:48:54 -0800 Subject: [PATCH 21/35] Fixed formatting --- docs/getting-started-guides/windows/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 113eb62b247dd..61a5e43221894 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -27,7 +27,7 @@ sudo apt-get install curl git build-essential docker.io conntrack 2. Run the following commands to build kubelet and kube-proxy: -``` +```code K8SREPO="github.com/kubernetes/kubernetes" go get -d $K8SREPO # Note: the above command may spit out a message about From 34bfdfc6b2a1b9c1da193f42d8f8e4a04a770ee0 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 15:08:31 -0800 Subject: [PATCH 22/35] Updated header link --- docs/getting-started-guides/windows/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 61a5e43221894..a9948951014f5 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -58,7 +58,7 @@ There are several supported network configurations with Kubernetes v1.9 on Windo 1. [Upstream L3 Routing](#upstream-l3-routing-topology) - IP routes configured in upstream ToR 2. [Host-Gateway](#host-gateway-topology) - IP routes configured on each host -3. [Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay](#overlay-using-ovn-controller-and-ovs-switch-extension-topology) - overlay networks (supports STT and Geneve tunneling types) +3. [Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay](#Using-OVN-with-OVS) - overlay networks (supports STT and Geneve tunneling types) 4. [Future - In Review] Overlay - VXLAN or IP-in-IP encapsulation using Flannel 5. [Future] Layer-3 Routing with BGP (Calico) @@ -71,7 +71,7 @@ An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxla The above networking approaches are already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. ### Windows -Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. At the time of this writing, the only publicly available CNI plugin is built from a private repo and available here [wincni.exe](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/cni/wincni.exe) which uses an l2bridge network created through the Windows Host Networking Service (HNS). An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows-host-setup) section below. Source code for the future CNI plugins will be made available publicly. +Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. At the time of this writing, the only publicly available CNI plugin from Microsoft is built from a private repo and available here [wincni.exe](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/cni/wincni.exe) which uses an l2bridge network created through the Windows Host Networking Service (HNS). An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows-host-setup) section below. Source code for the future CNI plugins will be made available publicly. #### Upstream L3 Routing Topology In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a pod CIDR assigned. All pods on a given worker node will be connected to the pod CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes, the upstream router has static routes configured with pod CIDR prefix => Host IP. From fcf42fa43ab33dbfbb8d2064a5422916272dc08d Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 15:28:04 -0800 Subject: [PATCH 23/35] Updated hyperlinks --- docs/getting-started-guides/windows/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index a9948951014f5..dcdfb5d28380d 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -43,7 +43,7 @@ KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy # You will find the output binaries under the folder _output/local/bin/windows/ ``` -More detailed build instructions will be maintained and kept up to date [here](https://github.com/microsoft/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) +More detailed build instructions will be maintained and kept up to date [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) ## Prerequisites In Kubernetes version 1.9 or later, Windows Server Containers for Kubernetes are supported using the following: @@ -58,7 +58,7 @@ There are several supported network configurations with Kubernetes v1.9 on Windo 1. [Upstream L3 Routing](#upstream-l3-routing-topology) - IP routes configured in upstream ToR 2. [Host-Gateway](#host-gateway-topology) - IP routes configured on each host -3. [Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay](#Using-OVN-with-OVS) - overlay networks (supports STT and Geneve tunneling types) +3. [Open vSwitch (OVS) & Open Virtual Network (OVN) with Overlay](#using-ovn-with-ovs) - overlay networks (supports STT and Geneve tunneling types) 4. [Future - In Review] Overlay - VXLAN or IP-in-IP encapsulation using Flannel 5. [Future] Layer-3 Routing with BGP (Calico) @@ -103,20 +103,20 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your ##### Linux Host Setup 1. Linux hosts should be setup according to their respective distro documentation and the requirements of the Kubernetes version you will be using. -2. Configure Linux Master node using steps [here](https://github.com/Microsoft/virtualization/windowscontainers/kubernetes/creating-a-linux-master.md) +2. Configure Linux Master node using steps [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/creating-a-linux-master.md) 3. [Optional] CNI network plugin installed. ##### Windows Host Setup 1. Windows Server container host running the required Windows Server and Docker versions. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. -2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/Microsoft/virtualization/windowscontainers/kubernetes/HOWTO-on-prem.md#building-kubernetes) +2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) 3. Copy Node spec file (kube config) from Linux master node with X.509 keys 4. Create the HNS Network, ensure the correct CNI network config, and start kubelet.exe using this script [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) 5. Start kube-proxy using this script [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) 6. [Only required for #2 Host-Gateway mode] Add static routes on Windows host using this script [AddRoutes.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/AddRoutes.ps1) -More detailed instructions can be found [here](https://github.com/Microsoft/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md) +More detailed instructions can be found [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md) **Windows CNI Config Example** Today, Windows CNI plugin is based on wincni.exe code with the following example, configuration file. From 21d530743a733fb2a30003dbbc8bd0491af65fd0 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 15:32:59 -0800 Subject: [PATCH 24/35] Updated warning --- docs/getting-started-guides/windows/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index dcdfb5d28380d..1374b0be4be37 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -440,5 +440,5 @@ Some of these limitations will be addressed by the community in future releases - Horizontal Pod Autoscaling for Windows Server Container pods has not been verified to work end-to-end - Hyper-V Containers are not supported -[!Warning] +![Warning] As of this writing, the Kube-proxy binary requires a pending Kubernetes [pull request](https://github.com/kubernetes/kubernetes/pull/56529) to work properly. You may need to build the binaries [manually](#Build) to work around this. \ No newline at end of file From 780d53d3a553b782c22c6ca3500fe5f5949cac58 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 15:48:37 -0800 Subject: [PATCH 25/35] formatting --- docs/getting-started-guides/windows/index.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 1374b0be4be37..979a452975a99 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -24,10 +24,10 @@ If you wish to build the code yourself, please follow the next instructions: ``` sudo apt-get install curl git build-essential docker.io conntrack ``` - + 2. Run the following commands to build kubelet and kube-proxy: -```code +```bash K8SREPO="github.com/kubernetes/kubernetes" go get -d $K8SREPO # Note: the above command may spit out a message about @@ -50,7 +50,7 @@ In Kubernetes version 1.9 or later, Windows Server Containers for Kubernetes are 1. Kubernetes control plane running on existing Linux infrastructure (version 1.9 or later). 2. Kubenet network plugin setup on the Linux nodes. -3. Windows Server 2016 RTM or later. Windows Server version 1709 or later is preferred; unlocks key capabilities like shared network namespace. +3. Windows Server 2016 RTM or later. Windows Server version 1709 or later is preferred; it unlocks key capabilities like shared network namespace. 4. Docker Version 17.06.1-ee-2 or later for Windows Server nodes (Linux nodes and Kubernetes control plane can run any Kubernetes supported Docker Version). ## Networking @@ -110,7 +110,7 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your 1. Windows Server container host running the required Windows Server and Docker versions. Follow the setup instructions outlined by this help topic: https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server. -2. Build or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions found [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) +2. [Build](#Build) or download kubelet.exe, kube-proxy.exe, and kubectl.exe using instructions 3. Copy Node spec file (kube config) from Linux master node with X.509 keys 4. Create the HNS Network, ensure the correct CNI network config, and start kubelet.exe using this script [start-kubelet.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubelet.ps1) 5. Start kube-proxy using this script [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) @@ -118,6 +118,7 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your More detailed instructions can be found [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md) + **Windows CNI Config Example** Today, Windows CNI plugin is based on wincni.exe code with the following example, configuration file. @@ -440,5 +441,5 @@ Some of these limitations will be addressed by the community in future releases - Horizontal Pod Autoscaling for Windows Server Container pods has not been verified to work end-to-end - Hyper-V Containers are not supported -![Warning] +[!Warning] As of this writing, the Kube-proxy binary requires a pending Kubernetes [pull request](https://github.com/kubernetes/kubernetes/pull/56529) to work properly. You may need to build the binaries [manually](#Build) to work around this. \ No newline at end of file From c9b268e06e9d1f1ee8200494d698126d98682575 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 15:54:05 -0800 Subject: [PATCH 26/35] formatting --- docs/getting-started-guides/windows/index.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 979a452975a99..501977014f699 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -21,9 +21,9 @@ If you wish to build the code yourself, please follow the next instructions: 1. Install the pre-requisites on a Linux host: -``` -sudo apt-get install curl git build-essential docker.io conntrack -``` + ``` + sudo apt-get install curl git build-essential docker.io conntrack + ``` 2. Run the following commands to build kubelet and kube-proxy: @@ -118,8 +118,7 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your More detailed instructions can be found [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md) - -**Windows CNI Config Example** +**Windows CNI Config Example** Today, Windows CNI plugin is based on wincni.exe code with the following example, configuration file. Note: this file assumes that a user previous created 'l2bridge' host networks on each Windows node using `-HNSNetwork` cmdlets as shown in the `start-kubelet.ps1` and `start-kubeproxy.ps1` scripts linked above From a091ea41df2bc47a0db90a02bf1bc78542ade840 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Mon, 4 Dec 2017 15:56:14 -0800 Subject: [PATCH 27/35] formatting --- docs/getting-started-guides/windows/index.md | 26 ++++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 501977014f699..2db24aab64b60 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -27,20 +27,20 @@ If you wish to build the code yourself, please follow the next instructions: 2. Run the following commands to build kubelet and kube-proxy: -```bash -K8SREPO="github.com/kubernetes/kubernetes" -go get -d $K8SREPO -# Note: the above command may spit out a message about -# "no Go files in...", but it can be safely ignored! + ```bash + K8SREPO="github.com/kubernetes/kubernetes" + go get -d $K8SREPO + # Note: the above command may spit out a message about + # "no Go files in...", but it can be safely ignored! -cd $GOPATH/src/k8s.io/kubernetes -# Build the kubelet -KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kubelet + cd $GOPATH/src/k8s.io/kubernetes + # Build the kubelet + KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kubelet -# Build the kube-proxy -KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy + # Build the kube-proxy + KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy -# You will find the output binaries under the folder _output/local/bin/windows/ + # You will find the output binaries under the folder _output/local/bin/windows/ ``` More detailed build instructions will be maintained and kept up to date [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) @@ -440,5 +440,5 @@ Some of these limitations will be addressed by the community in future releases - Horizontal Pod Autoscaling for Windows Server Container pods has not been verified to work end-to-end - Hyper-V Containers are not supported -[!Warning] -As of this writing, the Kube-proxy binary requires a pending Kubernetes [pull request](https://github.com/kubernetes/kubernetes/pull/56529) to work properly. You may need to build the binaries [manually](#Build) to work around this. \ No newline at end of file + +> As of this writing, the Kube-proxy binary requires a pending Kubernetes [pull request](https://github.com/kubernetes/kubernetes/pull/56529) to work properly. You may need to build the binaries [manually](#Build) to work around this. \ No newline at end of file From 616c34295aca8439ee434c0c7678d00c56944729 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Tue, 5 Dec 2017 07:41:06 -0800 Subject: [PATCH 28/35] Revert "Update access-cluster.md with a comment that for IPv6" This reverts commit 31e4dbdc25a60e4584ce01a6b1915e13ac63bc67. --- docs/tasks/access-application-cluster/access-cluster.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/tasks/access-application-cluster/access-cluster.md b/docs/tasks/access-application-cluster/access-cluster.md index 8993067de5b17..0ae68442b5373 100644 --- a/docs/tasks/access-application-cluster/access-cluster.md +++ b/docs/tasks/access-application-cluster/access-cluster.md @@ -55,8 +55,7 @@ $ kubectl proxy --port=8080 & See [kubectl proxy](/docs/user-guide/kubectl/{{page.version}}/#proxy) for more details. -Then you can explore the API with curl, wget, or a browser, replacing localhost -with [::1] for IPv6, like so: +Then you can explore the API with curl, wget, or a browser, like so: ```shell $ curl http://localhost:8080/api/ From a6bce7639e59552e998d43d06c3626dcb744d1cc Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Tue, 5 Dec 2017 07:43:01 -0800 Subject: [PATCH 29/35] Revert "fix typo" This reverts commit c05678752d3b481e2907bc53d3971bb49eab6609. --- docs/getting-started-guides/scratch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started-guides/scratch.md b/docs/getting-started-guides/scratch.md index 8d1cb7b3f24e8..b177f4a24b2db 100644 --- a/docs/getting-started-guides/scratch.md +++ b/docs/getting-started-guides/scratch.md @@ -705,7 +705,7 @@ Complete this template for the scheduler pod: "containers": [ { "name": "kube-scheduler", - "image": "$HYPERKUBE_IMAGE", + "image": "$HYBERKUBE_IMAGE", "command": [ "/hyperkube", "scheduler", From babfe580e502deb266d512df4789b82968b0843d Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Tue, 5 Dec 2017 07:43:33 -0800 Subject: [PATCH 30/35] Revert "Workaround for Jekyllr frontmatter" This reverts commit b84ac59624b625e6534ccd97bb4ba65e51b441e4. --- cn/docs/tutorials/stateful-application/web.yaml | 1 + cn/docs/tutorials/stateful-application/webp.yaml | 3 ++- cn/docs/user-guide/multi-pod.yaml | 1 + docs/tasks/access-application-cluster/frontend.yaml | 2 +- docs/tutorials/stateful-application/web.yaml | 1 + docs/tutorials/stateful-application/webp.yaml | 3 ++- docs/tutorials/stateful-application/zookeeper.yaml | 1 + docs/user-guide/environment-guide/backend-rc.yaml | 1 + docs/user-guide/environment-guide/backend-srv.yaml | 1 + docs/user-guide/environment-guide/show-rc.yaml | 1 + docs/user-guide/environment-guide/show-srv.yaml | 1 + docs/user-guide/multi-pod.yaml | 1 + test/examples_test.go | 9 +-------- 13 files changed, 15 insertions(+), 11 deletions(-) diff --git a/cn/docs/tutorials/stateful-application/web.yaml b/cn/docs/tutorials/stateful-application/web.yaml index 6c2770082bc8c..f5f246c47f7e9 100644 --- a/cn/docs/tutorials/stateful-application/web.yaml +++ b/cn/docs/tutorials/stateful-application/web.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Service metadata: diff --git a/cn/docs/tutorials/stateful-application/webp.yaml b/cn/docs/tutorials/stateful-application/webp.yaml index 74a71c90ac7b7..0a56f234e0cfc 100644 --- a/cn/docs/tutorials/stateful-application/webp.yaml +++ b/cn/docs/tutorials/stateful-application/webp.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Service metadata: @@ -41,4 +42,4 @@ spec: accessModes: [ "ReadWriteOnce" ] resources: requests: - storage: 1Gi + storage: 1Gi \ No newline at end of file diff --git a/cn/docs/user-guide/multi-pod.yaml b/cn/docs/user-guide/multi-pod.yaml index 2ace060d89eff..7f7d0a5745711 100644 --- a/cn/docs/user-guide/multi-pod.yaml +++ b/cn/docs/user-guide/multi-pod.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Pod metadata: diff --git a/docs/tasks/access-application-cluster/frontend.yaml b/docs/tasks/access-application-cluster/frontend.yaml index 63631c0d05ede..382c3786e5f8f 100644 --- a/docs/tasks/access-application-cluster/frontend.yaml +++ b/docs/tasks/access-application-cluster/frontend.yaml @@ -1,5 +1,5 @@ -apiVersion: v1 kind: Service +apiVersion: v1 metadata: name: frontend spec: diff --git a/docs/tutorials/stateful-application/web.yaml b/docs/tutorials/stateful-application/web.yaml index 9b34869298905..9f0ba1a343f5a 100644 --- a/docs/tutorials/stateful-application/web.yaml +++ b/docs/tutorials/stateful-application/web.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Service metadata: diff --git a/docs/tutorials/stateful-application/webp.yaml b/docs/tutorials/stateful-application/webp.yaml index 705d1207cb13d..231883742718d 100644 --- a/docs/tutorials/stateful-application/webp.yaml +++ b/docs/tutorials/stateful-application/webp.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Service metadata: @@ -44,4 +45,4 @@ spec: accessModes: [ "ReadWriteOnce" ] resources: requests: - storage: 1Gi + storage: 1Gi \ No newline at end of file diff --git a/docs/tutorials/stateful-application/zookeeper.yaml b/docs/tutorials/stateful-application/zookeeper.yaml index 952e5b45c5798..f07708c398b93 100644 --- a/docs/tutorials/stateful-application/zookeeper.yaml +++ b/docs/tutorials/stateful-application/zookeeper.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Service metadata: diff --git a/docs/user-guide/environment-guide/backend-rc.yaml b/docs/user-guide/environment-guide/backend-rc.yaml index 28c7eeb097629..6c57b95dac912 100644 --- a/docs/user-guide/environment-guide/backend-rc.yaml +++ b/docs/user-guide/environment-guide/backend-rc.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: ReplicationController metadata: diff --git a/docs/user-guide/environment-guide/backend-srv.yaml b/docs/user-guide/environment-guide/backend-srv.yaml index 1c306bc0f60da..7083b37bf88e0 100644 --- a/docs/user-guide/environment-guide/backend-srv.yaml +++ b/docs/user-guide/environment-guide/backend-srv.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Service metadata: diff --git a/docs/user-guide/environment-guide/show-rc.yaml b/docs/user-guide/environment-guide/show-rc.yaml index df2f03e3471c8..4de94c06ca30b 100644 --- a/docs/user-guide/environment-guide/show-rc.yaml +++ b/docs/user-guide/environment-guide/show-rc.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: ReplicationController metadata: diff --git a/docs/user-guide/environment-guide/show-srv.yaml b/docs/user-guide/environment-guide/show-srv.yaml index 17613104214cb..25a2d7473e021 100644 --- a/docs/user-guide/environment-guide/show-srv.yaml +++ b/docs/user-guide/environment-guide/show-srv.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Service metadata: diff --git a/docs/user-guide/multi-pod.yaml b/docs/user-guide/multi-pod.yaml index 2ace060d89eff..7f7d0a5745711 100644 --- a/docs/user-guide/multi-pod.yaml +++ b/docs/user-guide/multi-pod.yaml @@ -1,3 +1,4 @@ +--- apiVersion: v1 kind: Pod metadata: diff --git a/test/examples_test.go b/test/examples_test.go index 1999d1f1581f4..683a53250f0d4 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -199,10 +199,6 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er if err != nil { return err } - // workaround for Jekyllr limit - if bytes.HasPrefix(data, []byte("---\n")) { - return fmt.Errorf("YAML file cannot start with \"---\", please remove the first line") - } name := strings.TrimSuffix(file, ext) var docs [][]byte @@ -221,10 +217,7 @@ func walkConfigFiles(inDir string, fn func(name, path string, data [][]byte)) er if err != nil { return fmt.Errorf("%s: %v", path, err) } - // deal with "empty" document (e.g. pure comments) - if string(out) != "null" { - docs = append(docs, out) - } + docs = append(docs, out) } } else { docs = append(docs, data) From 45ea42d8c5bc35e1e0646c45f80c4c69e0101bfc Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Tue, 5 Dec 2017 08:02:14 -0800 Subject: [PATCH 31/35] Fixed grammatical issues and reverted non-related commits --- docs/getting-started-guides/windows/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 2db24aab64b60..a266d6339edb1 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -71,7 +71,7 @@ An additional two CNI plugins [win-l2bridge (host-gateway) and win-overlay (vxla The above networking approaches are already supported on Linux using a bridge interface, which essentially creates a private network local to the node. Similar to the Windows side, routes to all other pod CIDRs must be created in order to send packets via the "public" NIC. ### Windows -Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. At the time of this writing, the only publicly available CNI plugin from Microsoft is built from a private repo and available here [wincni.exe](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/cni/wincni.exe) which uses an l2bridge network created through the Windows Host Networking Service (HNS). An administrator creates a local host network using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows-host-setup) section below. Source code for the future CNI plugins will be made available publicly. +Windows supports the CNI network model and uses plugins to interface with the Windows Host Networking Service (HNS) to configure host networking and policy. At the time of this writing, the only publicly available CNI plugin from Microsoft is built from a private repo and available here [wincni.exe](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/cni/wincni.exe). It uses an l2bridge network created through the Windows Host Networking Service (HNS) by an administrator using HNS PowerShell commands on each node as documented in the [Windows Host Setup](#windows-host-setup) section below. Source code for the future CNI plugins will be made available publicly. #### Upstream L3 Routing Topology In this topology, networking is achieved using L3 routing with static IP routes configured in an upstream Top of Rack (ToR) switch/router. Each cluster node is connected to the management network with a host IP. Additionally, each node uses a local 'l2bridge' network with a pod CIDR assigned. All pods on a given worker node will be connected to the pod CIDR subnet ('l2bridge' network). In order to enable network communication between pods running on different nodes, the upstream router has static routes configured with pod CIDR prefix => Host IP. @@ -441,4 +441,4 @@ Some of these limitations will be addressed by the community in future releases - Hyper-V Containers are not supported -> As of this writing, the Kube-proxy binary requires a pending Kubernetes [pull request](https://github.com/kubernetes/kubernetes/pull/56529) to work properly. You may need to build the binaries [manually](#Build) to work around this. \ No newline at end of file +> As of this writing, the Kube-proxy binary requires a pending Kubernetes [pull request](https://github.com/kubernetes/kubernetes/pull/56529) to work properly. You may need to [build](#build) the binaries manually to work around this. \ No newline at end of file From 3b2f03ddb3cb2e66a1f8c56984b4a62c65b727de Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Tue, 5 Dec 2017 08:04:16 -0800 Subject: [PATCH 32/35] Revert "Rewrite PodSecurityPolicy guide" This reverts commit 5d39cfeae41b3237a5e1247bc1c1f98e0727c5fd. --- docs/concepts/policy/pod-security-policy.md | 656 ++++++------------ docs/concepts/policy/privileged-psp.yaml | 27 - .../policy/{example-psp.yaml => psp.yaml} | 9 +- docs/concepts/policy/restricted-psp.yaml | 48 -- test/examples_test.go | 4 +- 5 files changed, 206 insertions(+), 538 deletions(-) delete mode 100644 docs/concepts/policy/privileged-psp.yaml rename docs/concepts/policy/{example-psp.yaml => psp.yaml} (66%) delete mode 100644 docs/concepts/policy/restricted-psp.yaml diff --git a/docs/concepts/policy/pod-security-policy.md b/docs/concepts/policy/pod-security-policy.md index f1373a71302f8..a1e219c146126 100644 --- a/docs/concepts/policy/pod-security-policy.md +++ b/docs/concepts/policy/pod-security-policy.md @@ -1,523 +1,265 @@ --- approvers: - pweil- -- tallclair title: Pod Security Policies --- -{% include feature-state-beta.md %} +Objects of type `PodSecurityPolicy` govern the ability +to make requests on a pod that affect the `SecurityContext` that will be +applied to a pod and container. -Pod Security Policies enable fine-grained authorization of pod creation and -updates. +See [PodSecurityPolicy proposal](https://git.k8s.io/community/contributors/design-proposals/auth/pod-security-policy.md) for more information. * TOC {:toc} ## What is a Pod Security Policy? -A _Pod Security Policy_ is a cluster-level resource that controls security -sensitive aspects of the pod specification. The `PodSecurityPolicy` objects -define a set of conditions that a pod must run with in order to be accepted into -the system, as well as defaults for the related fields. They allow an +A _Pod Security Policy_ is a cluster-level resource that controls the +actions that a pod can perform and what it has the ability to access. The +`PodSecurityPolicy` objects define a set of conditions that a pod must +run with in order to be accepted into the system. They allow an administrator to control the following: -| Control Aspect | Field Names | -| ----------------------------------------------------| ------------------------------------------- | -| Running of privileged containers | `privileged` | -| Usage of the root namespaces | [`hostPID`, `hostIPC`](#host-namespaces) | -| Usage of host networking and ports | [`hostNetwork`, `hostPorts`](#host-namespaces) | -| Usage of volume types | [`volumes`](#volumes-and-file-systems) | -| Usage of the host filesystem | [`allowedHostPaths`](#volumes-and-file-systems) | -| Allocating an FSGroup that owns the pod's volumes | [`fsGroup`](#volumes-and-file-systems) | -| Requiring the use of a read only root file system | [`readOnlyRootFilesystem`](#volumes-and-file-systems) | -| The user and group IDs of the container | [`runAsUser`, `supplementalGroups`](#users-and-groups) | -| Restricting escalation to root privileges | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) | -| Linux capabilities | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) | -| The SELinux context of the container | [`seLinux`](#selinux) | -| The AppArmor profile used by containers | [annotations](#apparmor) | -| The seccomp profile used by containers | [annotations](#seccomp) | - - -## Enabling Pod Security Policies - -Pod security policy control is implemented as an optional (but recommended) -[admission -controller](/docs/admin/admission-controllers/#podsecuritypolicy). PodSecurityPolicies -are enforced by [enabling the admission -controller](/docs/admin/admission-controllers/#how-do-i-turn-on-an-admission-control-plug-in), -but doing so without authorizing any policies **will prevent any pods from being -created** in the cluster. - -Since the pod security policy API (`extensions/v1beta1/podsecuritypolicy`) is -enabled independently of the admission controller, for existing clusters it is -recommended that policies are added and authorized before enabling the admission -controller. - -## Authorizing Policies +| Control Aspect | Field Name | +| ---------------------------------------------------------------------- | ------------------------------------------- | +| Running of privileged containers | `privileged` | +| Default set of capabilities that will be added to a container | `defaultAddCapabilities` | +| Capabilities that will be dropped from a container | `requiredDropCapabilities` | +| Capabilities a container can request to be added | `allowedCapabilities` | +| Controlling the usage of volume types | [`volumes`](#controlling-volumes) | +| The use of host networking | [`hostNetwork`](#host-network) | +| The use of host ports | `hostPorts` | +| The use of host's PID namespace | `hostPID` | +| The use of host's IPC namespace | `hostIPC` | +| The SELinux context of the container | [`seLinux`](#selinux) | +| The user ID | [`runAsUser`](#runasuser) | +| Configuring allowable supplemental groups | [`supplementalGroups`](#supplementalgroups) | +| Allocating an FSGroup that owns the pod's volumes | [`fsGroup`](#fsgroup) | +| Requiring the use of a read only root file system | `readOnlyRootFilesystem` | +| Running of a container that allow privilege escalation from its parent | [`allowPrivilegeEscalation`](#allowprivilegeescalation) | +| Control whether a process can gain more privileges than its parent process | [`defaultAllowPrivilegeEscalation`](#defaultallowprivilegeescalation) | +| Whitelist of allowed host paths | [`allowedHostPaths`](#allowedhostpaths) | + +_Pod Security Policies_ are comprised of settings and strategies that +control the security features a pod has access to. These settings fall +into three categories: + +- *Controlled by a Boolean*: Fields of this type default to the most +restrictive value. +- *Controlled by an allowable set*: Fields of this type are checked +against the set to ensure their values are allowed. +- *Controlled by a strategy*: Items that have a strategy to provide +a mechanism to generate the value and a mechanism to ensure that a +specified value falls into the set of allowable values. + + +## Strategies + +### RunAsUser + +- *MustRunAs* - Requires a `range` to be configured. Uses the first value +of the range as the default. Validates against the configured range. +- *MustRunAsNonRoot* - Requires that the pod be submitted with a non-zero +`runAsUser` or have the `USER` directive defined in the image. No default +provided. +- *RunAsAny* - No default provided. Allows any `runAsUser` to be specified. -When a PodSecurityPolicy resource is created, it does nothing. In order to use -it, the requesting user or target pod's [service -account](/docs/tasks/configure-pod-container/configure-service-account/) must be -authorized to use the policy, by allowing the `use` verb on the policy. +### SELinux -Most Kubernetes pods are not created directly by users. Instead, they are -typically created indirectly as part of a -[Deployment](/docs/concepts/workloads/controllers/deployment/), -[ReplicaSet](/docs/concepts/workloads/controllers/replicaset/), or other -templated controller via the controller manager. Granting the controller access -to the policy would grant access for *all* pods created by that the controller, -so the preferred method for authorizing policies is to grant access to the -pod's service account (see [example](#run-another-pod)). +- *MustRunAs* - Requires `seLinuxOptions` to be configured if not using +pre-allocated values. Uses `seLinuxOptions` as the default. Validates against +`seLinuxOptions`. +- *RunAsAny* - No default provided. Allows any `seLinuxOptions` to be +specified. -### Via RBAC +### SupplementalGroups -[RBAC](/docs/admin/authorization/rbac/) is a standard Kubernetes authorization -mode, and can easily be used to authorize use of policies. +- *MustRunAs* - Requires at least one range to be specified. Uses the +minimum value of the first range as the default. Validates against all ranges. +- *RunAsAny* - No default provided. Allows any `supplementalGroups` to be +specified. -First, a `Role` or `ClusterRole` needs to grant access to `use` the desired -policies. The rules to grant access look like this: +### FSGroup -```yaml -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: -rules: -- apiGroups: ['extensions'] - resources: ['podsecuritypolicies'] - verbs: ['use'] - resourceNames: - - -``` +- *MustRunAs* - Requires at least one range to be specified. Uses the +minimum value of the first range as the default. Validates against the +first ID in the first range. +- *RunAsAny* - No default provided. Allows any `fsGroup` ID to be specified. -Then the `(Cluster)Role` is bound to the authorized user(s): +### Controlling Volumes + +The usage of specific volume types can be controlled by setting the +volumes field of the PSP. The allowable values of this field correspond +to the volume sources that are defined when creating a volume: + +1. azureFile +1. azureDisk +1. flocker +1. flexVolume +1. hostPath +1. emptyDir +1. gcePersistentDisk +1. awsElasticBlockStore +1. gitRepo +1. secret +1. nfs +1. iscsi +1. glusterfs +1. persistentVolumeClaim +1. rbd +1. cinder +1. cephFS +1. downwardAPI +1. fc +1. configMap +1. vsphereVolume +1. quobyte +1. photonPersistentDisk +1. projected +1. portworxVolume +1. scaleIO +1. storageos +1. \* (allow all volumes) + +The recommended minimum set of allowed volumes for new PSPs are +configMap, downwardAPI, emptyDir, persistentVolumeClaim, secret, and projected. + +### Host Network + - *HostPorts*, default `empty`. List of `HostPortRange`, defined by `min`(inclusive) and `max`(inclusive), which define the allowed host ports. + +### AllowPrivilegeEscalation + +Gates whether or not a user is allowed to set the security context of a container +to `allowPrivilegeEscalation=true`. This field defaults to `false`. + +### DefaultAllowPrivilegeEscalation + +Sets the default for the security context `AllowPrivilegeEscalation` of a container. +This bool directly controls whether the `no_new_privs` flag gets set on the +container process. It defaults to `nil`. The default behavior of `nil` +allows privilege escalation so as to not break setuid binaries. Setting it to `false` +ensures that no child process of a container can gain more privileges than +its parent. + +### AllowedHostPaths + +This specifies a whitelist of host paths that are allowed to be used by Pods. +An empty list means there is no restriction on host paths used. +Each item in the list must specify a string value named `pathPrefix` that +defines a host path to match. The value cannot be "`*`" though. +An example is shown below: ```yaml -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 +apiVersion: extensions/v1beta1 +kind: PodSecurityPolicy metadata: - name: -roleRef: - kind: ClusterRole - name: - apiGroup: rbac.authorization.k8s.io -subjects: -# Authorize specific service accounts: -- kind: ServiceAccount - name: - namespace: -# Authorize specific users (not recommended): -- kind: User - apiGroup: rbac.authorization.k8s.io - name: -``` - -If a `RoleBinding` (not a `ClusterRoleBinding`) is used, it will only grant -usage for pods being run in the same namespace as the binding. This can be -paired with system groups to grant access to all pods run in the namespace: -```yaml -# Authorize all service accounts in a namespace: -- kind: Group - apiGroup: rbac.authorization.k8s.io - name: system:serviceaccounts -# Or equivalently, all authenticated users in a namespace: -- kind: Group - apiGroup: rbac.authorization.k8s.io - name: system:authenticated -``` - -For more examples of RBAC bindings, see [Role Binding -Examples](docs/admin/authorization/rbac/#role-binding-examples). For a complete -example of authorizing a PodSecurityPolicy, see -[below](#example). - - -### Troubleshooting - -- The [Controller Manager](/docs/admin/kube-controller-manager/) must be run -against [the secured API port](/docs/admin/accessing-the-api/), and must not -have superuser permissions. Otherwise requests would bypass authentication and -authorization modules, all PodSecurityPolicy objects would be allowed, and users -would be able to create privileged containers. For more details on configuring -Controller Manager authorization, see [Controller -Roles](docs/admin/authorization/rbac/#controller-roles). - -## Policy Order - -In addition to restricting pod creation and update, pod security policies can -also be used to provide default values for many of the fields that it -controls. When multiple policies are available, the pod security policy -controller selects policies in the following order: - -1. If any policies successfully validate the pod without altering it, they are - used. -2. Otherwise, the first valid policy in alphabetical order is used. - -## Example - -_This example assumes you have a running cluster with the PodSecurityPolicy -admission controller enabled and you have cluster admin privileges._ - -### Set up - -Set up a namespace and a service account to act as for this example. We'll use -this service account to mock a non-admin user. - -```shell -$ kubectl create namespace psp-example -$ kubectl create serviceaccount -n psp-example fake-user -$ kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user -``` - -To make it clear which user we're acting as and save some typing, create 2 -aliases: - -```shell -$ alias kubectl-admin='kubectl -n psp-example' -$ alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example' -``` - -### Create a policy and a pod - -Define the example PodSecurityPolicy object in a file. This is a policy that -simply prevents the creation of privileged pods. - -{% include code.html language="yaml" file="example-psp.yaml" ghlink="/docs/concepts/policy/example-psp.yaml" %} - -And create it with kubectl: - -```shell -$ kubectl-admin create -f example-psp.yaml -``` - -Now, as the unprivileged user, try to create a simple pod: - -```shell -$ kubectl-user create -f- <` - Specify a profile as a file on the node located at - `/`, where `` is defined via the - `--seccomp-profile-root` flag on the Kubelet. +For pods created on behalf of a user, in most cases by Controller Manager, +access should be given to the service account specified on the pod spec +template. Examples of resources that create pods on behalf of a user are +Deployments, ReplicaSets, etc. -**seccomp.security.alpha.kubernetes.io/allowedProfileNames** - Annotation that -specifies which values are allowed for the pod seccomp annotations. Specified as -a comma-delimited list of allowed values. Possible values are those listed -above, plus `*` to allow all profiles. Absence of this annotation means that the -default cannot be changed. +For more details, see the +[PodSecurityPolicy RBAC example](https://git.k8s.io/examples/staging/podsecuritypolicy/rbac/README.md) +of applying PodSecurityPolicy to control access to privileged containers based +on role and groups when deploying Pods directly. diff --git a/docs/concepts/policy/privileged-psp.yaml b/docs/concepts/policy/privileged-psp.yaml deleted file mode 100644 index 6b6ec6687831d..0000000000000 --- a/docs/concepts/policy/privileged-psp.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: PodSecurityPolicy -metadata: - name: privileged - annotations: - seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' -spec: - privileged: true - allowPrivilegeEscalation: true - allowedCapabilities: - - '*' - volumes: - - '*' - hostNetwork: true - hostPorts: - - min: 0 - max: 65535 - hostIPC: true - hostPID: true - runAsUser: - rule: 'RunAsAny' - seLinux: - rule: 'RunAsAny' - supplementalGroups: - rule: 'RunAsAny' - fsGroup: - rule: 'RunAsAny' diff --git a/docs/concepts/policy/example-psp.yaml b/docs/concepts/policy/psp.yaml similarity index 66% rename from docs/concepts/policy/example-psp.yaml rename to docs/concepts/policy/psp.yaml index d8359220e42b5..f82f7a856f1a8 100644 --- a/docs/concepts/policy/example-psp.yaml +++ b/docs/concepts/policy/psp.yaml @@ -1,10 +1,8 @@ apiVersion: extensions/v1beta1 kind: PodSecurityPolicy metadata: - name: example + name: permissive spec: - privileged: false # Don't allow privileged pods! - # The rest fills in some required fields. seLinux: rule: RunAsAny supplementalGroups: @@ -13,5 +11,10 @@ spec: rule: RunAsAny fsGroup: rule: RunAsAny + hostPorts: + - min: 8000 + max: 8080 volumes: - '*' + allowedCapabilities: + - '*' diff --git a/docs/concepts/policy/restricted-psp.yaml b/docs/concepts/policy/restricted-psp.yaml deleted file mode 100644 index fe1c1d90fe33d..0000000000000 --- a/docs/concepts/policy/restricted-psp.yaml +++ /dev/null @@ -1,48 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: PodSecurityPolicy -metadata: - name: restricted - annotations: - seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default' - apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' - seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' - apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' -spec: - privileged: false - # Required to prevent escalations to root. - allowPrivilegeEscalation: false - # This is redundant with non-root + disallow privilege escalation, - # but we can provide it for defense in depth. - requiredDropCapabilities: - - ALL - # Allow core volume types. - volumes: - - 'configMap' - - 'emptyDir' - - 'projected' - - 'secret' - - 'downwardAPI' - # Assume that persistentVolumes set up by the cluster admin are safe to use. - - 'persistentVolumeClaim' - hostNetwork: false - hostIPC: false - hostPID: false - runAsUser: - # Require the container to run without root privileges. - rule: 'MustRunAsNonRoot' - seLinux: - # This policy assumes the nodes are using AppArmor rather than SELinux. - rule: 'RunAsAny' - supplementalGroups: - rule: 'MustRunAs' - ranges: - # Forbid adding the root group. - - min: 1 - max: 65535 - fsGroup: - rule: 'MustRunAs' - ranges: - # Forbid adding the root group. - - min: 1 - max: 65535 - readOnlyRootFilesystem: false diff --git a/test/examples_test.go b/test/examples_test.go index 683a53250f0d4..87b7e9a54a717 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -281,9 +281,7 @@ func TestExampleObjectSchemas(t *testing.T) { "nginx-deployment": {&extensions.Deployment{}}, }, "../docs/concepts/policy": { - "privileged-psp": {&extensions.PodSecurityPolicy{}}, - "restricted-psp": {&extensions.PodSecurityPolicy{}}, - "example-psp": {&extensions.PodSecurityPolicy{}}, + "psp": {&extensions.PodSecurityPolicy{}}, }, "../docs/concepts/services-networking": { "curlpod": {&extensions.Deployment{}}, From e320e97e7eb621ffc3951bd62427033f3fa2b09a Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Tue, 5 Dec 2017 08:05:15 -0800 Subject: [PATCH 33/35] Revert "Spelling correction and sentence capitalization." This reverts commit 47eed4346e4491c9a63c2e0cb76bdd37bff5677c. --- .../api-extension/custom-resources.md | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/concepts/api-extension/custom-resources.md b/docs/concepts/api-extension/custom-resources.md index 5ce45d4e3171b..710a334a48d45 100644 --- a/docs/concepts/api-extension/custom-resources.md +++ b/docs/concepts/api-extension/custom-resources.md @@ -48,24 +48,24 @@ When creating a new API, consider whether to [aggregate your API with the Kubern #### Declarative APIs In a Declarative API, typically: - - Your API consists of a relatively small number of relatively small objects (resources). - - The objects define configuration of applications or infrastructure. - - The objects are updated relatively infrequently. - - Humans often need to read and write the objects. - - The main operations on the objects are CRUD-y (creating, reading, updating and deleting). - - Transactions across objects are not required: the API represents a desired state, not an exact state. + - your API consists of a relatively small number of relatively small objects (resources). + - the objects define configuration of applications or infrastructure + - the objects are updated relatively infrequently + - humans often need to read and write the objects + - the main operations on the objects are CRUD-y (creating, reading, updating and deleting) + - transactions across objects are not required: the API represents a desired state, not an exact state. Imperative APIs are not declarative. Signs that your API might not be declarative include: - - The client says "do this", and then gets a synchornous response back when it is done. - - The client says "do this", and then gets an operation ID back, and has to check a separate Operation objects to determine completion of the request. - - You talk about Remote Procedure Calls (RPCs). - - Directly storing large amounts of data (e.g. > a few kB per object, or >1000s of objects). - - High bandwidth access (10s of requests per second sustained) needed. - - Store end-user data (such as images, PII, etc) or other large-scale data processed by applications. - - The natural operations on the objects are not CRUD-y. - - The API is not easily modeled as objects. - - You chose to represent pending operations with an operation ID or operation object. + - the client says "do this", and then gets a synchornous response back when it is done. + - the client says "do this", and then gets an operation ID back, and has to check a separate Operation objects to determine completion of the request. + - you talk about Remote Procedure Calls (RPCs) + - directly stoing large amounts of data (e.g. > a few kB per object, or >1000s of objects) + - high bandwidth access (10s of requests per second sustained) needed + - store end-user data (such as images, PII, etc) or other large-scale data processed by applications + - the natural operations on the objects are not CRUD-y. + - the API is not easily modeled as objects. + - you chose to represent pending operations with an operation ID or operation object. ### Should I use a configMap or a custom resource? @@ -102,7 +102,7 @@ Aggregated APIs are subordinate APIServers that sit behind the primary API serve Custom Resource Definitions (CRDS) allow users to create new types of resources without adding another APIserver. You do not need to understand API Aggregation to use CRDs. -Regardless of whether they are installed via CRDs or AA, the new resources are called Custom Resources to distinguish them from built-in Kubernetes resources (like pods). +Regardless of whether they are installed via CRDs or AA, the new resources are called Custom Resources to distinguish them from built-in Kubernetes resources (like pods) ## CustomResourceDefinitions @@ -215,9 +215,9 @@ Kubernetes [client libraries](/docs/reference/client-libraries/) can be used to When you add a custom resource, you can access it using: - kubectl - - The kubernetes dynamic client. - - A REST client that you write. - - A client generated using Kubernetes client generation tools (generating one is an advanced undertaking, but some projects may provide a client along with the CRD or AA). + - the kubernetes dynamic client + - a REST client that you write + - a client generated using Kubernetes client generation tools (generating one is an advanced undertaking, but some projects may provide a client along with the CRD or AA). {% endcapture %} From 61bec6ca2dd7c0f90b1aaa9d6773bd1e2b570e74 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Tue, 5 Dec 2017 08:12:06 -0800 Subject: [PATCH 34/35] Fixed auto-numbering --- docs/getting-started-guides/windows/index.md | 29 ++++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index a266d6339edb1..6b52d368fdf48 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -21,26 +21,25 @@ If you wish to build the code yourself, please follow the next instructions: 1. Install the pre-requisites on a Linux host: - ``` - sudo apt-get install curl git build-essential docker.io conntrack - ``` - + ``` + sudo apt-get install curl git build-essential docker.io conntrack + ``` 2. Run the following commands to build kubelet and kube-proxy: - ```bash - K8SREPO="github.com/kubernetes/kubernetes" - go get -d $K8SREPO - # Note: the above command may spit out a message about - # "no Go files in...", but it can be safely ignored! + ```bash + K8SREPO="github.com/kubernetes/kubernetes" + go get -d $K8SREPO + # Note: the above command may spit out a message about + # "no Go files in...", but it can be safely ignored! - cd $GOPATH/src/k8s.io/kubernetes - # Build the kubelet - KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kubelet + cd $GOPATH/src/k8s.io/kubernetes + # Build the kubelet + KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kubelet - # Build the kube-proxy - KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy + # Build the kube-proxy + KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy - # You will find the output binaries under the folder _output/local/bin/windows/ + # You will find the output binaries under the folder _output/local/bin/windows/ ``` More detailed build instructions will be maintained and kept up to date [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) From 907bc08bc16aafe1f8a80ba532a753e60e2d76d2 Mon Sep 17 00:00:00 2001 From: Jason Messer Date: Wed, 6 Dec 2017 19:37:40 -0800 Subject: [PATCH 35/35] Minor formatting updates --- docs/getting-started-guides/windows/index.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/getting-started-guides/windows/index.md b/docs/getting-started-guides/windows/index.md index 6b52d368fdf48..b8a33e1e96dc4 100644 --- a/docs/getting-started-guides/windows/index.md +++ b/docs/getting-started-guides/windows/index.md @@ -2,6 +2,7 @@ title: Using Windows Server Containers in Kubernetes --- **Note:** These instructions were recently updated based on Windows Server platform enhancements and the Kubernetes v1.9 release +{: .note} Kubernetes version 1.5 introduced Alpha support for Windows Server Containers based on the Windows Server 2016 operating system. With the release of Windows Server version 1709 and using Kubernetes v1.9 users are able to deploy a Kubernetes cluster either on-premises or in a private/public cloud using a number of different network topologies and CNI plugins. Some key feature improvements for Windows Server Containers on Kubernetes include: - Improved support for pods! Shared network namespace (compartment) with multiple Windows Server containers (shared kernel) @@ -13,6 +14,7 @@ Kubernetes version 1.5 introduced Alpha support for Windows Server Containers ba The Kubernetes control plane (API Server, Scheduler, Controller Manager, etc) continue to run on Linux, while the kubelet and kube-proxy can be run on Windows Server 2016 or later **Note:** Windows Server Containers on Kubernetes is a Beta feature in Kubernetes v1.9 +{: .note} ## Build We recommend using the release binaries that can be found at [https://github.com/kubernetes/kubernetes/releases](https://github.com/kubernetes/kubernetes/releases). Look for the Node Binaries section by visiting the binary downloads link. @@ -42,7 +44,7 @@ If you wish to build the code yourself, please follow the next instructions: # You will find the output binaries under the folder _output/local/bin/windows/ ``` -More detailed build instructions will be maintained and kept up to date [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md) +More detailed build instructions will be maintained and kept up to date [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/compiling-kubernetes-binaries.md). ## Prerequisites In Kubernetes version 1.9 or later, Windows Server Containers for Kubernetes are supported using the following: @@ -115,7 +117,7 @@ To run Windows Server Containers on Kubernetes, you'll need to set up both your 5. Start kube-proxy using this script [start-kubeproxy.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/start-kubeproxy.ps1) 6. [Only required for #2 Host-Gateway mode] Add static routes on Windows host using this script [AddRoutes.ps1](https://github.com/Microsoft/SDN/blob/master/Kubernetes/windows/AddRoutes.ps1) -More detailed instructions can be found [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md) +More detailed instructions can be found [here](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows.md). **Windows CNI Config Example** Today, Windows CNI plugin is based on wincni.exe code with the following example, configuration file.