使用Helm将ASP.NET Core应用程序部署到Kubernetes容器集群

在《容器化单页面应用中RESTful API的访问》以及《容器化单页面应用中Nginx反向代理与Kubernetes部署》两篇文章中,我介绍了一套容器化ASP.NET Core应用程序的方案,并对于Nginx反向代理的使用进行了介绍。在《使用Rancher在Microsoft Azure上搭建Kubernetes集群》一文中,我介绍了一种基于Rancher搭建Kubernetes容器集群的方案,大家会发现,使用Rancher来部署和管理Kubernetes容器集群非常方便。今天,我将结合这三篇文章的内容,将案例程序name-list封装成Helm Chart,然后部署到Kubernetes容器集群中。

要使用Helm来部署我们的案例程序,首先就是要安装Helm。Helm安装分两个步骤,先安装客户端,然后安装它的服务端部件Tiller。Tiller是运行在Kubernetes集群中的,有关Helm和Tiller的基础知识和基本概念,请参考官方文档,本文不会做过多介绍。

安装Helm客户端非常简单,官网上提供了多种安装方式。最简单的方式就是直接到Helm的Github repo,找到所需的版本下载后解压,然后将路径添加到系统的PATH环境变量,即可使用Helm客户端。之后,我们可以使用下面的命令验证客户端是否安装成功:

1

2

3

$ helm version

Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}

Error: could not find tiller

注意:在使用该命令之前,请先确保已经成功部署了Kubernetes,并且~/.kube/config文件中设置了正确的context。有关Kubernetes的部署,请参考《使用Rancher在Microsoft Azure上搭建Kubernetes集群》一文。

上面的命令用于检查Helm的版本,包括客户端版本和服务端Tiller的版本。由于我们还没有安装服务端,因此,提示“Error: could not find tiller”的错误信息。

使用下面的命令创建一个名为tiller的Service Account,然后将其赋予cluster-admin的角色,最后使用该Service Account安装Tiller:


$ kubectl -n kube-system create serviceaccount tiller

$ kubectl create clusterrolebinding tiller \

  --clusterrole=cluster-admin \

  --serviceaccount=kube-system:tiller

$ helm init --service-account tiller

待安装成功后,再次运行helm version,可以看到类似如下的信息,表示Helm以及Tiller安装成功。


$ helm version

Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}

Server: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}

Helm中有几个比较关键的概念,Helm Chart指的是一套应用程序部署的定义,比如一次Helm部署包含哪些Kubernetes的deployment以及service等等;Helm Release则表示一次应用程序的部署。在之前介绍name-list案例的文章中,我使用了docker-compose来组织各个所需的服务及其之间的依赖关系,并使用docker-compose命令行工具来实现整个应用程序的编译、容器化以及容器运行等任务。现在,我们仍然依赖这个docker-compose.yml文件来创建Helm Chart。

首先,到Kubernetes Kompose官方Github repo下载Kompose命令行工具,然后,在docker-compose.yml文件所在的目录中,运行:

1

$ kompose convert -c -o helm

此时,会在docker-compose.yml文件所在目录中,出现一个helm的子目录,然后,在该目录中,会包含Helm Chart相关的目录和文件。以name-list案例为例:

640?wx_fmt=png

  • helm:包含了两个文件和一个子目录:templates

    • Chart.yaml:Helm Chart的定义文件,里面可以指定Helm Chart的名称、描述等

    • README.md:说明文件,可以无视

    • templates目录:该目录下包含了应用程序部署的deployment、service以及ingress的描述文件,也是Helm Chart的主要部分

此外,helm目录下还可以有values.yaml文件,用来定义一些用户可以修改的变量,例如,可以在values.yaml中,使用“serviceTcpPort: 8080”来指定服务的端口号为8080,然后,在template中使用{{ .Values.serviceTcpPort }}来表示需要从values.yaml中读取服务的端口号。在name-list案例中,没有用到values.yaml。

默认情况下,Kompose会将基本的template文件都创建好,然后,还需要根据应用程序的情况进行一些手工调整,比如,将Helm Release的名称作为每个生成的deployment和service的名称前缀就是一个不错的习惯,这就需要手工地对生成的template文件进行调整。比如,在name-list案例中,前端应用的service定义如下:


apiVersion: v1

kind: Service

metadata:

  annotations:

    kompose.cmd: kompose convert -o k8s.deployment.yaml

    kompose.version: 1.18.0 (06a2e56)

  creationTimestamp: null

  labels:

    io.kompose.service: {{ .Release.Name }}-namelist-client

  name: {{ .Release.Name }}-namelist-client

