單頁網(wǎng)站對(duì)攻擊的好處如何做好互聯(lián)網(wǎng)營銷
前文
本文使用 Jenkins 結(jié)合 CodeBuild, CodeDeploy 實(shí)現(xiàn) Serverless 的 CI/CD 工作流,用于自動(dòng)化發(fā)布已經(jīng)部署 lambda 函數(shù)。 在 AWS 海外區(qū),CI/CD 工作流可以用 codepipeline 這項(xiàng)產(chǎn)品來方便的實(shí)現(xiàn),
CICD 基本概念
- 持續(xù)集成( Continuous Integration,簡(jiǎn)稱CI ) 是指在應(yīng)用代碼的新組件集成到共享存儲(chǔ)庫之后自動(dòng)測(cè)試和構(gòu)建軟件的流程。這樣一來,就可以打造出始終處于工作狀態(tài)的應(yīng)用“版本”。
- 持續(xù)交付( Continuous Deployment, 簡(jiǎn)稱CD )是指將CI流程中創(chuàng)建的應(yīng)用交付到類似生產(chǎn)環(huán)境的過程,在該過程中將對(duì)應(yīng)用進(jìn)行額外的自動(dòng)化測(cè)試,以確保應(yīng)用在部署到生產(chǎn)環(huán)境以及交付到真實(shí)用戶手中時(shí)能夠發(fā)揮預(yù)期作用。
架構(gòu)綜述
本文最終達(dá)到的效果為,源代碼在 Github repo 中,每當(dāng)有新的 commit,將自動(dòng)觸發(fā) Jenkins CICD 工作流,Jenkin 會(huì)利用 CodeBuild 做構(gòu)建,以及CodeDeploy 自動(dòng)部署發(fā)布 lambda 新版本。
jenkins環(huán)境準(zhǔn)備
jenkins EC2安裝
先拉一個(gè)每月750小時(shí)免費(fèi)的 EC2 實(shí)例t2.micro,? 最后配置一個(gè)固定的彈性ip,后面如果時(shí)不時(shí)要用停止/啟動(dòng)EC2 實(shí)后ip不用再重復(fù)配置
登錄EC2 安裝jenkins,? 我使用的是jenkins.war的方式部署為了避免jenkins 的使用環(huán)境上一些坑
jenkins.war的下載地址jenkins.war
安裝jdk-17
更新OS
sudo yum update -y設(shè)置yum源
sudo wget -O /etc/yum.repos.d/jenkins.repo \https://pkg.jenkins.io/redhat-stable/jenkins.repo導(dǎo)入公鑰
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key升級(jí)包
sudo yum upgrade安裝java
sudo dnf install java-17-amazon-corretto -y
把jenkins.war放到/usr/local/jenkins 目錄下,編輯 /etc/init.d/jenkins 作為啟動(dòng)腳本
#!/bin/bash# 在執(zhí)行過程中若遇到使用了未定義的變量或命令返回值為非零,將直接報(bào)錯(cuò)退出
set -eu
# Default-Start: 2 3 4 5# 檢查參數(shù)個(gè)數(shù)
if [ "${#}" -lt 1 ]; thenecho " 腳本使用示例: service jenkins start|stop|restart "exit
fi# 獲取腳本第一個(gè)參數(shù)
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
# 程序運(yùn)行參數(shù)
JAVA_OPTS="--httpPort=${APP_PORT}"echo "本次操作服務(wù)名:[${APP_NAME}]"
echo "本次操作選擇:[${APP_OPT}]"# 停止
function stop(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... stop ..."# 查看該jar進(jìn)程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}] 進(jìn)程不存在"fi
}# 運(yùn)行
function start(){echo "<-------------------------------------->"echo "[${APP_NAME}] ... start ..."cd ${APP_JAR_HOME}echo "當(dāng)前路徑:`pwd`"# 賦予可讀可寫可執(zhí)行權(quán)限chmod 777 ${APP_JAR}echo "啟動(dòng)命令: 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
}# 多分支條件判斷執(zhí)行參數(shù)
case "${APP_OPT}" in"stop")stop;;"start")start;;"restart")restart;;*)echo " 提示:不支持參數(shù) 命令 -> ${APP_OPT}";;
esac
jenkins工作目錄磁盤空間掛載
因?yàn)槲覀兪褂玫膍icro的EC2,? 需要給jenkins 工作目錄掛載更大的空間
Jenkins 默認(rèn)是安裝在/root/.jenkins 目錄下,查看目錄下使用和剩余空間
df -h /root/.jenkins/
將 /dev/nvme0n1p1 作為你的設(shè)備進(jìn)行掛載并增加 /root/.jenkins 的空間,以下是相應(yīng)的步驟: 步驟 1: 創(chuàng)建掛載點(diǎn)創(chuàng)建一個(gè)新的目錄作為掛載點(diǎn)(例如 /mnt/jenkins_data):
sudo mkdir -p /mnt/jenkins_data
步驟 2: 掛載文件系統(tǒng) 將設(shè)備 /dev/nvme0n1p1 掛載到新創(chuàng)建的目錄:
sudo mount /dev/nvme0n1p1 /mnt/jenkins_data
步驟 3: 更新 /etc/fstab 為了確保在重啟后仍然保持掛載,需要更新 /etc/fstab 文件。打開該文件進(jìn)行編輯:
sudo nano /etc/fstab
在文件末尾添加以下行:
/dev/nvme0n1p1 /mnt/jenkins_data ext4 defaults,nofail 0 2
確保根據(jù)實(shí)際文件系統(tǒng)類型(如 ext4)進(jìn)行調(diào)整。 步驟 4: 移動(dòng) Jenkins 數(shù)據(jù) 如果 /root/.jenkins 中的數(shù)據(jù)需要遷移到新的掛載點(diǎn):
sudo cp -r /root/.jenkins/* /mnt/jenkins_data/ sudo ln -s /mnt/jenkins_data /root/.jenkins
查看現(xiàn)在的工作空間大小
micro 免費(fèi)的同時(shí)就得隨時(shí)手動(dòng)掛載確??臻g足夠,后面jenkins 交換空間不夠也是這樣解決的,
Dashboard -> 系統(tǒng)管理 -> 節(jié)點(diǎn)列表上, 如果資源不夠是無法啟動(dòng)構(gòu)建job的
啟動(dòng)jenkins
查看 Jenkins 初始密碼
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
登錄后安裝必要的插件會(huì)花費(fèi)一些時(shí)間
Github 準(zhǔn)備
?創(chuàng)建一個(gè)項(xiàng)目類似于我做實(shí)踐用的
https://github.com/chenrui2200/aws-jenkins-codepipeline
?develop setting 里生成token
?
保存該token后面會(huì)用到多次
配置webhooks
在項(xiàng)目?jī)?nèi)setting里配置webhooks ,? PayloadUrl 填寫 <jenkins_url>/github-webhook/
點(diǎn)擊保存
jenkins system configure 配置access token
把a(bǔ)ccess token 錄入到credentials
跳轉(zhuǎn)system configuration
找到github server,? 使用access token配置https://api.github.com
添加認(rèn)證方式,在箭頭處填寫github access token
點(diǎn)擊測(cè)試連接出現(xiàn)下面字樣說明配置成功
項(xiàng)目文件準(zhǔn)備
新建基于 python 的 lambda 函數(shù)。此 lambda 函數(shù)為我們的目標(biāo) lambda 函數(shù),在本實(shí)驗(yàn)完成后,每當(dāng)有新的 commit,都會(huì)觸發(fā)此 lambda 函數(shù)進(jìn)行自動(dòng)化部署。 如您不清楚步驟,請(qǐng)參考創(chuàng)建您的第一個(gè) Lambda 函數(shù)?此文重在搭建 CICD 流水線,代碼會(huì)直接用默認(rèn)生成的 python 代碼 lambda_function.py。
publish 此 lambda,版本為1,并且創(chuàng)建別名(alias)。
除此以外,還需要添加另外兩個(gè)文件
- appspec.template.yaml, 用于 codedeploy 配置文件。請(qǐng)將此文件當(dāng)中的函數(shù)名以及 alias(別名)替換為自己對(duì)應(yīng)的值。
- buildspec.yml,用于 codebuild 配置文件,修改替換文件中尖括號(hào)標(biāo)注部分(去掉尖括號(hào))。
buildspec.yml
version: 0.2phases:install:runtime-versions:python: 3.7commands:- echo pre Installing ...pre_build:commands:- echo prebuild,Installing update ...# 基本環(huán)境更新#- yum update -ybuild:commands:- echo Build started on `date`post_build:commands:- ls - mkdir build- # 替換所有尖括號(hào)標(biāo)注,替換時(shí),去掉尖括號(hào)- CurrentVersion=$(echo $(aws lambda get-alias --function-name <替換為自己的 lambda 函數(shù) 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 函數(shù) ARN> --zip-file fileb://build/lambda.zip --region <your_region> --publish- TargetVersion=$(echo $(aws lambda list-versions-by-function --function-name <替換為自己的 lambda 函數(shù) 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 準(zhǔn)備
Codebuild 準(zhǔn)備
新建codebuild項(xiàng)目
【源】選擇github, 點(diǎn)擊管理認(rèn)證憑證配置訪問憑證
認(rèn)證成功
其他選項(xiàng)不用動(dòng)
選擇EC2 相同的vpc
使用buildspec文件構(gòu)建,文件名對(duì)應(yīng)的是github項(xiàng)目里的buildspec.yml 文件名稱
codebuild選擇的role需要具備 s3 codebuild的權(quán)限
CodeDeploy 準(zhǔn)備
計(jì)算平臺(tái)選擇lamda
創(chuàng)建部署組組
codedeploy選擇的role需要具備 codedeploy 的權(quán)限
構(gòu)建CI/CD 流程
創(chuàng)建一個(gè) Jenkin 的項(xiàng)目,配置 codedeploy 相應(yīng)信息
新建項(xiàng)目之前,先安裝 codebuild 的插件。點(diǎn)擊 系統(tǒng)管理 -- 插件管理(plugin)
新建一Jenkins個(gè)項(xiàng)目,點(diǎn)擊“Create a new project” -- "freestyle project"
配置Github項(xiàng)目的地址,源代碼管理選擇Git方式。
上面credentials沒有顯示secret text類別的,需要安裝Plain Credentials Plugin。您還需要安裝Credentials Binding Plugin來傳遞憑據(jù), 同時(shí)宿主機(jī)上需要安裝 git
觸發(fā)構(gòu)建,選擇 Github hook trigger for GITScm polling
配置 AK, SK , region, project-name
嘗試提交push下代碼, 看到push事件已經(jīng)觸發(fā)了jenkins
jenkins端插件已經(jīng)觸發(fā)了codebuild 去構(gòu)建,提交者是codebuild-jenkins plugin
整個(gè)流程已經(jīng)打通, 查看jenkins 的構(gòu)建日志
Codebuild 日志也看到成功了
查看lambda 函數(shù)已經(jīng)成功更新了
有小伙伴反饋無法啟動(dòng)jenkins job出現(xiàn)下面錯(cuò)誤
Dashboard ->? 系統(tǒng)管理 ->? 節(jié)點(diǎn)列表 下查看節(jié)點(diǎn)狀態(tài)
增加/tmp 目錄下磁盤空間, 使用/etc/fstab 擴(kuò)展空間
[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、登陸服務(wù)器,查看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