前言

容器化对现在(0202年)来说,已经不算是什么新东西了,老黄最近也在公司推动这一块的发展,有幸落地了几个项目,有.NET Core的,也有.NET Framework的。

容器化现在主流的就是docker,说到docker,51%的概率是离不开kubernetes的。

当容器数量不多的时候,可以考虑人工+半自动化的方式维护。

当容器数量多了的话,不言而喻是需要引入容器编排的利器。

这也算是一个渐进的过程吧。

下面来看看基于 Serverless Kubernetes 的简单实践(不会介绍kubernetes的相关内容哈)。

为什么选择 Serverless Kubernetes

国内云产商基本都会有提供多个版本的Kubernetes让我们自己选择,有的公司可能能力强,一套打包带走。

老黄这边选择的是 Serverless 版的,Serverless 可以说是比较火的一个概念,也可以说是真正的云原生所应该有的基本形态。

当然老黄做出这个决定还有一个更重要的原因,不用自己维护服务器,可以更加专注自身的业务,只需要交付打包好的镜像即可。

毕竟老黄公司没有运维,已经充当半个运维了,不想让自己累趴。。

相信这个是大部分中小型公司一个比较ok的选择。

准备镜像

这里会写两个简单Web Api项目用来演示,一个.NET Core的,一个.NET Framework的。

其中.NET Core会暴露给集群外部访问,.NET Framework只在集群内部访问,同时.NET Core还会调用.NET Framework的接口。

.NET Framework

代码的话就是一个默认的ValuesController。

public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2", "nfx in k8s" };
}
}

知道.NET Framework可以基于jexus跑在Linux下面的话,应该就知道要怎么打包制作镜像了。

可以直接用 beginor 做好的镜像 beginor/jexus-x64:6.2.1.12。

ps: 老黄这边是因为有不少项目需要用到图片,所以是自己单独弄了一个,加了libgdiplus 等一些必备的东西进去。

先准备一个jexus的配置文件,这里用的是最简单的。

port=80
root=/ /app
hosts=*

然后就是Dockerfile了

# 按需替换
FROM jexus-x64-img:6.1 AS base
# FROM beginor/jexus-x64:6.2.1.12 AS base FROM mono:6.8 AS build
WORKDIR /src
COPY . .
# 还原nuget包
RUN nuget restore ServerlessNetApp.sln -Source https://api.nuget.org/v3/index.json
# 编译
RUN msbuild NfxApi/NfxApi.csproj /t:ReBuild /p:Configuration=Release /p:OutDir=/src/out /p:DeleteExistingFiles=True /p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem FROM base AS final
WORKDIR /app
# 把发布文件复制过来
COPY --from=build /src/out/_PublishedWebsites/NfxApi /app
COPY ./nfxweb /usr/jexus/siteconf/default
# 按需放开
# RUN sed -i 's/TLSv1.2/TLSv1.0/g' /etc/ssl/openssl.cnf
CMD [ "jws", "restart"]

build一下,打包出一个镜像

docker build -t nfxapi:v1 -f ./Dockerfile.nfx .

还有重要的一步是,推送到镜像仓库,这样容器服务那边才可以拉取到。

.NET Core

代码也是很简单的,多了一个用HttpClient调用.NET Framework的接口就是了。

[ApiController]
[Route("")]
public class GwController : ControllerBase
{
private readonly IHttpClientFactory _factory; public GwController(IHttpClientFactory factory)
{
_factory = factory;
} [HttpGet]
public string Get()
{
return $"gw-svc in k8s";
} [HttpGet("svc")]
public async Task<string> GetAsync()
{
var client = _factory.CreateClient(); // 请求上面的.NET Framewore 项目
// 用服务名的方式来处理服务发现
var resp = await client.GetAsync("http://api-nfx-svc/api/values");
resp.EnsureSuccessStatusCode();
var res = await resp.Content.ReadAsStringAsync(); return $"ok - {res}";
}
}

下面这个Dockerfile应该好熟悉的了

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80 FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY . .
RUN dotnet restore "ServerlessNetApp.sln"
WORKDIR /src/GwApi
RUN dotnet build "GwApi.csproj" -c Release -o /app/build FROM build AS publish
RUN dotnet publish "GwApi.csproj" -c Release -o /app/publish FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish . # 按需放开
#RUN sed -i 's/TLSv1.2/TLSv1.0/g' /etc/ssl/openssl.cnf
ENTRYPOINT ["dotnet", "GwApi.dll"]

