百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

微服务实践 之 可落地微服务on k8s的持续集成/部署方案

connygpt 2024-09-09 03:09 8 浏览

我们隔一流的软件生产工艺还有多远?在距离15000公里外,Amazon一年可以进行5000万次部署,在这一边某电商平台的研发部门里,让他们引以为傲的是他们正在进行“敏捷”开发模式,并对外号称他们是以每周为迭代来进行升级。时间是定在周四(因为这样如果出现问题,周五还可以修复,不用周六加班),但是周四的晚上,开发/测试/还有产品的负责人是妥妥的要留下来了奋斗到天明了,如果运气好的话还可以在 12点之前回家。运气这种事情,总是不太好说。

这是我们曾经经历的痛, 由于缺少自动化测试以及完整的上线发布流程,每次一上线,总能折腾个4到5小时。所以后来在我们自己实现这套新零售的saas系统的时候,从一开始我就在思考如何避免这个问题。我们采用了微服务架构,由30多个微服务组成, 部署在K8S上, 测试环境与生产环境都是借助于gitlab ci来完成的,并且同时可以支持腾讯和阿里云的k8s容器服务。这个花了3天调研和实施出来的持续集成方案在时间收益上已经给我们带来了超过 20倍的回报 。

微服务

微服务存在着多个服务独立部署的情况,在没有k8s之前需要自己实现一套完整的持续部署工具,这个复杂度及成本可以说80%的公司都承受不起。但是微服务部署在 k8s上之后一切就变的简单的多了。

单个服务在k8s中的部署可以用 kubectl set image的语句在ci job中实现


kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1


如果是30多个甚至更多的服务,我们把所有的资源定义文件存放在一个单独的代码仓库中进行维护和版本管理会更合适一些。在没有helm之前,我们可能通过 kubectl apply -f ./ 的方式基于整个文件夹来创建和更新 k8s资源。即使这样,我们在不同测试环境与生产环境由于不同的配置需要有两个文件夹来保存资源定义文件。



Helm

helm可以将多个k8s的资源定义文件打包在一起进行整体的部署、更新,就像一个应用程序一样。

这种场景就特别适合微服务,我们可以将所有的服务以及中间件、数据库、证书等资源定义在一个helm package下来进行部署和更新。

一个helm package的构成主要由模板和参数来构成,模板就是 k8s的资源定义文件,在模板中可以引用外部的参数,我们一组微服务的应用可以用同一个包只需要替换不同的参数即可。

我们以一个简单的单体应用来举例,它包括一个api, 一个mysql数据库,以及一个ingress配置将api就暴露在k8s集群之外。在本地安装好helm client之后可以使用helm create [name]来创建一个package。


helm create Helm


在templates中新建api-deploy.yaml, ingress.yaml, mysql-svc.yaml,这些文件的内容和我们平台创建k8s资源的定义文件是一样的,只不过我们在这里可以使用helm提供的参数。

比如命名空间我们就可以这样来使用


kind: Service
apiVersion: v1
metadata:
name: {{ .Values.image.api.name }}
namespace: {{ .Values.namespace }}
spec:
{{ if .Values.image.api.nodePort }}type: NodePort{{ end }}
ports:
- port: 80
targetPort: 80
{{ if .Values.image.api.nodePort }}nodePort: {{ .Values.image.api.nodePort }}{{ end }}
selector:
name: {{ .Values.image.api.name }}

在模板中还支持条件判断,比如在测试环境我们可以配置nodePort来暴露服务,而生产环境中则不支持。

在values.yaml中我们定义以下内容供测试环境使用,在生产中可以将namespace改成生产环境对应的命名空间名以及移除nodePort节点即可。


namespace: hunterpro
image:
api:
name: hunterpro-api
version: 1.0.0.2991
nodePort: 31013

之后我们可以使用helm install -n [name] ./helm 来将这个helm package部署到k8s集群中 。 ./helm为包定义目录。helm 所连接的k8s集群为kubectl的配置。

Helm package Chartmuseum

一个helm的包存放在一个文件夹内,同时我们还可以使用 helm pakcage将它打包成一个文件来方便与其它人共享。同时也可以像上传docker我镜像一样上传helm package,并且同样可以在仓库上保存不同的版本。Chartmuseum就是一个开源的 helm package仓库服务。

我们可以使用docker将它快速安装


docker run --rm -it \
 -p 8080:8080 \
 -v $(pwd)/charts:/charts \
 -e DEBUG=true \
 -e STORAGE=local \
 -e STORAGE_LOCAL_ROOTDIR=/charts \
chartmuseum/chartmuseum:v0.8.1

以上我们就可以拿到一个远程 helm package repository的地址,只需要将它加入本地的repo list中即可


helm repo add [name] [url]


官方还提供了helm push插件,让我们可以轻松地将本地的helm package推送到远程的仓库


$ helm push mychart/ [repo name]
Pushing mychart-0.3.2.tgz to [repo name]...
Done.


完整实践

有了对 helm以及helm package repository的初步了解,我们就可以进入到我们整个ci方案了。

1. 开发提交代码到dev分支

2. 触发项目dev构建流水线 gitlab ci开始进行代码的构建,使用项目内dockerfile来构建 docker镜像

3. 镜像构建成功之后推送到镜像仓库 (我们根据不同的分支会把镜像分别推到阿里或者镜像云)

4. 触发buildscript dev构建流水线 (传送参数 :当前版本以及当前更新服务名称)

5. build script 下载最新代码并将helm package的参数内的对应服务的镜像版本更新至当前版本

6. 提交更改之后的代码

7. helm package 并且helm push将最新的包推送到远程镜像

8. 用最新的 helm package来更新开发的集群



我们使用gitlab ci来做持续集成,如果不了解gitlab ci可以查看这篇之前的文章。

GitLab CI 自动部署netcore web api 到Docker

.Net & Docker(二)5分钟快速用Docker部署你自己的GitLab

当我们的gitlab runner配置好之后,由于涉及到k8s我们还需要做以下事情。

- 安装kubectl 并配置连接到集群

- 安装helm client (helm client会直接使用kubectl 的连接操作对应集群)

- 安装 helm push 插件

- 由于我们在流水线执行过程中更新代码并推送用到了python脚本,所以我们需要安装python3.6

安装kubectl

与k8s相关的学习最大的问题是它有比较多新的概念,刚开始学习会比较难。而第二大问题就是那堵墙,在很多情况下会让我们直接想放弃。在安装kubectl 的时候,如果是 centos我们可以使用阿里的镜像:


cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

然后再安装kubectl


yum install -y kubectl


安装helm

centos 可以使用snap来安装并添加阿里的稳定仓库源来进初始化,默认使用谷哥的稳定源会失败 。


sudo snap install helm --classic
helm init --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.1 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
https://yq.aliyun.com/articles/159601


安装python和 PyYAML库

我们上面提到我们要通过 buildscript的构建流水线去更新helm pakcage内某个服务的镜像版本


image:
auctionapi:
name: auction-api
nodePort: 31100
version: 1.0.2532
deliveryapi:
name: delivery-api
nodePort: 31049
version: 1.0.2542
fundapi:
name: fund-api
nodePort: 31034
version: 1.0.2538
gatewaymp:
name: gateway-mp-api
nodePort: 31039
version: 1.0.2544


比如我们的 values.yaml 参数配置是这样的。当我们提交gateway-mp-api 之后,当前的版本号会升级主为 1.0.2545 。gateway-mp-api的构建流水线会将版本号为 1.0.2545的镜像推到镜像仓库,接下来我们要做的就是通过 helm upgrade 来更新我们在k8s中的服务。



gitlab ci中可以通过 web hook 的方式触发另一个仓库的ci,所以我们在这里每一个 api推送完镜像之后都会触发 buildscript的更新,并传入参数:当前服务名称(对应values.yaml中的 服务key) 和最新版本号。

然后借助一段python脚本来更新values.yaml, 下面的代码用到了python的 yaml库,可以比较方便的操作yaml格式的文件。


import sys
import yaml
with open("values.yaml") as f:
value = yaml.load(f)
value['image'][sys.argv[1]]['version'] = sys.argv[2]
with open("values.yaml","w") as f:
 yaml.dump(value, f)


buildscript 的.gitlab-ci.yaml文件 script


script:
 - helm init --client-only --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
 - helm repo add $helmRepoName $helmRepoUrl
 - cd BuildScript/dev-wotui/wotui-dev
 - python3.6 update.py $image $version
 - git add .
 - git commit -m "upgrade to $version" || true
 - git push origin wotui/develop
 - cd ../
 - helm push ./wotui-dev $helmRepoName -v $version
 - helm repo update
 - helm upgrade $helmReleaseName $helmPackageName

所完成的步骤包括:

- 初始化helm 仅客户端

- 添加远程 helm 仓库

- 更改 helm chart values.yaml 对应的服务镜像版本

- 提交buildscript 代码

- 推送 helm package

- 更新微服务

服务项目的构建流水线

每一个服务自己的gitlab-ci文件中只需要完成构建自己的镜像并推送到镜像仓库,之后再用curl发起buildscript 项目的构建并传入对应参数即可。


stages:
 - image
 - deploy
variables: 
 versionNo: $MAIN_VERSION.$SECONDARY_VERSION.$CI_PIPELINE_ID
 registry: registry-vpc.cn-shanghai.aliyuncs.com/
 registryUser: ********
 registryPwd: ********
 repository: namespace/delivery-api
docker image:
 stage: image
 tags:
 - wotui
 only: 
 - wotui/develop
 script:
 - docker build -t "$registry$repository:$versionNo" ./Collectin.Delivery.API
 - docker login -u $registryUser -p $registryPwd $registry
 - docker push "$registry$repository:$versionNo"
deploy:
 stage: deploy
 variables:
 GIT_STRATEGY: none
 tags:
 - wotui
 only:
 - wotui/develop
 script:
 - curl -X POST -F token=${PUBLISH_TRIGGER_TOKEN} -F ref=wotui/develop -F "variables[version]=$versionNo" -F "variables[image]=deliveryapi" http://code.collectin.cn/api/v4/projects/50/trigger/pipelin

以上,当你提交代码到服务的分支,接下来就是视频中全自动的编译,打包,部署流程。

关于微服务与K8S

只要找到了合适的方法,微服务就没有那么复杂 。即使不是粒度非常细的微服务,哪怕是粗粒度的服务,同样可以借用于K8S来进行运维管理。 在现在它可以节省大量的运维操作时间,在未来它也可以很好地适应业务快速扩展。 随着企业对于开发人员的要求不断增高,如果你希望在未来的两到三年晋升成为架构师,那么微服务架构和K8S是你不得不掌握的必要技能。

Jesse腾飞

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&amp;Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick &#39;n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...