Для начала следует разобраться с тем, что нового произошло с тех времен, как я рассказывал о поднятии кластера с Windows узлами:
Мы не будем его использовать в контексте Kubernetes. Нас теперь интересует только ContainerD. Тем не менее удалять Docker рано, т.к. он всё еще нужен для создания образов.
Я расскажу как настроить Kubernetes кластер с узлами на базе Windows Server 2022 и CRI-ContainerD. В качетсве CNI для кластера будет Calico.
Здесь ничего принциписльно не изменилось. Берем чистую Ubuntu 20.04 LTS и качаем пакеты для ContainerD, kubeadm, kubelet и kubectl. Затем с помощью kubeadm разворачиваем кластер. Т.к. Docker мы не устанавливали, то, ожидаему, что в качестве CRI на мастер узле будет ContainerD, который мы установили.
Calico умеет работать в 2 режимах:
Качаем calico.yaml ...
curl https://docs.projectcalico.org/manifests/calico.yaml -O
... и приступаем к модификации:
меняем местами значения переменных CALICO_IPV4POOL_IPIP и CALICO_IPV4POOL_VXLAN
env:
 # Enable IPIP
 - name: CALICO_IPV4POOL_IPIP
   value: "Never"
 # Enable or Disable VXLAN on the default IP pool.
 - name: CALICO_IPV4POOL_VXLAN
   value: "Always"
заменяем calico_backend: "bird" на calico_backend: "vxlan"
kind: ConfigMap
apiVersion: v1
metadata:
  name: calico-config
  namespace: kube-system
data:
  calico_backend: "vxlan"
отключем bird проверки в readiness/liveness пробах.
livenessProbe:
  exec:
    command:
    - /bin/calico-node
    - -felix-live
    # - -bird-live
readinessProbe:
  exec:
    command:
    - /bin/calico-node
    # - -bird-ready
    - -felix-ready
в итоге мы должны получить что-то вот такое. Применяем yaml
kubectl apply -f calico.yaml
Тут можно сделать небольшое отступление, качающееся количества IP адресов на 1 ноду. По умолчанию это всего 64 адреса. Это можно поменять, но об этом потом.
Нам не хватает DaemonSet'ов для Windows узлов. Берем их здесь: https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/calico/calico.yml https://raw.githubusercontent.com/kubernetes-sigs/sig-windows-tools/master/hostprocess/calico/kube-proxy/kube-proxy.yml
А чтобы они (DaemonSet'ы) работали необходимо убедиться что в конфигурации кластера есть вся необходимая информация:
#> kubectl -n kube-system get configmap/kubeadm-config -oyaml
apiVersion: v1
data:
  ClusterConfiguration: |
    apiServer:
      extraArgs:
        authorization-mode: Node,RBAC
      timeoutForControlPlane: 4m0s
    apiVersion: kubeadm.k8s.io/v1beta3
    certificatesDir: /etc/kubernetes/pki
    clusterName: kubernetes
    controllerManager: {}
    controlPlaneEndpoint: 192.168.99.150:6443
    dns: {}
    etcd:
      local:
        dataDir: /var/lib/etcd
    imageRepository: k8s.gcr.io
    kind: ClusterConfiguration
    kubernetesVersion: v1.22.2
    networking:
      dnsDomain: cluster.local
      podSubnet: 10.244.0.0/16
      serviceSubnet: 10.96.0.0/12
    scheduler: {}
kind: ConfigMap
metadata:
  creationTimestamp: "2021-10-24T08:02:20Z"
  name: kubeadm-config
  namespace: kube-system
  resourceVersion: "1168673"
  uid: 396b0bb8-e6ad-4a7a-9611-42538084e1ef
Здесь важно наличие строки controlPlaneEndpoint: 192.168.99.150:6443. Если ее нет (а может не быть), то надо добавить.
Качаем 2 файла:
На момент написания этой статейки, рабочей версией CRI-ContainerD был 1.6.0-beta.1. Запускаем его установку:
Install-Containerd.ps1 -ContainerDVersion 1.6.0-beta.1
Устанавливаем весь необходимый софт (kubelet, kubeadm, ...)
PrepareNode.ps1 -ContainerRuntime containerD -KubernetesVersion 1.22.2
Подлючаемся по SSH к мастеру и получаем токен для добавления узлов в кластер:
sudo kubeadm token create --print-join-command
Получаем что-то похожее на вот это:
kubeadm join 192.168.99.150:6443 --token thmvc8.s7tfy38ej3dcawjt --discovery-token-ca-cert-hash sha256:0c6a4b9bc9f03b32dc133b79c491c6820bbb73f09b4edbeb77e6b55407a774eb
Вспоминаем что при установке ContainerD нас просили добавить --cri-socket "npipe:////./pipe/containerd-containerd" к комманде kubeadm join. Получаем итоговую команду:
kubeadm join 192.168.99.150:6443 --token thmvc8.s7tfy38ej3dcawjt --discovery-token-ca-cert-hash sha256:0c6a4b9bc9f03b32dc133b79c491c6820bbb73f09b4edbeb77e6b55407a774eb --cri-socket "npipe:////./pipe/containerd-containerd"
Выполняем ее и радуемся результату. Все готово.
Результат должен быть примерно таким:
PS C:\Users\v.leschenko> kubectl get nodes -owide
NAME             STATUS   ROLES                  AGE    VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION     CONTAINER-RUNTIME
k8s-linux-1      Ready    control-plane,master   14d    v1.22.2   192.168.99.150   <none>        Ubuntu 20.04.3 LTS             5.4.0-89-generic   containerd://1.4.11
k8s-windows-1    Ready    <none>                 5d1h   v1.22.2   192.168.99.151   <none>        Windows Server 2022 Standard   10.0.20348.320     containerd://1.6.0-beta.1
k8s-windows-2    Ready    <none>                 2d2h   v1.22.2   192.168.99.152   <none>        Windows Server 2022 Standard   10.0.20348.320     containerd://1.6.0-beta.1
PS C:\Users\v.leschenko> kubectl -n kube-system get pods -owide
NAME                                       READY   STATUS    RESTARTS   AGE    IP               NODE             NOMINATED NODE   READINESS GATES
calico-kube-controllers-75f8f6cc59-6krlt   1/1     Running   0          162m   10.244.175.2     k8s-linux-1      <none>           <none>
calico-node-tggf4                          1/1     Running   0          162m   192.168.99.150   k8s-linux-1      <none>           <none>
calico-node-windows-6b8rc                  2/2     Running   0          158m   192.168.99.152   k8s-windows-2    <none>           <none>
calico-node-windows-ptx7m                  2/2     Running   0          136m   192.168.99.151   k8s-windows-1    <none>           <none>
coredns-78fcd69978-qsb9v                   1/1     Running   0          162m   10.244.175.3     k8s-linux-1      <none>           <none>
coredns-78fcd69978-wc5gd                   1/1     Running   0          162m   10.244.175.1     k8s-linux-1      <none>           <none>
etcd-k8s-linux-1                           1/1     Running   0          162m   192.168.99.150   k8s-linux-1      <none>           <none>
kube-apiserver-k8s-linux-1                 1/1     Running   0          162m   192.168.99.150   k8s-linux-1      <none>           <none>
kube-controller-manager-k8s-linux-1        1/1     Running   0          162m   192.168.99.150   k8s-linux-1      <none>           <none>
kube-proxy-windows-9p7xm                   1/1     Running   0          162m   192.168.99.151   k8s-windows-1    <none>           <none>
kube-proxy-windows-rnwtm                   1/1     Running   0          158m   192.168.99.152   k8s-windows-2    <none>           <none>
kube-proxy-x6h4q                           1/1     Running   0          162m   192.168.99.150   k8s-linux-1      <none>           <none>
kube-scheduler-k8s-linux-1                 1/1     Running   0          162m   192.168.99.150   k8s-linux-1      <none>           <none>
metrics-server-559f9dc594-c7vgv            1/1     Running   0          162m   10.244.175.4     k8s-linux-1      <none>           <none>