准備環境
- 需求
1.通過jenkins 完成k8s 項目的自動化構建需求,要求nodejs、java等不同開發語言運用不同的jenkins slave 節點構建
2.通過權限設置管控開發人員的項目使用及構建
- jenkins 節點准備
| 節點名稱 | ip地址 |
|---|---|
| jenkins-master | 10.65.91.164 |
| jenkins-slave-nodejs | 10.65.91.52 |
| jenkins-slave-java | 10.65.91.165 |
- k8s 環境
k8s 已完成部署,部署方式參照之前博客文檔,以下是博客地址
jenkins master 節點安裝
- 下載安裝包並啟動
#下載lts 版本war包
cd /opt/
wget https://get.jenkins.io/war-stable/2.289.1/jenkins.war --no-check-certificate
#安裝git
yum -y install git
#配置java 環境
vim /etc/profile
JAVA_HOME=/usr/local/jdk1.8.0_201
JRE_HOME=/usr/local/jdk1.8.0_201/jre
PATH=$JAVA_HOME/bin:$PATH:$JRE_HOME/bin:/usr/local/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME JRE_HOME CLASSPATH PATH
#查看java 安裝完成
source /etc/profile
java -version
#創建jenkins 普通用戶
useradd jenkins
#創建jenkins 數據目錄
mkdir /export/jenkins/
mkdir /var/log/jenkins/
chown jenkins:jenkins /export/jenkins/ -R
chown jenkins:jenkins /var/log/jenkins/ -R
#啟動jenkins
su - jenkins
java -Djava.awt.headless=true -DsessionTimeout=1440 -DJENKINS_HOME=/export/jenkins/ -jar /opt/jenkins.war --logfile=/var/log/jenkins/jenkins.log --httpPort=8608 --debug=5 --handlerCountMax=100 --handlerCountMaxIdle=20 &
Jenkins master 節點配置
- 安裝插件
#訪問Jenkins地址
http://10.65.91.164:8608/
#安裝推薦插件
將推薦插件安裝完成
#安裝權限插件
Role-based Authorization Strategy
#安裝時間戳插件
BUILD_TIMESTAMP
#安裝git參數插件
Git Parameter
#安裝注冊環境變量插件
Environment Injector
#安裝Maven 插件
Maven Intergration
#重啟jenkins
- 系統配置
#系統管理-系統配置-全局屬性,增加鍵值對
LANG->zh_CN.UTF-8

#系統管理-系統配置-Build Timestamp
Timezone->Asia/Shanghai
Pattern->yyyyMMddHHmmss

- 連接ldap
#系統管理-全局安全配置-安全域-LDAP
添加完ldap 配置后可以點擊 Test LDAP settings,檢測ldap 賬號密碼是否生效


#系統管理-全局安全配置-授權策略
選擇Role-Based Strategy
#應用-保存

- 配置權限
#系統管理-Manage and Assign Roles-Manage Roles,增加itemadmin 賬號,並授權

#系統管理-Manage and Assign Roles-Assign Roles,增加ldap 運維管理員人員權限
出現No type prefix: admin ,但是不影響后續權限使用,是沒有關系的
admin 用戶將不能登錄jenkins,只有分配admin 權限的ldap 賬戶可以登錄jenkins,並且擁有admin 權限

