用Serverless Kubernetes为.NET (Core)应用保驾护航
前言
容器化对现在(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),日志,监控等一系列的内容,这里是没有提及到的。
可能有人会问:
- 为什么还有.NET Framework,不直接.NET Core?
很多老业务不是说动就能动的那么干脆,毕竟还有数据库的限制。。。
- .NET Framework容器化有什么坑?
只要你代码没问题,可以在linux下面跑,那就没什么坑不坑的,要是用了一些不支持的特性,那谁也救不了的。
- serverless kubernetes的其他问题
可以参靠各大云产商的官方文档和提工单咨询。
最后就是这篇文章的代码可以在我的github查阅:
用Serverless Kubernetes为.NET (Core)应用保驾护航的更多相关文章
- 基于Kubernetes 构建.NET Core技术中台
今天下午在腾讯云+社区社区分享了<基于Kubernetes 构建.NET Core技术中台>,下面是演讲内容的文字实录. 我们为什么需要中台 我们现在处于企业信息化的新时代.为什么这样说呢 ...
- Serverless Kubernetes入门:对kubernetes做减法
背景 Kubernetes作为通用的容器编排系统,承载了广泛的应用和场景,包括CI/CD,数据计算,在线应用,AI等,然而由于其通用性和复杂性,管理一个kubernetes集群对于很多用户而言还是充满 ...
- Serverless Kubernetes全面升级2.0架构:支持多命名空间、RBAC、CRD、PV/PVC等功能
Serverless Kubernetes概述: 阿里云Serverless Kubernetes容器服务最新开放香港.新加坡.悉尼区域,同时全面开放2.0架构,帮助用户更加便捷.轻松地步入“以应用为 ...
- Serverless Kubernetes 入门:对 Kubernetes 做减法
作者 | 贤维 阿里巴巴高级技术专家 导读:Serverless Kubernetes 是阿里云容器服务团队对未来 Kubernetes 演进方向的一种探索,通过对 Kubernetes 做减法,降 ...
- 从零入门 Serverless | 一文讲透 Serverless Kubernetes 容器服务
作者 | 张维(贤维) 阿里云函数计算开发工程师 导读:Serverless Kubernetes 是以容器和 kubernetes 为基础的 Serverless 服务,它提供了一种简单易用.极致弹 ...
- 从零入门 Serverless | Serverless Kubernetes 应用部署及扩缩容
作者 | 邓青琳(轻零) 阿里云技术专家 导读:本文分为三个部分,首先给大家演示 Serverless Kubernetes 集群的创建和业务应用的部署,其次介绍 Serverless Kuberne ...
- Serverless Kubernetes 和 Serverless on Kubernetes 的区别
什么是 Kubernetes? Kubernetes 是一个可移植的.可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化. 什么是 Serverless ? 无服务器是一种云原 ...
- 基于Kubernetes 构建.NET Core 的技术体系
很多公司技术支持岗位的工作,如配置域名,部署环境,修改复位配置,服务重启,扩容缩容,梳理和完善监控,根据开发的需要查找日志等工作,需要和开发进行大量的沟通,如什么是外网域名,什么是内网域名.A nam ...
- EDAS Serverless & Kubernetes SLB LVS Nginx
分布式缓存负载均衡的规则处理:虚拟节点对一致性哈希的改进 - yanghuahui - 博客园https://www.cnblogs.com/yanghuahui/p/3755460.html EDA ...
随机推荐
- Shell中傻傻分不清楚的TOP3
Shell中傻傻分不清楚的TOP3 发布文章 近来小姐姐又犯憨憨错误,问组内小伙伴export命令不会持久化环境变量吗?反正我是问出口了..然后小伙伴就甩给了我一个<The Linux Comm ...
- 基于Azure IoT开发.NET物联网应用系列-全新的Azure IoT架构
物联网技术已经火了很多年了,业界各大厂商都有各自成熟的解决方案.我们公司主要搞新能源汽车充电,充电桩就是物联网技术的最大应用,车联网.物联网.互联网三网合一.2017年的时候重点研究过Azure Io ...
- 无监督LDA、PCA、k-means三种方法之间的的联系及推导
\(LDA\)是一种比较常见的有监督分类方法,常用于降维和分类任务中:而\(PCA\)是一种无监督降维技术:\(k\)-means则是一种在聚类任务中应用非常广泛的数据预处理方法. 本文的 ...
- 【百度前端学院 Day4】背景边框列表链接和更复杂的选择器
1. 背景 背景指的是元素内容.内边距和边界下层的区域(可用background-clip修改) background-color 背景色 background-image 背景图片(url) b ...
- java处理csv文件上传示例
前言:示例只是做了一个最最基础的上传csv的示例,如果要引用到代码中去,还需要根据自己的业务自行添加一些逻辑处理. ReadCsvUtil工具类 package com.hanfengyeqiao.g ...
- Excel经典教程之一
照片名称:未命名 照片名称:自动筛选 照片名称:在Excel中字符替换 照片名称:在Excel中直接编辑“宏” 照片名称:在Excel中为导入外部数据 照片名称:在Excel中行列快速转换 照片名称: ...
- centos7 hadoop 单机模式安装配置
前言 由于现在要用spark,而学习spark会和hdfs和hive打交道,之前在公司服务器配的分布式集群,离开公司之后,自己就不能用了,后来用ambari搭的三台虚拟机的集群太卡了,所以就上网查了一 ...
- Python中的队列
参考资料: https://www.cnblogs.com/yhleng/p/9493457.html 问:我们为什么想使用队列? 答:为了方便,我就想喂给队列一堆object,就想让它们先进先出(F ...
- Homebrew命令总结
brew又叫homebrew,是macos上的一个包管理工具,能够在mac中方便的进行包管理,类似于ubuntu系统下的apt-get,记得自己第一次接触brew是为了在mac上安装一个独立绿色的视频 ...
- 如何从二进制文件中读取int型序列
使用的主要函数是int.from_bytes 代码如下: f = open('./T26.dat', 'rb') for i in range(20): A = f.read(2) A = int.f ...