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

发布时间:2023年12月19日

目录

一、实验

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.8gitlab
被管理端192.168.204.180K8S master1
被管理端192.168.204.181K8S node1
被管理端192.168.204.182K8S 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

成功:

文章来源:https://blog.csdn.net/cronaldo91/article/details/135031479
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。