jenkins nodejs slave 節點添加並構建項目
- nodejs slave 節點系統環境配置
#安裝docker 環境
因后續要構建鏡像,因此需要有docker 環境,參照之前裝docker 的文檔安裝docker 環境
#配置docker 可以連接harbor
cat /etc/docker/daemon.json
{
"oom-score-adjust": -1000,
"registry-mirrors": [
"https://c6ai9izk.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn"
],
"log-driver":"json-file",
"log-opts":{ "max-size" :"100m","max-file":"1"},
"insecure-registries": ["harbor.dev.k8s.xxx.cn","harbor.k8s.xxx.cn"],
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"exec-opts": ["native.cgroupdriver=systemd"]
}
#安裝git
yum -y install git
#配置java 環境
vim /etc/profile
JAVA_HOME=/usr/local/jdk1.8.0_201
JRE_HOME=/usr/local/jdk1.8.0_201/jre
PATH=$JAVA_HOME/bin:$PATH:$JRE_HOME/bin:/usr/local/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME JRE_HOME CLASSPATH PATH
#查看java 安裝完成
source /etc/profile
java -version
#創建jenkins 普通用戶
useradd jenkins
#創建jenkins 數據目錄
mkdir /export/jenkins/
chown jenkins:jenkins /export/jenkins/ -R
#將jenkins 用戶添加到docker 組,可以用普通jenkins 用戶運行docker 命令
usermod -a -G jenkins,docker jenkins
#下載nodejs 二進制包node-v12.19.0-linux-x64,注意千萬不要使用別的機器拷貝過來的node 包,因為少軟連接,npm 運行會報錯的。
cd /opt/
wget https://nodejs.org/download/release/v12.19.0/node-v12.19.0-linux-x64.tar.gz
tar -xf node-v12.19.0-linux-x64.tar.gz
#測試node 環境是否可用
export PATH=/opt/node-v12.19.0-linux-x64/bin/:$PATH
node -v
npm -v
#安裝kubectl 、配置連接k8s 的config 文件
#從 k8s master節點上將Kubectl 傳至nodejs 節點
scp -qpr /usr/local/bin/kubectl 10.65.91.52:/usr/local/bin/
#將k8s master 節點上的config 文件傳至nodejs 節點
cd .kube
scp -qpr config 10.65.91.52:/root/
#登錄nodejs 10.65.91.52 節點
mkdir /opt/kubernetes
mv /root/config /opt/kubernetes
cd /opt/kubernetes
mv config config_prod
#測試是否可以連接k8s 集群,返回node 節點信息表示可以正常連接
/usr/local/bin/kubectl --kubeconfig=/opt/kubernetes/config_prod get node
# 將jenkins master 節點jenkins 普通用戶的公鑰傳至 nodejs 普通用戶jenkins 目錄下,以便於jenkins master 節點的jenkins 用戶可以免密登錄nodejs 節點
登錄 10.65.91.164,執行
su - jenkins
ssh jenkins@10.65.91.52
登錄成功即可
- 配置憑據 jenkins-slave 用來jenkins master節點可以通過秘鑰連接至 slave 節點
#系統管理-Manage Credentials-新創建憑據
范圍:全局(Jenkins,nodes,items,all child items,etc)
ID:jenkins-slave
描述:jenkins-slave
Username: jenkins
Private Key: 添加jenkins master jenkins 用戶的私鑰,因為之前已將jenkins 用戶的公鑰放至jenkins node slave 節點

- jenkins master 節點添加 nodejs jenkins slave 節點
系統管理-節點管理-新建節點
名稱:jks-node-1
描述:jks-node-1
Number of executors:2
遠程工作目錄:/export/jenkins
標簽:node
用法:只允許運行綁定到這台機器的JOb
啟動方式:Launch agents via SSH
主機:10.65.91.52
Credential:jenkins-slave (上面已經配置好的憑據)
Host Key Verification Strategy:Know hosts file Verification Strategy
可用性:盡量保持代理在線
節點屬性-環境變量:鍵:LANG 值:UTF-8
啟動slave 節點


- 部署jenkins nodejs 項目
#Dashboard - 新建任務文件夾 -Production (顯示名稱:正式環境) - 新建Item - 3Dmodel-Prod (顯示名稱:正式環境-3D模型分享平台-3Dmodel) -新建Item(構建一個自由風格的軟件項目) - 3Dmodel_Node_Prod

#增加gitlab 拉取代碼的憑據
#系統管理-Manage Credentials-新創建憑據
范圍:全局(Jenkins,nodes,items,all child items,etc)
用戶名: jenkins
密碼: 123456
ID: 不用寫
描述:gitlab token

#具體配置
#參數化構建過程
GIT 參數:
名稱: BranchName
參數類型: 分支
選項參數:
名稱:domain_name
選項:3dmodel.moviebook.cn
描述:選擇業務域名
#限制項目運行的節點
標簽表達式
jks-node-1
#源碼管理
Repository URL
http://git.xxx.com/video_ai/code/frontend.git
#Credentials
gitlab token
#Branches to build
指定分支(為空時代表any)
${BranchName}
#構建環境
Delete workspace before build starts --> 勾選
Inject environment variables to the build process -->勾選
Properties Content 內容:
mirror_store=harbor.k8s.xxx.cn
image_name=3dmodel/prod/000001-3dmodel/node_prod
deploy_env=node_prod
k8s_resource_list=threedmodel-node-prod
namespace=3dmodel
base_version=nginx:latest
#構建
#執行shell
mkdir /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/code/ -p
cp -af /export/jenkins/workspace/${JOB_NAME}/. /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/code/
cd /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}
cat > $(echo ${domain_name} |sed 's/\(.moviebook.cn\|.videoyi.com\)$//').conf << EOF
server {
server_name ${domain_name};
location / {
index index.html index.htm index.php;
root /export/home/webroot/${namespace}/;
proxy_read_timeout 10000;
try_files \$uri \$uri/ /index.html;
}
access_log /export/home/logs/${namespace}/access.log main;
}
EOF
#執行shell
cd /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/code/
#echo "window.env = 'prod';" > public/env.js
#npm install && npm run build
source /etc/profile
export PATH=/opt/node-v12.19.0-linux-x64/bin/:$PATH
node -v
npm -v
npm install --unsafe-perm && npm run build:prod
#執行shell
whoami
docker_img=`docker images -a -q --filter reference=${mirror_store}/base/${base_version}`
if [ $docker_img ]
then
docker rmi ${mirror_store}/base/${base_version}
fi
cd /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/
cat > Dockerfile << EOF
FROM ${mirror_store}/base/${base_version}
ADD $(echo ${domain_name} |sed 's/\(.moviebook.cn\|.videoyi.com\)$//').conf /opt/openresty/nginx/conf/vhost/
RUN mkdir -p /export/home/webroot/${namespace}/
COPY code/dist/ /export/home/webroot/${namespace}/
RUN mkdir -p /export/home/logs/${namespace}/ && chown -R nobody.nobody /export/home/webroot/${namespace}/
WORKDIR /export/home/webroot/${namespace}/
EXPOSE 80
CMD ["/opt/openresty/nginx/sbin/nginx","-g","daemon off;"]
EOF
docker build . -t ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
docker push ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
docker rmi ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
#執行shell
mkdir -p /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/yaml/
cd /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/yaml
cat > ${k8s_resource_list}-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${namespace}
name: ${k8s_resource_list}
labels:
name: ${k8s_resource_list}
spec:
replicas: 1
selector:
matchLabels:
name: ${k8s_resource_list}
template:
metadata:
labels:
name: ${k8s_resource_list}
spec:
containers:
- name: ${k8s_resource_list}
image: ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
imagePullPolicy: IfNotPresent # Always、Never、IfNotPresent
resources:
limits:
cpu: "1000m"
memory: 2048Mi
requests:
cpu: "500m"
memory: 1024Mi
EOF
cat > ${k8s_resource_list}-svc.yaml << EOF
kind: Service
apiVersion: v1
metadata:
name: ${k8s_resource_list}
namespace: ${namespace}
labels:
name: ${k8s_resource_list}
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
name: ${k8s_resource_list}
EOF
cat > ${k8s_resource_list}-ingress.yaml << EOF
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: ${k8s_resource_list}
namespace: ${namespace}
spec:
rules:
- host: ${domain_name}
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: ${k8s_resource_list}
port:
number: 80
EOF
_kubectl='/usr/local/bin/kubectl --kubeconfig=/opt/kubernetes/config_prod'
${_kubectl} apply -f ${k8s_resource_list}-deployment.yaml
${_kubectl} apply -f ${k8s_resource_list}-svc.yaml
${_kubectl} apply -f ${k8s_resource_list}-ingress.yaml
cd /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/code && ls |grep -v node_modules | xargs rm -rf









- k8s 查看pod 創建完成
kubectl get pod -n 3dmodel

權限管理與分配
#系統管理-Manage and Assign Roles - Manage Roles - Item roles -Add
Role to add: 3D模型分享平台-3Dmodel
Pattern: Production/3Dmodel-Prod/.*
#權限選擇
任務:Build、Cancel、Discover、Read
SCM:Tag
#應用-保存,截圖如下

#系統管理-Manage and Assign Roles - Assign Roles
Global roles: 增加用戶 zhao.liliang
選擇之前創建的 itemadmin
Item roles:增加用戶: zhao.liliang
選擇3D模型分享平台-3Dmodel
截圖如下:

#退出當前賬號用 zhao.liliang 賬號登錄jenkins,發現只有 構建權限,沒有配置權限

jenkins java slave 節點添加並構建項目
- java slave 節點系統環境配置
#安裝docker 環境
因后續要構建鏡像,因此需要有docker 環境,參照之前裝docker 的文檔安裝docker 環境
#配置docker 可以連接harbor
cat /etc/docker/daemon.json
{
"oom-score-adjust": -1000,
"registry-mirrors": [
"https://c6ai9izk.mirror.aliyuncs.com",
"https://docker.mirrors.ustc.edu.cn"
],
"log-driver":"json-file",
"log-opts":{ "max-size" :"100m","max-file":"1"},
"insecure-registries": ["harbor.dev.k8s.xxx.cn","harbor.k8s.xxx.cn"],
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
],
"exec-opts": ["native.cgroupdriver=systemd"]
}
#安裝git
yum -y install git
#配置java 環境
vim /etc/profile
JAVA_HOME=/usr/local/jdk1.8.0_201
JRE_HOME=/usr/local/jdk1.8.0_201/jre
PATH=$JAVA_HOME/bin:$PATH:$JRE_HOME/bin:/usr/local/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export JAVA_HOME JRE_HOME CLASSPATH PATH
#因在后續添加slave 節點時候報錯找不到java 路徑,因此需要以下修改操作,重點
cp /usr/local/jdk1.8.0_201 /usr/local/java
ln -s /usr/local/jdk1.8.0_201/bin/java /usr/bin/java
#查看java 安裝完成
source /etc/profile
java -version
#創建jenkins 普通用戶
useradd jenkins
#創建jenkins 數據目錄
mkdir /export/jenkins/
chown jenkins:jenkins /export/jenkins/ -R
#將jenkins 用戶添加到docker 組,可以用普通jenkins 用戶運行docker 命令
usermod -a -G jenkins,docker jenkins
#安裝kubectl 、配置連接k8s 的config 文件
#從 k8s master節點上將Kubectl 傳至nodejs 節點
scp -qpr /usr/local/bin/kubectl 10.65.91.165:/usr/local/bin/
#將k8s master 節點上的config 文件傳至nodejs 節點
cd .kube
scp -qpr config 10.65.91.165:/root/
#登錄nodejs 10.65.91.165 節點
mkdir /opt/kubernetes
mv /root/config /opt/kubernetes
cd /opt/kubernetes
mv config config_prod
#測試是否可以連接k8s 集群,返回node 節點信息表示可以正常連接
/usr/local/bin/kubectl --kubeconfig=/opt/kubernetes/config_prod get node
# 將jenkins master 節點jenkins 普通用戶的公鑰傳至 nodejs 普通用戶jenkins 目錄下,以便於jenkins master 節點的jenkins 用戶可以免密登錄nodejs 節點
登錄 10.65.91.164,執行
su - jenkins
ssh jenkins@10.65.91.165
登錄成功即可
- jenkins master 節點添加 java jenkins slave 節點
系統管理-節點管理-新建節點
名稱:jks-java-1
描述:jks-java-1
Number of executors:2
遠程工作目錄:/export/jenkins
標簽:java
用法:只允許運行綁定到這台機器的JOb
啟動方式:Launch agents via SSH
主機:10.65.91.165
Credential:jenkins-slave (上面已經配置好的憑據)
Host Key Verification Strategy:Know hosts file Verification Strategy
可用性:盡量保持代理在線
節點屬性-環境變量:鍵:LANG 值:UTF-8
啟動slave 節點


- 部署 jenkins java 項目
- 配置maven
#系統管理-全局工具配置-Maven-新增maven,選擇自動安裝,下載兩個版本的,分別是maven-3.5.0 和 maven-3.0.5,等待安裝完成


#Dashboard - 新建任務文件夾 -Production (顯示名稱:正式環境) - 新建Item - AGC-Video-Engine (顯示名稱:正式環境-AGC-Video-Engine) -新建Item(構建一個 maven 項目) - Agc-Video-Engine_Java_Prod

#具體配置
#參數化構建過程
GIT 參數:
名稱: BranchName
參數類型: 分支
選項參數:
名稱:domain_name
選項:work-order.center.xxx.cn
描述:選擇業務域名
#限制項目運行的節點
標簽表達式
jks-java-1
#源碼管理
Repository URL
http://git.xxx.com/video_ai/code/backend.git
#Credentials
gitlab token
#Branches to build
指定分支(為空時代表any)
${BranchName}
#構建環境
Delete workspace before build starts --> 勾選
Inject environment variables to the build process -->勾選
Properties Content 內容:
mirror_store=harbor.k8s.xxx.cn
image_name=message-center/prod/000004-message-center/java_prod
deploy_env=java_prod
k8s_resource_list=message-center-java-prod
namespace=message-center
base_version=jdk:8u201
#Build
Maven Version : maven-3.5.0
Root Pom: pom.xml
Goals and options:clean package -Dmaven.test.skip=true -P prod
#Post Steps
選擇 Run only if build succeeds
#執行shell
docker_img=`docker images -a -q --filter reference=${mirror_store}/base/${base_version}`
if [ $docker_img ];then
docker rmi ${mirror_store}/base/${base_version}
fi
git checkout HEAD
artifactId=`awk '/<artifactId>[^<]+<\/artifactId>/{gsub(/<artifactId>|<\/artifactId>/,"",$1);print $1;exit;}' pom.xml`
version=`awk '/<version>[^<]+<\/version>/{gsub(/<version>|<\/version>/,"",$1);print $1;exit;}' pom.xml`
packaging='jar'
cat > entrypoint.sh << EOF
#!/bin/bash -
#ln -sf /storage/resource /export/home/webroot/${namespace}/resource
ln -sf /storage/data /data
cd /
java -jar app.jar >> /export/home/logs/${namespace}/${namespace}_prod.log
EOF
chmod +x entrypoint.sh
echo 'center-message-system_java_prod' > prod_env
cat > Dockerfile << EOF
FROM ${mirror_store}/base/${base_version}
ENV LANG en_US.utf8
COPY target/${artifactId}-${version}.${packaging} /app.jar
COPY prod_env /env
RUN mkdir -p /export/home/logs/${namespace}/
EXPOSE 80
ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT /entrypoint.sh
EOF
docker build . -t ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
docker push ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
docker rmi ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
#執行shell
mkdir -p /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/yaml/
cd /export/jenkins/workspace/op_dockerfile/${namespace}/${deploy_env}/yaml
cat > ${k8s_resource_list}-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${namespace}
name: ${k8s_resource_list}
labels:
name: ${k8s_resource_list}
spec:
replicas: 1
selector:
matchLabels:
name: ${k8s_resource_list}
template:
metadata:
labels:
name: ${k8s_resource_list}
spec:
containers:
- name: ${k8s_resource_list}
image: ${mirror_store}/${image_name}:${BUILD_TIMESTAMP}
imagePullPolicy: IfNotPresent # Always、Never、IfNotPresent
resources:
limits:
cpu: "1000m"
memory: 2048Mi
requests:
cpu: "500m"
memory: 1024Mi
EOF
cat > ${k8s_resource_list}-svc.yaml << EOF
kind: Service
apiVersion: v1
metadata:
name: ${k8s_resource_list}
namespace: ${namespace}
labels:
name: ${k8s_resource_list}
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
name: ${k8s_resource_list}
EOF
cat > ${k8s_resource_list}-ingress.yaml << EOF
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: ${k8s_resource_list}
namespace: ${namespace}
spec:
rules:
- host: ${domain_name}
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: ${k8s_resource_list}
port:
number: 80
EOF
_kubectl='/usr/local/bin/kubectl --kubeconfig=/opt/kubernetes/config_prod'
${_kubectl} apply -f ${k8s_resource_list}-deployment.yaml
${_kubectl} apply -f ${k8s_resource_list}-svc.yaml
${_kubectl} apply -f ${k8s_resource_list}-ingress.yaml










- k8s 查看pod 創建完成
kubectl get pod -n message-center

至此,兩個需求完成
1.通過jenkins 完成k8s 項目的自動化構建需求,要求nodejs、java等不同開發語言運用不同的jenkins slave 節點構建
2.通過權限設置管控開發人員的項目使用及構建