同样的要把它打包成镜像推送到镜像仓库。

docker build -t ncapi:v1 -f ./Dockerfile.nc .

运行起来

运行起来的话就是准备一些yml文件了,这里就贴出部分内容,具体的可以去github看。

先来看看Deployment和Service。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: api-nfx-svc
namespace: test
labels:
app: api-nfx-svc
spec:
replicas: 1
selector:
matchLabels:
app: api-nfx-svc
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: api-nfx-svc
spec:
containers:
image: >-
镜像仓库地址/api-nfx:v1
imagePullPolicy: IfNotPresent
name: api-nfx
resources:
requests:
cpu: 250m
memory: 512Mi
# 省略部分 ...
---
apiVersion: v1
kind: Service
metadata:
name: api-nfx-svc
namespace: test
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: api-nfx-svc
clusterIP: None
sessionAffinity: None

因为要把.NET Core项目暴露出去,让外部访问,所以我们还要有一个Ingress。

这里的话是基于阿里云的负载均衡,没有用ingress-nginx或ingress-traefik,不那么通用。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
# 指定 SLB 的Id
service.beta.kubernetes.io/alicloud-loadbalancer-id: lb-xxxxxxx
name: gw-ingress
namespace: test
spec:
rules:
- host: ncgw.xxx.com
http:
paths:
- backend:
serviceName: api-nc-svc
servicePort: 80
path: /
status:
loadBalancer:
ingress:
- ip: xxx.xxx.xxx.xxxx

依次把服务,路由跑起来。

kubectl apply -f ../k8s/svc-nfx.yml

kubectl apply -f ../k8s/svc-nc.yml

kubectl apply -f ../k8s/ingress.yml

然后就可以看到在控制台的无状态中出现了我们刚才创建的两个应用。

ps: 老黄手抖,把应用名加了个-svc。。。

服务还有路由

最后就是负载均衡

最后通过DNS解析一下域名到这个负载均衡的IP就可以了。

这个时候应用已经跑起来了,现在是只暴露出了.NET Core的项目可以给外面的访问

访问.NET Core项目的这个地址, http://ncgw.domain.com/svc, 就是通过SLB->集群里的.NET Core->集群里面.NET Framework

一些额外细节

阿里云的serverless kubernetes是基于弹性容器实例(ECI)的,所以最终创建的pod是运行在ECI里面的。

下面是ECI的一个列表。

对比一下两者的监控,

先是.NET Core的

再看看.NET Framwork的

.NET Framework的项目确实是占用的资源多一点。

进去容器里面看看吧。

进来容器里面,其实就是进入了集群环境了。

我们同样可以通过服务名去访问到对应的服务了。

最后一个就是服务发现是基于DNS的。

写在最后

serverless kubernetes用起来确实比较方便,省了很多不必要的麻烦,不过也是踩着坑过来的,坑踩多了,也就可以轻车熟路了。

这里也只是演示了最简单的应用,还有水平伸缩(HPA),日志,监控等一系列的内容,这里是没有提及到的。

可能有人会问:

  1. 为什么还有.NET Framework,不直接.NET Core?

很多老业务不是说动就能动的那么干脆,毕竟还有数据库的限制。。。

  1. .NET Framework容器化有什么坑?

只要你代码没问题,可以在linux下面跑,那就没什么坑不坑的,要是用了一些不支持的特性,那谁也救不了的。

  1. serverless kubernetes的其他问题

可以参靠各大云产商的官方文档和提工单咨询。

最后就是这篇文章的代码可以在我的github查阅:

ServerlessNetApp

