jenkins自动部署教程

女爷i 2022-12-08 04:51 474阅读 0赞

文章目录

  • 参考文章
  • jenkins+k8s+git自动部署
    • 缺陷记录
    • 部署步骤
  • jenkins+ansible+git自动部署
    • 缺陷记录
    • 实践步骤如下:
  • jenkins凭证credentials
  • jenkins传递参数到shell脚本以及ansible启动脚本
  • jenkins自动部署注意点
  • jenkins:解决root无法su到jenkins用户
  • 安装jenkins
  • 安装maven
  • jenkins用户执行权限诸多问题
    • 解决方案1:
    • 解决方案2:
    • 解决方案3:
    • 解决方案四:

参考文章

jenkins pipeline基础语法与示例
Linux 下 Jenkins 安装及将 Jenkins 设置为 root 权限
jenkins:解决root无法su到jenkins用户

jenkins+k8s+git自动部署

缺陷记录

部署好之后,kubectl查看服务运行状态正常,但就是外界访问不到
jenkins的pipeline如下:

  1. pipeline {
  2. //说明流水线哪一个节点运行
  3. agent any
  4. options {
  5. // 默认15分钟 timeout (15)
  6. timeout(time: 13, unit: 'MINUTES')
  7. }
  8. environment {
  9. build_dir="/opt/k8s-cicd/build-workspace"
  10. project_name="hello-world"
  11. host="k8s-web.muoo.com"
  12. }
  13. stages {
  14. stage('build') {
  15. steps{
  16. git 'https://gitee.com/goodshred/k8s-hello-world.git'
  17. sh "mvn -Dmaven.test.failure.ignore=true clean package"
  18. sh 'echo "curUser=${USER}"'
  19. //script {
  20. //本质还是不应该写在这里,碰到无权限问题应该手动去操作linux机器,比如配置两台机器的免密登陆,使用root权限给某个文件赋予允许jenkins执行的权限
  21. //chmod: changing permissions of ‘/opt/k8s-cicd/script/build.sh’: Operation not permitted
  22. //我是用的root创建的脚本文件,因此jenkins用户无法更改其权限
  23. //sh "chmod +x /opt/k8s-cicd/script/build.sh"
  24. //sh "chmod +x /opt/k8s-cicd/script/deploy.sh"
  25. // }
  26. sh "${build_dir}/script/build.sh"
  27. sh "${build_dir}/script/deploy.sh"
  28. }
  29. }
  30. }
  31. post {
  32. success {
  33. script {
  34. echo "post==success"
  35. }
  36. }
  37. failure {
  38. script {
  39. echo "post==failure"
  40. }
  41. }
  42. //构建不稳定时
  43. //随着项目的开发和持续扩展,使用Jenkins构建(build)项目越来越多,Jenkins服务器的磁盘可能被大日志文件占满造成无法继续构建项目的异常(一般会出现构建按钮为黄色)
  44. unstable {
  45. script {
  46. echo "post==unstable "
  47. }
  48. }
  49. }
  50. }

创建目录结构如下:
在这里插入图片描述

Dockerfile文件

  1. FROM openjdk:8-jdk-alpine
  2. COPY hello-world-0.0.1-SNAPSHOT.jar /hello-world-0.0.1-SNAPSHOT.jar
  3. ENTRYPOINT ["java", "-jar","/hello-world-0.0.1-SNAPSHOT.jar"]

