You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkinsfile调用Docker MySQL镜像时启动失败的问题排查

解决Jenkins Docker Agent中MySQL初始化失败的问题

问题背景

在Windows 11的WSL环境上部署了Docker-in-Docker的Jenkins容器,通过Jenkinsfile创建node:14、mysql:8容器执行测试任务。JavaScript阶段运行正常,但MySQL阶段出现以下异常:

  • 执行mysql命令返回错误:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
  • 查看mysqld状态发现InnoDB初始化失败,报错无法找到指定路径、无法打开ibdata1文件
  • 直接在Jenkins外部运行mysql:8镜像容器并通过docker exec进入操作时,MySQL可正常运行

原Jenkinsfile

pipeline {
    agent none

    stages {
        stage('Checkout code from github') {
            agent any
            steps {
                git branch: 'main', url: 'https://github.com/OzMashiah/learningjenkins.git'
            }
        }

        stage('Run JavaScript') {
            agent {
                docker {
                    image 'node:14'
                }
            }
            steps {
                script {
                    sh 'ls -l'
                    sh 'node script.js'
                }
            }
        }

        stage('Run MySQL Query') {
            agent {
                docker {
                    image 'mysql:8'
                }
            }
            environment {
                MYSQL_USER = 'root'
                MYSQL_DB = 'test_db'
                MYSQL_ALLOW_EMPTY_PASSWORD = true
            }
            steps {
                script {
                // Ensure MySQL is initialized before running commands
                        sh 'sleep 15'
                        sh '/usr/sbin/mysqld status'

                        sh '''
                                mysql -u ${MYSQL_USER} -e "CREATE DATABASE IF NOT EXISTS ${MYSQL_DB};"
                                mysql -u ${MYSQL_USER} ${MYSQL_DB} -e "
                                        CREATE TABLE IF NOT EXISTS users (
                                                id INT PRIMARY KEY,
                                                name VARCHAR(50)
                                        );
                                        INSERT INTO users (id, name) VALUES (1, 'John Doe');
                                        INSERT INTO users (id, name) VALUES (2, 'Jane Doe');
                                        "
                        '''
                        sh '''
                                mysql -u ${MYSQL_USER} ${MYSQL_DB} -e "SELECT * FROM users;"
                        '''
                }
            }
        }
    }

    post {
        always {
            // Clean up resources after the build
            echo 'Cleaning up resources...'
        }
    }
}

错误日志

MySQL连接错误

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

mysqld状态日志

+ /usr/sbin/mysqld status

2024-12-12T10:12:15.290153Z 0 [System] [MY-015015] [Server] MySQL Server - start.

2024-12-12T10:12:15.564828Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.4.3) starting as process 46

2024-12-12T10:12:15.600460Z 0 [Warning] [MY-010075] [Server] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 8fd96474-b871-11ef-a35e-0242ac110002.

2024-12-12T10:12:15.621615Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.

2024-12-12T10:12:15.639907Z 1 [ERROR] [MY-012592] [InnoDB] Operating system error number 2 in a file operation.

2024-12-12T10:12:15.639958Z 1 [ERROR] [MY-012593] [InnoDB] The error means the system cannot find the path specified.

2024-12-12T10:12:15.639972Z 1 [ERROR] [MY-012594] [InnoDB] If you are installing InnoDB, remember that you must create directories yourself, InnoDB does not create them.

2024-12-12T10:12:15.639980Z 1 [ERROR] [MY-012646] [InnoDB] File ./ibdata1: 'open' returned OS error 71. Cannot continue operation

2024-12-12T10:12:15.640283Z 1 [ERROR] [MY-012981] [InnoDB] Cannot continue operation.

script returned exit code 3

问题原因

Jenkins的Docker Agent默认会覆盖容器的ENTRYPOINT/CMD,直接以shell模式启动容器。而mysql:8镜像的默认ENTRYPOINT是一个初始化脚本,会自动处理数据目录权限、创建必要路径、启动mysqld服务等流程。当以Jenkins Agent方式运行时,这个初始化流程被跳过,导致:

  1. mysqld服务未自动启动
  2. 数据目录(如/var/lib/mysql、/var/run/mysqld)不存在或权限不足,InnoDB无法创建ibdata1文件

