基于AWS EKS的K8S实践系列文章是基于企业级的实战文章,一些设置信息需要根据公司自身要求进行设置,如果大家有问题讨论或咨询可以加我微信(公众号后台回复 程序员修炼笔记 可获取联系方式)。
Jenkins搭建
Jenkins的搭建工作按照官网的文档来进行就可以,这里建议主节点和工作节点分开,主节点不负责构建任务。
Jenkins的工作节点需要安装以下工具:
Jenkins需要安装以下插件:
让Jenkins可以连接集群
由于我们之前没有k8s集群,因此这里Jenkins我们还是使用之前部署在云主机上的Jenkins(不在k8s集群中),首先需要修改aws-auth ConfigMap,如下:
kubectl edit configmap -n kube-system aws-auth
需要在aws-auth ConfigMap中增加红框中的内容,其中rolearn是Jenkins Slave节点上的role。
最后Jenkins在执行连接集群的时候使用的是匿名用户,我这里比较简单粗暴,直接允许匿名用户访问集群所有资源,如下:
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
准备应用DeploymentFile模板文件
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: application-dev
name: xxxx
labels:
app: xxxx
spec:
replicas: 2
selector:
matchLabels:
app: xxxx
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
template:
metadata:
labels:
app: xxxx
spec:
restartPolicy: Always
containers:
- name: xxxx
image: DEPLOY_IMAGE
imagePullPolicy: Always
ports:
- containerPort: 8004
protocol: TCP
livenessProbe:
httpGet:
port: 8004
path: "/health/check"
initialDelaySeconds: 180
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
port: 8004
path: "/health/check"
initialDelaySeconds: 90
periodSeconds: 5
timeoutSeconds: 5
successThreshold: 5
failureThreshold: 3
以上模板文件大家根据公司的实际应用情况定制,目前我这里只需要在部署的时候替换镜像的版本(DEPLOY_IMAGE),其他的配置如果大家有人力开发自己的持续交付系统,像健康检测的地址Pod的数量也可以做成可配置的,在实际部署时进行替换。
Jenkins项目配置
这里我们选择自由风格类型的项目,后续我们会把Jenkins只用做构建,目前暂时没有持续集成交付系统,Jenkins是既要负责构建也要负责部署。
2. 设置Git构建参数,如下图:
红框中的地方替换成自己的Git项目地址。
3. 设置部署模块参数,类型为Extended Choice Parameter,如下图:
我们一个应用可能会有多个模块,比如app、admin之类的,这里是在我们构建部署的时候去选择,表明我们是去构建部署哪个模块(也可以全选)。
4. 设置部署环境参数,如下图:
通常我们一般会有多套应用环境,比如开发、测试、生产、UAT、预发等,这里的参数可以根据公司实际的应用环境进行填写。
5. 增加一个隐藏参数,用来设置项目名称,该参数不需要由用户选择,但是会在我们的构建脚本中进行使用,如下图:
6. 设置编译环境和Jenkins Slave节点,如下图:
比如我们这里的是Java应用,JDK版本需要根据每个应用的来定,比如选择是JDK8还是JDK11。
7. 设置代码仓库,如下图:
8. 设置构建环境,如下图:
这里我们设置k8s集群的地址和凭证,方便我们在部署时能够连接到k8s集群上。
9. 设置Build Steps,我们这里选择Shell,具体的脚本如下:
#!/bin/bash -e
### 解析需要部署的Module
deploy_modules=(${DEPLOY_MODULE//,/ })
echo ">>>>>>>>>>>>>>>>开始编译代码<<<<<<<<<<<<<<<<<<<<<<"
# 编译Java代码,这里需要根据每个应用来决定,我们这里是gradle
./gradlew build -x test
echo ">>>>>>>>>>>>>>>>结束编译代码<<<<<<<<<<<<<<<<<<<<<<"
### 我们这里使用的AWS ECR作为镜像仓库,这里请替换成公司的真实地址
ECR=xxxxxx.dkr.ecr.ap-southeast-3.amazonaws.com
### 定义镜像仓库,需要提前在ECR上建好
REPOSITORY_URI={ECR}/{PROJECT_NAME}
### 登录AWS ECR,这样后续可以进行镜像的推送
aws ecr get-login-password --region ap-southeast-3 | docker login --username AWS --password-stdin ${ECR}
IMAGE_TAG_SUFFIX=(echo {GIT_COMMIT} | cut -c 1-7)
### 定义部署脚本的临时目录
K8S_DEPLOY_LOCATION_PREFIX=/tmp/deploy-scripts/{PROJECT_NAME}/{BUILD_NUMBER}
mkdir -p ${K8S_DEPLOY_LOCATION_PREFIX}
### 按照部署模块生成构建镜像和部署脚本
for i in "${!deploy_modules[@]}"; do
APPLICATION_MODULE=${deploy_modules[i]}
DOCKER_FILE_NAME=${APPLICATION_MODULE}-dockerfile
IMAGE_NAME=REPOSITORY_URI:{APPLICATION_MODULE}-
SOURCE_FILE={APPLICATION_MODULE}/deploy-{DEPLOY_ENV}.yaml
TARGET_FILE={K8S_DEPLOY_LOCATION_PREFIX}/{SOURCE_FILE}
DEPLOY_IMAGE=(echo "
echo ">>>>>>>>>>>>>>>>开始构建应用模块:${APPLICATION_MODULE}<<<<<<<<<<<<<<<<<<<<<<"
### 从s3上拷贝模块的Dockerfile到本地,Dockefile请提前在s3上存储好
aws s3 cp s3://xxx-bucket/dockerfiles/{PROJECT_NAME}/{DOCKER_FILE_NAME} .
### 构建并推送镜像到ECR
docker build -t {IMAGE_NAME} -f ./{DOCKER_FILE_NAME} .
docker push {IMAGE_NAME} && docker rmi
### 将应用的Deployment文件拷贝到本地,模板文件请提前在s3上存储好
aws s3 cp s3://xxx-bucket/k8s-deployment-templates/{PROJECT_NAME}/{SOURCE_FILE}
### 替换Deployment中的镜像版本
sed -i "s/DEPLOY_IMAGE/
### 清理无用的Dockerfile
rm -rf ${DOCKER_FILE_NAME}
echo ">>>>>>>>>>>>>>>>结束构建应用模块:${APPLICATION_MODULE}<<<<<<<<<<<<<<<<<<<<<<"
done
### 保存此次部署执行的脚本及相关文件到S3
aws s3 cp {K8S_DEPLOY_LOCATION_PREFIX} s3://xxx-bucket/build-artifacts/{PROJECT_NAME}/
### 按模块执行部署
for i in "${!deploy_modules[@]}"; do
APPLICATION_MODULE=${deploy_modules[i]}
echo ">>>>>>>>>>>>>>>>开始部署:
kubectl apply -f {K8S_DEPLOY_LOCATION_PREFIX}/{APPLICATION_MODULE}/deploy-
echo ">>>>>>>>>>>>>>>>结束部署:
done
### 删除本地的部署脚本,避免占用构建服务过多空间
rm -rf ${K8S_DEPLOY_LOCATION_PREFIX}
构建触发
我们选择分支,部署模块,部署环境即可开始构建,如下图: