从零开始在 Windows 上部署 .NET Core 到 Kubernetes
本章節所有代碼已上傳至:https://github.com/Seanwong933/.NET-Core-on-Kubernetes
文末附有本人遇到過的 Docker 和 k8s 的故障排除。
本文目標:帶領大家在 Kubernetes 上部署一個 .NET Core Api 的單節點集群。
后續文章會幫助大家繼續深入。
安裝 Kubernetes
以下所有命令都要在管理員模式下執行。
下載安裝最新版 Docker for Windows
https://hub.docker.com/editions/community/docker-ce-desktop-windows
然后跑一下docker ps看安裝成功沒有,沒有就重啟一下你的命令行工具或電腦,環境變量沒起作用。
設置國內鏡像?https://registry.docker-cn.com
下載 docker 鏡像并加載
這一步是為了把 Kubernetes 所需要的依賴鏡像先下載到本地,相當于一個加速服務,不過根據我的個人經驗,如果你不用這個加速的話基本沒可能下得下來,即使你有代理。
git clone https://github.com/AliyunContainerService/k8s-for-docker-desktop.gitcd k8s-for-docker-desktop
.\load_images.ps1
打開 docker 開啟 Kubernetes,等待安裝完成
在 Powershell 中安裝 kubectl
kubectl 簡單來說,就是一個操作 Kubernetes 的工具。
Install-Script -Name install-kubectl -Scope CurrentUser -Force然后在類似這樣的位置中?E:\文檔\WindowsPowerShell\Scripts?找到腳本并執行
install-kubectl.ps1可能會報錯,不管,不影響使用。
或通過 Chocolatey 來安裝(推薦)
Chocolatey 是一個包管理器,沒有的同學自己裝一下。
choco install kubernetes-clikubectl version
如果說找不到,就跑一下choco search kubernetes-cli和choco list kubernetes-cli,有時候會抽風。
進入你的用戶目錄:cd C:\users\yourusername
創建.kube目錄:mkdir .kube
進入:cd .kube
添加配置文件:New-Item config -type file
此時可以跑一下kubectl get nodes、kubectl get services檢查安裝效果
三大組件:POD & Service & Deployment
在正式開始之前,先粗略一下里面關鍵組件,如果你看完還是啥也不明白,可以配合這篇文章一起閱讀:十分鐘帶你理解Kubernetes核心概念
Pod
Kubernetes 中的最小單元,一個 Pod 里面可以放很多個應用,支持多容器在一個 Pod 中通過進程進行通信
Service 服務
Pod 的對外入口,需要這個才能在外部訪問 Pod
Deployment 部署
表示用戶對 Kubernetes 的一次更新操作,通過部署模板將 Pod 跟 Service 綁定
粗暴理解,用 Deployment 可以部署 Pod,然后通過 Service 來暴露對 Pod 的訪問。
Service 的三種類型
ClusterIP
一個集群內部服務,默認情況外部無法訪問,需要通過 kubectl 的代理命令轉發訪問。
NodePort
在所有節點上開放一個特定端口,將該端口的流量轉發到對應的服務,是開發時經常使用的暴露 Pod 的方法,沒有代理那么麻煩。
LoadBalancer
Kubernetes 的負載均衡,需要把你的負載均衡器(你集群的負載均衡器或云服務商的)與它關聯起來,就可以幫你轉發流量了。
安裝 Kubernetes Dashboard
顧名思義儀表盤嘛,用來展示 Kubernetes 的各方面數據,也可以做一些比較簡單的操作。
找回剛才的 k8s-for-docker-desktop 目錄,我們要用里面的配置文件來安裝。
kubectl create -f kubernetes-dashboard.yaml在配置文件中,有一個namespace的配置,指的是你服務的命名空間。
然后我們來用命名空間練練手:
用kubectl get namespace獲取你所有的命名空間
用kubectl get deploy -n kube-system命令獲取你這個空間下的部署
用kubectl get service -n kube-system獲取服務的內部地址
上面的這些示例命令應該不會有什么問題,接下來輸入kubectl proxy,將內部地址通過代理轉發出來,就可以看到dashboard了。
如果你沒有做什么特殊操作,以下URL應該就能夠訪問到它:http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login
然后我們的dashboard就跑在其中一個pod下:
這個dashboard的訪問地址很長,所以接下來要把它配置成NodePort轉發出來。
把剛才的配置文件搞下來,找到最后一坨,把帶注釋的兩句加進去:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kube-system spec: type: NodePort ports: - port: 443 targetPort: 8443 nodePort: 30003 selector: k8s-app: kubernetes-dashboard |
刪除deploy和service,再創建一下
kubectl delete deploy kubernetes-dashboard -n kube-systemkubectl delete svc kubernetes-dashboard -n kube-system
kubectl create -f .\kubernetes.dashboard.yaml
這時會提示你有些東西已經存在了,不管就是了。
然后通過kubectl get svc -n kube-system可以看到你的新服務已經部署上去了:
這個時候再kubectl proxy訪問一下?https://localhost:30003
這里要注意的是,默認分配的443端口也就是默認https,windows下訪問會被欄掉而mac下不會,不過這不是重點,學會改NodePort就行了。
額外參考
kubectl命令技巧大全
初始化一個 .NET Core API 并 push 到 docker hub
接下來我們放一下Kubernetes,需要先學習一下如何部署一個.NET Core應用到Docker上,并提交到 Docker Hub,畢竟學會了走才能跑。
創建一個web api
dotnet new webapi -n k8s-demo修改一個action方便看效果,然后本地測試一下看能不能跑通
// GET api/values/5[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return $"你輸入的是:{id}";
}
創建Dockerfile
FROM microsoft/dotnet:sdk AS build-envWORKDIR /app
EXPOSE 80
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "k8s-demo.dll"] # 注意這里改一下dll名稱
在本地運行Docker鏡像,注意這里的dockerusername換成你的docker用戶名。
docker run -d -p 8080:80 --name k8s-demo dockerusername/k8s-demo .查看效果
docker ps再進入對應的頁面看一下:http://127.0.0.1:8080/api/values/5
登錄 docker 以 push 你的鏡像,或者你本地登錄過直接docker login即可
docker login --username dockerusername推送鏡像
docker push dockerusername/k8s-demo把 .Net Core API 部署到 Kubernetes
部署文件
還記得之前說的三大組件嗎?這個文件就是用來部署 Kubernetes 集群的。
同時,我們這里用的是一個Yaml格式的文件,Yaml是一個可以和Json無縫轉換的配置文件類型,字符串不需要加引號,可以自動被識別,字典前帶-號,注意Yaml是通過縮進來管理配置節點的子父級的,所以不能隨意縮進。
以下是一個標準的 .net core api 的 kubernetes 部署文件,部署Deployment跟Service兩個組件。
---kind: Deployment # 組件類型
apiVersion: apps/v1
metadata:
name: hello-api
namespace: netcore # 可指定,不指定時使用默認命名空間
labels:
name: hello-api
spec:
replicas: 2 # 部署兩份叫 hello-api 的容器
selector:
matchLabels:
name: hello-api
template:
metadata:
labels:
name: hello-api
spec:
containers:
- name: hello-api
image: yourdockername/k8s-demo # docker hub 中的鏡像名稱,修改為你的鏡像名稱
ports:
- containerPort: 80
imagePullPolicy: Always
---
kind: Service
apiVersion: v1
metadata:
name: hello-api
namespace: netcore
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
selector:
name: hello-api # 對應要映射的Pod
我們將它命名為deploy.yaml,記住修改yourdockername/k8s-demo為你的鏡像名稱。
然后執行部署命令。
kubectl create -f deploy.yaml如果這里指定了不存在的namespace要用kubectl create namespace命令創建。
查看URL,我的namespace就叫netcore
kubectl get svc -n netcore打開這個頁面試一下:http://localhost:31295/api/values/5
這個時候進入dashboard,可以查看.net core的日志甚至可以執行命令。
額外參考
通過?kubectl explain path.to.nodes?查看各個配置文件節點的解釋,比如你要看metadata節點下的name節點的解釋,就執行kubectl explain metadata.name
到這里就恭喜你已經成功部署了一個 Kubernetes 的單節點集群了,下面我們繼續深入介紹一下。
Kubernetes 集群高級概念
圖左邊是 Master 控制節點,右邊是 Worker 工作節點。
Master部分
從上到下依次來說
kubectl → authentication → REST(apiserver)
這一個流程是用戶交互、認證、然后調用 Kubernetes 各種接口的一個流程(kubectl xxx)
ETCD
右下角的ETCD是一個分布式數據庫,負責保存整個 Kubernetes 集群的狀態
scheduler
負責調度,比如創建一個 Pod,找一個負載低一點的 CPU 存儲,而 ETCD 是只知道存儲,但不知道存哪兒好,所以需要 Scheduler 來調度一下
controller manager
負責維護集群的狀態,比如故障檢測、自動擴展、滾動更新等
Worker部分
Node
表示集群中的一個主機單元,可以是物理機也可以是虛擬機
kubelet
kubernetes 與 docker 的交互組件,負責容器的各種操作、生命周期等
Proxy
Proxy 負責網絡轉發
Pod
這個不用多說,就是你創建的一個個容器
而以上的這些組件,其實也都是 docker 的鏡像,跑一下docker images就能看見各個組件的鏡像。
還有些圖上沒有的,比如 container runtime,負責鏡像管理和容器的真正運行。
Kubernetes 調度過程
下圖展現了一個完成的調度過程,一步一步來說。
kubectl 將創建 Deployment 資源這個命令發送到 API Server ,會先將這個命令保存到ETCD中,驗證成功后直接返回,因為這里采用的是異步調用。
上一步驗證完成后,Controller Manager 收到通知
Controller Manager 讓 Deployment Controller 創建一個 ReplicaSet(副本)
ReplicaSet Controller 收到通知,創建 Pod
Scheduler 收到通知,將 Pod 分配到 Worker 中某一個合適的 Node 上
然后 Kubelet 告訴 Docker 我要(根據 Pod)創建容器了,它的鏡像是什么,版本是什么
啟動 Containers
可以看到整個 Kubernetes 調度基本全都是在 Master 節點在做的,所以 Master 節點絕對不能掛。
下面大概介紹一下,一套 Kubernetes 高可用集群大概是什么樣的:
后續文章會繼續教大家深入 Kubernetes。
額外章節:故障排除
Unable to create: 已停止該運行的命令,因為首選項變量“ErrorActionPreference”或通用參數設置為 Stop: 對象已存在。
當你的 Docker 運行在 linux 容器模式下就可能會報這個錯誤。
| Unable to create: 已停止該運行的命令,因為首選項變量“ErrorActionPreference”或通用參數設置為 Stop: 對象已存在。 在 Docker.Core.Pipe.NamedPipeClient.Send(String action, Object[] parameters) 位置 C:\workspaces\stable-18.09.x\src\github.com\docker\pinata\win\src\Docker.Core\pipe\NamedPipeClient.cs:行號 36 在 Docker.Actions.DoStart(SynchronizationContext syncCtx, Boolean showWelcomeWindow, Boolean executeAfterStartCleanup) 位置 C:\workspaces\stable-18.09.x\src\github.com\docker\pinata\win\src\Docker.Windows\Actions.cs:行號 92 在 Docker.Actions.<>c__DisplayClass19_0.<Start>b__0() 位置 C:\workspaces\stable-18.09.x\src\github.com\docker\pinata\win\src\Docker.Windows\Actions.cs:行號 74 在 Docker.WPF.TaskQueue.<>c__DisplayClass19_0.<.ctor>b__1() 位置 C:\workspaces\stable-18.09.x\src\github.com\docker\pinata\win\src\Docker.WPF\TaskQueue.cs:行號 59 |
解決方案:執行以下命令
| MOFCOMP %SYSTEMROOT%\System32\WindowsVirtualization.V2.mof |
或刪掉、卸載、禁用所有 在設備管理器 -> 網絡適配器下的 Hyper-V 虛擬網絡適配器。
參考地址:
https://github.com/docker/for-win/issues/1538
https://community.spiceworks.com/how_to/122307-fix-error-managing-hyper-v-server-2012-r2-from-windows-10
執行 docker ps 等命令時彈出:error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.26/containers/json: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.
報這個有很多原因,有可能是你混裝了Docker for Windows和Docker Toolbox,并混用了 Windows 容器模式跟 Linux 容器模式,用以下方式應該可以解決:
卸載 Docker for Windows 和 Docker Toolbox
關閉 Hyper-V 重啟
設備管理器 -> 網絡適配器 中卸載所有 Hyper-V 適配器跟 VirtualBox 適配器
刪除所有 AppData 等用戶文件夾下的 Docker 相關文件
清除所有關于 Docker 的環境變量(重要),然后開啟 Hyper-V -> 重啟 -> 重裝Docker for Windows
原文地址:https://siegrain.netlify.com/kubernetes/windows-net-core-kubernetes/
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?
總結
以上是生活随笔為你收集整理的从零开始在 Windows 上部署 .NET Core 到 Kubernetes的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS Code 即将迎来再一次的 log
- 下一篇: iNeuOS云操作系统,.NET Cor