持续集成交付CICD:Jenkins使用GitLab共享库实现基于Ansible的CD流水线部署前后端应用

目录

一、实验

1.部署Ansible自动化运维工具

2.K8S 节点安装nginx

3.Jenkins使用GitLab共享库实现基于Ansible的CD流水线部署前后端应用

二、问题

1.ansible安装报错

2.ansible远程ping失败

3. Jenkins流水线通过ansible命令直接ping多台机器的网络状态报错


一、实验

1.部署Ansible自动化运维工具

(1)环境

表1 主机

管理端 192.168.204.8 gitlab
被管理端 192.168.204.180 K8S master1
被管理端 192.168.204.181 K8S node1
被管理端 192.168.204.182 K8S node2

(2)  管理端安装ansible

#安装epel-release
yum install  -y epel-release 

#安装ansible
yum install -y  ansible

#hosts文件位置:/etc/ansible/hosts
vim /etc/ansible/hosts

# 主机hosts文件
vim /etc/hosts

(3)ansible远程ping

# ansible all -m ping

2.K8S 节点安装nginx

(1)K8S查看节点状态

# kubectl get node

(2) 节点安装nginx

1)添加 nginx 到 yum 源中
sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
 
2)安装 nginx (在把nginx添加到 yum 源之后,就可以使用 yum 安装了)
sudo yum install -y nginx
 
3)稍等一会,即可安装完成
 
4)启动 nginx
sudo systemctl start nginx.service
 
5)设置 nginx 开机自启动
sudo systemctl enable nginx.service

(3)nginx 配置信息

 
1)网站文件存放默认位置(Welcome to nginx 页面)
/usr/share/nginx/html
 
2)网站默认站点配置
/etc/nginx/conf.d/default.conf
 
3)自定义 nginx 站点配置文件存放目录
/etc/nginx/conf.d/
 
4)nginx 全局配置文件
/etc/nginx/nginx.conf
 
5)启动 nginx
service nginx start
 
6)关闭 nginx
service nginx stop
 
7)重启 nginx
service nginx restart
service nginx reload
 
8) 加成nginx
nginx -t

(4)修改nginx配置文件

# /etc/nginx/nginx.conf


user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}



http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    types_hash_max_size 2048;


    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;


server {
    listen 8099;
    server_name _;
    root /usr/share/nginx/html/devops03-devops-ui;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
 }

}

master1节点:

node1节点:

node2节点:

3.Jenkins使用GitLab共享库实现基于Ansible的CD流水线部署前后端应用

(1)修改GitLab共享库目录

(2) 修改部署类 Deploy.groovy

package org.devops

//SaltStack

def DeployBySalt(){
    targetHosts = "${env.saltHosts}"
    localDeployDir = "/srv/salt/${env.projectName}"
    sh """
        [ -d ${localDeployDir} ] || mkdir -p ${localDeployDir}
        mv ${env.pkgName} ${localDeployDir}
        
        # 清理发布目录
        salt -L "${targetHosts}" cmd.run  "rm -fr ${targetDir}/${env.projectName}/* &&  mkdir -p ${targetDir}/${env.projectName} || echo file is exists"
            
        # 发布应用
        salt -L "${targetHosts}" cp.get_file salt://${env.projectName}/${env.pkgName} ${targetDir}/${env.projectName}
                   
    """

    if ("${env.projectType}" == "npm") {
        sh """
        # 解压
        salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;tar zxf ${env.pkgName}"

        """

    }

    if ("${env.projectType}" == "maven") {
    // 文件内容写到本地
    gitlab = new Gitlab()
    response = gitlab.GetRepoFile(21, "service.sh", "master")
    writeFile file: 'service.sh', text: "${response}"
    sh "ls -a "

    sh """
        mv service.sh  ${localDeployDir}
        # 发布启动脚本
        salt -L "${targetHosts}" cp.get_file salt://${env.projectName}/service.sh ${targetDir}/${env.projectName}
                             
        # 启动服务
        salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} start"
    
        # 检查服务
        sleep 5
        salt -L "${targetHosts}" cmd.run  "cd ${targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} check"
                                
    """
    }
}



