摘要:使用Jenkins对项目代码进行持续集成和持续发布,代码提交后,通过Gitlab Trigger触发Jenkins任务,Jenkins完成项目构建打包,image制作,最后部署新的版本的k8s集群上。
一、在Kubernetes上快速部署Jenkins
1. Helm安装Jenkins
社区提供的charts https://github.com/jenkinsci/helm-charts
截止2020年10月4号,最新的chart tag是2.8.1
自定义配置参数
master:
resources:
requests:
cpu: "4"
memory: "8Gi"
limits:
cpu: "4"
memory: "8Gi"
ingress:
enabled: true
apiVersion: "networking.k8s.io/v1beta1"
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
path: "/"
hostName: jenkins2.3incloud.com
tls:
- secretName: tls-3incloudcom
hosts:
- jenkins2.3incloud.com
prometheus:
enabled: true
persistence:
size: 80Gi
agent:
image: "harbor.3incloud.com/jenkins/jnlp"
resources:
requests:
cpu: "1"
memory: "1024Mi"
limits:
cpu: "1"
memory: "1024Mi"
volumes:
- type: HostPath
hostPath: /var/run/docker.sock
mountPath: /var/run/docker.sock
command: ""
args: ""
其中agent的镜像来自于下面的自定义Jnlp
二、自定义Jnlp
自定义agent的镜像目的是为了让agent可以操作k8s的API,在完成CI任务后,就可以操作k8s完成CD过程。
做法是在原社区镜像的基础上,安装kubectl,helm和docker工具,下述Dockfile示例。
FROM jenkins/inbound-agent:4.3-4
MAINTAINER David Tesar <david.tesar@microsoft.com>
ARG VCS_REF
ARG BUILD_DATE
# Metadata
LABEL org.label-schema.vcs-ref=$VCS_REF \
org.label-schema.vcs-url="https://github.com/dtzar/jnlp-slave-helm" \
org.label-schema.build-date=$BUILD_DATE \
org.label-schema.docker.dockerfile="/Dockerfile"
USER root
# Note: Latest version of kubectl may be found at:
# https://aur.archlinux.org/packages/kubectl-bin/
ENV KUBE_LATEST_VERSION="v1.18.6"
# Note: Latest version of helm may be found at:
# https://github.com/kubernetes/helm/releases
ENV HELM_VERSION="v3.3.1"
# Note: Latest version of docker may be found at:
# https://get.docker.com/builds
ENV DOCKER_VERSION="18.09.9"
RUN apt-get update && apt-get install -y --no-install-recommends \
# Install Kubectl
&& curl -L https://storage.googleapis.com/kubernetes-release/release/${KUBE_LATEST_VERSION}/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl \
&& chmod +x /usr/local/bin/kubectl \
# Install Helm
&& curl -L https://get.helm.sh/helm-v3.3.4-linux-amd64.tar.gz -o /tmp/helm.tar.gz \
&& tar -zxvf /tmp/helm.tar.gz -C /tmp \
&& cp /tmp/linux-amd64/helm /usr/local/bin/helm \
# Install Docker
&& curl -L https://download.docker.com/linux/static/stable/x86_64/docker-19.03.12.tgz -o /tmp/docker-19.03.12.tgz \
&& tar --strip-components=1 -xvzf /tmp/docker-19.03.12.tgz -C /usr/local/bin \
&& chmod a+x /usr/local/bin/dockerd \
# Cleanup uncessary files
&& apt-get clean \
&& rm -rf /tmp/* ~/*.tgz
三、Jenkins集成Gitlab
安装完成后,登录Jenkins,安装Gitlab、NodeJS和DockerPipline插件。
Jenkins配置
1. 在系统配置中设置Gitlab
2. 在Credentials中增加一组密钥,过程省略。
- harbor用来管理镜像
- 采用https pull代码
3. 在全局工具中配置NodeJS
4. 在k8s中设置Agent使用的ServiceAccount权限
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: default
namespace: jenkins
EOF
上述示例是将命名空间为jenkins的默认服务账号关联到集群管理员。Jenkins完成项目的部署和更新需要比较多的权限,这里采用简化版的操作,一刀切了,给它最大权限。
5. 配置image pull secret
kubectl create secret docker-registry harborsecret \
--docker-server='<registry server>' \
--docker-username='<username>' \
--docker-password='<password>' \
--docker-email='<email>' \
-n <namespace>
四、使用Pipline部署Node应用
1. 在项目根目录添加Jenkinsfile文件
Jenkinsfile示例
pipeline {
agent any
environment {
ENV_NAME = "alpha"
}
parameters {
choice(name: 'DEPLOY_ACTION',choices:['TEST', 'PRODUCT', 'FALSE'], description:'Deploy To Kubernetes Cluster')
}
tools {
nodejs "node"
}
stages {
stage('Build') {
when {
expression { BRANCH_NAME ==~ /test/ }
}
steps {
echo '3. Build Stage'
script {
if (params.DEPLOY_ACTION == 'PRODUCT') {
ENV_NAME = 'prod'
}
}
sh "npm install --registry=https://registry.npm.taobao.org && npm run build"
sh "docker build . -t harbor.3incloud.com/shiia/shiia-app-api:${build_tag}"
}
}
stage('Push') {
when {
expression { BRANCH_NAME ==~ /test/ }
}
steps {
echo '4. Push Stage'
withDockerRegistry([credentialsId: 'harbor-wuyuexin', url: "https://harbor.3incloud.com"]) {
sh "docker push harbor.3incloud.com/shiia/shiia-app-api:${build_tag}"
}
}
}
stage('DeployToTest') {
when {
expression { return params.DEPLOY_ACTION == 'TEST'}
expression { BRANCH_NAME ==~ /test/ }
}
steps {
echo '5. Deploy Stage'
sh "ls -la"
sh "helm upgrade test-shiia-app-api helm-charts/shiia-platform-api/ --namespace test-shiia-app --reuse-values --set-string image.tag=${build_tag}"
}
}
}
}
2. Jenkins创建新的项目
五、快速发布与更新
为了简化部署,使用Helm对软件安装包进行管理,这样大大简化了部署流程以及版本的更新。
在完成一系列的配置操作后,整个过程就结束啦。整个过程的复杂的地方主要包含
- Jenkins Agent自定义镜像制作
- Jenkins 一系列插件的安装与配置
- 部署包chart的编写
- Jenkinsfile的编写