涿州城乡建设局网站,中国电建成都设计院,个人网站建设一般流程,浙江网站备案查询最近闲了点#xff0c;写个大活#xff1a;部署Dotnet应用到K8s。写在前边的话一直想完成这个主题。但这个主题实在太大了#xff0c;各种拖延症的小宇宙不时爆发一下#xff0c;结果就拖到了现在。这个主题#xff0c;会是一个系列。在这个系列中#xff0c;我会讨论将应… 最近闲了点写个大活部署Dotnet应用到K8s。 写在前边的话一直想完成这个主题。但这个主题实在太大了各种拖延症的小宇宙不时爆发一下结果就拖到了现在。 这个主题会是一个系列。在这个系列中我会讨论将应用部署到K8s时需要的各个内容和知识以及各种刨过的坑。为了避免这个系列被扩得过大我不深入讨论K8s的技术也不去解释如何建立K8s集群之类的问题。这个主题会侧重在开发人员方面侧重于如何开发适合K8s的应用以及在K8s上部署。另外这个主题也不会关注Docker。在我看来Docker是一个附加技术而不是必要内容。 在项目中是否需要使用K8s算是一个问题。从各个方面来看很多中大型的项目都倾向于往这个方面去做但我们必须清楚使用K8s增加了项目的复杂度。如果构建的是一个独立的应用程序那用K8s实在没有必要。而即便是一个大的系统其实也没有必要从开头就加入K8s。本主题中的内容大多来自我自己部署Dotnet Core到K8s集群的经验。如果有任何问题可以在评论中告诉我。K8sKubernetes面向开发的组件前边说了这个主题我们仅关注部署应用程序相关的部分而不讨论K8s的全部。面向开发面向部署我们需要了解下面几个概念节点NodePod部署Deployment服务Service入口Ingress这几个概念是整个内容的基础。1. 节点Node在K8s中Node对应的是虚拟机或物理硬件是K8s实际运行容器的地方。一般来说有两类节点:主节点Master用来运行所有的控制级Control-plane服务。主节点也可以运行应用程序但一般来说主节点只处理控制管理服务不运行工作负载。其它节点用来运行真正的应用程序。一个节点可以运行多个应用程序或应用程序容器。一个典型的K8s集群会像下面图中的样子当然在实际应用中看K8s的规模。必要时也可以做成单机主节点运行控制服务的同时也运行应用程序。在集群中节点越多可以运行的应用或容器就越多节点宕机时的容错能力也就越大。2. PodK8s中最小的管理单元不是一个个独立的容器而是Pod。要在K8s中运行应用程序需要将其打包到一个容器通常是Docker容器中并让K8s运行它。Pod是可以让K8s运行的最小单元。它包含一个或多个容器。当一个Pod被创建或销毁时它里面的所有容器也会被创建或销毁。 在网上很多的文章都介绍说如果有一个依赖于数据库的应用那应该把应用容器和数据库容器部署在同一个Pod中以便同步创建或销毁。以我的经验来说这个说法很不准确而且容易造成对K8s应用的误解。在K8s的实际应用中只包含单个容器的Pod会更常用也更好用。就好像“支付API”或“订单API”这样的每个API都有不同的扩展需求、部署要求和迭代速度因此单独设置Pod给它们是非常合理的。同样数据库容器也应该部署在独立的Pod中因为它与应用/服务/API会有不同的生命周期。还有一个比较常用的是SideCar模式就是在一个Pod下的主容器旁边部署“SIdeCar“容器用来充当代理为主应用程序进行身份证认处理或服务发现以及服务通讯甚至能充当应用性能监控的接收器来用。一个典型的节点下的Pod是下面的样子再重申一下一个节点下面可以有多个Pod。一个Pod在K8s中会作为一个整体单元进行调度。一个Pod可能包含一个容器也可能包含多个容器。容器用于部署应用或API。3. 部署在我的概念中K8s主要做了两件事管理容器的生存期管理容器之间的通讯K8s的部署主要完成的是第一件事即管理容器的生存周期。所以部署可以看做是定义K8s如何部署Pod以及如果管理Pod的一组规则。比方我们可能这样定义一个部署Pod包含支付API应用Docker映像的一个实例我们要运行这个Pod的三个副本保证每个容器至少有200Mb的可用内存并限制它最多不超过400Mb当我们部署Pod新版本时采用滚动更新策略定义完后K8s就会严格执行这个规则。如果应用崩溃了K8s会删除Pod并安排一个新的Pod以保证规则规定的副本数量。如果Pod需要更多内存K8s会选择一个运行容器较少的节点上运行它或者结束并重新部署它。当应用更新一个新版本时K8s会创建一个新的部署来替换旧版本并将运行转到新的版本。当然上面这个例子做了一定的简化。不过基本上K8s的基本工作就是这么做的。这里的关键就是部署定义了规则K8s在这个部署的整个生命周期中维护并保持这个规则。4. 服务前面说过部署可以用来创建跨多个节点Node的Pod的多个副本。这其实就是K8s提高性能及提高可用性的主要原理。服务是应用对外的部分供其它API去调用。而在K8s内部服务可以看作是Pod在集群内的负载均衡器。当我们创建部署时通常还会创建一个与该应用的Pod关联的服务。在上面的例子中当我们创建部署时也会创建一个“Payment API”的服务供其它API调用。而当其它Pod需要与这个支付API的Pod通讯时实际不会与支付API的一个Pod直接联系而是将请求发给服务然后由服务将请求传递给某一个Pod的实例。这个过程参见下面的图服务与网络相关。因此服务有多种不同的网络模式。这里不详细说了只拿一个常用的模式举个例子K8s将服务分配到一个DNS记录并通过这个记录将请求从一个Pod转发到另一个Pod。假设我们有一个支付服务而我们的购买服务需要调用这个服务。K8s不需要知道Pod的真实IP我们只需要分配一个DNS记录给服务payment-api.xxx.local
通过这个域名购买服务可以调用支付服务而不需要知道支付服务对应的Pod的真正IP。这个工作方式与Dotnet体系完全一样。通过这种方式可以实现对资源的逻辑分组这是题外话。5. 入口入口与服务很像但有本质的不同。服务本质上是K8s集群内部的东西用来实现Pod之间的内部调用。而入口将HTTP/HTTPS从集群外部路由到内部的服务这样外部应用例如前端、APP或小程序就可以通过这个入口调用内部服务来处理请求。同时入口也可以当成提供外部负载均衡即跨多个节点平衡对给定服务的请求。除此之外入口也可以提供其它一些特性例如主机名或基于路径的路由。通常我们可以为每个应用或API配置一个入口。还有入口设置也可以用来做应用的反向代理。例如通过一个Nginx实例来配置入口。这都是可以的而且这样的方式可以让API隐藏在反向代理之后而不用直接暴露在外网。这个部分在后面的文章我会专门写。总结一下这篇文章是这个系列的一个引子。当我们在K8s中部署一个Dotnet Core的应用时我们需要配置Pod部署添加服务来在K8s内部公开这些Pod并添加一个入口来公开服务。本系列的后续文章中我会从开发的各个环节来解释如何使用这些组件来部署Dotnet Core应用到K8s。敬请关注未完待续喜欢就来个三连让更多人因你而受益