用Serverless Kubernetes为.NET (Core)应用保驾护航的更多相关文章

  1. 基于Kubernetes 构建.NET Core技术中台

    今天下午在腾讯云+社区社区分享了<基于Kubernetes 构建.NET Core技术中台>,下面是演讲内容的文字实录. 我们为什么需要中台 我们现在处于企业信息化的新时代.为什么这样说呢 ...

  2. Serverless Kubernetes入门:对kubernetes做减法

    背景 Kubernetes作为通用的容器编排系统,承载了广泛的应用和场景,包括CI/CD,数据计算,在线应用,AI等,然而由于其通用性和复杂性,管理一个kubernetes集群对于很多用户而言还是充满 ...

  3. Serverless Kubernetes全面升级2.0架构:支持多命名空间、RBAC、CRD、PV/PVC等功能

    Serverless Kubernetes概述: 阿里云Serverless Kubernetes容器服务最新开放香港.新加坡.悉尼区域,同时全面开放2.0架构,帮助用户更加便捷.轻松地步入“以应用为 ...

  4. Serverless Kubernetes 入门:对 Kubernetes 做减法

    作者 | 贤维  阿里巴巴高级技术专家 导读:Serverless Kubernetes 是阿里云容器服务团队对未来 Kubernetes 演进方向的一种探索,通过对 Kubernetes 做减法,降 ...

  5. 从零入门 Serverless | 一文讲透 Serverless Kubernetes 容器服务

    作者 | 张维(贤维) 阿里云函数计算开发工程师 导读:Serverless Kubernetes 是以容器和 kubernetes 为基础的 Serverless 服务,它提供了一种简单易用.极致弹 ...

  6. 从零入门 Serverless | Serverless Kubernetes 应用部署及扩缩容

    作者 | 邓青琳(轻零) 阿里云技术专家 导读:本文分为三个部分,首先给大家演示 Serverless Kubernetes 集群的创建和业务应用的部署,其次介绍 Serverless Kuberne ...

  7. Serverless Kubernetes 和 Serverless on Kubernetes 的区别

    什么是 Kubernetes? Kubernetes 是一个可移植的.可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化. 什么是 Serverless ? 无服务器是一种云原 ...

  8. 基于Kubernetes 构建.NET Core 的技术体系

    很多公司技术支持岗位的工作,如配置域名,部署环境,修改复位配置,服务重启,扩容缩容,梳理和完善监控,根据开发的需要查找日志等工作,需要和开发进行大量的沟通,如什么是外网域名,什么是内网域名.A nam ...

  9. EDAS Serverless & Kubernetes SLB LVS Nginx

    分布式缓存负载均衡的规则处理:虚拟节点对一致性哈希的改进 - yanghuahui - 博客园https://www.cnblogs.com/yanghuahui/p/3755460.html EDA ...

随机推荐

  1. c/c++混编

    /* head.h */#ifndef __SUM_H__ #define __SUM_H__ #ifdef __cplusplus extern "C" { #endif int ...

  2. jmeter怎么衡量tps的值

    jmeter也没有tps这么个报告数据,后来又翻了翻loadrunner关于tps的定义 1.TPS:Trasaction per second也就是事务数/秒.它是软件测试结果的测量单位.一个事务是 ...

  3. (四)rsync未授权访问

    01 漏洞描述 rsync是Linux/Unix下的一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件和目录,默认运行在873端口.由于配置不当,导致任何人可未授权访问rsync,上传 ...

  4. 温故知新-Mysql的体系结构概览&sql优化步骤

    文章目录 Mysql的体系结构概览 连接层 服务层 引擎层 存储层 存储引擎 存储引擎概述 存储引擎特性![存储引擎特性对比](https://img-blog.csdnimg.cn/20200510 ...

  5. .NET Web应用中为什么要使用async/await异步编程

    前言 什么是async/await? await和async是.NET Framework4.5框架.C#5.0语法里面出现的技术,目的是用于简化异步编程模型. async和await的关系? asy ...

  6. Flask flush 闪现

    闪现 要用必须导入 flash , get_flashed_messages flash 用于存闪现的值.他有两个参数,1 messsage,用来存储信息 2 category ,用于给信息分类,该参 ...

  7. 听说你的资源被盗用了,那你知道 Nginx 怎么防盗链吗?

    上一篇文章讲了 Nginx 中的变量和运行原理,下面就来说一个主要提供变量并修改变量的值的模块,也就是我们要讲的防盗链模块:referer 模块. 简单有效的防盗链手段 场景 如果做过个人站点的同学, ...

  8. 从零开始的Spring Boot(3、Spring Boot静态资源和文件上传)

    Spring Boot静态资源和文件上传 写在前面 从零开始的Spring Boot(2.在Spring Boot中整合Servlet.Filter.Listener的方式) https://www. ...

  9. Anaconda 安装 以及conda使用

    下载 https://www.anaconda.com/distribution/#macos 管理 conda 版本查看 conda --version conda 版本更新 conda updat ...

  10. DS-4-单链表的各种插入与删除的实现

    typedef struct LNode { int data; struct LNode *next; }LNode, *LinkList; 带头结点的按位序插入: //在第i个位置插入元素e bo ...