这里主要使用 Windows 节点作为 Worker,而 Master 控制平面依然在 Linux 。
1. 系统配置
1.1 Kubernetes 控制平面
Kubernetes 自 1.14 版本,增加了对 Windows 节点生产级的支持。由于微软官方文档主要提供的是 flannel 网络插件的安装方式,这里建议 Kubernetes 也采用 flannel 插件。
1
2
3
4
|
kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.6", GitCommit:"d32e40e20d167e103faf894261614c5b45c44198", GitTreeState:"clean", BuildDate:"2020-05-20T13:16:24Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.6", GitCommit:"d32e40e20d167e103faf894261614c5b45c44198", GitTreeState:"clean", BuildDate:"2020-05-20T13:08:34Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
|
在全部节点上启用到 iptables 链的桥接 IPv4 流量
1
|
sysctl net.bridge.bridge-nf-call-iptables=1
|
配置参数,在 net-conf.json 中添加 VNI 和 Port 端口
1
|
kubectl -n kube-system edit cm kube-flannel-cfg
|
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan",
"VNI" : 4096,
"Port": 4789
}
}
重启 flannel
1
|
kubectl rollout restart ds kube-flannel-ds-amd64 -n kube-system
|
- 安装 Windows 的 flannel 和 kube-proxy 相关的 Daemonset
1
2
|
curl -L https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/kube-proxy.yml | sed 's/VERSION/v1.17.6/g' | kubectl apply -f -
kubectl apply -f https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/flannel-overlay.yml
|
1
2
3
4
|
kubectl get all --all-namespaces |grep windows
kube-system daemonset.apps/kube-flannel-ds-windows-amd64 0 0 0 0 0 <none> 34s
kube-system daemonset.apps/kube-proxy-windows 0 0 0 0 0 kubernetes.io/os=windows 36s
|
由于没有 Windows 节点,无法调度相关 Pod ,这里只有 Daemonset 而没有 Pod 。
1
2
3
|
kubeadm token create --print-join-command
kubeadm join 192.168.13.43:6443 --token b29c63.aqvsg0953edz2ozw --discovery-token-ca-cert-hash sha256:529c64ad705bf356a2efa3c1bdb8181b852e2bc5d46f5d161dee1105e872bae6
|
1.2 Windows 节点
对 Windows OS 要求:
- Windows Server Version 1803+
- Docker Version 17.06+
我使用的是 Windows Server 2019 英文版,在运行中执行 winver
可以查看到系统为 1809 版本。有些文档描述需要两张网卡,因为 Flannel 默认会占用一张名为 Ethernet 的网卡,但我发现并不需要。
开启 Hyper-v,用于安装 Docker
1
|
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
|
重启后,再继续操作。
开启 RRAS 功能,用于 Pod 跨主机通信
重启后,再继续操作。
2. Windows 节点配置
2.1 安装 Docker
以 Administrator 权限运行 PowerShell 。
1
2
3
|
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name docker -ProviderName DockerMsftProvider -Force -RequiredVersion 18.09
Restart-Computer -Force
|
1
2
3
|
docker -v
Docker version 18.09.11, build 6112046bc9
|
2.2 [可选]配置 Kubectl
- 拷贝 Master 节点的
.kube/config
文件到 Windows 的 C:node
目录下
1
2
|
mkdir C:/node
scp -r [email protected]_master_host_ip:/root/.kube/config C:/node/config
|
- 下载对应版本的 Kubernetes Windows 节点组件
v1.17.6 的下载地址为: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.17.md#v1176 。下载文件 kubernetes-node-windows-amd64.tar.gz ,解压,找到 bin 目录,拷贝 kubectl 文件到 C:node
目录下
1
2
3
4
|
ls C:node
config
kubectl
|
配置组件路径到环境变量
1
|
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:node", [EnvironmentVariableTarget]::Machine)
|
配置 kubeconfig 路径到环境变量
1
|
[Environment]::SetEnvironmentVariable("KUBECONFIG", "C:nodeconfig", [EnvironmentVariableTarget]::User)
|
再次打开命令行工具才会生效。
2.3 添加 Windows 节点
1
2
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
wget https://github.com/kubernetes-sigs/sig-windows-tools/releases/download/v0.1.2/PrepareNode.ps1 -o PrepareNode.ps1
|
1
|
./PrepareNode.ps1 -KubernetesVersion v1.17.6
|
如果执行过程中报错,将会很难调试,需要单步执行 PrepareNode.ps1 脚本。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
kubeadm join 192.168.13.43:6443 --token b29c63.aqvsg0953edz2ozw --discovery-token-ca-cert-hash
sha256:529c64ad705bf356a2efa3c1bdb8181b852e2bc5d46f5d161dee1105e872bae6
W0613 12:53:11.738383 1576 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
W0613 12:53:13.019694 1576 defaults.go:186] The recommended value for "clusterDNS" in "KubeletConfiguration" is: [10.233.0.10]; the provided value is: [169.254.25.10]
W0613 12:53:13.020730 1576 defaults.go:186] The recommended value for "authentication.x509.clientCAFile" in "KubeletConfiguration" is: etckubernetespkica.crt; the provided value is: /etc/kubernetes/pki/ca.crt
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.17" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "\var\lib\kubelet\config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "\var\lib\kubelet\kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
|
Windows 相关的镜像都很大,需要多等待一会儿才能 Ready 。
1
2
3
4
5
|
kubectl get node -o wide --show-labels
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME LABELS
i-fuu1ub1t Ready <none> 9h v1.17.6 192.168.13.55 <none> Windows Server 2019 Standard 10.0.17763.379 docker://18.9.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows,kubernetes.io/arch=amd64,kubernetes.io/hostname=i-fuu1ub1t,kubernetes.io/os=windows,node.kubernetes.io/windows-build=10.0.17763
node1 Ready master,worker 9h v1.17.6 192.168.13.43 <none> CentOS Linux 7 (Core) 3.10.0-957.21.3.el7.x86_64 docker://19.3.8 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node1,kubernetes.io/os=linux,node-role.kubernetes.io/master=,node-role.kubernetes.io/worker=
|
3. 创建并查看负载
1
|
kubectl run iis --image=microsoft/iis --overrides='{"spec": { "nodeSelector": { "kubernetes.io/os": "windows" } } }'
|
1
|
kubectl expose deploy iis --type=NodePort --port=80 --target-port=80
|
1
2
3
4
5
6
7
8
9
10
11
|
kubectl get pod,deploy,svc -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/iis-5575988c89-cz66z 1/1 Running 0 42m 10.233.65.4 i-fuu1ub1t <none> <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/iis 1/1 1 1 63m iis microsoft/iis run=iis
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/iis NodePort 10.233.23.109 <none> 80:30552/TCP 11m run=iis
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 8h <none>
|
- 查看 Windows Server 上的镜像和容器
1
2
3
4
5
6
7
8
9
|
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23fa7cbbe450 mcr.microsoft.com/k8s/core/pause:1.2.0 "cmd /S /C 'cmd /c p…" 18 seconds ago Up 18 seconds k8s_POD_iis-776c85bc49-9hrn9_default_20a5eac5-9335-4ce6-b4e5-0e1a0fcadc5c_1293
9a8a58dcd2c4 b5fe926a6fe0 "powershell -file /v…" 19 seconds ago Up 16 seconds k8s_kube-proxy_kube-proxy-windows-rtlvf_kube-system_73093c85-a6fa-4da4-a153-c8cb2e0f3ff4_0
23ef060dd278 mcr.microsoft.com/k8s/core/pause:1.2.0 "cmd /S /C 'cmd /c p…" 20 seconds ago Up 19 seconds k8s_POD_kube-proxy-windows-rtlvf_kube-system_73093c85-a6fa-4da4-a153-c8cb2e0f3ff4_788
09b765ebeb13 mcr.microsoft.com/k8s/core/pause:1.2.0 "cmd /S /C 'cmd /c p…" 20 seconds ago Up 20 seconds k8s_POD_iis-5575988c89-cz66z_default_0181697d-8356-463b-8e55-a0183c9cf3fe_736
105f32355a94 9499a92cb176 "powershell -file /e…" 46 seconds ago Up 43 seconds k8s_kube-flannel_kube-flannel-ds-windows-amd64-fgkv8_kube-system_46d18acf-7ff1-4673-aca8-50eba8aac221_0
e08cc8145660 mcr.microsoft.com/k8s/core/pause:1.2.0 "cmd /S /C 'cmd /c p…" 47 seconds ago Up 46 seconds k8s_POD_kube-flannel-ds-windows-amd64-fgkv8_kube-system_46d18acf-7ff1-4673-aca8-50eba8aac221_117
|
1
2
3
4
5
6
7
|
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
sigwindowstools/kube-proxy v1.17.6 b5fe926a6fe0 12 hours ago 5.07GB
microsoft/iis latest 0916eec6d2f2 3 days ago 5.18GB
sigwindowstools/flannel 0.12.0 9499a92cb176 2 months ago 5.06GB
mcr.microsoft.com/k8s/core/pause 1.2.0 a74290a8271a 11 months ago 253MB
|
Windows 镜像真够大的。
4. 可能碰到的一些问题
主要的问题是,现在的大部分文档不具有普适性。也就是,只有在特定的 Windows 、Kubernetes 、Docker 、Network 环境下,才能安装成功,同时会遇到各种各样查不到的错误提示。如果没有比较深入地理解 Kubernetes 的运行机制,整个过程将会非常艰难。
4.1 Kubelet 起不来
在有的版本中,kubelet 一直起不来,需要将 C:varlibkubeletetckubernetespkica.crt 证书拷贝到 C:varlibkubeletetckubernetessslca.art 。
4.2 Network host not found
这是 kubectl describe
的 Event 中出现的一个错误提示。查看 Docker 的 Network :
1
2
3
4
5
|
docker network ls
NETWORK ID NAME DRIVER SCOPE
efc374609b5e nat nat local
ed0985e480b1 none null local
|
发现没有 host 网络,由于使用了 Hyper-V,这里不能使用 host 类型的网络,而是 nat 类型名为 host 的网络。
1
|
docker network create -d nat host
|
4.3 找不到 /run/flannel/subnet.env
在 master 节点上,执行
1
|
cat /run/flannel/subnet.env
|
得到子网配置如下:
1
2
3
4
|
FLANNEL_NETWORK=10.233.64.0/18
FLANNEL_SUBNET=10.233.64.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
|
在 Windows 节点上新建文件 C:runflannelsubnet.env
,增加上面查看到的内容。
4.4 Pod 一直初始化起不来
Windows 系统下的 pause 镜像,并不是通用的,不同版本的系统需要不同的 pause 镜像。在 Kubelet 的启动参数中,可以修改镜像。编辑 C:kStartKubelet.ps1 文件,然后重启 Kubelet 组件。
4.5 安装 KB4489899 补丁
使用 vxlan 模式下的 Flannel 配置虚拟覆盖网络,需要安装 Windows Server 2019 with KB4489899。
5. 参考
- https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/joining-windows-workers
- https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/adding-windows-nodes/
- https://feisky.gitbooks.io/kubernetes/deploy/windows.html
- http://logicalshift.blogspot.com/2019/07/windows-kubernetes-nodes.html
- https://docs.microsoft.com/zh-cn/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows