github action 实现CI/CD
两种github action 打包.Net Core 项目docker镜像推送到阿里云镜像仓库
1、GitHub Actions 是什么?
大家知道,持续集成由很多操作组成,比如抓取代码、运行测试、登录远程服务器,发布到第三方服务等等。GitHub 把这些操作就称为 actions。
很多操作在不同项目里面是类似的,完全可以共享。GitHub 注意到了这一点,想出了一个很妙的点子,允许开发者把每个操作写成独立的脚本文件,存放到代码仓库,使得其他开发者可以引用。如果你需要某个 action,不必自己写复杂的脚本,直接引用他人写好的 action 即可,整个持续集成过程,就变成了一个 actions 的组合。这就是 GitHub Actions 最特别的地方。
2、基本概念
GitHub Actions 有一些自己的术语。
(1)workflow (工作流程):持续集成一次运行的过程,就是一个 workflow。
(2)job (任务):一个 workflow 由一个或多个 jobs 构成,含义是一次持续集成的运行,可以完成多个任务。
(3)step(步骤):每个 job 由多个 step 构成,一步步完成。
(4)action (动作):每个 step 可以依次执行一个或多个命令(action)。
3、workflow 文件
GitHub Actions 的配置文件叫做 workflow 文件,存放在代码仓库的.github/workflows目录。workflow 文件采用 YAML 格式,文件名可以任意取,但是后缀名统一为.yml,比如foo.yml。一个库可以有多个 workflow 文件。GitHub 只要发现.github/workflows目录里面有.yml文件,就会自动运行该文件。
4、Github Action打包
第一种是在github action 中将项目publish完成然后在进行打包
对应的yml
name: Sukt.Core.API
on:
push:
branches: [dev/main]
pull_request:
branches: [dev/main]
env:
IMAGE_NAME: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #
IMAGE_TAG: dev
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
- name: dotnet restore #还原包
run: dotnet restore src/Sukt.Core.API
- name: dotnet publish #发布项目
run: dotnet publish src/Sukt.Core.API --configuration -c Release --no-restore -o app
# 拷贝dockerfile
- name: Run Crrpath
run: ls
- name: Copy Dockerfile # 拷贝Dockerfile到发布目录 ##生成随机数 echo "$RANDOM"|md5sum|cut -c 5-15
run: cp Dockerfile /home/runner/work/Sukt.Core/Sukt.Core/app
- name: Login To Docker #登录到镜像仓库
uses: docker/login-action@v1
with:
username: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_USERNAME }}
password: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_PASSWORD }}
registry: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #镜像仓库地址
- name: Build Docker Image # Build Docker镜像并推送到镜像仓库
uses: docker/build-push-action@v2
with:
tags: ${{env.IMAGE_NAME}}:${{env.IMAGE_TAG}}.${{ github.run_id }}.${{ github.run_number }} #动态变量镜像TAG 使用github运行job和jobid设置tag
context: /home/runner/work/Sukt.Core/Sukt.Core/app
file: /home/runner/work/Sukt.Core/Sukt.Core/app/Dockerfile # 指定Dockerfile
push: true
对应的Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
ENV TZ=Asia/Shanghai
EXPOSE 80
COPY . .
ENTRYPOINT ["dotnet", "Sukt.Core.API.dll"]
第二种是在Dockerfile发布项目并打包
对应的yml
name: Sukt.Core.API.Dockerfile.Compile
on:
push:
branches: [dev/suktauthserver]
pull_request:
branches: [dev/suktauthserver]
env:
IMAGE_NAME: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #
IMAGE_TAG: dockerfilebuild
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
- name: Login To Docker #登录到镜像仓库
uses: docker/login-action@v1
with:
username: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_USERNAME }}
password: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_PASSWORD }}
registry: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #镜像仓库地址
- name: Build Docker Image # Build Docker镜像并推送到镜像仓库
uses: docker/build-push-action@v2
with:
tags: ${{env.IMAGE_NAME}}:${{env.IMAGE_TAG}}.${{ github.run_id }}.${{ github.run_number }} #动态变量镜像TAG 使用github运行job和jobid设置tag
context: /home/runner/work/Sukt.Core/Sukt.Core
file: /home/runner/work/Sukt.Core/Sukt.Core/Dockerfilepublish # 指定Dockerfile
push: true
- name: Docker Images Lst # 列出所有镜像
run: docker images
对应的Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
ENV TZ=Asia/Shanghai
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
RUN ls
COPY ["src/Sukt.Core.API/Sukt.Core.API.csproj", "src/Sukt.Core.API/"]
COPY ["src/Sukt.Core.Dtos/Sukt.Core.Dtos.csproj", "src/Sukt.Core.Dtos/"]
COPY ["src/Sukt.Core.Domain.Models/Sukt.Core.Domain.Models.csproj", "src/Sukt.Core.Domain.Models/"]
COPY ["src/Sukt.Core.Identity/Sukt.Core.Identity.csproj", "src/Sukt.Core.Identity/"]
COPY ["src/Sukt.Core.Shared/Sukt.Core.Shared.csproj", "src/Sukt.Core.Shared/"]
COPY ["src/Sukt.Core.Application/Sukt.Core.Application.csproj", "src/Sukt.Core.Application/"]
COPY ["src/Sukt.Core.Domain.Services/Sukt.Core.Domain.Services.csproj", "src/Sukt.Core.Domain.Services/"]
COPY ["src/Sukt.Core.EntityFrameworkCore/Sukt.Core.EntityFrameworkCore.csproj", "src/Sukt.Core.EntityFrameworkCore/"]
RUN dotnet restore "src/Sukt.Core.API/Sukt.Core.API.csproj"
RUN ls
COPY . .
WORKDIR "/src/src/Sukt.Core.API"
RUN dotnet build "Sukt.Core.API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Sukt.Core.API.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Sukt.Core.API.dll"]
5、Github Action实现CD
因为是个人开源的项目,所以在部署项目的时候不想在做CI/CD服务器,就想使用github Action来做持续集成和发布了,最近这两天研究了一下使用github Action 实现K8s的持续交付,大概的实现方式分为两部。
- 第一步编写K8sdeployment
我们项目在部署到K8s的时候需要一个deployment的yaml,但是这个yaml里面的镜像tag是随着github action的自动创建的ID生成的,所以第一步就是要解决这个问题,这里我使用了一个这个仓库 datamonsters/replace-action 来做的替换,下面看我K8s的deployment里面具体怎么写的。设置指定标签【$IMAGE_TAG】
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: sukt-platform-admin
name: sukt-platform-admin
namespace: sukt-platform
spec:
replicas: 3
selector:
matchLabels:
app: sukt-platform-admin
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: sukt-platform-admin
spec:
containers:
- name: sukt-platform-admin
image: registry.cn-hangzhou.aliyuncs.com/sukt-platform/sukt-admin-api:$IMAGE_TAG
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /api/healthchecks/liveness
port: 80
scheme: HTTP
initialDelaySeconds: 120
periodSeconds: 30
# timeoutSeconds: 60
readinessProbe:
httpGet:
path: /api/healthchecks/readiness
port: 80
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 60
# timeoutSeconds: 60
resources:
limits:
memory: "2Gi"
cpu: "1000m"
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- mountPath: /app/appsettings.json # 这个对应的是容器内的地址
name: appsettings
readOnly: true
subPath: appsettings.json # #这个位置对应的是comfigmap中的名字,不是 /usr/local/apisix-dashboard/conf/conf.yaml的
- mountPath: /app/skyapm.json # 这个对应的是容器内的地址
name: skyapm
readOnly: true
subPath: skyapm.json # #这个位置对应的是comfigmap中的名字,不是 /usr/local/apisix-dashboard/conf/conf.yaml的
env:
- name: ASPNETCORE_HOSTINGSTARTUPASSEMBLIES # 需要通过映射的方式传入,不能通过Dockerfile的方式默认
value: SkyAPM.Agent.AspNetCore
restartPolicy: Always
imagePullSecrets:
- name: aliyun-iamge-secret
volumes:
- configMap:
defaultMode: 420
name: sukt-admin-appsettings
name: appsettings
- configMap:
defaultMode: 420
name: skyapm
name: skyapm
- 第二步替换指定标签
我们需要在github action运行时替换【$IMAGE_TAG】这个标签,需要在github action 执行的时候替换成github action 自动生成的Id。下面我们看具体的替换实现。
uses: datamonsters/replace-action@v2
with:
files: 'K8sdeploy/sukt-platform-admin-deployment-and-service.yaml'
replacements: '$IMAGE_TAG=${{env.IMAGE_TAG}}.${{ github.run_number }}'
- 第三步部署到K8s
在部署到K8s之前我们需要先创建一个secrets用来存储K8sconfig,我使用的是【actions-hub/kubectl】这个库需要将K8s的config转换成base64,剩下的操作就是在github action里面引用这个库,并使用配置好的secret。具体代码如下:
- uses: actions-hub/kubectl@master
name: deploy to k8s
env:
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
with:
args: apply -f K8sdeploy/sukt-platform-admin-deployment-and-service.yaml
6、Github Action部署心得
在使用github action第二种方式部署的时候遇到过一个问题,因为我项目的解决方案和项目目录还有一层src相隔,在执行dockerfile的时候会报错无法找到Sukt.Core.API/Sukt.Core.API.csproj项目路径,所以在这里我把dockerfile手动移动到了和解决方案一层的目录中解决了这个问题,所以使用的时候要先确定路径。暂时先做到持续集成,因为我的k8s集群在内网,在cd的时候使用的是frp+阿里云的一台服务器穿透出来的,感觉这种方式还是挺好的避免了云服务器的花费。
secrets.ALIYUN_DOCKER_IMAGESTORE_USERNAME、secrets.ALIYUN_DOCKER_IMAGESTORE_PASSWORD这两个是变量配置的是阿里云 镜像仓库的账号密码,需要参考下图自行添加
github action 实现CI/CD的更多相关文章
- GitHub Actions 完成CI CD
在之前我的部署.版本控制.CI.CD都是在Jenkins 下来完成的 在前几天看到github上的一个新玩具actions,简直惊为天人 它能在你的仓库触发事件(Push,Pull,issue,... ...
- 使用CI/CD工具Github Action发布jar到Maven中央仓库
之前发布开源项目Payment Spring Boot到Maven中央仓库我都是手动执行mvn deploy,在CI/CD大行其道的今天使用这种方式有点"原始".于是我一直在寻求一 ...
- 用 GitHub Action 构建一套 CI/CD 系统
缘起 Nebula Graph 最早的自动化测试是使用搭建在 Azure 上的 Jenkins,配合着 GitHub 的 Webhook 实现的,在用户提交 Pull Request 时,加个 r ...
- 技术番外篇丨Github Action CI/CD
起源 看到.Net群里再聊CI/CD,我就这里分享一下我目前自己一些小东西的做法,我目前在Github有一个自己私有的组织,里面存放了我的部分商业化项目,早期我采用Jenkins用Webhooks进行 ...
- Github原生CI/CD,初尝Github Actions
Github 原生 CI/CD,初尝 Github Actions Intro Github 目前已经推出了自己的 CICD 服务 -- Github Actions,而且比微软的 Azure Dev ...
- CI / CD in Action
CI / CD in Action Continuous Integration (CI) & Continuous Delivery (CD) https://github.com/mark ...
- 好代码是管出来的——使用GitHub实现简单的CI/CD
软件开发一般来说是一项团队作业,在本系列文章开始就提到过软件的编码是由一个团队“并行”完成的,为了保证编码任务正常完成,首先引入版本控制工具来完成代码管理,为了保证代码质量引入了代码分析器以及代码测试 ...
- 使用.NET 6开发TodoList应用(31)——实现基于Github Actions和ACI的CI/CD
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求和目标 在这个系列的最后一节中,我们将使用GitHub Actions将TodoList应用部署到Azure Container ...
- Jenkins 结合 Docker 为 .NET Core 项目实现低配版的 CI&CD
随着项目的不断增多,最开始单体项目手动执行 docker build 命令,手动发布项目就不再适用了.一两个项目可能还吃得消,10 多个项目每天让你构建一次还是够呛.即便你的项目少,每次花费在发布上面 ...
随机推荐
- 开发工具-Visual Studio / Visual Studio Code 官方下载地址
更新记录 2022年6月10日 完善标题. Visual Studio官方下载地址 https://visualstudio.microsoft.com/ Visual Studio Code官方下载 ...
- 七、服务器硬件及RAID配置实战
一.RAID磁盘阵列介绍 磁盘阵列的全名(Redundant Arrays of Inexpensive Disk,RAID),中文简称是独立冗余磁盘阵列.冗余(如果磁盘出现故障,可以保证数据不丢) ...
- # 【由浅入深_打牢基础】WEB缓存投毒(上)
image-20220611092344882 [由浅入深_打牢基础]WEB缓存投毒(上) 1. 什么是WEB缓存投毒 简单的来说,就是利用缓存将有害的HTTP响应提供给用户 什么是缓存,这里借用Bu ...
- 实现领域驱动设计 - 使用ABP框架 - 创建实体
用例演示 - 创建实体 本节将演示一些示例用例并讨论可选场景. 创建实体 从实体/聚合根类创建对象是实体生命周期的第一步.聚合/聚合根规则和最佳实践部分建议为Entity类创建一个主构造函数,以保证创 ...
- 毕业论文着急了?Python疫情数据分析,并做数据可视化展示
采集流程 一..明确需求 采集/确诊人数/新增人数 二.代码流程 四大步骤 发送请求 获取数据 网页源代码 解析数据 筛选一些我想用的数据 保存数据 保存成表格 做数据可视化分析 开始代码 1. 发送 ...
- Mybatis整合第三方缓存
1) 为了提高扩展性.MyBatis定义了缓存接口Cache.我们可以通过实现Cache接口来自定义二级缓存 2) EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点. 3) 整合 ...
- 本地使用 Docker Compose 与 Nestjs 快速构建基于 Dapr 的 Redis 发布/订阅分布式应用
Dapr(分布式应用程序运行时)介绍 Dapr 是一个可移植的.事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的.无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言 ...
- Java中运算符和方法的区别
1.多数情况下,运算符是程序语言里固有的.比如+,-,*,/.可以直接被编译为机器语言而无需再调用其它方法编译. 2.运算符在被定义时会被规定运算的优先级.如4+3*3,会得到13.而不是21. 3. ...
- 记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究
开心一刻 一天在路边看到一个街头采访 记者:请问,假如你儿子娶媳妇,给多少彩礼合适呢 大爷:一百万吧,再给一套房,一辆车 大爷沉思一下,继续说到:如果有能力的话再给老丈人配一辆车,毕竟他把女儿养这么大 ...
- webapi <Message>已拒绝为此请求授权。</Message>
webapi <Message>已拒绝为此请求授权.</Message> 原有的调用base.OnAuthorization(actionContext); 换成下面这个 // ...