解决方案

方案一:修正MySQL Agent阶段的初始化流程

手动创建必要目录、设置权限、启动mysqld服务,并等待服务就绪后执行SQL命令:

stage('Run MySQL Query') {
    agent {
        docker {
            image 'mysql:8'
        }
    }
    environment {
        MYSQL_USER = 'root'
        MYSQL_DB = 'test_db'
        MYSQL_ALLOW_EMPTY_PASSWORD = true
    }
    steps {
        script {
            // 创建MySQL所需的目录并设置权限
            sh 'mkdir -p /var/lib/mysql /var/run/mysqld'
            sh 'chown -R mysql:mysql /var/lib/mysql /var/run/mysqld'
            sh 'chmod 777 /var/run/mysqld'
            
            // 后台启动mysqld服务
            sh '/usr/sbin/mysqld --daemonize'
            
            // 等待MySQL服务就绪(比固定sleep更可靠)
            sh 'until mysqladmin ping -u ${MYSQL_USER} --silent; do sleep 2; done'
            
            // 执行SQL操作
            sh '''
                mysql -u ${MYSQL_USER} -e "CREATE DATABASE IF NOT EXISTS ${MYSQL_DB};"
                mysql -u ${MYSQL_USER} ${MYSQL_DB} -e "
                        CREATE TABLE IF NOT EXISTS users (
                                id INT PRIMARY KEY,
                                name VARCHAR(50)
                        );
                        INSERT INTO users (id, name) VALUES (1, 'John Doe');
                        INSERT INTO users (id, name) VALUES (2, 'Jane Doe');
                        "
            '''
            sh '''
                mysql -u ${MYSQL_USER} ${MYSQL_DB} -e "SELECT * FROM users;"
            '''
        }
    }
}

方案二:使用独立MySQL容器(推荐)

避免将MySQL镜像作为Jenkins Agent,而是在Pipeline中启动独立的MySQL容器,通过容器网络访问:

stage('Run MySQL Query') {
    agent any
    environment {
        MYSQL_CONTAINER = 'mysql-test'
        MYSQL_USER = 'root'
        MYSQL_DB = 'test_db'
        MYSQL_ALLOW_EMPTY_PASSWORD = true
    }
    steps {
        script {
            // 启动独立的MySQL容器
            sh "docker run -d --name ${MYSQL_CONTAINER} -e MYSQL_ALLOW_EMPTY_PASSWORD=${MYSQL_ALLOW_EMPTY_PASSWORD} -e MYSQL_DATABASE=${MYSQL_DB} mysql:8"
            
            // 等待MySQL服务就绪
            sh "until docker exec ${MYSQL_CONTAINER} mysqladmin ping -u ${MYSQL_USER} --silent; do sleep 2; done"
            
            // 在容器内执行SQL命令
            sh "docker exec ${MYSQL_CONTAINER} mysql -u ${MYSQL_USER} ${MYSQL_DB} -e \"
                    CREATE TABLE IF NOT EXISTS users (
                            id INT PRIMARY KEY,
                            name VARCHAR(50)
                    );
                    INSERT INTO users (id, name) VALUES (1, 'John Doe');
                    INSERT INTO users (id, name) VALUES (2, 'Jane Doe');
                    SELECT * FROM users;
            \""
        }
    }
    post {
        always {
            // 清理测试用的MySQL容器
            sh "docker stop ${MYSQL_CONTAINER} && docker rm ${MYSQL_CONTAINER}"
        }
    }
}

补充说明

直接在Jenkins外部运行mysql:8镜像时,Docker会执行默认的ENTRYPOINT脚本,自动完成目录创建、权限配置、服务启动等步骤,因此可以正常运行。而Jenkins Agent模式会跳过这个初始化流程,导致服务无法正常启动。

内容的提问来源于stack exchange,提问作者user28749644

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:05:02