# Windows Server 容器
k8s v1.5 引入了对 Windows Server 容器的支持。在版本 1.5 中,k8s 控制面板(API 服务器,调度器,控制管理器等)仍然运行在 Linux 上,但是 kubelet 和 kube-proxy 可以运行在 Windows Server 上。
注意: 在 k8s 1.5 中,k8s 中的 Windows Server 容器还属于 Alpha 功能。
# 前提条件
在 k8s v1.5 中,Windows Server 容器对 k8s 的支持使用如下方法:
- k8s 控制面板还是运行在已有的 Linux 基础设施(v1.5 及以后的版本)上
- 在 Linux 节点上搭建 Kubenet 网络插件
- Windows Server 2016 (RTM 版本 10.0.14393 或之后的)
- 对 Windows Server 节点而言,需要 Docker 版本 v1.12.2-cs2-ws-beta 或之后的(Linux 节点和 k8s 控制面板可以运行在任何支持 Docker 版本的 k8s 上)
# 网络
网络是通过 L3 路由实现的。由于第三方的网络插件(比如 flannel,calico 等)本身在 Windows Server 上无法工作,它只能依赖于内嵌在 Windows 和 Linux 操作系统中的已有技术。在这个 L3 网络方法中,集群中的节点都选择使用/16 的子网,每个工作节点选择/24 的子网。在给定工作节点上的所有 pod 都会连接到/24 的子网。这样,在同一个节点上的所有 pod 就能相互通信。为了激活运行在不同节点上的 pod 之间的网络,它使用了内嵌在 Window server 2016 和 Linux 内的路由功能。
# Linux
以上网络方法在 Linux 上已经使用网桥接口实现,网桥接口本质上是在节点上创建了一个本地私有网络。与 Windows 方面一样,为了使用“公开”NIC 发送数据包,必须创建到所有其他节点 CIDR 的路由。
# Windows
每个 Windows server 节点都必须做如下配置:
- 每个 Windows Server 节点都都必须要有两块 NIC(虚拟网络适配器) - 这两种 Windows 容器网络模式(传输层和 L2 网桥)使用一个外部 Hyper-V 虚拟交换机。这意味着其中有一个 NIC 完全分配给该网桥,这也是为什么还需要创建一个 NIC。
- 创建传输层容器网络 - 这是一个手工配置步骤,会在下面的 Route Setup 章节中介绍
- 启用 RRAS(路由)Windows 功能 - 允许同一台机器上两个 NIC 之间的路由,并能“截获”目标地址是运行在该节点上的 POD 的数据包。要启用该功能,打开“服务器管理”,点击“角色”,“添加角色”,点击“下一步”,选择“网络策略和访问服务”,点击“路由和远程访问服务”,并选择底下的复选框。
- 通过“公开”NIC 将 - 这些路由添加到内嵌的路由表中,请参考下面的 Route Setup 章节
以下图表显示了在 Windows Server 上搭建 k8s 的网络配置
# 在 k8s 上搭建 Windows server 容器
要在 k8s 上运行 Windows Server 容器,你需要配置你的主机机器和 Windows 上的 k8s 节点组件,并为在不同的节点上 Pod 之间的通信搭建路由。
# 主机配置
Windows 主机配置
- Windows Server 容器要运行 Windows Server 2016 和 Docker v1.12。
- 对 Windows DNS 的支持最近刚并到 docker master 中,目前在稳定的 docker 发布版中还不支持。要使用 DNS,你可以从 master 中构建 docker,或从 docker master 中下载二进制。
- 从 docker pause 中拖拽 apprenda/pause 镜像
- 启用 RRAS(路由) Windows 功能
- 在 PowerShell 窗口下运行 New-VMSwitch -Name KubeProxySwitch -SwitchType Internal 命令来安装类型为‘Internal’的 VMSwitch。这会创建一个新的名为 vEthernet (KubeProxySwitch)的网络接口。kube-proxy 会使用这个接口来添加 Service IP。
Linux 主机配置
- Linux 主机必须根据他们各自发行版的文档和你准备使用的 k8s 的版本需求来配置。
- 安装 CNI 网络插件。
# 组件配置
要求
- Git
- Go 1.7.1+
- make (如果使用的是 Linux 或 MacOS)
kubelet
要构建 kubelet,运行:
- cd $GOPATH/src/k8s.io/kubernetes
- 构建 kubelet
- Linux/MacOS: KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kubelet
- Windows: go build cmd/kubelet/kubelet.go
kube-proxy
要投建 kube-proxy,运行:
- cd $GOPATH/src/k8s.io/kubernetes
- 构建 kube-proxy
- Linux/MacOS: KUBE_BUILD_PLATFORMS=windows/amd64 make WHAT=cmd/kube-proxy
- Windows: go build cmd/kube-proxy/proxy.go
# 路由配置
如下实例配置是假设你有一个 Linux 和两个 Windows Server 2016 节点,以及集群 CIDR 192.168.0.0/16。
Hostname | Routable IP address | Pod CIDR |
---|---|---|
Lin01 | <IP of Lin01 host> | 192.168.0.0/24 |
Win01 | <IP of Win01 host> | 192.168.1.0/24 |
Win02 | <IP of Win02 host> | 192.168.2.0/24 |
Lin01
ip route add 192.168.1.0/24 via <IP of Win01 host>
ip route add 192.168.2.0/24 via <IP of Win02 host>
Win01
docker network create -d transparent --gateway 192.168.1.1 --subnet 192.168.1.0/24 <network name>
# 创建了一个适配器名为"vEthernet (HNSTransparent)"的网桥。将它的 IP 地址设置为传输层网络网关
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 <Interface Id of the Routable Ethernet Adapter> -p
route add 192.168.2.0 mask 255.255.255.0 192.168.2.1 if <Interface Id of the Routable Ethernet Adapter> -p
Win02
docker network create -d transparent --gateway 192.168.2.1 --subnet 192.168.2.0/24 <network name>
# 创建了一个适配器名为"vEthernet (HNSTransparent)"的网桥。将它的 IP 地址设置为传输层网络网关
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 <Interface Id of the Routable Ethernet Adapter> -p
route add 192.168.1.0 mask 255.255.255.0 192.168.1.1 if <Interface Id of the Routable Ethernet Adapter> -p
# 启动集群
要启动你的集群,你需要将基于 Linux 的 k8s 控制面板和基于 Windows Server 的 k8s 节点组件都启动。
# 启动基于 Linux 的 k8s 控制面板
你可以使用喜欢的方式在 Linux 上启动 k8s 集群。请注意,该集群的 CIDR 可能需要更新。
# 启动 Windows 节点组件
要在你的 Windows 节点上启动 kubelet: 在 PowerShell 窗口下运行以下命令。需要注意的是,如果节点重启或进程退出了,你需要重新运行以下命令来重启 kubelet
- 将环境变量 CONTAINER_NETWORK 的值设置为 docker 容器网络
$env:CONTAINER_NETWORK = "<docker network>"
- 使用如下命令运行可执行文件 kubelet kubelet.exe
--hostname-override=<ip address/hostname of the windows node>
--pod-infra-container-image="apprenda/pause"
--resolv-conf=""
--api_servers=<api server location>
要在你的 Windows 节点上启动 kube-proxy: 使用管理员权限在 PowerShell 窗口里运行以下命令。需要注意的是,如果节点重启或进程退出了,你需要重新运行以下命令来重启 kube-proxy。 .\proxy.exe --v=3 --proxy-mode=userspace
--hostname-override=<ip address/hostname of the windows node> ``````--master=<api server location>
--bind-address=<ip address of the windows node>
# 在 Windows 上调度 pod
由于你的集群中既有 Linux 也有 Windows 节点,为了能将 pod 调度到 Windows 节点上,你必须显示地设置 nodeSelector 限制条件。你必须把 nodeSelector 的标签 beta.kubernetes.io/os 的值设置为 windows;请看下面的例子:
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "iis",
"labels": {
"name": "iis"
}
},
"spec": {
"containers": [
{
"name": "iis",
"image": "microsoft/iis",
"ports": [
{
"containerPort": 80
}
]
}
],
"nodeSelector": {
"beta.kubernetes.io/os": "windows"
}
}
}
# 已知限制:
- Windows 系统没有网络命名空间,因此目前只支持一个 pod 上只有一个容器。
- 由于 Windows Server 容器的一个问题,Secrets 目前不可用。
- ConfigMaps 目前还没有实现。
- kube-proxy 的实现使用了 netsh portproxy,由于 netsh portproxy`只支持 TCP,因此只有在客户端使用 TCP 来重试 DNS 查询的时候,DNS 才会有用。
← k8s 垃圾收集 kubectl 概述 →