.Net Core 商城微服务项目系列(十二):使用k8s部署商城服务
一、简介
本篇我们将会把商城的服务部署到k8s中,同时变化的还有以下两个地方:
1.不再使用Consul做服务的注册和发现,转而使用k8s-dns来实现。
2.不再使用Ocelot作为业务网关,使用Traefik来实现。
正如上面所讲,服务发现和网关均使用k8s的相关工具,当然,相比与以上两个工具,Traefik还有自己的不足,比如Consul的健康检查、Ocelot的限流、熔断机制,不过这些我们后面可以通过其它方式来实现。
整体思路很简单哈,就是编写Dockerfile文件,将各个服务打包成镜像上传到DockerHub,然后再我们的k8s集群中部署,并使用Traefik路由。
二、打包镜像
Dockerfile文件都一样的,所以我这里只列出IdentityServer4服务的Dockerfile:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
Copy . . RUN dotnet restore
RUN dotnet build -c Release -o /app FROM build as publish
RUN dotnet publish -c Releease -o /app FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "MI.Service.Identity.dll"]
通过以下命令进行打包:
docker build -t 镜像名 .
这里需要注意的是镜像名要用自己DockerHub的用户名作为前缀,比如 用户名/mi.service.identity ,只有这样才能再后面上传镜像。
然后通过以下命令登录Docker,上传镜像:
docker login --username xxx docker push 用户名/mi.service.identity
这里需要注意的是如果我们的项目是包含类库的,比如下面这种:

那我们的Dockerfile文件写法要改成下面这样,并且要把它放在和解决方案.sln同级的文件夹内,因为类库也需要进行编译:
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
Copy . .
WORKDIR /src/MI.Service.Account
RUN dotnet restore
RUN dotnet build -c Release -o /app
FROM build as publish
RUN dotnet publish -c Releease -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "MI.Service.Account.dll"]
三、部署到k8s
我们的需要编写deployment、Service和ingress的yaml文件,分别如下
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: mi-service
name: mi-service-identity
namespace: mi
spec:
replicas:
selector:
matchLabels:
k8s-app: mi-service-identity
template:
metadata:
labels:
k8s-app: mi-service-identity
spec:
containers:
- name: mi-service-identity
image: 用户名/mi.service.identity
ports:
- containerPort:
apiVersion: v1
kind: Service
metadata:
name: mi-service-identity
namespace: mi
spec:
selector:
k8s-app: mi-service-identity
ports:
- name: http
port:
targetPort:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: mi-service
namespace: mi
spec:
rules:
- host: mi.service.identity
http:
paths:
- path: /
backend:
serviceName: mi-service-identity
servicePort: http
通过以下命令部署(拉取镜像需要点时间):
kubectl apply -f mi_identity.yaml
kubectl apply -f mi_identity_service.yaml
kubectl apply -f mi-service-ingress.yaml
完成后查看svc、pod、ingress的状态:
[root@localhost ~]# kubectl get pods -n mi
NAME READY STATUS RESTARTS AGE
mi-service-identity-7dfbf85d-x7w82 / Running 23h
mi-service-identity-7dfbf85d-z4hz9 / Running 23h [root@localhost ~]# kubectl get deployment -n mi
NAME READY UP-TO-DATE AVAILABLE AGE
mi-service-identity / 23h [root@localhost service-yaml]# kubectl get svc -n mi
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mi-service-identity ClusterIP 10.109.13.2 <none> /TCP 7s [root@localhost k8s-mi]# kubectl get ing -n mi
NAME HOSTS ADDRESS PORTS AGE
mi-service mi.service.identity 33m
这个时候我们已经可以再集群内部访问了:
[root@localhost service-yaml]# curl http://10.109.13.2/api/Health
ok
然后配置下Host文件,通过浏览器访问

这个服务是用来获取token令牌的,所以呢我们需要postman测试下能不能获取到Token:

成功!
然后我们需要把另外的服务也部署到k8s,同时更新Ingress的配置,如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: mi-service
namespace: mi
spec:
rules:
- host: mi.service.identity
http:
paths:
- path: /
backend:
serviceName: mi-service-identity
servicePort: http
- host: mi.service.account
http:
paths:
- path: /
backend:
serviceName: mi-service-account
servicePort: http
- host: mi.service.monitor
http:
paths:
- path: /
backend:
serviceName: mi-service-monitor
servicePort: http
- host: mi.service.picture
http:
paths:
- path: /
backend:
serviceName: mi-service-picture
servicePort: http
- host: mi.service.shopcar
http:
paths:
- path: /
backend:
serviceName: mi-service-shopcar
servicePort: http
这个时候其实我们已经可以正常使用了,我们将Web项目里的服务地址修改下,不再通过调用Ocelot进行转发,而是使用k8s中Service的标识,修改appsettings:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Warning"
}
},"ServiceAddress": {
"Service.Identity": "http://mi.service.identity",
"Service.Account": "http://mi.service.account","Service.Picture": "http://mi.service.picture",
"Service.Monitor": "http://mi.service.monitor",
"Service.ShopCar": "http://mi.service.shopcar"
}
}
然后运行项目查看:

