Kubernetes for Windows 實做

提醒:本篇文章包含很多 Kubernetes 技術名詞與步驟。因為筆者用 Kubernetes 有一段時間了,如果解釋不夠,歡迎留言互動。

承 Kubernetes for Windows 心得文章,筆者在這分享 Kubernetes for Windows 實做。本篇文章包含下述主題。

架構

Kubernetes for Windows 組成如下:

筆者在這提醒,不是掛著 Windows 名稱就不用 Linux OS 了,Kubernetes 許多原件仍然是跑在 Linux OS 的 Control Plane,再者神奇的 gMSA 其中一個服務也是跑在 Linux node 上,所以古早年代純 Windows 環境已經不存在了,連 Microsoft 也在大力的擁抱 Linux 中。這就是為什麼筆者會用 Kubernetes for Windows 技術名詞,不會用 Windows Kubernetes,因為前者更能代表原來的 Kubernetes 加上 Windows node。

有關於 Kubernetes components 介紹可以參考官方文件(註一)。筆者在這篇文章將主要介紹 Windows node 上 Kubernetes components 是怎麼運作的。

一個 Windows node 要可以運作需要二個 Kubernetes 元件 kubelet, kube-proxy 與一個 network add-on (註二)。

kubelet,在 Windows node 是用 service 方式在 Cluster 內的每一台 node 運作,讀者可以透過 PowerShell command 如下得到狀態。根據官方文件 kubelet 是確保 PodSpecs 有 container 的記錄,以及確保 Container 是 running and healthy,由此可見 Container 的管理就是透過 kubelet。

get-service kubelet

kube-proxy,筆者在 1.14 版時,kube-proxy 如同 kubelet 一樣是用 service 方式在 Cluster 內的每一台 Windows node 運行,到了 1.16 OR 1.18 版之後,kube-proxy 就是以 Pod 的方式運作,這相對簡單非常的多,也就是說 kubelet service 有問題時,kube-proxy 就不會正常的運作。kube-proxy 主要是維護 Kubernetes network policy,這些 network policy 允許 Cluster 內部與 Cluster 外部可以跟 Pod 溝通。

Network add-on,有了 kube-proxy 後,node 與 node 之間就知道怎麼分配網路資源,但跨 node 的 Pod 與 Pod 之間要真正連接就需要 Network add-on 來實作。目前筆者建議地端的 Kubernetes 用 flannel network add-on,至於雲端 Kubernetes 就依照供應商方案。

安裝

Kubernetes for Windows 的安裝,筆者分為下述二部份:

雲端供應商 Kubernetes for Windows

雖然筆者有在用 KOps (一種運作在 AWS 上的 Kubernetes),但筆者目前只實做 EKS for Windows,等未來有機會接觸到 KOps for Windows,筆者會另外寫一篇介紹。

回到在 EKS 上要實做 Windows 其實非常的簡單,筆者建議可以透過 eksctl (一種 AWS 提供的 EKS cli)實做,過去筆者在 1.14 版時有嚐試過 CloudFormation,但那真的是吃裡不討好的做法。另外如果要實作 gMSA 就有點難度了,因為這會需要實做 Windows node auto join AD domain 來搭配 Node AutoScaling,而相關的介紹筆者將會在 gMSA for your Windows Container 文章中介紹,本篇只專注在如何建立 Windows node,其步驟如下:

eksctl create nodegroup \
--cluster=$CLUST_NAME \
--name $NODE_NAME \
--node-ami-family WindowsServer2019CoreContainer \
--node-type=t3.large \
--nodes-min=1 \
--nodes-max=1 \
--node-private-networking \
--ssh-public-key=$SSHKEY \
--node-volume-size=100 \
--asg-access \
--external-dns-access \
--full-ecr-access \
--alb-ingress-access
eksctl utils install-vpc-controllers --name=$CLUST_NAME --approve
aws eks  — region $YOUR_REGION update-kubeconfig  — name $CLUST_NAME
kubectl get nodes

地端 Kubernetes for Windows

地端的安裝方法相對雲端困難很多,如果要做到 Multiple Control Plane 難度又增加了一點,如果安裝的環境又要指定 http proxy 才能對外連線,那難度就更大了。關於要怎麼要怎麼安裝原生 Kubernetes,筆者會寫一篇文章介紹,這邊讀者可以用下面的步驟清單確認安裝好 Control Plane & Linux node。

Docker service

Control Plane (google search the following action, or refer to 註三)

