目录

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

    1. 系统配置

    1.1 Kubernetes 控制平面

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

    • 查看当前集群 Kubernetes 版本
    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 流量

    sysctl net.bridge.bridge-nf-call-iptables=1
    

    配置参数,在 net-conf.json 中添加 VNI 和 Port 端口

    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

    kubectl rollout restart ds kube-flannel-ds-amd64 -n kube-system
    
    • 安装 Windows 的 flannel 和 kube-proxy 相关的 Daemonset
    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
    
    • 查看
    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 用于添加节点
    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
    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
    

    重启后,再继续操作。

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

    重启后,再继续操作。

    2. Windows 节点配置

    2.1 安装 Docker

    以 Administrator 权限运行 PowerShell 。

    • 安装 Docker
    Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
    Install-Package -Name docker -ProviderName DockerMsftProvider -Force -RequiredVersion 18.09
    Restart-Computer -Force
    
    • 启动 Docker
    Start-Service docker
    
    • 查看 Docker 版本
    docker -v
    
    Docker version 18.09.11, build 6112046bc9
    

    2.2 [可选]配置 Kubectl

    • 拷贝 Master 节点的 .kube/config 文件到 Windows 的 C:\node 目录下
    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 目录下

    ls  C:\node
    
    config
    kubectl
    
    • 环境变量配置

    配置组件路径到环境变量

    [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\node", [EnvironmentVariableTarget]::Machine)
    

    配置 kubeconfig 路径到环境变量

    [Environment]::SetEnvironmentVariable("KUBECONFIG", "C:\node\config", [EnvironmentVariableTarget]::User)
    

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

    2.3 添加 Windows 节点

    • 初始化 Windows 节点
    [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
    
    ./PrepareNode.ps1 -KubernetesVersion v1.17.6
    

    如果执行过程中报错,将会很难调试,需要单步执行 PrepareNode.ps1 脚本。

    • 添加节点
    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 。

    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
    kubectl run iis --image=microsoft/iis --overrides='{"spec": { "nodeSelector": { "kubernetes.io/os": "windows" } } }'
    
    • 创建 Service
    kubectl expose deploy iis --type=NodePort --port=80 --target-port=80
    
    • 查看负载
    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 上的镜像和容器
    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
    
    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 :

    docker network ls
    
    NETWORK ID          NAME                DRIVER              SCOPE
    efc374609b5e        nat                 nat                 local
    ed0985e480b1        none                null                local
    

    发现没有 host 网络,由于使用了 Hyper-V,这里不能使用 host 类型的网络,而是 nat 类型名为 host 的网络。

    docker network create -d nat host
    

    4.3 找不到 /run/flannel/subnet.env

    在 master 节点上,执行

    cat /run/flannel/subnet.env
    

    得到子网配置如下:

    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. 参考