从零开始在 Windows 上部署 .NET Core 到 Kubernetes

本章节所有代码已上传至:https://github.com/Seanwong933/.NET-Core-on-Kubernetes

文末附有本人遇到过的 Docker 和 k8s 的故障排除。

本文目标:带领大家在 Kubernetes 上部署一个 .NET Core Api 的单节点集群。

后续文章会帮助大家继续深入。

安装 Kubernetes

以下所有命令都要在管理员模式下执行。

  1. 下载安装最新版 Docker for Windows

    https://hub.docker.com/editions/community/docker-ce-desktop-windows

    然后跑一下docker ps看安装成功没有,没有就重启一下你的命令行工具或电脑,环境变量没起作用。

  2. 设置国内镜像 https://registry.docker-cn.com

    640?wx_fmt=png


  3. 下载 docker 镜像并加载

    这一步是为了把 Kubernetes 所需要的依赖镜像先下载到本地,相当于一个加速服务,不过根据我的个人经验,如果你不用这个加速的话基本没可能下得下来,即使你有代理。

    git clone https://github.com/AliyunContainerService/k8s-for-docker-desktop.git
    cd k8s-for-docker-desktop
    .\load_images.ps1
  4. 打开 docker 开启 Kubernetes,等待安装完成

    640?wx_fmt=png

  5. 在 Powershell 中安装 kubectl

    kubectl 简单来说,就是一个操作 Kubernetes 的工具。

    Install-Script -Name install-kubectl -Scope CurrentUser -Force

    然后在类似这样的位置中 E:\文档\WindowsPowerShell\Scripts 找到脚本并执行

    install-kubectl.ps1

    可能会报错,不管,不影响使用。

    或通过 Chocolatey 来安装(推荐)

    Chocolatey 是一个包管理器,没有的同学自己装一下。

    choco install kubernetes-cli
    kubectl version

    如果说找不到,就跑一下choco search kubernetes-clichoco list kubernetes-cli,有时候会抽风。

    进入你的用户目录:cd C:\users\yourusername

    创建.kube目录:mkdir .kube

    进入:cd .kube

    添加配置文件:New-Item config -type file

  6. 此时可以跑一下kubectl get nodeskubectl get services检查安装效果

    640?wx_fmt=png

三大组件:POD & Service & Deployment

在正式开始之前,先粗略一下里面关键组件,如果你看完还是啥也不明白,可以配合这篇文章一起阅读:十分钟带你理解Kubernetes核心概念

640?wx_fmt=png

  • Pod

    Kubernetes 中的最小单元,一个 Pod 里面可以放很多个应用,支持多容器在一个 Pod 中通过进程进行通信

  • Service 服务

    Pod 的对外入口,需要这个才能在外部访问 Pod

  • Deployment 部署

    表示用户对 Kubernetes 的一次更新操作,通过部署模板将 Pod 跟 Service 绑定

粗暴理解,用 Deployment 可以部署 Pod,然后通过 Service 来暴露对 Pod 的访问。

Service 的三种类型

  1. ClusterIP

    一个集群内部服务,默认情况外部无法访问,需要通过 kubectl 的代理命令转发访问。

  2. NodePort

    在所有节点上开放一个特定端口,将该端口的流量转发到对应的服务,是开发时经常使用的暴露 Pod 的方法,没有代理那么麻烦。

  3. LoadBalancer

    Kubernetes 的负载均衡,需要把你的负载均衡器(你集群的负载均衡器或云服务商的)与它关联起来,就可以帮你转发流量了。

安装 Kubernetes Dashboard

顾名思义仪表盘嘛,用来展示 Kubernetes 的各方面数据,也可以做一些比较简单的操作。

找回刚才的 k8s-for-docker-desktop 目录,我们要用里面的配置文件来安装。

kubectl create -f kubernetes-dashboard.yaml

在配置文件中,有一个namespace的配置,指的是你服务的命名空间。

640?wx_fmt=png

然后我们来用命名空间练练手:

kubectl get namespace获取你所有的命名空间

kubectl get deploy -n kube-system命令获取你这个空间下的部署

kubectl get service -n kube-system获取服务的内部地址

640?wx_fmt=png

上面的这些示例命令应该不会有什么问题,接下来输入kubectl proxy,将内部地址通过代理转发出来,就可以看到dashboard了。

如果你没有做什么特殊操作,以下URL应该就能够访问到它:http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login

640?wx_fmt=png

然后我们的dashboard就跑在其中一个pod下:

640?wx_fmt=png

这个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

删除deployservice,再创建一下

kubectl delete deploy kubernetes-dashboard -n kube-system
kubectl delete svc kubernetes-dashboard -n kube-system
kubectl create -f .\kubernetes.dashboard.yaml

这时会提示你有些东西已经存在了,不管就是了。

然后通过kubectl get svc -n kube-system可以看到你的新服务已经部署上去了:

640?wx_fmt=png

这个时候再kubectl proxy访问一下 https://localhost:30003

这里要注意的是,默认分配的443端口也就是默认https,windows下访问会被栏掉而mac下不会,不过这不是重点,学会改NodePort就行了。

额外参考

kubectl命令技巧大全

640?wx_fmt=png

初始化一个 .NET Core API 并 push 到 docker hub

接下来我们放一下Kubernetes,需要先学习一下如何部署一个.NET Core应用到Docker上,并提交到 Docker Hub,毕竟学会了走才能跑。

  1. 创建一个web api

    dotnet new webapi -n k8s-demo
  2. 修改一个action方便看效果,然后本地测试一下看能不能跑通

    // GET api/values/5
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
    return $"你输入的是:{id}";
    }

    640?wx_fmt=png

  3. 创建Dockerfile

    FROM microsoft/dotnet:sdk AS build-env
    WORKDIR /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名称
  4. 在本地运行Docker镜像,注意这里的dockerusername换成你的docker用户名。

    docker run -d -p 8080:80 --name k8s-demo dockerusername/k8s-demo .
  5. 查看效果

    docker ps

    640?wx_fmt=png

    再进入对应的页面看一下:http://127.0.0.1:8080/api/values/5

  6. 登录 docker 以 push 你的镜像,或者你本地登录过直接docker login即可

    docker login --username dockerusername
  7. 推送镜像

    docker push dockerusername/k8s-demo

把 .Net Core API 部署到 Kubernetes

部署文件

还记得之前说的三大组件吗?这个文件就是用来部署 Kubernetes 集群的。

同时,我们这里用的是一个Yaml格式的文件,Yaml是一个可以和Json无缝转换的配置文件类型,字符串不需要加引号,可以自动被识别,字典前带-号,注意Yaml是通过缩进来管理配置节点的子父级的,所以不能随意缩进。

以下是一个标准的 .net core api 的 kubernetes 部署文件,部署DeploymentService两个组件。

---

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

640?wx_fmt=png

打开这个页面试一下:http://localhost:31295/api/values/5

这个时候进入dashboard,可以查看.net core的日志甚至可以执行命令。

640?wx_fmt=png

额外参考

通过 kubectl explain path.to.nodes 查看各个配置文件节点的解释,比如你要看metadata节点下的name节点的解释,就执行kubectl explain metadata.name

到这里就恭喜你已经成功部署了一个 Kubernetes 的单节点集群了,下面我们继续深入介绍一下。

Kubernetes 集群高级概念

640?wx_fmt=png

图左边是 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 调度过程

下图展现了一个完成的调度过程,一步一步来说。

640?wx_fmt=png

  1. kubectl 将创建 Deployment 资源这个命令发送到 API Server ,会先将这个命令保存到ETCD中,验证成功后直接返回,因为这里采用的是异步调用。

  2. 上一步验证完成后,Controller Manager 收到通知

  3. Controller Manager 让 Deployment Controller 创建一个 ReplicaSet(副本)

  4. ReplicaSet Controller 收到通知,创建 Pod

  5. Scheduler 收到通知,将 Pod 分配到 Worker 中某一个合适的 Node 上

  6. 然后 Kubelet 告诉 Docker 我要(根据 Pod)创建容器了,它的镜像是什么,版本是什么

  7. 启动 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 WindowsDocker Toolbox,并混用了 Windows 容器模式跟 Linux 容器模式,用以下方式应该可以解决:

  1. 卸载 Docker for Windows 和 Docker Toolbox

  2. 关闭 Hyper-V 重启

  3. 设备管理器 -> 网络适配器 中卸载所有 Hyper-V 适配器跟 VirtualBox 适配器

  4. 删除所有 AppData 等用户文件夹下的 Docker 相关文件

  5. 清除所有关于 Docker 的环境变量(重要),然后开启 Hyper-V -> 重启 -> 重装Docker for Windows