kubeadm init --pod-network-cidr=172.31.0.0/16 --service-cidr=172.30.0.0/16 --kubernetes-version=1.18.6
kubectl apply -f kube-flannel.yml

Linux node,在完成上述的 Control Plane 後就可以安裝 Linux node

kubeadm token create --print-join-command
kubeadm join {API SERVER} --token XXXXXXXXXXXXXXXX --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxx

Docker for Windows,在完成上述的 Control Plane node 與 Linux node 安裝後就可以開始 Windows node。

Windows node,筆者很建議要用 Windows Server Core,筆者從 1.14 開始用 Windows node,當時步驟更為複雜。

netsh firewall set opmode mode=disable
docker pull sigwindowstools/kube-proxy:v1.18.6
docker pull sigwindowstools/flannel:0.12.0
docker pull mcr.microsoft.com/windows/nanoserver:1809
docker tag mcr.microsoft.com/windows/nanoserver:1809 microsoft/nanoserver:latest
docker run microsoft/nanoserver:latest
docker pull mcr.microsoft.com/k8s/core/pause:1.2.0
kubectl apply -f kube-flannel-overlay.yml
kubectl apply -f kube-proxy-win.yml
Install-WindowsFeature RSAT-AD-PowerShell
Install-Module -Name CredentialSpec
Rename-NetAdapter "Ethernet0" -NewName Ethernet -ErrorAction SilentlyContinue
Get-NetAdapter | ? {$_.name -ne "Ethernet"} | Disable-NetAdapter
mkdir c:\k
kubeadm token create --print-join-command
powershell -command "if((docker network ls) -match 'host                nat'){$null}else{docker network create -d nat host}"
kubectl get nodes

驗證

在驗證之前讀者需要安裝 kubectl 在你的電腦裡,你才能操作 Kubernetes Cluster,並且需要把複製 kubeconfig 內容檔案到你的電腦 ~/.kube/config 裡,在這筆者非常推廌 Kubernetes Lensapp,它是一套非常容易上手的 Kubernetes IDE app,它支援 Windows Desktop, MacOS, Linux Desktop。

在安裝完 Windows node 後,是時來佈署一個簡單的 Web on Windows Pod。

kubectl apply -f aspnet.yaml
# get pods
kubectl get pods
# output
NAME READY STATUS RESTARTS AGE
aspnet-56887957d-4m5xg 0/1 ContainerCreating 0 10m
# describe pods
kubectl describe pods aspnet-56887957d-4m5xg
# output
Name: aspnet-56887957d-4m5xg
Namespace: default
Priority: 0
Node: <Windows NODE NAME>
Start Time: Sat, 28 Nov 2020 11:43:56 +0800
Labels: app=aspnet
pod-template-hash=56887957d
Annotations: <none>
Status: Pending
IP:
Controlled By: ReplicaSet/aspnet-56887957d
Containers:
aspnet:
Container ID:
Image: mcr.microsoft.com/dotnet/framework/aspnet:4.8
Image ID:
Port: 80/TCP
Host Port: 0/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-72dc8 (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-72dc8:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-72dc8
Optional: false
QoS Class: BestEffort
Node-Selectors: beta.kubernetes.io/os=windows
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/aspnet-56887957d-4m5xg to xx-xxx-xxxxxx
Normal Pulling 10m kubelet, xx-xxx-xxxxxx Pulling image "mcr.microsoft.com/dotnet/framework/aspnet:4.8"
# get pods
kubectl get pods
# output
NAME READY STATUS RESTARTS AGE
aspnet-56887957d-4m5xg 1/1 Running 0 15m
# get servicekubectl get service# outputNAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
aspnet NodePort 172.30.2.14 <none> 80:31114/TCP 19m

實做心得

筆者第一次實做 Windows node 是 1.14 版本,當時的 Windows node 的安裝方法比 1.18 版本複雜很多,現在 Windows node 可以跟 Linux node 一樣的用 kubeadm join 加入 Cluster 相信是很多人的付出才有這樣的便利。

在完成 Windows node 後,接下來的挑戰就是如何佈署 Windows Application 到 Kubernetes,並且集中 Windows Container log ,有關 Application 方面的探討筆者會另外寫一個 Kubernetes for Windows Application 篇。

至於真的需要 Windows node 嗎?這個問題其實要讀者們自行評估,筆者自己的 Cluster 是混合模式,因為 Windows 仍然有像 gMSA 這個優點,是 Linux node 沒有的,筆者在這是把過去所學與所遭遇到一一分享各位。

參考與註釋

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store