但是我们现在还存在一个问题。虽然Pod的IP可以被Service发现,但是Service的IP被谁发现呢,现在Traefik中配置host和其IP是我们手动配置,当然Service的IP一般是固定不变的,但是如果变了,我们希望能被自动发现和映射,这一步将通过k8s dns来实现。
三、使用k8s-dns做服务发现
k8s中的service分配的虚拟IP是固定的,而pod异常后新生成的pod ip会发生变化,可以通过service做代理关联到后端的pod。
kube-dns可以解决Service的发现问题,k8s将Service的名称当做域名注册到kube-dns中,通过Service的名称就可以访问其提供的服务。
通过设置k8s中的dns服务可以直接解析service的名字,得到对应service的ip,可以实现服务在集群内部互相访问。
.Net Core 商城微服务项目系列(十二):使用k8s部署商城服务的更多相关文章
- .Net Core 商城微服务项目系列(二):使用Ocelot + Consul构建具备服务注册和发现功能的网关
1.服务注册 在上一篇的鉴权和登录服务中分别通过NuGet引用Consul这个包,同时新增AppBuilderExtensions类: public static class AppBuilderEx ...
- 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— 准备
==== 目录 ==== 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之一 —— 开篇 跟我学: 使用 fireasy 搭建 asp.net core 项目系列之二 —— ...
- Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】
2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...
- SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据
原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...
- Alamofire源码解读系列(十二)之请求(Request)
本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...
- struts2官方 中文教程 系列十二:控制标签
介绍 struts2有一些控制语句的标签,本教程中我们将讨论如何使用 if 和iterator 标签.更多的控制标签可以参见 tags reference. 到此我们新建一个struts2 web 项 ...
- 爬虫系列(十二) selenium的基本使用
一.selenium 简介 随着网络技术的发展,目前大部分网站都采用动态加载技术,常见的有 JavaScript 动态渲染和 Ajax 动态加载 对于爬取这些网站,一般有两种思路: 分析 Ajax 请 ...
- HBase 系列(二)安装部署
HBase 系列(二)安装部署 本节以 Hadoop-2.7.6,HBase-1.4.5 为例安装 HBase 环境.HBase 也有三种模式:本地模式.伪分布模式.分布模式. 一.环境准备 (1) ...
- Greeplum 系列(二) 安装部署
Greeplum 系列(二) 安装部署 本章将介绍如何快速安装部署 Greenplum,以及 Greenplum 的一些常用命令及工具.本章不会涉及硬件选型.操作系统参数讲解.机器性能测试等高级内容, ...
- yum 系列(二) 离线部署
yum 系列(二) 离线部署 一.下载 rpm 依赖包 (1) yum 下载 rpm 包 准备一台 全新的 CentOS7 mini 虚拟机 ,联网下载所有所需的 rpm 包和其依赖, yum ins ...
随机推荐
- c#搭建webapi项目
一.添加WebApi项目 二.nuget下载WebApi所需的类库引用 install-package Microsoft.AspNet.WebApi install-package Micr ...
- DOM的高级操作-一种JS控制元素的视觉假象
1.运动中的边界处理(让其在一个指定区域内运动) 当元素的offsetLeft值超出一定距离或达到一个我们想要设置的边界值时,停止计时器. var timer; timer = setInterval ...
- CCPC 网络赛
array 做法 比赛中的表现..... 已经无法言语形容了. 题意是,查询前缀中大于某个数字的 mex,在线. 一下把问题转化为偏序问题.... 带修主席树?????这下好,直接一箭穿心,武将被移除 ...
- HDU - 2255 奔小康赚大钱 KM算法 模板题
HDU - 2255 题意: 分配n所房子给n个家庭,不同家庭对一所房子所需缴纳的钱是不一样的,问你应当怎么分配房子,使得最后收到的钱最多. 思路: KM算法裸题.上模板 #include <i ...
- AOJ-2249-Road Construction-dijkstra-最小花费
Road Construction 题意:在一个无向图中,每条边上有建设的花费和路径的长度,要求求得,在保持每个点到1号点最小距离不变的情况下,求最小的总花费: 思路:用dijkstra 找出每个点的 ...
- CodeForces 293E Close Vertices 点分治
题目传送门 题意:现在有一棵树,每条边的长度都为1,然后有一个权值,求存在多少个(u,v)点对,他们的路劲长度 <= l, 总权重 <= w. 题解: 1.找到树的重心. 2.求出每个点到 ...
- bzoj 1146 网络管理Network (CDQ 整体二分 + 树刨)
题目传送门 题意:求树上路径可修改的第k大值是多少. 题解:CDQ整体二分+树刨. 每一个位置上的数都会有一段持续区间 根据CDQ拆的思维,可以将这个数拆成出现的时间点和消失的时间点. 然后通过整体二 ...
- Codeforces Technocup 2017 - Elimination Round 2 E Subordinates(贪心)
题目链接 http://codeforces.com/contest/729/problem/E 题意:给你n个人,主管id为s,然后给你n个id,每个id上对应一个数字表示比这个人大的有几个. 最后 ...
- Ubuntu开机出现grub指令,无法正常开机
问题 最近开机出现了如下的界面: 分析问题 首先看看GNU GRUB是什么东东?干什么用的? GNU GRUB是多重引导加载程序.通俗点说,它就是用来一个可以让你选择运行什么操作系统的程序. 在你开机 ...
- python实现持久化存储,操作表格,时间戳
import xlrd,xlwt,pickle,time,datetime book = xlrd.open_workbook("练习.xlsx") sheet1 = book.s ...