原文地址:https://siegrain.netlify.com/kubernetes/windows-net-core-kubernetes/

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315738.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core微服务 权限系统+工作流(一)权限系统

一、前言实际上权限系统老早之前我就在一直开发&#xff0c;大概在刚毕业没多久就想一个人写一个系统&#xff0c;断断续续一直坚持到现在&#xff0c;毕竟自己亲动手自写的系统才有收获&#xff0c;本篇仅介绍权限。小小系统上不了台面&#xff0c;望各位大神勿喷。二、系统介…

iNeuOS云操作系统,.NET Core全系打造

一.演示地址演示地址&#xff1a; 进入iNeuOS系统。&#xff08;建议使用chrome浏览器&#xff09;http://192.144.173.38:8081/login.html测试名称&#xff1a;admin测试密码&#xff1a;admin下载《iNeuOS云操作系统演示应用手册》 链接&#xff1a;https://pan.baidu.co…

译 | 你到底有多精通 C# ?

点击上方蓝字关注“汪宇杰博客”文&#xff1a;Damir Arh译&#xff1a;Edi Wang即使是具有良好 C# 技能的开发人员有时候也会编写可能会出现意外行为的代码。本文介绍了属于该类别的几个 C# 代码片段&#xff0c;并解释了令人惊讶的行为背后的原因。Null 值我们都知道&#xf…

各大主流K8S服务全方位能力比对

大家好&#xff0c;趁打开流量主的东风&#xff0c;特此贡献一篇长文&#xff0c;分析一下目前国内国外几大著名云厂商的kubernetes服务&#xff0c;以飨诸君。文起之前&#xff0c;先聊态度。 我本人是十分看好k8s的发展的&#xff0c;为何&#xff1f; 理因古往今来&#xff…

.NET Core 的Generic Host 之Generic Host Builder

通用Host(Generic Host) 与 web Host 不同的地方就是通用Host解耦了Http请求管道&#xff0c;使得通用Host拥有更广的应用场景。比如&#xff1a;消息收发、后台任务以及其他非http的工作负载。这些场景都可以通过使用通用Host拥有横切&#xff08;Cross-cutting&#xff09;的…

.NET Core微服务 权限系统+工作流(二)工作流系统

一、前言接上一篇 .NET Core微服务 权限系统工作流&#xff08;一&#xff09;权限系统 &#xff0c;再来一发工作流&#xff0c;我在接触这块开发的时候一直好奇它的实现方式&#xff0c;翻看各种工作流引擎代码&#xff0c;探究其实现方式&#xff0c;个人总结出来一个核心要…

开源分布式Job系统,调度与业务分离-如何创建一个计划HttpJob任务

项目介绍&#xff1a;Hangfire&#xff1a;是一个开源的job调度系统,支持分布式JOB&#xff01;&#xff01;Hangfire.HttpJob 是我针对Hangfire开发的一个组件,该组件和Hangfire本身是独立的。可以独立更新Hangfire版本不影响&#xff01;该组件已被Hangfire官方采纳&#xff…

Angular 8正式发布!

Angular 团队今天宣布推出 Angular 8 正式版。作为一个期待已久的重大版本更新&#xff0c;Angular 8 为框架、Angular Material 和命令行界面工具 Angular CLI 带来了大量的改进和新功能。团队表示 Angular 8 显著减少了在现代浏览器中应用程序的启动时间、提供了用于定制 CLI…

.NET Core 3.0 webapi集成Swagger 5.0

在项目中引用Swashbuckle.AspNetCore和Swashbuckle.AspNetCore.Filters两个dll&#xff0c;在Startup中的ConfigureServices相关配置代码如下 两个重点&#xff1a;1、options.DocumentFilter<HiddenApiFilter>();定义那些接口方法被隐藏2、启用oauth2安全授权访问…

站点部署,IIS配置优化指南

