做的好的淘宝客网站,wordpress数据库删除,二手网站开发,做淘宝图标网站1.前言 
该devpos架构为gitlabjenkinsharbork8s#xff0c;项目是java项目#xff0c;流程为从gitlab拉取项目代码到jenkins#xff0c;jenkins通过maven将项目代码打成jar包#xff0c;通过dockerfile构建jdk环境的镜像并把jar包放到镜像中启动#xff0c;构建好的镜像通…1.前言 
该devpos架构为gitlabjenkinsharbork8s项目是java项目流程为从gitlab拉取项目代码到jenkinsjenkins通过maven将项目代码打成jar包通过dockerfile构建jdk环境的镜像并把jar包放到镜像中启动构建好的镜像通过docker上传到harbor镜像仓库中最后k8s通过更新镜像的方式去发布新的服务此套流程通过jenkins的pipeline实现其中还涉及多分支、回滚操作 
2.部署环境 
gitlab部署参考gitlab部署_Apex Predator的博客-CSDN博客 
jenkins部署参考jenkins部署_Apex Predator的博客-CSDN博客 
harbor部署参考k8s harbor镜像仓库搭建_k8s镜像仓库_Apex Predator的博客-CSDN博客 
k8s部署参考kubeadm部署k8s 1.26.0版本高可用集群_Apex Predator的博客-CSDN博客 
3.配置环境 
jenkins主机配置 
在部署jnekins环境的时候已经安装了jdk、maven、git环境现在还需要在安装docker、kubectldocker用于构建镜像和推送镜像到harbor仓库kubectl用于操作k8s发布新版本 docker部署参考部署docker-ce_Apex Predator的博客-CSDN博客 
部署完成后需要配置一下docker的daemon.json文件(因为是私有仓库docker是不允许拉取不安全仓库的镜像)  
vi /etc/docker/daemon.json 
{registry-mirrors: [https://sudzwtcw.mirror.aliyuncs.com],insecure-registries: [harbor.apex.com]      #配置该项使得docker允许访问不安全的镜像仓库
} 
重启docker服务 
systemctl restart docker  部署kubectl 
配置阿里云的k8s yum源 cat  /etc/yum.repos.d/kubernetes.repo  EOF [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled1 gpgcheck0 repo_gpgcheck0 gpgkeyhttps://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF 安装kubectl 
yum -y install kubectl-1.26.0 在jenkins上引用安装的环境 在jenkins中安装以下插件 
Git
Git plugin
Git Parameter
GitLab
Credentials
Credentials Binding
CloudBees Docker Build and Publish plugin
Build With Parameters
Dynamic Extended Choice Parameter Plug-In
Dynamic Parameter Plug-in
Extended Choice Parameter
List Git Branches Parameter
Pipeline
Pipeline: Declarative
kubernetes
Kubernetes plugin
Kubernetes CLI Plugin
Kubernetes Credentials Plugin 在jenkins上配置ssh密钥(一路回车即可) 
ssh-keygen 
查看公钥并拷贝到gitlba上 
cat ~/.ssh/id_rsa.pub 将以上公钥填入以下gitlab配置中即可  配置jenkins Credentials 
创建gitlab凭据 
查看jenkins的私钥 
cat ~/.ssh/id_rsa      #复制输出的所有内容 创建harbor凭据 创建k8s凭据 
先在k8s下载密钥文件(就是集群的配置文件里面包含有密钥和请求集群的接口等配置) 
ls .kube/config sz .kube/config  harbor配置 
配置harbor仓库项目信息 
分别创建两个项目一个存放基础镜像叫base_image,一个存放后端服务镜像叫jdk gitlab配置 
创建项目 创建完成后上传项目代码 k8s集群配置  在k8s的node节点上配置docker的daemon.json文件 
vi /etc/docker/daemon.json 
{registry-mirrors: [https://sudzwtcw.mirror.aliyuncs.com],insecure-registries: [harbor.apex.com],  #配置该项使得docker允许访问不安全的镜像仓库exec-opts: [native.cgroupdriversystemd]
} 
重启docker服务 
systemctl restart docker 4.构建发布 
使用jenkins的pipeline和webhook实现ci/cd自动化发布 
jenkins配置 
新建流水线项目 配置Choice Parameter直接在Jenkins file中写parameter不手动配置parameter的话第一次执行会失败执行完后会自动生成parameter所以还是手动也配置一下 配置webhook tigger用于触发自动构建 配置流水线脚本 
选择pipeline script模式 填入以下脚本 
pipeline {        #配置pipelineagent any       #客户端配置jenkins可以使用k8s作为agent环境去发布这里使用any为任意环境environment {             #配置环境变量参数用来给下面调用registry  harbor.apex.com     #配置harbor仓库地址harbor_auth  a1e2c627-dc62-4599-a035-8e98d74665ab   #配置harbor credentials凭据idproject  jdk      #配置harbor仓库镜像项目app_name  k8s-cs     #配置k8s的pod名称namespace  k8s-cs    #配置k8s的命名空间k8s_auth  k8s-kubeconfig   #配置k8s credentials凭据id     }parameters {     #配置parameters功能choice(choices: [,master, apex], description: choice branch, name: branch)       #配置分支选择的choice用于回滚和手动发布的分支选择此处默认时空值避免下面阶段使用branch变量判断出现问题choice(choices: [deploy, rollback], description: deploy ---部署  rollback  ---回滚, name: status)    #配置发布回滚选择的choice用于选择发布还是回滚此处默认时deploy发布}stages {         #配置构建的每个阶段stage(Checkout code) {        #配置从gitlab拉取代码parallel {     #配置以下两个阶段的操作并行执行stage(webhook tigger) {    #配置自动触发执行的操作when {    #使用when判断env.gitlabBranch的值是否为空使用webhook自动构建是通过env.gitlabBranch变量来赋予分支值判断该值是否为空就能判断是通过webhook构建还是手动构建的expression { params.status  deploy  env.gitlabBranch ! null }}    #params的值用来判断是否执行的是发布操作如果是发布操作才执行该操作使用是需要两个条件都为true才执行steps {     #以上判断通过后执行从gitlab对应的分支拉取代码的操作checkout([$class: GitSCM, branches: [[name: ${env.gitlabBranch}]], extensions: [], userRemoteConfigs: [[credentialsId: gitlab_auth, url: git10.1.60.114:gitlab-instance-c484dcfc/java-project.git]]])  #可以看到branch使用的是env.gitlabBranch这个变量因为webhook自动构建是将分支的值赋予到这个变量中credentialsId就配置gitlab的credentials凭据idsh git branch     #这里是测试是否能获取到分支的值echo Current branch: ${env.gitlabBranch}   #这里是输出分支的值script {   #提取gitlab的项目id用来制作镜像tagcommit_id  sh(returnStdout: true, script: git log -n 1 --prettyformat:%h).trim()tag  BUILD_TAG  -  commit_id  #使用jenkins的构建标签和gitlab的项目id作为镜像标签的tag}}}stage(jenkins scm) {   #此处就是判断是否用的手动构建when {   #使用when判断env.gitlabBranch是否等于空值是空值就证明是通过手动构建的expression { params.status  deploy  env.gitlabBranch  null }}  #params的值用来判断是否执行的是发布操作steps {    #执行拉取gitlab代码操作checkout([$class: GitSCM, branches: [[name: ${branch}]], extensions: [], userRemoteConfigs: [[credentialsId: gitlab_auth, url: git10.1.60.114:gitlab-instance-c484dcfc/java-project.git]]])   #这里和上面自动构建的命令没有什么区别就除了branches使用branch作为变量因为我们上面配置parameters手动构建需要选择名为branch的choice去选择分支所以我们就通过该变量获取到选择的分支名称sh git branchecho Current branch: ${branch}script {commit_id  sh(returnStdout: true, script: git log -n 1 --prettyformat:%h).trim()tag  BUILD_TAG  -  commit_id}}}}  #到这里parallel并行操作就结束了}    #到这里上面的拉取代码操作就结束了stage(Build jar) {   #接下来就是编译代码打包的操作步骤when {   #使用when判断是否是发布操作回滚是不用执行这个阶段的上面的拉代码操作也是expression { params.status  deploy }}steps {  #when判断通过后执行以下命令打包打包命令可能会不一样可以咨询一下开发sh mvn clean install -DskipTests  #编译打包命令sh ls target/      #查看是否有打出来jar包}}stage(docker image build and push) {   #构建镜像和推送镜像到harbor仓库步骤when {expression { params.status  deploy }}steps {withCredentials([usernamePassword(credentialsId: ${harbor_auth}, passwordVariable: password, usernameVariable: username)]) {  #使用harbor的credentials凭据因为推镜像和拉基础镜像都是需要访问harbor仓库的sh docker build -t ${registry}/${project}/${app_name}:${tag} .sh docker push ${registry}/${project}/${app_name}:${tag}} #可能生产、测试环境打包的镜像名称要求不一样这时就需要跟上面一样使用when去判断是哪个环境构建镜像}}stage(k8s update iamge version) {  #发布版本操作parallel {   #以上有讲解此参数stage (to apex) {when {   #判断分支决定发布到哪个环境中expression { params.status  deploy  ( env.gitlabBranch  apex || params.branch  apex ) }}   #后面用了一个|| 或的判断即两个获取分支的变量只要有一个成立即可主要是自动构建和手动构建的分支变量不一样所以必须得使用两个分支变量判断steps {  #配置k8s集群得credentials凭据通过凭据调用k8s集群的apiserverwithCredentials([file(credentialsId: ${k8s_auth}, variable: KUBECONFIG)]) {sh kubectl --kubeconfig ${KUBECONFIG} set image deployment -l app${app_name} ${app_name}${registry}/${project}/${app_name}:${tag} -n ${namespace} --record}   #使用kubectl命令指定k8s集群的配置文件执行更新镜像命令的操作更新镜像操作即发布版本并记录该操作用于回滚}}stage(to master) {when {  #判断分支决定发布到哪个环境中expression { params.status  deploy  ( env.gitlabBranch  master || params.branch  master ) }}steps {withCredentials([file(credentialsId: ${k8s_auth}, variable: KUBECONFIG)]) {sh kubectl --kubeconfig ${KUBECONFIG} get pod -n ${namespace}sh echo ${params.branch}sh echo ${env.gitlabBranch}}  #以上命令是测试用的要是发版命令改为以上的set命令即可}}}}stage(rollback version) {  #回滚操作当发布的版本有问题时会需要使用到回滚操作parallel {stage(to  apex) {when {  #判断params.status变量是否为rollback且判断分支因为回滚操作都是手动操作的所以使用branch变量判断分支即可expression { params.status  rollback  params.branch  apex }}steps {   #此处也是配置k8s集群的credentials凭据withCredentials([file(credentialsId: ${k8s_auth}, variable: KUBECONFIG)]) {sh kubectl --kubeconfig ${KUBECONFIG} rollout undo deployment ${app_name} -n ${namespace}}  #使用rollout命令并指定deployment回滚版本}    }stage(to  master) {when {expression { params.status  rollback  params.branch  master }}steps {withCredentials([file(credentialsId: ${k8s_auth}, variable: KUBECONFIG)]) {sh kubectl --kubeconfig ${KUBECONFIG} get deployment ${app_name} -n ${namespace}}  #此处也是测试命令回滚命令参照上面写即可}    }}}}
}制作基础镜像(打包的时候直接使用基础镜像会更快) 
vim dockerfile 
FROM alpine:latest      #拉取系统镜像
ENV TZAsia/Shanghai  #这个环境变量用于下面配置时区
RUN sed -i s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g /etc/apk/repositories \  #配置源apk add --upgrade --no-cache openjdk8 tzdata ttf-dejavu fontconfig \    #安装jdk环境、字体等工具cp /usr/share/zoneinfo/${TZ} /etc/localtime \    #配置时区echo ${TZ}  /etc/timezone 
构建镜像 docker build -t harbor.apex.com/base_image/jdk8_image:latest . 上传镜像 docker push  harbor.apex.com/base_image/jdk8_image:latest gitlab配置 
在项目代码仓库中创建dockerfile用于构建发布镜像 dockerfile内容如下 
FROM harbor.apex.com/base_image/jdk8_image:latest   #使用harbor仓库中的基础镜像
ENV JVM_OPTS-Xms512m -Xms512m   #配置关于java的环境变量
ENV HEAP_DUMP_OPTS-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/opt/java_jar/log
RUN mkdir -p /opt/java_jar/log   #创建存放jar包目录还有日志目录
WORKDIR /opt/java_jar/    #设置存放jar包目录为工作目录即相当于cd到这个目录上
COPY ./target/*.jar ./    #拷贝jar包到镜像中target目录是在jenkins上打包后jar包的生成目录
EXPOSE 8761        #配置需要暴露的端口
ENTRYPOINT java ${JVM_POST} ${HEAP_DUMP_OPTS} -jar *.jar  #配置启动jar包服务 配置webhook用于触发jenkins自动化构建 k8s集群 配置在master节点执行 
创建namespace kubectl create namespace k8s-cs 创建secret用于拉取harbor仓库的镜像使用 kubectl create secret docker-registry harbor-secret --namespacek8s-cs --docker-serverhttps://harbor.apex.com --docker-usernameadmin --docker-passwordHarbor12345 查看secret kubectl get secret -n k8s-cs 创建yaml vim k8s-cs.yaml 
apiVersion: apps/v1
kind: Deployment
metadata: labels:app: k8s-csname: k8s-csnamespace: k8s-cs
spec:replicas: 5progressDeadlineSeconds: 600minReadySeconds: 10strategy:         #配置滚动更新策略rollingUpdate:maxSurge: 1maxUnavailable: 0type: RollingUpdateselector:matchLabels:app: k8s-cstemplate:metadata:labels:app: k8s-csspec:containers:- name: k8s-csimage: harbor.apex.com/jdk/k8s-cs   #填写harbor仓库的镜像地址imagePullPolicy: IfNotPresent       ports:- containerPort: 8761readinessProbe:      #配置就绪探针httpGet:path: /port: 8761scheme: HTTPinitialDelaySeconds: 30periodSeconds: 10timeoutSeconds: 2successThreshold: 1failureThreshold: 2livenessProbe:     #配置存活探针tcpSocket:port: 8761initialDelaySeconds: 30periodSeconds: 10successThreshold: 1timeoutSeconds: 2failureThreshold: 2 imagePullSecrets:         #配置拉取镜像使用的secret- name: harbor-secretrestartPolicy: Always
---
apiVersion: v1
kind: Service          #配置service映射端口
metadata:name: k8s-csnamespace: k8s-cs
spec:selector:app: k8s-cstype: NodePort   clusterIP:ports:- port: 8761targetPort: 8761nodePort: 30002protocol: TCP 
执行yaml创建pod kubectl apply -f k8s-cs.yaml 5.测试发布、回滚 
手动构建 回滚  自动化构建 
更改一下分支合并到master看看会不会触发自动化构建 
更改的过程我就省略了更改好之后创建合并请求 批准且合并后触发Jenkins构建 这个也是多分支的发布合并其它分支也是可以触发我就不演示了 6.补充 
pipeline有两种模式还有一种是pipeline script from scm就是在流水线配置界面就编辑好从gitlab仓库拉代码的信息并且把jenkinsfile放到gitlab的仓库中跟着代码一起拉下来接下来也说一下这种方式的使用 
创建pipeline项目这里就不贴图了 
配置git parameter,用来选择发布时的分支 在gitlab的项目上创建jenkinsfile文件 jenkinsfile脚本如下 
pipeline {agent anyenvironment {registry  harbor.apex.comharbor_auth  a1e2c627-dc62-4599-a035-8e98d74665abproject  jdkapp_name  k8s-csnamespace  k8s-csimage_url  ${registry}/${project}/${app_name}:${tag}k8s_auth  k8s-kubeconfigk8s_name  kubernetes}   #这里和之前的pipeline不同因为配置了scm后在jenkinsfile中就不需要再配置拉取代码的步骤了其它的配置都是一样的不过我这是一个简化版的适合单分支stages {stage(Build jar) {steps {sh mvn clean install -DskipTestssh ls target/}}stage(docker image build and push) {steps {withCredentials([usernamePassword(credentialsId: ${harbor_auth}, passwordVariable: password, usernameVariable: username)]) {sh docker build -t ${image_url} .sh docker push ${image_url}}}}stage(push yaml to k8s) {steps {withCredentials([file(credentialsId: ${k8s_auth}, variable: KUBECONFIG)]) {sh kubectl --kubeconfig ${KUBECONFIG} set image deployment -l app${app_name} ${app_name}${image_url} -n ${namespace} --record}}}}
} 
去执行构建就可以了这里是jenkins项目通过scm的gitlab拉取项目代码拉取了项目后再去执行流水线的jenkinsfile脚本所以jenkinsfile里是不需要配置拉代码这个动作的 以下再 讲解一下通过jenkins agent来执行流水线这里讲诉使用k8s集群的pod作为jenkins agent去发布大概流程就是使用k8s插件连接k8s集群调用k8s的api server去创建jenkins agent流水线的所有步骤都在jenkins agent上执行期间还需要配置所有需要用的环境的pod这里就不详细介绍就说一下踩到的坑 
jenkins agent使用的jnlp镜像的jdk环境需要和jenkins的jdk环境一致不然是没办法连接的 
使用jenkins agent除了要打开jenkins 50000端口与Jenkins agent通信外还需要配置Git Host Key Verification Configuration项不然的话在从gitlab拉代码的适合会一直报错 里面填写的密钥在 known_hosts文件中配置的是gitlab主机的密钥 一定要配置此项不然pod拉不到gitlab的项目代码 
cat /root/.ssh/known_hosts  还有就是使用docker镜像镜像里的docker是没办法配置daemon.json的所以访问不到harbor的私有仓库除非harbor使用的是公有证书和公有域名