การตั้งค่าการอนุญาตที่ถูกต้องเมื่อเรียกใช้ Docker ใน Jenkins Pipeline คืออะไร


11

ฉันพยายามดึงเจนกินส์ไปป์ไลน์ใหม่ด้วยกันเพื่อทดสอบคำขอดึงใหม่ไปยังโค้ดของเรา ฉันใช้นักเทียบท่าพร้อมกับubuntu:14.04ภาพเพื่อจำลองสภาพแวดล้อมการผลิตของเรา

นี่คือตัวอย่างการทำงานขั้นต่ำ:

#jenkinsfile
stage('Checkout and provision'){
docker.image('ubuntu:14.04').withRun('-u root'){
    checkout scm
    sh 'chmod -R 770 ./'
    sh './init-script.sh'
    }
}

และ

 #init-script.sh
 sudo add-apt-repository ppa:ondrej/php
 sudo apt-get update -y
 sudo apt-get dist-upgrade -y
 sudo apt-get install \
    apache2 \
    php \
    php-mysql \
    php-xml \
    libapache2-mod-auth-mysql \
    libapache2-mod-php \
    php5-curl \
    zip \
    htop \
    supervisor \
    mailutils \
    git \
    build-essential -y
 sudo apt-get autoremove -y

และ/etc/sudoersไฟล์สำหรับคอนเทนเนอร์มีดังนี้:

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults:jenkins !requiretty

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

jenkins ALL=(ALL:ALL) NOPASSWD:ALL

ปัญหาที่ฉันมีคือนักเทียบท่านั้นไม่ได้ทำงานเหมือนรูทอย่างที่ฉันคุ้นเคยและเก็บรหัสผู้ใช้ของผู้ใช้เจนกินส์จากเครื่องโฮสต์แทน นี่ทำให้มันยากที่จะ sudo

ฉันได้พยายามเพิ่มผู้ใช้เจนกินส์กับภาชนะบรรจุ/etc/passwdไฟล์และทำงานchmodกับไฟล์นั้น jenkinsfileแต่ไม่ได้มีสิทธิ์ที่จะทำอย่างใดอย่างหนึ่งเหล่านี้จาก

ด้วยการกำหนดค่านี้ฉันควรเป็นผู้ใช้รูท อย่างไรก็ตามฉันเห็นError: must run as rootว่าฉันไม่ได้ใช้sudoหรือ sudo: no tty present and no askpass program specifiedถ้าฉันทำ

มีวิธีที่ถูกต้องในการจัดการกับสถานการณ์นี้หรือไม่? เป็นการดีจากjenkinsfile; ฉันต้องการหลีกเลี่ยงการสร้างเพิ่มเติมDockerfileหากเป็นไปได้เพราะจะเป็นความแตกต่างเพิ่มเติมระหว่างการทดสอบและการผลิต


แชร์ jenkinsfile และ unit.sh ของคุณได้ไหม เสียงส่วนใหญ่คาดเดาที่จุดนี้ ...
Tensibai

นี่เป็นคำถามที่ไม่คาดฝันที่พยายามทำให้ผู้คนแก้ปัญหาการบ้านของคุณ มีฟอรั่มเจนกินส์จริงๆสำหรับสิ่งนั้น คำถามของคุณควรถูกถามในรูปแบบที่สามารถพบได้ในการค้นหา google เมื่อมีปัญหาที่คล้ายกันและเป็นประโยชน์กับคนอื่นที่ไม่ใช่ตัวคุณเองเพื่อเป็นคำถามที่ดีสำหรับเว็บไซต์นี้
Jiri Klouda

ฉันได้ทำสิ่งนี้มาหลายวันแล้วและได้สืบค้นเอกสารของเจนกินส์ ฉันยังหาวิธีแก้ปัญหา หากมีคำศัพท์ที่ฉันไม่สามารถหาคำตอบที่ฉันต้องการได้โปรดแจ้งให้เราทราบ ฉันได้อัปเดตคำถามเพื่อให้ชัดเจนยิ่งขึ้นในสิ่งที่ฉันถาม แต่ฉันไม่เห็นด้วยว่านี่คือ 'สตริง' หรือ 'การบ้าน'
tobassist

ฉันได้อัปเดตคำถามด้วยตัวอย่างเล็ก ๆ น้อย ๆ
tobassist

1
บางทีนี่อาจช่วยได้: wiki.jenkins-ci.org/display/JENKINS/Docker+Plugin (ฉันคิดว่า -u root เมื่อคุณไม่ใช่รูทไม่ทำงานมันเปลี่ยนชื่อผู้ใช้ แต่ไม่ใช่ชื่อผู้ใช้) คุณจะต้องเตรียมภาพของคุณด้วยผู้ใช้เจนกินส์อนุญาตให้ sudo รหัสผ่าน
Tensibai

คำตอบ:


12

ดังนั้นหลังจากเซสชันดีบั๊กในการแชทสิ่งที่จำเป็นคือการอนุญาตให้ผู้ใช้ที่เรียกใช้เจนกินส์สามารถsudo dockerรหัสผ่านบนโฮสต์นักเทียบท่าได้

ไฟล์ sudoers ทั่วไปบน ubuntu อาจเข้าได้ /etc/sudoers.d/jenkins

jenkins_user ALL=(ALL) NOPASSWD:ALL

ได้รับการเตือนว่าการอนุญาตให้jenkins_userรันเป็น root โดยไม่มีรหัสผ่านคำสั่งใด ๆ ไฟล์ที่ดีกว่าควรเป็น:

jenkins_user ALL=(ALL) NOPASSWD:/full/path/to/docker
jenkins_user ALL=(ALL) NOPASSWD:<other needed command to be run as root>

สิ่งนี้จะอนุญาตให้เริ่มคอนเทนเนอร์ในฐานะรูทและจะให้สิทธิ์ทั้งหมดภายในคอนเทนเนอร์ด้วยการรันเป็น uid 0

ทรัพยากรที่มีประโยชน์ที่ใช้กัน:


2

เป็นความคิดที่ดีที่จะเรียกใช้ Docker เป็นรูท สิ่งที่คุณควรทำแทนการเพิ่มผู้ใช้ Jenkins ในกลุ่มนักเทียบท่า sudo usermod -aG docker jenkins. สิ่งนี้จะหลีกเลี่ยงการเปิดช่องโหว่ที่ไม่จำเป็นและอนุญาตให้ Jenkins ทำทุกอย่างที่จำเป็นต้องทำกับ Docker รวมถึงการทำงานเป็นรากภายในคอนเทนเนอร์ ฉันทำสิ่งนี้เป็นประจำกับงานสร้างของฉันโดยใช้สิ่งนี้เป็นตัวอย่าง:

stage ('Build Docker Image') {
  steps {
    script {
      // Build the Docker image for compiling
      dockerImage = docker.build("myapp:v1")
    }
  }
}
stage ('Run UnitTests') {
  steps {
    script {
      dockerImage.inside("-itu root") {
        sh(script: "nosetests app-test.py --verbose")
      }
    }
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.