Jenkins 流水线中调用 Ansible

172次阅读
没有评论

共计 3703 个字符,预计需要花费 10 分钟才能阅读完成。

背景

Jenkins 和 ansible 功能有重叠,但是它们各有优势。

Jenkins:

  • 主要擅长构建流程控制和任务编排
  • 对服务器配置管理支持较弱
  • 需要编写大量shell脚本来实现配置管理

Ansible:

  • 专注于配置管理和应用部署
  • 使用声明式的YAML描述目标状态
  • 内置大量配置管理模块,开箱即用

在 Jenkins 中使用 ansible, 各自发挥所长,Jenkins负责流程控制,Ansible负责具体的配置管理和部署操作,实现更复杂的部署流程。

实践

Ansible 安装

Jenkins 直接部署时,在对应服务器下安装 ansible 即可,不展开讲。

若 Jenkins 部署在容器中,需要 build 一个安装了ansible 的镜像。

# 编辑 Dockerfile
# vim Dockerfile
FROM jenkins/jenkins:lts
USER root

# 安装 Python 和 Ansible
FROM jenkins/jenkins:lts
USER root

# 安装 Python 和 Ansible
RUN apt-get update && \
    apt-get install -y \
    ansible \
    sudo \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# 配置 sudo 权限
RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

WORKDIR /var/jenkins_home/

USER jenkins

# 构建镜像
docker build --no-cache -t jenkins-with-ansible .

# 引用新镜像
# vim docker-compose.yml
services:
  jenkins:
    #image: jenkins/jenkins:lts
    image: jenkins-with-ansible:latest
    ports:
      - "8081:8080"
    volumes:
      - /disk-st4000vx015-4t-no1/jenkins-data:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/local/bin/docker:/usr/local/bin/docker
      - /etc/docker:/etc/docker

    group_add:
      - "0"
    environment:
      TZ: Asia/Shanghai
  ssh-agent:
    image: jenkins/ssh-agent

# 启动
docker-compose up -d 

插件安装

Jenkins 流水线中调用 Ansible

核心插件:

Ansible Plugin

作用:
- 提供Ansible命令行调用接口
- 支持执行playbook
- 可配置Ansible安装路径
- 提供构建步骤中的Ansible选项

SSH Agent Plugin

作用:
- 管理SSH密钥认证
- 在构建过程中提供SSH认证
- 支持多个SSH密钥
- 确保密钥使用的安全性

Credentials Plugin

作用:
- 统一管理各类凭据
- 支持用户名密码、SSH密钥等
- 提供凭据加密存储
- 是SSH Agent Plugin的依赖插件

其他常用插件:

Pipeline Plugin

作用:
- 支持编写Pipeline脚本
- 提供声明式和脚本式Pipeline
- 更好地组织Ansible任务
- 支持多阶段部署

AnsiColor Plugin

作用:
- 支持控制台输出颜色
- 使Ansible输出更易读
- 更好地展示错误信息
- 提高日志可读性

Workspace Cleanup Plugin

作用:
- 清理工作空间
- 删除临时文件
- 确保构建环境干净
- 避免磁盘空间占用

安装建议:

基础配置

必装插件:
- Ansible Plugin
- SSH Agent Plugin
- Credentials Plugin

进阶配置

建议安装:
- Pipeline Plugin
- AnsiColor Plugin
- Workspace Cleanup Plugin

凭据配置

在 Jenkins 中的流水线调用 Ansible,Ansible 的凭据支持以多种方式配置:

  1. 使用Jenkins凭据管理 + 环境变量方案:
pipeline {
    agent any

    environment {
        // 使用 Jenkins 凭据
        SSH_KEY = credentials('ansible-ssh-key')
    }

    stages {
        stage('Run Ansible') {
            steps {
                // 创建临时SSH密钥文件
                sh '''
                    mkdir -p ~/.ssh
                    echo "$SSH_KEY" > ~/.ssh/id_rsa
                    chmod 600 ~/.ssh/id_rsa

                    # 运行ansible命令
                    ansible-playbook -i inventory playbook.yml

                    # 清理密钥
                    rm -f ~/.ssh/id_rsa
                '''
            }
        }
    }
}
  1. 使用ansible-vault方案:
pipeline {
    agent any

    environment {
        ANSIBLE_VAULT_PASSWORD = credentials('ansible-vault-password')
    }

    stages {
        stage('Run Ansible') {
            steps {
                // 创建vault密码文件
                sh '''
                    echo "$ANSIBLE_VAULT_PASSWORD" > vault.pass

                    # 使用vault密码文件运行ansible
                    ansible-playbook -i inventory playbook.yml --vault-password-file vault.pass

                    # 清理
                    rm -f vault.pass
                '''
            }
        }
    }
}
  1. 使用SSH Agent插件方案(推荐):
pipeline {
    agent any

    stages {
        stage('Run Ansible') {
            steps {
                sshagent(['ansible-ssh-key']) {
                    sh '''
                        # SSH Agent 会自动处理密钥
                        ansible-playbook -i inventory playbook.yml
                    '''
                }
            }
        }
    }
}

推荐使用SSH Agent插件的方案,因为:

  1. 安全性最高
  2. 使用最简单
  3. 维护成本最低
  4. 无需手动管理密钥文件
  5. Jenkins原生支持

系统管理 –> 凭据管理 –> 系统 –> 全局凭据 –> Add Credentials 录入 ssh key 凭据:
Jenkins 流水线中调用 Ansible

流水线配置

在 gitlab 中以工程形式管理 jenkinsfile 和 ansible 相关配置文件:

# tree
.
├── inventory
├── Jenkinsfile
└── uptime.yml

# cat inventory 
[ALL]
192.168.2.10 ansible_user=root
192.168.2.11 ansible_user=root

# cat Jenkinsfile 
pipeline {
    agent any

    options {
        ansiColor('xterm') // 控制台输出添加对标准 ANSI 转义序列(包括颜色)的支持。
    }

    environment {
        ANSIBLE_HOST_KEY_CHECKING = 'False'  // 全局禁用主机密钥检查
    }

    stages {
        stage('Run Ansible') {
            steps {
                sshagent(credentials: ['ansible-ssh-key']) {
                    ansiblePlaybook(
                        playbook: 'uptime.yml',
                        inventory: 'inventory',
                        colorized: true,
                        hostKeyChecking: false,
                        // 可选:添加额外变量
                        extraVars: [
                            'env': 'production'
                        ]
                    )
                }
            }
        }
    }

    post {
        always {
            cleanWs()  // 清理工作空间
        }
        success {
            echo 'Ansible playbook execution successful!'
        }
        failure {
            echo 'Ansible playbook execution failed!'
        }
    }
}

# cat uptime.yml 
- hosts: all
  tasks:
    - name: Run uptime
      shell: uptime
      register: uptime_output

    - debug:
        msg: "{{ uptime_output.stdout }}"

需要注意,Ansible 在确定连接用户时有一个优先级顺序:

  1. 命令行参数 -u​ 或 --user
  2. ANSIBLE_REMOTE_USER 环境变量
  3. inventory 文件中的 ansible_user 变量
  4. ansible.cfg 中的 remote_user 配置
  5. 当前执行 Ansible 的用户名(在这种情况下是 Jenkins 容器中的 jenkins 用户)

即使在 Jenkins 凭据中设置了 Username ,这个设置主要用于 SSH 密钥认证,不会改变 Ansible 默认使用的连接用户。

所以在 inventory 文件中显式指定了 ansible_user 变量。

创建流水线任务:

Jenkins 流水线中调用 Ansible

执行构建

Jenkins 流水线中调用 Ansible

总结

Jenkins 着重于流程控制和版本控制,结合 Ansible 可以更好实现复杂部署需求,避免维护冗长繁杂的 Jenkinsfile。

使用 Asnbile 时需注意安全性,采用 ssh agent 插件可以保证密钥的安全使用。

本文属于专题:Jenkins

正文完
 
pengyinwei
版权声明:本站原创文章,由 pengyinwei 2024-11-18发表,共计3703字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处:https://www.opshub.cn
评论(没有评论)