//ansible
def DeployByAnsible(){
    //将主机写入清单文件
    sh "rm -fr hosts"
    for (host in "${env.ansibleHosts}".split(',')){
        sh " echo ${host} >> hosts"
    }
    // sh " cat hosts"

    // ansible 发布
    sh """
        # 主机连通性检测
        ansible "${env.ansibleHosts}" -m ping -i hosts 

        # 清理和创建发布目录
        ansible "${env.ansibleHosts}" -m shell -a "rm -fr ${env.targetDir}/${env.projectName}/* &&  mkdir -p ${env.targetDir}/${env.projectName} || echo file is exists" 
            
        # 复制app
        ansible "${env.ansibleHosts}" -m copy -a "src=${env.pkgName}  dest=${env.targetDir}/${env.projectName}/${env.pkgName}" 
    """

    if ("${env.projectType}" == "npm"){
        sh """ ansible "${env.ansibleHosts}" -m shell -a "cd ${env.targetDir}/${env.projectName} ; tar zxf ${env.pkgName} " -u root """
    }

    if ("${env.projectType}" == "maven"){
        // 文件内容写到本地
        gitlab = new Gitlab()
        response = gitlab.GetRepoFile(21,"service.sh", "master")
        writeFile file: 'service.sh', text: "${response}"
        sh "ls -a "
        sh """
            # 复制脚本
            ansible "${env.ansibleHosts}" -m copy -a "src=service.sh  dest=${env.targetDir}/${env.projectName}/service.sh" 

            # 启动服务
            ansible "${env.ansibleHosts}" -m shell -a "cd ${env.targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} start" -u root

            # 检查服务 
            sleep 10
            ansible "${env.ansibleHosts}" -m shell -a "cd ${env.targetDir}/${env.projectName} ;source /etc/profile  && sh service.sh ${env.projectName} ${env.releaseVersion} ${env.port} check" -u root
        """
    }
}

(3) 修改流水线 cd.jenkinsfile

@Library("mylib@master") _
import org.devops.*

def artifacts = new Artifacts()
def gitlabutil = new Gitlab()
def deployer = new Deploy()

pipeline {
    agent { label "build" }
    
    options {
      skipDefaultCheckout true
    }

    stages{
        stage("PullArtifacts"){
            steps{
                script{
                    repoName = "${JOB_NAME}".split("/")[0]
                    env.projectName ="${JOB_NAME}".split("/")[-1].split("_")[0]

                    if ("${env.projectType}" == "maven"){
                        type="jar"
                    }
                    if ("${env.projectType}" == "npm"){
                        type="tar.gz"
                    }
                    artifacts.PullArtifacts("${env.releaseVersion}","${env.projectName}",repoName,type)

                    env.pkgName="${env.projectName}-${env.releaseVersion}.${type}"
                }
            }
        }
        stage("DeployHost"){
            steps{
                script{
                    print("DeployHost")
                    if ("${env.deployTool}" == "saltstack"){
                        deployer.DeployBySalt()               
                    }

                    if ("${env.deployTool}" == "ansible"){
                        deployer.DeployByAnsible()           
                    }
                }
            }
        }
        
    }
}

(4) Jenkins修改前后端项目流水线参数

 

(5)手动构建前端流水线

(6)Blue Ocean查看

成功

(7)手动构建后端流水线

(8)Blue Ocean查看

二、问题

1.ansible安装报错

(1)报错

(2)原因分析

yum源

(3)解决方法

# vim /etc/resolv.conf
nameserver 8.8.8.8
nameserver 114.114.114.114

成功:

2.ansible远程ping失败

(1) 报错

(2)原因分析

从输出提示上基本可以了解到由于在本机的~/.ssh/known_hosts文件中并有fingerprint key串,ssh第一次连接的时候一般会提示输入yes 进行确认为将key字符串加入到 ~/.ssh/known_hosts 文件中

(3)解决方法

第一种:在本地先SSH登录一下对方设备,下次ansible 就可以正常操作了,但是比较麻烦

第二种:设置参数为不检查key

vim /etc/ansible/ansible.cfg
 
host_key_checking = False           #71行取消注释

如继续操作出现如下报错,需要修改被管理端/etc/hosts

注释被管理端域名

如继续操作出现如下报错,修改 /etc/ansible/hosts

修改后

192.168.204.180 ansible_port=22 ansible_user=root ansible_password=123123
192.168.204.181 ansible_port=22 ansible_user=root ansible_password=123123
192.168.204.182 ansible_port=22 ansible_user=root ansible_password=123123

成功:

3. Jenkins流水线通过ansible命令直接ping多台机器的网络状态报错

(1) 报错

(2)原因分析

单向的ssh验证

(3)解决方法

ssh-keygen一路回车,主要是用来免密通信的

ssh-copy-id 被控端IP 需要输入对应主节的root密码

# ssh-copy-id root@192.168.204.180

# ssh-copy-id root@192.168.204.181

# ssh-copy-id root@192.168.204.182

成功:

最近更新

  1. TCP协议是安全的吗?

    2023-12-17 04:56:09       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-17 04:56:09       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-17 04:56:09       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-17 04:56:09       18 阅读

热门阅读

  1. 第十七章 : Spring Boot 集成RabbitMQ(一)

    2023-12-17 04:56:09       32 阅读
  2. 求一个数组中的最大子序列和。

    2023-12-17 04:56:09       33 阅读
  3. python之画动态图 gif效果图

    2023-12-17 04:56:09       37 阅读
  4. SLAM ORB-SLAM2(12)估算运动并初始地图点

    2023-12-17 04:56:09       30 阅读
  5. springboot中的一些重要的注解

    2023-12-17 04:56:09       29 阅读
  6. Python简介、开发环境配置与工具准备

    2023-12-17 04:56:09       38 阅读
  7. 《C++新经典设计模式》之第1章 介绍

    2023-12-17 04:56:09       20 阅读
  8. 什么是npm?

    2023-12-17 04:56:09       35 阅读