spec:

  ports:

  - name: "80"

    port: 80

    targetPort: 80

  selector:

    io.kompose.service: {{ .Release.Name }}-namelist-client

status:

  loadBalancer: {}

在高亮的几行,使用{{ .Release.Name }}来表示当前Helm Release的名称。因此,对于name-list的前端应用而言,在部署到Kubernetes之后,该前端服务的名称就是{{ .Release.Name }}-namelist-client,虽然在Kubernetes集群中,可以通过这个前缀来区分不同的Helm Release,但对于Nginx来说,它将无法找到这个前端服务,因为目前我们的Nginx配置如下:


events {

    worker_connections 1024;

}

http {

    server {

      listen        80;

      server_name   localhost;

      resolver 127.0.0.11 ipv6=off;

      include  /etc/nginx/mime.types;

      location / {

      }

      location ~ ^/name-service/(.*)$ {

       rewrite ^ $request_uri;

       rewrite ^/name-service/(.*)$ $1 break;

       return 400;

      }

    }

    upstream namelistsvc {

     server namelist-service:5000;

    }

    upstream namelistcli {

     server namelist-client:80;

    }

}

可以看到,在Nginx配置中,前端服务的主机地址被写死成namelist-client了,而在我们的Helm Release中,应该是{{ .Release.Name }}-namelist-client。下面我们来解决这个问题。

解决Nginx中主机名称的问题,可以使用dockerize工具,它的官方Github repo是:https://github.com/jwilder/dockerize。dockerize可以在容器启动的时候,实现模板替换,将容器环境变量的值替换到指定模板文件中。比如,对于Nginx的配置而言,我们可以首先定义一个nginx.conf.tmpl的文件,在其中使用一些模板变量,然后使用dockerize,使其在容器启动时,使用环境变量来替换这些模板变量,于是,容器运行时所使用的nginx.conf文件就是dockerize最终生成的文件。

仍然以name-list为例,首先,定义一个nginx.conf.tmpl文件,内容如下:


server {

  listen        80;

  server_name   localhost;

  include  /etc/nginx/mime.types;

  location / {

  }

  location ~ ^/name-service/(.*)$ {

    rewrite ^ $request_uri;

    rewrite ^/name-service/(.*)$ $1 break;

    return 400;

  }

}

upstream namelistsvc {

  server {{ .Env.RELEASE_NAME }}-namelist-service:5000;

}

upstream namelistcli {

  server {{ .Env.RELEASE_NAME }}-namelist-client:80;

}

其中{{ .Env.RELEASE_NAME }}表示使用RELEASE_NAME环境变量来替换当前位置的值。然后,修改Nginx所在容器的Dockerfile,内容如下:


FROM ubuntu:14.04

ENV DOCKERIZE_VERSION=v0.6.1

# Install Nginx.

# RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C300EE8C

RUN apt-get update

RUN apt-get install -y wget nginx

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

RUN tar -C /usr/local/bin -xvzf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz

ADD nginx.conf.tmpl /etc/nginx/sites-available/default.tmpl

EXPOSE 80

CMD dockerize -template /etc/nginx/sites-available/default.tmpl:/etc/nginx/sites-available/default -stdout /var/log/nginx/access.log -stderr /var/log/nginx/error.log nginx

这个Dockerfile的关键部分就是最后一行,它会调用dockerize命令,将之前编入容器的/etc/nginx/sites-available/default.tmpl文件替换并输出为/etc/nginx/sites-available/default文件。

再看看Nginx的deployment.yaml中,是如何设置这个RELEASE_NAME环境变量的:


apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  annotations:

    kompose.cmd: kompose convert -c -o helm

    kompose.version: 1.18.0 (06a2e56)

  creationTimestamp: null

  labels:

    io.kompose.service: {{ .Release.Name }}-namelist-nginx

  name: {{ .Release.Name }}-namelist-nginx

spec:

  replicas: 1

  strategy: {}

  template:

    metadata:

      creationTimestamp: null

      labels:

        io.kompose.service: {{ .Release.Name }}-namelist-nginx

    spec:

      containers:

      - image: daxnet/namelist-nginx

        name: namelist-nginx

        env:

        - name: RELEASE_NAME

          value: {{ .Release.Name | quote }}

        ports:

        - containerPort: 80

        resources: {}

      restartPolicy: Always

status: {}

由此可见,Helm Release的名称,也就是{{ .Release.Name }}的值,被作为环境变量RELEASE_NAME的值,注入到daxnet/namelist-nginx容器中。

