Please enable Javascript to view the contents

Kubernetes 添加 Windows 节点

 ·  ☕ 4 分钟

这里主要使用 Windows 节点作为 Worker,而 Master 控制平面依然在 Linux 。

1. 系统配置

1.1 Kubernetes 控制平面

Kubernetes 自 1.14 版本,增加了对 Windows 节点生产级的支持。由于微软官方文档主要提供的是 flannel 网络插件的安装方式,这里建议 Kubernetes 也采用 flannel 插件。

  • 查看当前集群 Kubernetes 版本
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"}
  • flannel 配置

在全部节点上启用到 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 。

  • 生成一个 Join Token 用于添加节点
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 的网卡,但我发现并不需要。

  1. 开启 Hyper-v,用于安装 Docker
1
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

重启后,再继续操作。

  1. 开启 RRAS 功能,用于 Pod 跨主机通信

重启后,再继续操作。

2. Windows 节点配置

2.1 安装 Docker

以 Administrator 权限运行 PowerShell 。

  • 安装 Docker
1
2
3
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name docker -ProviderName DockerMsftProvider -Force -RequiredVersion 18.09
Restart-Computer -Force
  • 启动 Docker
1
Start-Service docker
  • 查看 Docker 版本
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 root@your_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:\node\config", [EnvironmentVariableTarget]::User)

再次打开命令行工具才会生效。

2.3 添加 Windows 节点

  • 初始化 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: \etc\kubernetes\pki\ca.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. 创建并查看负载

  • 创建 Deploy
1
kubectl run iis --image=microsoft/iis --overrides='{"spec": { "nodeSelector": { "kubernetes.io/os": "windows" } } }'
  • 创建 Service
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:\var\lib\kubelet\etc\kubernetes\pki\ca.crt 证书拷贝到 C:\var\lib\kubelet\etc\kubernetes\ssl\ca.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:\run\flannel\subnet.env ,增加上面查看到的内容。

4.4 Pod 一直初始化起不来

Windows 系统下的 pause 镜像,并不是通用的,不同版本的系统需要不同的 pause 镜像。在 Kubelet 的启动参数中,可以修改镜像。

编辑 C:\k\StartKubelet.ps1 文件,然后重启 Kubelet 组件。

4.5 安装 KB4489899 补丁

使用 vxlan 模式下的 Flannel 配置虚拟覆盖网络,需要安装 Windows Server 2019 with KB4489899

5. 参考


微信公众号
作者
微信公众号