从 jenkins 中的 docker 容器获取日志
Getting logs from a docker container inside jenkins
我正在尝试让 docker 设置一个完整的测试环境,我可以在其中 运行 进行集成测试,但到目前为止它还没有真正发挥作用,我什至在获取日志方面遇到了问题从它回来。
所以我想 运行 它作为管道,我想使用 jenkinsfile。这是我到目前为止得到的:
pipeline {
agent any
stages {
stage('build war') {
agent {
docker {
image 'gradle:latest'
reuseNode true
}
}
steps {
sh 'gradle war -b oven/build.gradle'
}
}
stage('test') {
steps {
script {
docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c ->
docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h ->
docker.image('mysql:latest').inside("--link ${c.id}:db") {
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
}
docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
sh 'sleep 5'
}
docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
sh 'gradle test -b oven/build.gradle'
}
sh "docker logs ${h.id}"
}
}
}
}
}
stage('build dockerimage') {
steps {
script {
dir('oven') {
def image = docker.build("munhunger/highly-oven")
docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
image.push("${env.BUILD_NUMBER}")
image.push("latest")
}
}
}
}
}
}
}
但是我的后端和数据库之间的连接好像有问题...
我从构建日志中得到的是这样的:
se.munhunger.oven.rest.UserTest > System is up and running, Creating a user, it returns 204 upon creation FAILED
java.lang.AssertionError at UserTest.java:38
指向:
Assert.assertEquals("non 204 from backend", 204,
client.target(baseURL + "/api/user")
.request()
.header("email", "mail@mail.mail")
.post(Entity.json(null))
.getStatus());
我相信测试人员和后端之间的连接正常,因为以下测试成功
Assert.assertEquals(200,
client.target(baseURL + "/swagger")
.request()
.get()
.getStatus());
这让我想到了主要问题,即如何从后端 docker 图像获取日志?
我觉得没有它,几乎不可能调试出什么问题
编辑
我已经退出了一些日志,但是在错误的时间。
如果我更改为以下内容:
docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c ->
docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h ->
docker.image('mysql:latest').inside("--link ${c.id}:db") {
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
}
docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
sh 'sleep 5'
}
sh "docker logs ${h.id}"
docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
sh 'gradle test -b oven/build.gradle'
}
sh "docker logs ${h.id}"
}
}
我从启动时获取所有日志。但它没有打印出测试失败后的日志
原来你可以直接抓住那个狗屎:
pipeline {
agent any
stages {
stage('build war') {
agent {
docker {
image 'gradle:latest'
reuseNode true
}
}
steps {
sh 'gradle war -b oven/build.gradle'
}
}
stage('test') {
steps {
script {
docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c ->
docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h ->
docker.image('mysql:latest').inside("--link ${c.id}:db") {
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
}
docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
sh 'sleep 5'
}
try {
docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
sh 'gradle test -b oven/build.gradle'
}
}
catch (exc) {
sh "docker logs ${h.id}"
throw exc
}
}
}
}
}
}
stage('build dockerimage') {
steps {
script {
dir('oven') {
def image = docker.build("munhunger/highly-oven")
docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
image.push("${env.BUILD_NUMBER}")
image.push("latest")
}
}
}
}
}
}
}
当您能够 运行 集成测试而不使用您的 Jenkins 文件时,它会有所帮助,因此您应该使用 docker-compose 而不是使用这些嵌套的 docker.image 语句。
我要像这样进行集成测试:
stage('Run integration tests') {
steps {
script {
try {
timeout(30) {
// Tear up integration test environment
sh "docker-compose up -d"
// Wait until it is ready
waitUntil {
"healthy" == sh(returnStdout: true,
script: "docker inspect CONTAINER_NAME --format=\"{{ .State.Health.Status }}\"").trim()
}
docker.image('IMAGENAME').inside('--network projectname_default') {
sh "gradle integrationTest"
}
}
} finally {
try {
step([$class: 'JUnitResultArchiver', testResults: '**/build/integrationTest-results/TEST-*.xml'])
} catch (Exception e) {
// Ignore exception when there are no test results
}
sh "docker-compose logs >integration-test.log"
sh "docker-compose down --rmi local --volumes --remove-orphans"
archive 'integration-test.log'
}
}
}
}
如您所见,我将 Gradle 测试容器附加到由 docker-compose 设置的网络。这允许您重新使用您的撰写,而不仅仅是为了测试。
现在您必须确保您使用的所有容器都记录到标准输出。最后,您将在存档集成-test.log 中获得所有日志。当然,你也可以扩展这个,为每个容器获取一个单独的日志文件。
我正在尝试让 docker 设置一个完整的测试环境,我可以在其中 运行 进行集成测试,但到目前为止它还没有真正发挥作用,我什至在获取日志方面遇到了问题从它回来。
所以我想 运行 它作为管道,我想使用 jenkinsfile。这是我到目前为止得到的:
pipeline {
agent any
stages {
stage('build war') {
agent {
docker {
image 'gradle:latest'
reuseNode true
}
}
steps {
sh 'gradle war -b oven/build.gradle'
}
}
stage('test') {
steps {
script {
docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c ->
docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h ->
docker.image('mysql:latest').inside("--link ${c.id}:db") {
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
}
docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
sh 'sleep 5'
}
docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
sh 'gradle test -b oven/build.gradle'
}
sh "docker logs ${h.id}"
}
}
}
}
}
stage('build dockerimage') {
steps {
script {
dir('oven') {
def image = docker.build("munhunger/highly-oven")
docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
image.push("${env.BUILD_NUMBER}")
image.push("latest")
}
}
}
}
}
}
}
但是我的后端和数据库之间的连接好像有问题...
我从构建日志中得到的是这样的:
se.munhunger.oven.rest.UserTest > System is up and running, Creating a user, it returns 204 upon creation FAILED
java.lang.AssertionError at UserTest.java:38
指向:
Assert.assertEquals("non 204 from backend", 204,
client.target(baseURL + "/api/user")
.request()
.header("email", "mail@mail.mail")
.post(Entity.json(null))
.getStatus());
我相信测试人员和后端之间的连接正常,因为以下测试成功
Assert.assertEquals(200,
client.target(baseURL + "/swagger")
.request()
.get()
.getStatus());
这让我想到了主要问题,即如何从后端 docker 图像获取日志? 我觉得没有它,几乎不可能调试出什么问题
编辑 我已经退出了一些日志,但是在错误的时间。 如果我更改为以下内容:
docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c ->
docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h ->
docker.image('mysql:latest').inside("--link ${c.id}:db") {
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
}
docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
sh 'sleep 5'
}
sh "docker logs ${h.id}"
docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
sh 'gradle test -b oven/build.gradle'
}
sh "docker logs ${h.id}"
}
}
我从启动时获取所有日志。但它没有打印出测试失败后的日志
原来你可以直接抓住那个狗屎:
pipeline {
agent any
stages {
stage('build war') {
agent {
docker {
image 'gradle:latest'
reuseNode true
}
}
steps {
sh 'gradle war -b oven/build.gradle'
}
}
stage('test') {
steps {
script {
docker.image('mysql:latest').withRun('-e "MYSQL_ROOT_PASSWORD=password" -e "MYSQL_USER=root" -e "MYSQL_DATABASE=highlygroceries"') { c ->
docker.image('munhunger/highly-oven').withRun('-e "test=test"') { h ->
docker.image('mysql:latest').inside("--link ${c.id}:db") {
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
}
docker.image('munhunger/highly-oven').inside("--link ${c.id}:db -e 'DB_URL=db:3306' -e 'DB_PASS=password' -e 'DB_USER=root'") {
sh 'sleep 5'
}
try {
docker.image('gradle:latest').inside("--link ${h.id}:backend -e 'OVEN_URL=http://backend:8080'") {
sh 'gradle test -b oven/build.gradle'
}
}
catch (exc) {
sh "docker logs ${h.id}"
throw exc
}
}
}
}
}
}
stage('build dockerimage') {
steps {
script {
dir('oven') {
def image = docker.build("munhunger/highly-oven")
docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
image.push("${env.BUILD_NUMBER}")
image.push("latest")
}
}
}
}
}
}
}
当您能够 运行 集成测试而不使用您的 Jenkins 文件时,它会有所帮助,因此您应该使用 docker-compose 而不是使用这些嵌套的 docker.image 语句。
我要像这样进行集成测试:
stage('Run integration tests') {
steps {
script {
try {
timeout(30) {
// Tear up integration test environment
sh "docker-compose up -d"
// Wait until it is ready
waitUntil {
"healthy" == sh(returnStdout: true,
script: "docker inspect CONTAINER_NAME --format=\"{{ .State.Health.Status }}\"").trim()
}
docker.image('IMAGENAME').inside('--network projectname_default') {
sh "gradle integrationTest"
}
}
} finally {
try {
step([$class: 'JUnitResultArchiver', testResults: '**/build/integrationTest-results/TEST-*.xml'])
} catch (Exception e) {
// Ignore exception when there are no test results
}
sh "docker-compose logs >integration-test.log"
sh "docker-compose down --rmi local --volumes --remove-orphans"
archive 'integration-test.log'
}
}
}
}
如您所见,我将 Gradle 测试容器附加到由 docker-compose 设置的网络。这允许您重新使用您的撰写,而不仅仅是为了测试。
现在您必须确保您使用的所有容器都记录到标准输出。最后,您将在存档集成-test.log 中获得所有日志。当然,你也可以扩展这个,为每个容器获取一个单独的日志文件。