在Chart.yaml所在目录,运行下面的命令,将name-list部署到Kubernetes集群,我们将这次部署命名为myapp:

1

$ helm upgrade --install myapp .

运行结果如下:

640?wx_fmt=png

使用kubectl get pods命令查看所有pod是否正常运行:

640?wx_fmt=png

使用kubectl exec查看Nginx是否正确配置:

640?wx_fmt=png

使用helm list命令,查看我们的Helm Releases:

640?wx_fmt=png

在Microsoft Azure中,找到由Rancher创建的Kubernetes节点虚机,确保80端口已在安全组中打开,然后访问该虚拟机的IP地址,可以看到,我们的name-list案例已经成功运行在Kubernetes集群中:

640?wx_fmt=png

本文主要介绍了使用Helm将ASP.NET Core应用程序部署到Kubernetes容器集群的方法,并对其中遇到的问题进行了概括性描述。事实上,本文所使用的name-list案例是一套集前端、后端以及Nginx于一体的完整案例,代码完全免费开源,地址是:https://github.com/daxnet/name-list。有需要的读者欢迎查阅。

原文链接:https://sunnycoding.cn/2019/10/02/deploying-aspnetcore-apps-to-kubernetes-with-helm/


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

640?wx_fmt=jpeg

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

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

相关文章

微软如何利用机器学习改进Win 10更新体验

微软在 2018 年 4 月 Windows 更新时第一次大规模使用机器学习(ML),ML 通过监测 PC 运行状况的六个核心领域(例如总体可靠性),以确定功能更新过程是否顺利进行。而在 2019 年 5 月发布的更新推送中&#xf…

使用.NET Core创建Windows服务(一) - 使用官方推荐方式

