两种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

  1. name: Sukt.Core.API
  2. on:
  3. push:
  4. branches: [dev/main]
  5. pull_request:
  6. branches: [dev/main]
  7. env:
  8. IMAGE_NAME: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #
  9. IMAGE_TAG: dev
  10. jobs:
  11. build:
  12. runs-on: ubuntu-latest
  13. steps:
  14. - uses: actions/checkout@v2
  15. - name: Setup .NET Core
  16. uses: actions/setup-dotnet@v1
  17. with:
  18. dotnet-version: 5.0.x
  19. - name: dotnet restore #还原包
  20. run: dotnet restore src/Sukt.Core.API
  21. - name: dotnet publish #发布项目
  22. run: dotnet publish src/Sukt.Core.API --configuration -c Release --no-restore -o app
  23. # 拷贝dockerfile
  24. - name: Run Crrpath
  25. run: ls
  26. - name: Copy Dockerfile # 拷贝Dockerfile到发布目录 ##生成随机数 echo "$RANDOM"|md5sum|cut -c 5-15
  27. run: cp Dockerfile /home/runner/work/Sukt.Core/Sukt.Core/app
  28. - name: Login To Docker #登录到镜像仓库
  29. uses: docker/login-action@v1
  30. with:
  31. username: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_USERNAME }}
  32. password: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_PASSWORD }}
  33. registry: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #镜像仓库地址
  34. - name: Build Docker Image # Build Docker镜像并推送到镜像仓库
  35. uses: docker/build-push-action@v2
  36. with:
  37. tags: ${{env.IMAGE_NAME}}:${{env.IMAGE_TAG}}.${{ github.run_id }}.${{ github.run_number }} #动态变量镜像TAG 使用github运行job和jobid设置tag
  38. context: /home/runner/work/Sukt.Core/Sukt.Core/app
  39. file: /home/runner/work/Sukt.Core/Sukt.Core/app/Dockerfile # 指定Dockerfile
  40. push: true

对应的Dockerfile

  1. FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
  2. WORKDIR /app
  3. ENV TZ=Asia/Shanghai
  4. EXPOSE 80
  5. COPY . .
  6. ENTRYPOINT ["dotnet", "Sukt.Core.API.dll"]

第二种是在Dockerfile发布项目并打包

对应的yml

  1. name: Sukt.Core.API.Dockerfile.Compile
  2. on:
  3. push:
  4. branches: [dev/suktauthserver]
  5. pull_request:
  6. branches: [dev/suktauthserver]
  7. env:
  8. IMAGE_NAME: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #
  9. IMAGE_TAG: dockerfilebuild
  10. jobs:
  11. build:
  12. runs-on: ubuntu-latest
  13. steps:
  14. - uses: actions/checkout@v2
  15. - name: Setup .NET Core
  16. uses: actions/setup-dotnet@v1
  17. with:
  18. dotnet-version: 5.0.x
  19. - name: Login To Docker #登录到镜像仓库
  20. uses: docker/login-action@v1
  21. with:
  22. username: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_USERNAME }}
  23. password: ${{ secrets.ALIYUN_DOCKER_IMAGESTORE_PASSWORD }}
  24. registry: registry.cn-hangzhou.aliyuncs.com/suktcore/sukt-core-admin-api #镜像仓库地址
  25. - name: Build Docker Image # Build Docker镜像并推送到镜像仓库
  26. uses: docker/build-push-action@v2
  27. with:
  28. tags: ${{env.IMAGE_NAME}}:${{env.IMAGE_TAG}}.${{ github.run_id }}.${{ github.run_number }} #动态变量镜像TAG 使用github运行job和jobid设置tag
  29. context: /home/runner/work/Sukt.Core/Sukt.Core
  30. file: /home/runner/work/Sukt.Core/Sukt.Core/Dockerfilepublish # 指定Dockerfile
  31. push: true
  32. - name: Docker Images Lst # 列出所有镜像
  33. run: docker images