build.sh文件:

  1. #!/bin/bash
  2. if [ "${build_dir}" == "" ];then
  3. echo "env 'build_dir' is not set"
  4. exit 1
  5. fi
  6. # 构建时候的工作名,比如Jenkins自动构建个项目,取名叫k8s-cicd,那么${JOB_NAME}=k8s-cicd,它是Jenkins自带的全局变量
  7. # /opt/k8s-cicd/build-workspace/k8s-web-demo
  8. docker_dir=${build_dir}/${JOB_NAME}
  9. if [ ! -d ${docker_dir} ];then
  10. mkdir -p ${docker_dir}
  11. fi
  12. echo "docker workspace: ${docker_dir}"
  13. # ${WORKSPACE}/${MODULE}=/var/lib/jenkins/workspace/k8s-web-demo/
  14. jenkins_dir=${WORKSPACE}/${MODULE}
  15. export jenkins_dir=${jenkins_dir}
  16. echo "jenkins_dir is ${jenkins_dir}"
  17. if [ ! -f ${jenkins_dir}target/*jar ];then
  18. echo "target file not found ${jenkins_dir}target/*jar"
  19. exit 1
  20. fi
  21. \cp ${jenkins_dir}target/*jar ${docker_dir}
  22. cd ${docker_dir}
  23. # VERSION=$(date + %y%m%d%H%M%S%)
  24. VERSION=$(date "+%y-%m-%d_%H-%M-%S")
  25. IMAGE_NAME=goodshred/${project_name}:${VERSION}
  26. echo ${IMAGE_NAME}
  27. echo "${IMAGE_NAME}" > ${WORKSPACE}/IMAGE
  28. echo "workspave is : ${WORKSPACE}======================"
  29. cat ${WORKSPACE}/IMAGE
  30. echo "build image ${IMAGE_NAME}"
  31. docker build -t ${IMAGE_NAME} .
  32. docker push ${IMAGE_NAME}

deploy.sh文件如下:

  1. #!/bin/bash
  2. name=${JOB_NAME}
  3. image=$(cat ${ WORKSPACE}/IMAGE)
  4. \cp ${build_dir}/template/web.yaml ${build_dir}/script/web.yaml
  5. sed -i "s,{ {name}},${name},g" ${build_dir}/script/web.yaml
  6. sed -i "s,{ {image}},${image},g" ${build_dir}/script/web.yaml
  7. kubectl apply -f ${build_dir}/script/web.yaml
  8. cat ${build_dir}/script/web.yaml

web.yaml如下:

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: { { name}}
  5. namespace: default
  6. labels:
  7. app: { { name}}
  8. spec:
  9. type: NodePort
  10. ports:
  11. - port: 30009
  12. targetPort: 19999
  13. # type: NodePort # 在主机上暴露端口
  14. nodePort: 19999 #service对外开放端口
  15. selector:
  16. app: { { name}}
  17. ---
  18. apiVersion: extensions/v1beta1
  19. #apps/v1,extensions/v1beta1需要根据自己k8s的版本选择
  20. kind: Deployment #对象类型
  21. metadata:
  22. name: { { name}} #名称
  23. labels:
  24. app: { { name}} #标注
  25. spec:
  26. replicas: 1 #运行容器的副本数,修改这里可以快速修改分布式节点数量
  27. selector:
  28. matchLabels:
  29. app: { { name}}
  30. template:
  31. metadata:
  32. labels:
  33. app: { { name}}
  34. spec:
  35. containers: #docker容器的配置
  36. # { {name}}
  37. - name: { { name}}
  38. #image: goodshred/hello-world:latest
  39. ## 192.168.1.253:8081/pasq/dockertest:0.0.1 # pull镜像的地址 ip:prot/dir/images:tag
  40. # { {image}}
  41. image: { { image}}
  42. imagePullPolicy: IfNotPresent #pull镜像时机,
  43. ports:
  44. - containerPort: 19999 #容器对外开放端口

部署步骤

jenkins的pipeline如下:

  1. pipeline {
  2. //说明流水线哪一个节点运行
  3. agent any
  4. options {
  5. // 默认15分钟 timeout (15)
  6. timeout(time: 13, unit: 'MINUTES')
  7. }
  8. environment {
  9. build_dir="/opt/k8s-cicd/build-workspace"
  10. project_name="hello-world"
  11. host="k8s-web.muoo.com"
  12. }
  13. stages {
  14. stage('build') {
  15. steps{
  16. git 'https://gitee.com/goodshred/k8s-hello-world.git'
  17. sh "mvn -Dmaven.test.failure.ignore=true clean package"
  18. sh 'echo "curUser=${USER}"'
  19. //script {
  20. //本质还是不应该写在这里,碰到无权限问题应该手动去操作linux机器,比如配置两台机器的免密登陆,使用root权限给某个文件赋予允许jenkins执行的权限
  21. //chmod: changing permissions of ‘/opt/k8s-cicd/script/build.sh’: Operation not permitted
  22. //我是用的root创建的脚本文件,因此jenkins用户无法更改其权限
  23. //sh "chmod +x /opt/k8s-cicd/script/build.sh"
  24. //sh "chmod +x /opt/k8s-cicd/script/deploy.sh"
  25. // }
  26. sh "${build_dir}/script/build.sh"
  27. sh "${build_dir}/script/deploy.sh"
  28. }
  29. }
  30. }
  31. post {
  32. success {
  33. script {
  34. echo "post==success"
  35. }
  36. }
  37. failure {
  38. script {
  39. echo "post==failure"
  40. }
  41. }
  42. //构建不稳定时
  43. //随着项目的开发和持续扩展,使用Jenkins构建(build)项目越来越多,Jenkins服务器的磁盘可能被大日志文件占满造成无法继续构建项目的异常(一般会出现构建按钮为黄色)
  44. unstable {
  45. script {
  46. echo "post==unstable "
  47. }
  48. }
  49. }
  50. }

创建目录结构如下:
在这里插入图片描述

Dockerfile文件

  1. FROM openjdk:8-jdk-alpine
  2. COPY hello-world-0.0.1-SNAPSHOT.jar /hello-world-0.0.1-SNAPSHOT.jar
  3. ENTRYPOINT ["java", "-jar","/hello-world-0.0.1-SNAPSHOT.jar"]

build.sh文件:

  1. #!/bin/bash
  2. if [ "${build_dir}" == "" ];then
  3. echo "env 'build_dir' is not set"
  4. exit 1
  5. fi
  6. # 构建时候的工作名,比如Jenkins自动构建个项目,取名叫k8s-cicd,那么${JOB_NAME}=k8s-cicd,它是Jenkins自带的全局变量
  7. # /opt/k8s-cicd/build-workspace/k8s-web-demo
  8. docker_dir=${build_dir}/${JOB_NAME}
  9. if [ ! -d ${docker_dir} ];then
  10. mkdir -p ${docker_dir}
  11. fi
  12. echo "docker workspace: ${docker_dir}"
  13. # ${WORKSPACE}/${MODULE}=/var/lib/jenkins/workspace/k8s-web-demo/
  14. jenkins_dir=${WORKSPACE}/${MODULE}
  15. export jenkins_dir=${jenkins_dir}
  16. echo "jenkins_dir is ${jenkins_dir}"
  17. if [ ! -f ${jenkins_dir}target/*jar ];then
  18. echo "target file not found ${jenkins_dir}target/*jar"
  19. exit 1
  20. fi
  21. \cp ${jenkins_dir}target/*jar ${docker_dir}
  22. cd ${docker_dir}
  23. # VERSION=$(date + %y%m%d%H%M%S%)
  24. VERSION=$(date "+%y-%m-%d_%H-%M-%S")
  25. IMAGE_NAME=goodshred/${project_name}:${VERSION}
  26. echo ${IMAGE_NAME}
  27. echo "${IMAGE_NAME}" > ${WORKSPACE}/IMAGE
  28. echo "workspave is : ${WORKSPACE}======================"
  29. cat ${WORKSPACE}/IMAGE
  30. echo "build image ${IMAGE_NAME}"
  31. docker build -t ${IMAGE_NAME} .
  32. docker push ${IMAGE_NAME}

deploy.sh文件如下:

  1. #!/bin/bash
  2. name=${JOB_NAME}
  3. image=$(cat ${ WORKSPACE}/IMAGE)
  4. \cp ${build_dir}/template/web.yaml ${build_dir}/script/web.yaml
  5. sed -i "s,{ {name}},${name},g" ${build_dir}/script/web.yaml
  6. sed -i "s,{ {image}},${image},g" ${build_dir}/script/web.yaml
  7. kubectl apply -f ${build_dir}/script/web.yaml
  8. cat ${build_dir}/script/web.yaml

web.yaml如下:

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: { { name}}
  5. namespace: default
  6. labels:
  7. app: { { name}}
  8. spec:
  9. type: NodePort
  10. ports:
  11. - port: 30009
  12. targetPort: 19999
  13. # type: NodePort # 在主机上暴露端口
  14. nodePort: 19999 #service对外开放端口
  15. selector:
  16. app: { { name}}
  17. ---
  18. apiVersion: extensions/v1beta1
  19. #apps/v1,extensions/v1beta1需要根据自己k8s的版本选择
  20. kind: Deployment #对象类型
  21. metadata:
  22. name: { { name}} #名称
  23. labels:
  24. app: { { name}} #标注
  25. spec:
  26. replicas: 1 #运行容器的副本数,修改这里可以快速修改分布式节点数量
  27. selector:
  28. matchLabels:
  29. app: { { name}}
  30. template:
  31. metadata:
  32. labels:
  33. app: { { name}}
  34. spec:
  35. containers: #docker容器的配置
  36. # { {name}}
  37. - name: { { name}}
  38. #image: goodshred/hello-world:latest
  39. ## 192.168.1.253:8081/pasq/dockertest:0.0.1 # pull镜像的地址 ip:prot/dir/images:tag
  40. # { {image}}
  41. image: { { image}}
  42. imagePullPolicy: IfNotPresent #pull镜像时机,
  43. ports:
  44. - containerPort: 19999 #容器对外开放端口

jenkins+ansible+git自动部署

缺陷记录

最后一行java -jar没有执行,或者执行失败。

实践步骤如下:

在这里插入图片描述
jenkinsfile

  1. pipeline{
  2. agent any
  3. environment {
  4. GIT_USERNAME1 = credentials('git_username')
  5. GIT_PASSWORD1 = credentials('git_password')
  6. }
  7. stages{
  8. stage('部署'){
  9. steps{
  10. //${WORKSPACE}=/var/lib/jenkins/workspace
  11. // sh """
  12. // bash -e ${WORKSPACE}/sh/build.sh ${BRANCH} ${GIT_USERNAME} ${GIT_PASSWORD}
  13. // """
  14. // python deploy.py ${BRANCH} ${GIT_USERNAME} ${GIT_PASSWORD}
  15. //python deploy.py $env.BRANCH $env.GIT_USERNAME $env.GIT_PASSWORD
  16. sh """
  17. cd /root/ansible/role/demo/playbook/
  18. python deploy.py ${ BRANCH} ${ GIT_USERNAME1} ${ GIT_PASSWORD1}
  19. """
  20. }
  21. }
  22. }
  23. }

start.sh

  1. #!/bin/bash
  2. # 对于source命令而言,这个地方很重要
  3. CURRENT_PATH=$(cd `dirname $0`; pwd)
  4. # 不能写成source env.sh,除非我执行该脚本用的./start.sh,如果是sh start.sh就要这样写
  5. source ${CURRENT_PATH}/env.sh >/dev/null 2>&1
  6. echo "name is========${name}"
  7. JAR_NAME=hello-world-0.0.1-SNAPSHOT.jar
  8. rm -rf ~/lmj/module-workspace/
  9. mkdir -p ~/lmj/module-workspace/
  10. cd ~/lmj/module-workspace/
  11. git clone -b { { BRANCH}} https://{ { GIT_USERNAME}}:{ { GIT_PASSWORD}}@gitee.com/goodshred/ansible-jenkins-git-demo.git
  12. cd ansible-jenkins-git-demo/
  13. mvn -Dmaven.test.failure.ignore=true clean package
  14. ps -ef | grep -w ${JAR_NAME} | grep -v grep | awk '{print $2}'
  15. proc_id=`ps -ef|grep -w ${ JAR_NAME}|grep -v grep|awk '{print $2}'`
  16. proc_msg=`ps -ef|grep -w ${ JAR_NAME}|grep -v grep|awk '{print $8 $9 $10}'`
  17. if [ -n proc_id ]; then
  18. kill -9 ${proc_id}
  19. echo ${proc_id} ${proc_msg}
  20. fi
  21. JAVA_OPTS="-Xmx512m -Xms512m"
  22. echo "nohup java ${JAVA_OPTS} -Dspring.profiles.active={ {BRANCH}} -jar target/${JAR_NAME} &"
  23. nohup java ${JAVA_OPTS} -Dspring.profiles.active={ { BRANCH}} -jar target/${JAR_NAME} &

env_dev.json

  1. {
  2. "name": "env.develop"
  3. }

deploy.yaml

  1. ---
  2. - hosts: localhost
  3. name: deploy hello world
  4. gather_facts: no #不收集facts
  5. roles:
  6. - hw
  7. vars:
  8. name: { name}
  9. GIT_USERNAME: { GIT_USERNAME}
  10. GIT_PASSWORD: { GIT_PASSWORD}
  11. BRANCH: { BRANCH}

deploy.py

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import sys
  4. import os
  5. import json
  6. try:
  7. reload(sys)
  8. sys.setdefaultencoding("utf-8")
  9. except:
  10. pass
  11. BRANCH=sys.argv[1]
  12. GIT_USERNAME=sys.argv[2]
  13. GIT_PASSWORD=sys.argv[3]
  14. print("===================================================================")
  15. # print(BRANCH+"========="+GIT_USERNAME+"======="+GIT_PASSWORD)
  16. conf=json.load(open('env_dev.json'))
  17. print("执行替换")
  18. raw_yaml=open('deploy.yaml').read()
  19. with open('deploy.yaml',"w+") as f:
  20. f.write(raw_yaml.format(
  21. name=conf["name"],
  22. BRANCH=BRANCH,
  23. GIT_USERNAME=GIT_USERNAME,
  24. GIT_PASSWORD=GIT_PASSWORD
  25. ))
  26. print("执行部署")
  27. # os.system("cd playbook/ && ansible-playbook deploy.yaml -v")
  28. os.system("ansible-playbook deploy.yaml -v")

templates/env.j2

  1. #!/bin/bash
  2. export name={ { name}}
  3. export BRANCH={ { BRANCH}}
  4. export GIT_USERNAME={ { GIT_USERNAME}}
  5. export GIT_PASSWORD={ { GIT_PASSWORD}}

tasks/main.yaml

  1. ---
  2. # tasks file for /root/ansible/role/lisi
  3. # 这里的.路径是执行python的哪个路径,比如我是在playbook下执行的python deploy.py
  4. # 那么生成的env.sh在playbook/env.sh
  5. - name: delever
  6. template:
  7. src: env.j2
  8. dest: env.sh
  9. # 由于这里使用的是sh执行,因此在运行source env.sh这样是不对,需要使用绝对路径cd `dirname $0`/env.sh ,如果是./方式倒无所谓
  10. - name: start
  11. shell: "sh start.sh"
  12. register: haha
  13. # 会自动打印调试信息
  14. - name: debug info
  15. debug: var=haha

jenkins凭证credentials

在这里插入图片描述

  1. pipeline{
  2. agent any
  3. environment {
  4. GIT_USERNAME1 = credentials('git_username')
  5. GIT_PASSWORD1 = credentials('git_password')
  6. }
  7. stages{
  8. stage('部署'){
  9. steps{
  10. sh """
  11. cd /root/ansible/role/demo/playbook/
  12. python deploy.py ${ BRANCH} ${ GIT_USERNAME1} ${ GIT_PASSWORD1}
  13. """
  14. }
  15. }
  16. }
  17. }

在这里插入图片描述

jenkins传递参数到shell脚本以及ansible启动脚本

jenkins设置参数
在这里插入图片描述
这样我们在jenkinsfile中就可以通过${GIT_USERNAME}获取到

  1. steps{
  2. //${WORKSPACE}=/var/lib/jenkins/workspace
  3. sh """
  4. bash -e ${ WORKSPACE}/sh/build.sh ${ BRANCHE} ${ GIT_USERNAME} ${ PASSWORD}
  5. """
  6. }

shell脚本中接收

  1. #!/bin/bash
  2. # 接受参数
  3. GIT_URL=gitee.com
  4. BRANCH=$1
  5. GIT_USERNAME=$2
  6. GIT_PASSWORD=$3
  7. git clone -b ${BRANCH} https://${GIT_USERNAME}:${GIT_PASSWORD}@${GIT_URL}/goodshred/ansible-jenkins-git-demo.git

我们在ansible的deploy.yaml中可以这样接收

  1. conf_file = sys.argv[1]
  2. rio_flag = sys.argv[2]
  3. steps {
  4. sh "python deploy.py $env.DEPLOY_CONF_FILE $env.RIO_FLAG"
  5. }

jenkins自动部署注意点

当前我的项目是这个:
在这里插入图片描述
所以${WORKSPACE}=/var/lib/jenkins/workspace/k8s-web-demo/

其git迁下来的代码在

WORKSPACE/ansible-jenkins-git-demo

mvn打包后的文件在

WORKSPACE/target/

jenkins:解决root无法su到jenkins用户

yum安装jenkins后root无法su到jenkins用户
cat /etc/passwd发jenkins用户后被yum安装设置为了/bin/false
在这里插入图片描述

sudo vim /etc/passwd改为/bin/bash
在这里插入图片描述

再次su jenkins发现用户变为了-bash-4.1#

在该用户下编辑环境变量
vim ~/.bash_profile
加入:
export PS1=’[\u@\h \W]$’
使脚本生效:
source ~/.bash_profile
再次su jenkins,发现正常

安装jenkins

  1. yum install -y java # 我的java路径为:/opt/jdk8/jdk1.8.0_152
  2. sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo
  3. sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
  4. vi /etc/sysconfig/jenkins 可在里面修改jenkins端口号
  5. 关闭防火墙
  6. systemctl stop firewalld.service
  7. systemctl disable firewalld.service
  8. 启动jenkins
  9. service jenkins start/stop/restart

安装maven

  1. wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
  2. yum -y install apache-maven
  3. find / -name mvn
  4. mvn --version
  5. 打印的结果里可以看到maven的安装路径:/opt/maven/apache-maven-3.6.3

vim /etc/maven/settings.xml 在mirrors节点下添加阿里镜像源

  1. <mirror>
  2. <id>nexus-aliyun</id>
  3. <mirrorOf>central</mirrorOf>
  4. <name>Nexus aliyun</name>
  5. <url>http://maven.aliyun.com/nexus/content/groups/public</url>
  6. </mirror>

我的git路径为:/usr/bin/git

参考文章:https://www.jianshu.com/p/cc67d1740649

我自己创建的用户名密码是lmj/lmj,但是这个不是jenkins登陆linux的shell的用户,jenkins操作shell脚本的用户名身份是jenkins,它的权限比较低。

jenkins用户执行权限诸多问题

解决方案1:

Jenkins 安装好后,会自动创建一个 jenkins 用户。jenkins 在构建工程时,默认的权限是不够写入文件的。这时就需要把它的权限提升为root。

1.将 jenkins 账号加入到 root 组中。

gpasswd -a jenkins root

2.修改/etc/sysconfig/jenkins文件,添加如下配置。

JENKINS_USER=“root”
JENKINS_GROUP=“root”

3.重启 Jenkins

systemctl restart jenkins

4.验证

groups jenkins

查看jenkins是在哪个用户组,显示的是root。

解决方案2:

将所有自动部署的脚本项目啊等等都移动到/home/jenkins目录下操作

解决方案3:

遇到权限问题,就到linux上使用root登陆,然后执行权限不足的那段代码(比如创建文件夹),第一次需要半自动(人工参与),以后就可以完全自动化。

解决方案四:

使用su切换到jenkins,执行自动部署里面的shell脚本代码。遇到问题就手动解决。

发表评论

表情:
评论列表 (有 0 条评论,474人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Jenkins自动部署项目

    目录 1.安装插件 2.配置 -------------------- 本文只讲解通过插件来自动部署项目,Jenkins的安装可以看博主的另一篇文章,绝对保姆级,简洁

    相关 Jenkin自动部署

    一、在系统管理 -> 插件管理中,安装\[Publish over SSH\]插件。然后点击一键安装,并重启Jenkins ![这里写图片描述][70] 二、系统管理 -