AWS codebuild + jenkins + github 实践CI/CD
前文
本文使用 Jenkins 结合 CodeBuild, CodeDeploy 实现 Serverless 的 CI/CD 工作流,用于自动化发布已经部署 lambda 函数。 在 AWS 海外区,CI/CD 工作流可以用 codepipeline 这项产品来方便的实现,
CICD 基本概念
- 持续集成( Continuous Integration,简称CI ) 是指在应用代码的新组件集成到共享存储库之后自动测试和构建软件的流程。这样一来,就可以打造出始终处于工作状态的应用“版本”。
- 持续交付( Continuous Deployment, 简称CD )是指将CI流程中创建的应用交付到类似生产环境的过程,在该过程中将对应用进行额外的自动化测试,以确保应用在部署到生产环境以及交付到真实用户手中时能够发挥预期作用。
架构综述
本文最终达到的效果为,源代码在 Github repo 中,每当有新的 commit,将自动触发 Jenkins CICD 工作流,Jenkin 会利用 CodeBuild 做构建,以及CodeDeploy 自动部署发布 lambda 新版本。
jenkins环境准备
jenkins EC2安装
先拉一个每月750小时免费的 EC2 实例t2.micro, 最后配置一个固定的弹性ip,后面如果时不时要用停止/启动EC2 实后ip不用再重复配置
登录EC2 安装jenkins, 我使用的是jenkins.war的方式部署为了避免jenkins 的使用环境上一些坑
jenkins.war的下载地址jenkins.war
安装jdk-17
更新OS
sudo yum update -y设置yum源
sudo wget -O /etc/yum.repos.d/jenkins.repo \https://pkg.jenkins.io/redhat-stable/jenkins.repo导入公钥
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key升级包
sudo yum upgrade安装java
sudo dnf install java-17-amazon-corretto -y
把jenkins.war放到/usr/local/jenkins 目录下,编辑 /etc/init.d/jenkins 作为启动脚本
#!/bin/bash# 在执行过程中若遇到使用了未定义的变量或命令返回值为非零,将直接报错退出
set -eu
# Default-Start: 2 3 4 5# 检查参数个数
if [ "${#}" -lt 1 ]; thenecho " 脚本使用示例: service jenkins start|stop|restart "exit
fi# 获取脚本第一个参数
APP_OPT=${1}
# 端口
APP_PORT=9001
# 名称
APP_NAME=jenkins
# jar名 | war名
APP_JAR=${APP_NAME}.war
# 程序根目录
APP_JAR_HOME=/usr/local/jenkins
# 日志名
APP_LOG_NAME=app-jenkins
# 日志根目录
APP_LOG_HOME=/usr/local/jenkins/log
# 程序运行参数
JAVA_OPTS="--httpPort=${APP_PORT}"echo "本次操作服务名:[${APP_NAME}]"
echo "本次操作选择:[${APP_OPT}]"# 停止
function stop(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... stop ..."# 查看该jar进程pid=`ps -ef | grep ${APP_NAME} | grep -v 'grep' | awk '{print $2}'`echo "[${APP_NAME}] pid="${pid}# 存在则kill,不存在打印一下吧if [ "${pid}" ]; thenkill -9 ${pid}# 检查kill是否成功if [ "$?" -eq 0 ]; thenecho "[${APP_NAME}] stop success"elseecho "[${APP_NAME}] stop fail"fielseecho "[${APP_NAME}] 进程不存在"fi
}# 运行
function start(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... start ..."cd ${APP_JAR_HOME}echo "当前路径:`pwd`"# 赋予可读可写可执行权限chmod 777 ${APP_JAR}echo "启动命令: nohup java -jar ${APP_JAR} ${JAVA_OPTS} >> ${APP_LOG_HOME}/${APP_LOG_NAME}.log 2>&1 &"sudo nohup java -jar ${APP_JAR} ${JAVA_OPTS} >> ${APP_LOG_HOME}/${APP_LOG_NAME}.log 2>&1 &if [ "$?" -eq 0 ]; thenecho "[${APP_NAME}] start success"elseecho "[${APP_NAME}] start fail"fi
}# 重启
function restart(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... restart ..."stopsleep 3start
}# 多分支条件判断执行参数
case "${APP_OPT}" in"stop")stop;;"start")start;;"restart")restart;;*)echo " 提示:不支持参数 命令 -> ${APP_OPT}";;
esac
jenkins工作目录磁盘空间挂载
因为我们使用的micro的EC2, 需要给jenkins 工作目录挂载更大的空间
Jenkins 默认是安装在/root/.jenkins 目录下,查看目录下使用和剩余空间
df -h /root/.jenkins/
将 /dev/nvme0n1p1 作为你的设备进行挂载并增加 /root/.jenkins 的空间,以下是相应的步骤: 步骤 1: 创建挂载点创建一个新的目录作为挂载点(例如 /mnt/jenkins_data):
sudo mkdir -p /mnt/jenkins_data
步骤 2: 挂载文件系统 将设备 /dev/nvme0n1p1 挂载到新创建的目录:
sudo mount /dev/nvme0n1p1 /mnt/jenkins_data
步骤 3: 更新 /etc/fstab 为了确保在重启后仍然保持挂载,需要更新 /etc/fstab 文件。打开该文件进行编辑:
sudo nano /etc/fstab
在文件末尾添加以下行:
/dev/nvme0n1p1 /mnt/jenkins_data ext4 defaults,nofail 0 2
确保根据实际文件系统类型(如 ext4)进行调整。 步骤 4: 移动 Jenkins 数据 如果 /root/.jenkins 中的数据需要迁移到新的挂载点:
sudo cp -r /root/.jenkins/* /mnt/jenkins_data/ sudo ln -s /mnt/jenkins_data /root/.jenkins
查看现在的工作空间大小

micro 免费的同时就得随时手动挂载确保空间足够,后面jenkins 交换空间不够也是这样解决的,
Dashboard -> 系统管理 -> 节点列表上, 如果资源不够是无法启动构建job的

启动jenkins

查看 Jenkins 初始密码
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
登录后安装必要的插件会花费一些时间

Github 准备
创建一个项目类似于我做实践用的
https://github.com/chenrui2200/aws-jenkins-codepipeline
develop setting 里生成token

保存该token后面会用到多次
配置webhooks
在项目内setting里配置webhooks , PayloadUrl 填写 <jenkins_url>/github-webhook/

点击保存

jenkins system configure 配置access token
把access token 录入到credentials
跳转system configuration

找到github server, 使用access token配置https://api.github.com

添加认证方式,在箭头处填写github access token

点击测试连接出现下面字样说明配置成功

项目文件准备
新建基于 python 的 lambda 函数。此 lambda 函数为我们的目标 lambda 函数,在本实验完成后,每当有新的 commit,都会触发此 lambda 函数进行自动化部署。 如您不清楚步骤,请参考创建您的第一个 Lambda 函数 此文重在搭建 CICD 流水线,代码会直接用默认生成的 python 代码 lambda_function.py。
publish 此 lambda,版本为1,并且创建别名(alias)。
除此以外,还需要添加另外两个文件
- appspec.template.yaml, 用于 codedeploy 配置文件。请将此文件当中的函数名以及 alias(别名)替换为自己对应的值。
- buildspec.yml,用于 codebuild 配置文件,修改替换文件中尖括号标注部分(去掉尖括号)。
buildspec.yml
version: 0.2phases:install:runtime-versions:python: 3.7commands:- echo pre Installing ...pre_build:commands:- echo prebuild,Installing update ...# 基本环境更新#- yum update -ybuild:commands:- echo Build started on `date`post_build:commands:- ls - mkdir build- # 替换所有尖括号标注,替换时,去掉尖括号- CurrentVersion=$(echo $(aws lambda get-alias --function-name <替换为自己的 lambda 函数 ARN> --name <替换为自己的lambda alias> --region <your_region> | grep FunctionVersion | tail -1 |tr -cd "[0-9]"))- zip -r ./build/lambda.zip ./lambda_function.py- aws lambda update-function-code --function-name <替换为自己的 lambda 函数 ARN> --zip-file fileb://build/lambda.zip --region <your_region> --publish- TargetVersion=$(echo $(aws lambda list-versions-by-function --function-name <替换为自己的 lambda 函数 ARN> --region <your_region> | grep Version | tail -1 | tr -cd "[0-9]"))- echo $CurrentVersion- echo $TargetVersion- sed -e 's/{{CurrentVersion}}/'$CurrentVersion'/g' -e 's/{{TargetVersion}}/'$TargetVersion'/g' appspec.template.yaml > appspec.yaml- aws s3 cp appspec.yaml s3://<替换为自己的S3 Bucket名称>/jenkins/codedeploy/appspec.yaml- # 替换 first-try-with-jenkins 为自己的codedeploy名称- aws deploy create-deployment --application-name first-try-with-jenkins --deployment-group-name first-try-with-jenkins --s3-location bucket='<替换为自己的S3 Bucket名称>',key='jenkins/codedeploy/appspec.yaml',bundleType=YAML
artifacts:type: yamlfiles:- appspec.yaml
appspec.template.yaml
version: 0.0
Resources:- test: # Replace "MyFunction" with the name of your Lambda functionType: AWS::Lambda::FunctionProperties:Name: "test" # Specify the name of your Lambda functionAlias: "beta" # Specify the alias for your Lambda functionCurrentVersion: "{{CurrentVersion}}" # Specify the current version of your Lambda functionTargetVersion: "{{TargetVersion}}" # Specify the version of your Lambda function to deploy
lambda_function.py
import jsondef lambda_handler(event, context):# TODO implementreturn {'statusCode': 200,'body': json.dumps('Hello from Lambda!')}
AWS 准备
Codebuild 准备
新建codebuild项目

【源】选择github, 点击管理认证凭证配置访问凭证
认证成功

其他选项不用动


选择EC2 相同的vpc

使用buildspec文件构建,文件名对应的是github项目里的buildspec.yml 文件名称


codebuild选择的role需要具备 s3 codebuild的权限
CodeDeploy 准备
计算平台选择lamda

创建部署组组

codedeploy选择的role需要具备 codedeploy 的权限
构建CI/CD 流程
创建一个 Jenkin 的项目,配置 codedeploy 相应信息
新建项目之前,先安装 codebuild 的插件。点击 系统管理 -- 插件管理(plugin)



新建一Jenkins个项目,点击“Create a new project” -- "freestyle project"

配置Github项目的地址,源代码管理选择Git方式。

上面credentials没有显示secret text类别的,需要安装Plain Credentials Plugin。您还需要安装Credentials Binding Plugin来传递凭据, 同时宿主机上需要安装 git
触发构建,选择 Github hook trigger for GITScm polling

配置 AK, SK , region, project-name

尝试提交push下代码, 看到push事件已经触发了jenkins

jenkins端插件已经触发了codebuild 去构建,提交者是codebuild-jenkins plugin

整个流程已经打通, 查看jenkins 的构建日志

Codebuild 日志也看到成功了

查看lambda 函数已经成功更新了

有小伙伴反馈无法启动jenkins job出现下面错误

Dashboard -> 系统管理 -> 节点列表 下查看节点状态

增加/tmp 目录下磁盘空间, 使用/etc/fstab 扩展空间
[root@ip-10-0-13-218 ~]# sudo mount -t tmpfs -o size=2G tmpfs /tmp
[root@ip-10-0-13-218 ~]# echo "tmpfs /tmp tmpfs defaults,size=2G 0 0" | sudo tee -a /etc/fstab
tmpfs /tmp tmpfs defaults,size=2G 0 0
[root@ip-10-0-13-218 ~]# df -h /tmp/
Filesystem Size Used Avail Use% Mounted on
tmpfs 2.0G 0 2.0G 0% /tmp
剩余交换空间不足问题通过下面命令解决
参考这篇帖子 Jenkins - Free Swap Space 0(剩余交换空间为0)_jenkins free swap space-CSDN博客
解决方式:
1、登陆服务器,查看swap,如下所示,没有配置swap
free|grep -i Swap
Swap: 0 0 0
2、配置swap
dd if=/dev/zero of=swapfile bs=1M count=1K
mkswap swapfile
sudo chown root:root swapfile
sudo chmod 600 swapfile
sudo swapon swapfile
3、查看swap,配置成
free|grep -i Swap
Swap: 1048572 0 1048572
相关文章:
AWS codebuild + jenkins + github 实践CI/CD
前文 本文使用 Jenkins 结合 CodeBuild, CodeDeploy 实现 Serverless 的 CI/CD 工作流,用于自动化发布已经部署 lambda 函数。 在 AWS 海外区,CI/CD 工作流可以用 codepipeline 这项产品来方便的实现, CICD 基本概念 持续集成( Continuous…...
Android PMS(Package Manager Service)源码介绍
文章目录 前言一、PMS 启动流程二、APK 安装流程三、APK 卸载流程四、权限管理静态权限动态权限 五、 数据存储与一致性六、 PMS 的安全性策略1、权限检查2、签名认证3、动态权限管理4、应用安装验证5、保护系统目录 七、PMS 调试方法总结 前言 PackageManagerService…...
运维面试整理总结
面试题可以参考:面试题总结 查看系统相关信息 查看系统登陆成功与失败记录 成功:last失败:lastb 查看二进制文件 hexdump查看进程端口或连接 netstat -nltp ss -nltp补充:pidof与lsof命令 pidof [进程名] #根据 进程名 查询进程id ls…...
图数据库 Cypher语言
图数据库 属性图 属性图(Property Graph)概述 属性图是一种广泛用于建模关系数据的图数据结构,它将**顶点(节点)和边(关系)**进行结构化存储,并为它们附加属性以提供丰富的语义信…...
阿里云oss转发上线-实现不出网钓鱼
本地实现阿里云oss转发上线,全部代码在文末,代码存在冗余 实战环境 被钓鱼机器不出网只可访问内部网络包含集团oss 实战思路 若将我们的shellcode文件上传到集团oss上仍无法上线,那么就利用oss做中转使用本地转发进行上线,先发送…...
Spring Boot 3.4.0 发行:革新与突破的里程碑
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
【网络安全】
黑客入侵 什么是黑客入侵? “黑客”是一个外来词,是英语单词hacker的中文音译。最初,“黑客”只是一个褒义词,指的是那些尽力挖掘计算机程序最大潜力的点脑精英,他们讨论软件黑客的技巧和态度,以及共享文化…...
在SQLyog中导入和导出数据库
导入 假如我要导入一个xxx.sql,我就先创建一个叫做xxx的数据库。 然后右键点击导入、执行SQL脚本 选择要导入的数据库文件的位置,点击执行即可 注意: 导入之后记得刷新一下导出 选择你要导出的数据库 右键选择:备份/导出、…...
RabbitMQ简单应用
概念 RabbitMQ 是一种流行的开源消息代理(Message Broker)软件,它实现了高级消息队列协议(AMQP - Advanced Message Queuing Protocol)。RabbitMQ 通过高效的消息传递机制,主要应用于分布式系统中解耦应用…...
使用LUKS对Linux磁盘进行加密
前言 本实验用于日常学习用,如需对存有重要数据的磁盘进行操作,请做好数据备份工作。 此实验只是使用LUKS工具的冰山一角,后续还会有更多功能等待探索。 LUKS(Linux Unified Key Setup)是Linux系统中用于磁盘加密的一…...
戴尔电脑安装centos7系统遇到的问题
1,找不到启动盘(Operation System Loader signature found in SecureBoot exclusion database(‘dbx’).All bootable devices failed secure Boot Verification) 关闭 Secure Boot(推荐): 进入 BIOS/UEFI…...
3.4.SynchronousMethodHandler组件之ResponseHandler
前言 feign发送完请求后, 拿到返回结果, 那么这个返回结果肯定是需要经过框架进一步处理然后再返回到调用者的, 其中ResponseHandler就是用来处理这个返回结果的, 这也是符合正常思维的处理方式, 例如springmvc部分在调用在controller端点前后都会增加扩展点。 从图中可以看得…...
Linux 下进程的状态
操作系统中常见进程状态 在操作系统中有六种常见进程状态: 新建状态: 进程正在被创建. 此时操作系统会为进程分配资源, 如: 内存空间等, 进行初始化就绪状态: 进程已经准备好运行了, 只需要等待被调度, 获取 CPU 资源就可以执行了, 操作系统中可能同时存在多个进程处于就绪状…...
【计算机网络】核心部分复习
目录 交换机 v.s. 路由器OSI七层更实用的TCP/IP四层TCPUDP 交换机 v.s. 路由器 交换机-MAC地址 链接设备和设备 路由器- IP地址 链接局域网和局域网 OSI七层 物理层:传输设备。原始电信号比特流。数据链路层:代表是交换机。物理地址寻址,交…...
Spring Boot开发实战:从入门到构建高效应用
Spring Boot 是 Java 开发者构建微服务、Web 应用和后端服务的首选框架之一。其凭借开箱即用的特性、大量的自动化配置和灵活的扩展性,极大简化了开发流程。本文将以实战为核心,从基础到高级,全面探讨 Spring Boot 的应用开发。 一、Spring B…...
pyshark安装使用,ubuntu:20.04
1.容器创建 命令 docker run -d --name pyshark -v D:\src:/root/share ubuntu:2004 /bin/bash -c "while true;do sleep 1000;done" 用于创建并启动一个新的 Docker 容器。 docker run -d --name pyshark -v D:\src:/root/share ubuntu:2004 /bin/bash -c "w…...
基本功能实现
目录 1、环境搭建 2、按键控制灯&电机 LED 电机 垂直按键(机械按键) 3、串口调试功能 4、定时器延时和定时器中断 5、振动强弱调节 6、万年历 7、五方向按键 1、原理及分析 2、程序设计 1、环境搭建 需求: 搭建一个STM32F411CEU6工程 分析: C / C 宏定义栏…...
《那个让服务器“跳舞”的bug》
在程序的世界里,bug 就像隐藏在暗处的小怪兽,时不时跳出来捣乱。而在我的职业生涯中,有一个bug让我至今难忘,它不仅让项目差点夭折,还让我熬了无数个通宵。这个故事发生在一个风和日丽的下午,我们正在开发一…...
Python 网络爬虫进阶:动态网页爬取与反爬机制应对
在上一篇文章中,我们学习了如何使用 Python 构建一个基本的网络爬虫。然而,在实际应用中,许多网站使用动态内容加载或实现反爬机制来阻止未经授权的抓取。因此,本篇文章将深入探讨以下进阶主题: 如何处理动态加载的网…...
创建可直接用 root 用户 ssh 登陆的 Docker 镜像
有时候我们在 Mac OS X 或 Windows 平台下需要开发以 Linux 为运行时的应用,IDE 或可直接使用 Docker 容器,或 SSH 远程连接。本地命令行下操作虽然可以用 docker exec 连接正在运行的容器,但 IDE 远程连接的话 SSH 总是一种较为通用的连接方…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
Android屏幕刷新率与FPS(Frames Per Second) 120hz
Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数,单位是赫兹(Hz)。 60Hz 屏幕:每秒刷新 60 次,每次刷新间隔约 16.67ms 90Hz 屏幕:每秒刷新 90 次,…...
Qwen系列之Qwen3解读:最强开源模型的细节拆解
文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...
C++11 constexpr和字面类型:从入门到精通
文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...