通常把站点发布到IIS上运行正常后&#xff0c;很少会去考虑IIS提供的各种参数&#xff0c;如何配置才是最适合当前站点运行需要的&#xff1f;这篇文章&#xff0c;从基本设置、回收机制、性能、并发、安全性等IIS设置讲解应当如何优化。先来“IIS应用程序池”优化后的参数配置…

张高兴的.NET Core IoT 入门指南:(四)使用 SPI 进行通信

什么是 SPI和上一篇文章的 I2C 总线一样&#xff0c;SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;也是设备与设备间通信方式的一种。SPI 是一种全双工&#xff08;数据可以两个方向同时传输&#xff09;的串行通信总线&#xff0c;由摩托罗…

ASP.NET Core 中使用IHttpClientFactory发出HTTP请求

1.HttpClient类使用存在的问题HttpClient类的使用所存在的问题&#xff0c;百度搜索的文章一大堆&#xff0c;好多都是单纯文字描述&#xff0c;让人感觉不太好理解&#xff0c;为了更好理解HttpClient使用存在的问题&#xff0c;下面让我们通过代码跟示例来描述。using(var cl…

linux 安装 powershell

linux 安装 powershellIntropowershell 已经推出了一个 Powershell Core&#xff0c; 版本号对应 Powershell 6.x&#xff0c;可以跨平台&#xff0c;支持 Linux 和 mac. 这使得对于熟练使用 Powershell 进行开发运维的一些开发者来说无疑是个福音。PowerShell 和 PowerShell C…

精彩回放 | 玩转 VS Code 物联网开发

"Visual Studio Code&#xff1a;物联网开发利器"技术分享圆满落下帷幕&#xff01;感谢韩老师的粉丝们&#xff01;感谢热情的观众朋友们&#xff01;点击文末阅读原文&#xff0c;可以观看视频回放~这几年物联网越来越火&#xff0c;大家都在说物联网&#xff0c;那…

重磅!开放EasyCharts插件源代码!

开源代码地址https://github.com/EasyChart/EasyCharts前 言不知不觉&#xff0c;Excel图表插件EasyCharts已经面世两年啦&#xff0c;今天突然发现百度网盘中的下载次数居然达到近4万&#xff0c;在这里非常感谢大家对EasyCharts的厚爱。由于工作太忙&#xff0c;时间有限&a…

构建可读性更高的 ASP.NET Core 路由

一、前言不知你在平时上网时有没有注意到&#xff0c;绝大多数网站的 URL 地址都是小写的英文字母&#xff0c;而我们使用 .NET/.NET Core MVC 开发的项目&#xff0c;因为在 C# 中类和方法名采用的是 Pascal 命名规范&#xff0c;根据 .NET 框架默认的路由规则&#xff0c;项目…

【18】ASP.NET Core MVC 中的 Model介绍

ASP.NET Core MVC 中的 Model在本视频中&#xff0c;我们将通过一个示例讨论 ASP.NET Core MVC 中的 Model。我们希望最终从 Student 数据库表中查询特定的学生详细信息并显示在网页上&#xff0c;如下所示。MVC 中的模型包含一组表示数据的类和管理该数据的逻辑。 因此&#x…

使用 Powershell 远程连接 windows server

使用 Powershell 远程连接 windows serverIntro最近我们的开发环境增加了一个 windows 服务器&#xff0c;没有界面的&#xff0c;不能直接远程桌面连上去管理&#xff0c;需要使用 Powershell 管理&#xff0c;于是就有了这篇文章的探索。windows服务器配置以下所有命令需要在…

.NET Core WEB API中接口参数的模型绑定的理解

在.NET Core WEB API中参数的模型绑定方式有以下表格中的几种&#xff1a;微软官方文档说明地址&#xff1a;https://docs.microsoft.com/zh-cn/aspnet/core/web-api/?viewaspnetcore-2.1特性 绑定源[FromHeader]请求标头[FromQuery]请求查询字符串参数[FromForm]请求正文中的…

ASP.Net Core Razor 部署AdminLTE框架

1、AdminLTE一个基于 bootstrap 的轻量级后台模板2、AdminLTE 文档在线中文Demo&#xff1a;http://adminlte.la998.com/在线中文文档&#xff1a;http://adminlte.la998.com/documentation/index.htmlGithub&#xff1a;https://github.com/almasaeed2010/AdminLTE/releases3、…