对应的Dockerfile

  1. FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
  2. WORKDIR /app
  3. EXPOSE 80
  4. ENV TZ=Asia/Shanghai
  5. FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
  6. WORKDIR /src
  7. RUN ls
  8. COPY ["src/Sukt.Core.API/Sukt.Core.API.csproj", "src/Sukt.Core.API/"]
  9. COPY ["src/Sukt.Core.Dtos/Sukt.Core.Dtos.csproj", "src/Sukt.Core.Dtos/"]
  10. COPY ["src/Sukt.Core.Domain.Models/Sukt.Core.Domain.Models.csproj", "src/Sukt.Core.Domain.Models/"]
  11. COPY ["src/Sukt.Core.Identity/Sukt.Core.Identity.csproj", "src/Sukt.Core.Identity/"]
  12. COPY ["src/Sukt.Core.Shared/Sukt.Core.Shared.csproj", "src/Sukt.Core.Shared/"]
  13. COPY ["src/Sukt.Core.Application/Sukt.Core.Application.csproj", "src/Sukt.Core.Application/"]
  14. COPY ["src/Sukt.Core.Domain.Services/Sukt.Core.Domain.Services.csproj", "src/Sukt.Core.Domain.Services/"]
  15. COPY ["src/Sukt.Core.EntityFrameworkCore/Sukt.Core.EntityFrameworkCore.csproj", "src/Sukt.Core.EntityFrameworkCore/"]
  16. RUN dotnet restore "src/Sukt.Core.API/Sukt.Core.API.csproj"
  17. RUN ls
  18. COPY . .
  19. WORKDIR "/src/src/Sukt.Core.API"
  20. RUN dotnet build "Sukt.Core.API.csproj" -c Release -o /app/build
  21. FROM build AS publish
  22. RUN dotnet publish "Sukt.Core.API.csproj" -c Release -o /app/publish
  23. FROM base AS final
  24. WORKDIR /app
  25. COPY --from=publish /app/publish .
  26. 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】
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: sukt-platform-admin
  6. name: sukt-platform-admin
  7. namespace: sukt-platform
  8. spec:
  9. replicas: 3
  10. selector:
  11. matchLabels:
  12. app: sukt-platform-admin
  13. strategy:
  14. rollingUpdate:
  15. maxSurge: 1
  16. maxUnavailable: 1
  17. type: RollingUpdate
  18. template:
  19. metadata:
  20. labels:
  21. app: sukt-platform-admin
  22. spec:
  23. containers:
  24. - name: sukt-platform-admin
  25. image: registry.cn-hangzhou.aliyuncs.com/sukt-platform/sukt-admin-api:$IMAGE_TAG
  26. imagePullPolicy: IfNotPresent
  27. livenessProbe:
  28. httpGet:
  29. path: /api/healthchecks/liveness
  30. port: 80
  31. scheme: HTTP
  32. initialDelaySeconds: 120
  33. periodSeconds: 30
  34. # timeoutSeconds: 60
  35. readinessProbe:
  36. httpGet:
  37. path: /api/healthchecks/readiness
  38. port: 80
  39. scheme: HTTP
  40. initialDelaySeconds: 30
  41. periodSeconds: 60
  42. # timeoutSeconds: 60
  43. resources:
  44. limits:
  45. memory: "2Gi"
  46. cpu: "1000m"
  47. ports:
  48. - containerPort: 80
  49. protocol: TCP
  50. volumeMounts:
  51. - mountPath: /app/appsettings.json # 这个对应的是容器内的地址
  52. name: appsettings
  53. readOnly: true
  54. subPath: appsettings.json # #这个位置对应的是comfigmap中的名字,不是 /usr/local/apisix-dashboard/conf/conf.yaml的
  55. - mountPath: /app/skyapm.json # 这个对应的是容器内的地址
  56. name: skyapm
  57. readOnly: true
  58. subPath: skyapm.json # #这个位置对应的是comfigmap中的名字,不是 /usr/local/apisix-dashboard/conf/conf.yaml的
  59. env:
  60. - name: ASPNETCORE_HOSTINGSTARTUPASSEMBLIES # 需要通过映射的方式传入,不能通过Dockerfile的方式默认
  61. value: SkyAPM.Agent.AspNetCore
  62. restartPolicy: Always
  63. imagePullSecrets:
  64. - name: aliyun-iamge-secret
  65. volumes:
  66. - configMap:
  67. defaultMode: 420
  68. name: sukt-admin-appsettings
  69. name: appsettings
  70. - configMap:
  71. defaultMode: 420
  72. name: skyapm
  73. name: skyapm
  • 第二步替换指定标签

    我们需要在github action运行时替换【$IMAGE_TAG】这个标签,需要在github action 执行的时候替换成github action 自动生成的Id。下面我们看具体的替换实现。
  1. uses: datamonsters/replace-action@v2
  2. with:
  3. files: 'K8sdeploy/sukt-platform-admin-deployment-and-service.yaml'
  4. replacements: '$IMAGE_TAG=${{env.IMAGE_TAG}}.${{ github.run_number }}'
  • 第三步部署到K8s

    在部署到K8s之前我们需要先创建一个secrets用来存储K8sconfig,我使用的是【actions-hub/kubectl】这个库需要将K8s的config转换成base64,剩下的操作就是在github action里面引用这个库,并使用配置好的secret。具体代码如下:
  1. - uses: actions-hub/kubectl@master
  2. name: deploy to k8s
  3. env:
  4. KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
  5. with:
  6. 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的更多相关文章

  1. GitHub Actions 完成CI CD

    在之前我的部署.版本控制.CI.CD都是在Jenkins 下来完成的 在前几天看到github上的一个新玩具actions,简直惊为天人 它能在你的仓库触发事件(Push,Pull,issue,... ...

  2. 使用CI/CD工具Github Action发布jar到Maven中央仓库

    之前发布开源项目Payment Spring Boot到Maven中央仓库我都是手动执行mvn deploy,在CI/CD大行其道的今天使用这种方式有点"原始".于是我一直在寻求一 ...

  3. 用 GitHub Action 构建一套 CI/CD 系统

    ​ 缘起 Nebula Graph 最早的自动化测试是使用搭建在 Azure 上的 Jenkins,配合着 GitHub 的 Webhook 实现的,在用户提交 Pull Request 时,加个 r ...

  4. 技术番外篇丨Github Action CI/CD

    起源 看到.Net群里再聊CI/CD,我就这里分享一下我目前自己一些小东西的做法,我目前在Github有一个自己私有的组织,里面存放了我的部分商业化项目,早期我采用Jenkins用Webhooks进行 ...

  5. Github原生CI/CD,初尝Github Actions

    Github 原生 CI/CD,初尝 Github Actions Intro Github 目前已经推出了自己的 CICD 服务 -- Github Actions,而且比微软的 Azure Dev ...

  6. CI / CD in Action

    CI / CD in Action Continuous Integration (CI) & Continuous Delivery (CD) https://github.com/mark ...

  7. 好代码是管出来的——使用GitHub实现简单的CI/CD

    软件开发一般来说是一项团队作业,在本系列文章开始就提到过软件的编码是由一个团队“并行”完成的,为了保证编码任务正常完成,首先引入版本控制工具来完成代码管理,为了保证代码质量引入了代码分析器以及代码测试 ...

  8. 使用.NET 6开发TodoList应用(31)——实现基于Github Actions和ACI的CI/CD

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求和目标 在这个系列的最后一节中,我们将使用GitHub Actions将TodoList应用部署到Azure Container ...

  9. Jenkins 结合 Docker 为 .NET Core 项目实现低配版的 CI&CD

    随着项目的不断增多,最开始单体项目手动执行 docker build 命令,手动发布项目就不再适用了.一两个项目可能还吃得消,10 多个项目每天让你构建一次还是够呛.即便你的项目少,每次花费在发布上面 ...

随机推荐

  1. Typora配置阿里云图床

    一.Typora安装PicGo 更新typora到最新版,打开文件-->偏好设置-->图像-->上传服务选择PicGo-Core-->下载或更新   二.注册并配置阿里云 1. ...

  2. GitHub 官方大动作频频「GitHub 热点速览 v.22.24」

    作者:HelloGitHub-小鱼干 本周 GitHub 官方 Blog 很是热闹,GitHub 官方大动作频频也带来了 GitHub Blog 的频繁更新,除了本周 News 快读收录的 GitHu ...

  3. SQL Server导出MDF数据库文件

    更新日志 2022年6月13日 发布. 2022年6月2日 开始. 一句话总结:先分离,然后复制. 先分离要导出mdf数据库文件的数据库. 在Microsoft SQL Server Manageme ...

  4. 编程技巧│浏览器 Notification 桌面推送通知

    目录 一.什么是 Notification 二.弹窗授权 三.弹窗使用 四.浏览器支持检测 五.授权回调 六.3秒后关闭弹窗 一.什么是 Notification Notification 是浏览器最 ...

  5. SAP 实例- 下拉框

    效果图 源代码 REPORT rsdemo_dropdown_listbox . DATA init. TABLES scarr. TABLES spfli. TABLES sflight. TABL ...

  6. Java创建TXT文件并写入 内容

    public static void main(String[] args) { String filePath = "E:/" + "1.txt"; Stri ...

  7. Oracle数据库常用查询语句

    1.[oracle@dbserver ~]$ sqlplus / as sysdbaSQL*Plus: Release 11.2.0.4.0 Production on Tue Mar 15 15:1 ...

  8. Whats On Tap | Tapdata Cloud 如何助力大型家居连锁商城推进数字化经营?

    Tapdata Cloud 的操作有多便捷,上手试一下就能充分了解了.--Tapdata Cloud 用户 | 报表实施 @某大型家居服务平台 一边是监管政策趋严,推动房地产回归本源,存量竞争时代开启 ...

  9. Linux快捷方式创建模板

    1.创建快捷方式文件 sudo gedit /usr/share/applications/Navicat.desktop 模板: [Desktop Entry] Name=Navicat Exec= ...

  10. springboot中配置skywalking请求日志

    pom.xml配置 <dependency> <groupId>org.apache.skywalking</groupId> <artifactId> ...