自定义的jenkins镜像
自己做的Dockerfile,打包了常用插件,以及跳过初始化密码和选择插件阶段
Dockerfile
FROM jenkins/jenkins:2.346.2-lts
# 先使用root用户下载软件
USER root
# 设置镜像的apt源
COPY --chown=root:root debian11.list /etc/apt/sources.list
# 设置pip源
COPY --chown=root:root pip.conf /root/.pip/pip.conf
# 设置公钥私钥
COPY --chown=root:root .ssh /root/.ssh
# 设置jenkins用户公钥私钥
COPY --chown=jenkins:jenkins .ssh /var/jenkins_home/.ssh
# 添加提前安装好的plugin
COPY --chown=jenkins:jenkins plugin /usr/share/jenkins/ref/plugins/
# 添加初始化脚本,用户提前设置用户名和密码
COPY --chown=jenkins:jenkins set_user_password.groovy /usr/share/jenkins/ref/init.groovy.d/set_user_password.groovy
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3.9 python3.9-dev python3.9-venv \
&& ln -s /usr/bin/python3.9 /usr/local/bin/python3 \
&& ln -s /usr/bin/python3.9 /usr/local/bin/python \
&& curl -s https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
&& python3 get-pip.py \
&& rm -f get-pip.py
RUN echo root:1234 | chpasswd
RUN pip install python-jenkins pyyaml requests
RUN apt-get install -y --no-install-recommends wget vim sshpass ansible inetutils-ping
USER jenkins
EXPOSE 8080 50000
# Djenkins.install.runSetupWizard=false 代表跳过jenkins初始化阶段
ENV JAVA_OPTS=-Djenkins.install.runSetupWizard=false -Duser.timezone=GMT+08
set_user_password.groovy`文件
#!groovy
import hudson.security.*
import jenkins.model.*
def instance = Jenkins.getInstance()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
def users = hudsonRealm.getAllUsers()
users_s = users.collect { it.toString() }
// Create the admin user account if it doesn't already exist.
if ("admin" in users_s) {
println "Admin user already exists - updating password"
def user = hudson.model.User.get('admin');
def password = hudson.security.HudsonPrivateSecurityRealm.Details.fromPlainPassword('admin')
user.addProperty(password)
user.save()
}
else {
println "--> creating local admin user"
hudsonRealm.createAccount('admin', 'admin')
instance.setSecurityRealm(hudsonRealm)
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
instance.setAuthorizationStrategy(strategy)
instance.save()
}
// update 不使用这个了
//println "--> Update Plugin Center."
//Jenkins j = Jenkins.getInstance()
//j.pluginManager.doSiteConfigure("https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json")
//j.pluginManager.doCheckUpdatesServer()
pip.conf
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
trusted-host = mirrors.aliyun.com
debian11.list
deb https://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb https://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src https://mirrors.aliyun.com/debian-security/ bullseye-security main
deb https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src https://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
.ssh 自己设置的公用私钥和公钥
ssh-keygen -t rsa -f ~/.ssh/id_rsa -C "root@jenkins" -P '' &>/dev/null
# 然后将~/.ssh 拷贝到Dockerfile所在目录
运行jenkins的jenkins/jenkins:2.346.2-lts基础容器,手动下载需要的插件
docker run -d -p 8080:8080 --name=jenkins_plugin_container jenkins/jenkins:2.346.2-lts
# http://{dockerhsotsIP}:8080/ 访问,然后输入账号密码,安装插件
使用一下python脚本,将已经安装好的jenkins的插件的所有hpi文件全部下载下载,
python get_jenkinsPlugin_jenkins_package.py -url http://{dockerhsotsIP}:8080/ -u {上一步设置的用户} -p {上一步设置的密码} -o dir --repo_url “https://mirror.tuna.tsinghua.edu.cn/jenkins/plugins/” -d
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project :docker_study
@File :get_jenkins_plugin_list
@Author :lpx
@Date :2022/8/3 16:31
@Use: python get_jenkinsPlugin_jenkins_package.py
-url http://192.168.0.66:8080/
-u admin -p admin
-o dir
--repo_url "https://mirror.tuna.tsinghua.edu.cn/jenkins/plugins/" # 添加repo_url 就代表,
-d # 添加-d就下载,
python get_jenkinsPlugin_jenkins_package.py -url http://192.168.0.66:8080/ -u admin -p Lipanxiang1102 -o dir --repo_url "https://mirror.tuna.tsinghua.edu.cn/jenkins/plugins/" -d
# 该脚本为下载问件事未使用多线程,后续改进
# 该脚本 可以做成jenkins工程,然后将生成的plugin_version_file_name.txt 和 plugin_download_url.txt 存放到jenkins构建中,打包成制品,
# 默认只要下载,就默认使用gz进行打包,并删除下载的文件夹。
# 该方式 需要基础环境中 有 jenkins-python包,requests包,然后需要知道 jenkins的账号和密码
'''
import os
import sys
import argparse
import requests
import tarfile
import shutil
requests.packages.urllib3.disable_warnings()
import jenkins
def getArgs():
parse=argparse.ArgumentParser()
parse.add_argument('-u',type=str,help='jenkins的用户名')
parse.add_argument('-p',type=str,help='jenkins的密码')
parse.add_argument('-url',type=str,help="jenkins的地址")
parse.add_argument('-o',type=str,help='输出文件夹')
parse.add_argument('-d', action='store_true', help='下载所有jenkins版本插件')
parse.add_argument('--repo_url', type=str,default='https://updates.jenkins-ci.org/download/plugins', help='插件仓库的地址')
args=parse.parse_args()
return vars(args)
# 创建空文件,如果之前存在先删除
def touch_empty_file(file_path):
if os.path.exists(file_path):
os.remove(file_path)
with open(file_path,'w') as f:
pass
# 写入内容到文件,追加写入
def write_line_in_file(file_path,content):
with open(file_path, 'a') as f:
f.write(content)
# 下载文件,没有使用多线程,单线程下载
def download_file(file_path,download_url):
proxies = {"http": None, "https": None}
res = requests.get(url=download_url, proxies=proxies, verify=False)
with open(file_path, 'wb') as f:
f.write(res.content)
# 筛选数据并写入文件,如果需要下载也下载文件
def filter_data_and_wirte_file(InstanceJenkins, output_dir,plugin_dir_name, plugin_version_file_name, plugin_download_file_name,
download_is_ok,repo_url):
# 使用这种方式来创建空文件,如果之前存在就删除
plugin_version_file_path = os.path.join(output_dir,plugin_version_file_name)
plugin_download_file_path = os.path.join(output_dir,plugin_download_file_name)
touch_empty_file(plugin_version_file_path)
touch_empty_file(plugin_download_file_path)
# 遍历数据,循环写入数据
plugins = InstanceJenkins.get_plugins(depth=1)
for one_plugin_detail in plugins.values():
plugin_name_version = "{0}:{1}".format(one_plugin_detail.get('shortName'), one_plugin_detail.get('version'))
download_url = "{0}/{1}/{2}/{1}.hpi".format(repo_url, one_plugin_detail.get('shortName'), one_plugin_detail.get('version'))
write_line_in_file(plugin_version_file_path, plugin_name_version+'\n')
write_line_in_file(plugin_download_file_path, download_url+'\n')
if download_is_ok == True:
file_name = download_url.split('/')[-1]
if not os.path.exists(os.path.join(output_dir, plugin_dir_name)):
os.makedirs(os.path.join(output_dir, plugin_dir_name))
file_path = os.path.join(output_dir, "plugin", file_name)
if os.path.exists(file_path):
print('{0}:已经存在'.format(file_name))
else:
download_file(file_path, download_url)
print('{0}:下载成功'.format(file_name))
def exec_gzip_plugin_dir(output_dir, plugin_dir_name, jenkins_version, mode):
os.chdir(output_dir)
plugin_dir_path = plugin_dir_name
plugin_gz_path = "{0}_{1}.tar.{2}".format(plugin_dir_name,jenkins_version,mode)
with tarfile.open(name=plugin_gz_path, mode='w:{0}'.format(mode)) as tf:
tf.add(plugin_dir_path)
if os.path.exists(plugin_gz_path):
print('{0}压缩sueecee'.format(plugin_gz_path))
else:
print('{0}压缩 Failed'.format(plugin_gz_path))
sys.exit(1)
if os.path.exists(plugin_dir_name):
shutil.rmtree(plugin_dir_name)
if __name__ == '__main__' :
args = getArgs()
jenkins_url = args['url'][:-1] if args['url'][-1] == "/" else args['url']
username = args['u']
password = args ['p']
output_dir = args ['o']
if not os.path.exists(output_dir):
os.makedirs(output_dir)
download_is_ok = args ['d'] # 是否下载文件
repo_url = args['repo_url'][:-1] if args['repo_url'] == '/' else args['repo_url']
# 获取jenkins实例
InstanceJenkins = jenkins.Jenkins(jenkins_url, username, password)
# 获取jenkinsversion
jenkins_version = InstanceJenkins.get_version()
plugin_version_file_name = "plugin_version_file_name_{0}.txt".format(jenkins_version)
plugin_download_file_name = "plugin_download_url_{0}.txt".format(jenkins_version)
plugin_dir_name = "plugin"
# 筛选数据并写入文件,并下载插件
filter_data_and_wirte_file(InstanceJenkins, output_dir,plugin_dir_name, plugin_version_file_name, plugin_download_file_name,
download_is_ok,repo_url)
# 压缩插件目录
# http://www.juzicode.com/python-tutorial-zip-unzip-tarfile/#5
# gz bz2 xz
if download_is_ok :
exec_gzip_plugin_dir(output_dir, plugin_dir_name, jenkins_version, 'gz')
插件获取成功之后,最好关掉容器 docker stop jenkins_plugin_container
- 给一个我自己常用的插件列表
最终的文件结果
构建镜像
docker build -t harbor.lpx.com/k8s_study/jenkins/jenkins-2.346.2:v1.0 .
验证镜像:
docker run -d --name=jenkins_master -p 8080:8080 -p 50000:50000 harbor.lpx.com/k8s_study/jenkins/jenkins-2.346.2:v1.0
- 打开网页查看 http:// <docker_host>:8080
如果想省事直接使用我构建好的镜像
docker pull lpx03/jenkins-2.346.2:v1.0