原文:Creating Windows Services In .NET Core – Part 1 – The “Microsoft” Way创建Windows服务来运行批处理任务或者运行后台任务,是一种非常常见的模式,但是由于云服务(Amazon Lambda, Azure WebJobs以及Azure Functions&am…

关于.NET HttpClient方式获取微信小程序码(二维码

随着微信小程序的火热应用,市面上有关小程序开发的需求也多了起来。近来分析了一项生成有关生成微信小程序码的需求——要求扫码跳转到小程序指定页面(带参数);看了下小程序官方文档,以及网上的例子,未看到…

从零开始使用Skywalking分布式链路追踪系统

当我们用很多服务时,各个服务间的调用关系是怎么样的?各个服务单调用的顺序\时间性能怎么样?服务出错了,到底是哪个服务引起的?这些问题我们用什么方案解决呢,以前的方式是各个系统自己单独做日志,出了问题…

快速排序 (Quick Sort)(Java实现)

快速排序(Quicksort)是对冒泡排序的一种改进,借用了分治的思想,由C. A. R. Hoare在1962年提出。 1、基本思想 快速排序的基本思想:挖坑填数分治法。 首先选一个轴值(pivot,也有叫基准的),通过…

使用.net core3.0 正式版创建Winform程序

前阵子一直期待.net core3.0正式版本的出来,以为这个版本出来,Winform程序又迎来一次新生了,不过9.23日出来的马上下载更新VS,创建新的.net core Winform项目,发现并没有Winform窗体设计器。而微软目前则是通过插件的方…

深入理解 ValueTask

.NET Framework 4 里面的命名空间为 System.Threading.Tasks的 Task 类。这个类以及它派生的 Task<TResult> 早已成为编程的主要部分&#xff0c;在 C#5 中的异步编程模式当作介绍了 async/await。在这篇文章里&#xff0c;我会覆盖新的类 ValueTask / ValueTask<TRes…

NET Core 3.0 AutoFac替换内置DI的新姿势

.NET Core 3.0 和 以往版本不同&#xff0c;替换AutoFac服务的方式有了一定的变化&#xff0c;在尝试着升级项目的时候出现了一些问题。原来在NET Core 2.1时候&#xff0c;AutoFac返回一个 IServiceProvider 参数注入到ConfigureServices .NET Core 服务中&#xff0c;基本大痣…

asp.net core 使用Mysql和Dapper

序曲&#xff1a;学习编程最好的方式就是敲代码&#xff0c;没有比这个更好的方法&#xff0c;哪怕你看了上百G的视频&#xff0c;都不如你自己敲几行代码更为有效。还有要记得敲完代码然后写一篇随笔来记录一下你所学所想。大家都知道&#xff0c;.netcore是微软一个具有历史意…

CSFR(跨站请求伪造)攻击与防御

一、CSRF是什么&#xff1f; CSRF&#xff08;Cross-site request forgery&#xff09;&#xff0c;中文名称&#xff1a;跨站请求伪造&#xff0c;也被称为&#xff1a;one click attack/session riding&#xff0c;缩写为&#xff1a;CSRF/XSRF。 二、CSRF可以做什么&#…

Vue 3源码公布

10 月 5 日凌晨&#xff0c;Vue.js 框架的作者兼核心开发者尤雨溪公布了尚处于 Pre-Alpha 状态的 Vue 3 源码。说学不动的童鞋抓紧剩余的假期时间撸一遍源码吧 : D作者表示&#xff0c;Vue 3 主要的架构改进、优化和新功能均已完成&#xff0c;剩下的主要任务是完成一些 Vue 2 …

在副业刚需的时代,如何掌握副业的正确姿势?

前言近期&#xff0c;伴随着“副业刚需”这个词语的流行&#xff0c;关于“职场人要不要发展副业”的话题再一次被炒得沸沸扬扬。有人认为副业是刚需&#xff0c;是抵御中年危机的锦囊妙计&#xff0c;甚至是中年人该有的自觉&#xff0c;没有副业的人不足以谈人生&#xff0c;…

使用.NET Core创建Windows服务(二) - 使用Topshelf方式

原文&#xff1a;Creating Windows Services In .NET Core – Part 2 – The “Topshelf” Way作者&#xff1a;Dotnet Core Tutorials译者&#xff1a;Lamond Lu译文&#xff1a;使用.NET Core创建Windows服务&#xff08;二&#xff09; - 使用Topshelf方式使用.NET Core创建…

常用加密算法(Java实现)总结

1、Java的安全体系架构 Java中为安全框架提供类和接口。JDK 安全 API 是 Java 编程语言的核心 API&#xff0c;位于 java.security 包&#xff08;及其子包&#xff09;&#xff0c;以及sun.securityAPI包&#xff08;及其子包&#xff09;中。设计用于帮助开发人员在程序中同…

怎样的项目才能称为“成功项目”?

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区合伙人&#xff01;引子这个故事讲的是一家拥有百年历史的制造业大厂的信息化转型过程中的波折。这家企业拥有超过三万名员工&#xff0c;它是某行业的领先品牌&#xff0c;但是在信息化程度上却…

彩虹表

一、简介 彩虹表就是一个庞大的、针对各种可能的字母组合预先计算好的哈希值的集合&#xff0c;不一定是针对MD5算法的&#xff0c;各种算法的都有&#xff0c;有了它可以快速的破解各类密码。越是复杂的密码&#xff0c;需要的彩虹表就越大&#xff0c;现在主流的彩虹表都是1…

深入Dapper.NET源码

经过业界前辈、StackOverflow多年推广,「Dapper搭配Entity Framework」成为一种功能强大的组合,它满足「安全、方便、高效、好维护」需求。但目前中文网路文章,虽然有很多关于Dapper的文章但都停留在如何使用,没人系统性解说底层原理。所以有了此篇「深入Dapper源码」想带大家进…

DDoS攻击与防御

一、DDOS介绍 要了解DDOS攻击是什么&#xff0c;首先要了解DOS攻击的基本原理是至关重要的。 DoS攻击是最早出现的&#xff0c;它的攻击方法说白了就是单挑&#xff0c;是比谁的机器性能好、速度快。但是现在的科技飞速发展&#xff0c;一般的网站主机都有十几台主机&#xf…

DRDoS(memcache漏洞导致的反射型分布式拒绝服务攻击)

一、DDoS基础 见博文&#xff1a;DDoS攻击与防御 二、Memcached 反射DDOS攻击原理 反射DDOS是发送大量带有被害者IP地址的请求给反射服务器&#xff0c;反射服务器对IP地址源做出大量回应&#xff0c;形成拒绝服务攻击。CLOUDFLARE的这张图很好的解释了DDOS反射攻击过程&…

田牌魔术 | .NET Core 3.0 + Azure 远程点亮树莓派上的一盏灯

点击上方蓝字关注“汪宇杰博客”导语3年前&#xff0c;我写过一篇《Windows 10 IoT Core Azure 远程控制LED》&#xff0c;实现了《生活大爆炸》中的注孤生实验&#xff0c;让信号从家里出发&#xff0c;绕地球转一圈&#xff0c;经过微软美国数据中心&#xff0c;返回家里点亮…