没有安装docker的可以通过docker install进行安装。
docker jenkins
运行jenkins
首先创建一个目录存储容器中的信息mkdir jenkins-blue
,然后执行命令sudo chown -R 1000:1000 ./jenkins-blue/
,否则可能会报错touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied
,
其中用来改变./jenkins-blue/
目录下所有文件和子目录的所有者和所属组。1000:1000代表所有者和所属组的用户ID和组ID。
- 创建network
docker network create jenkins
- 创建jenkins-docker
docker run --name jenkins-docker --rm --detach \
--privileged --network jenkins --network-alias docker \
--env DOCKER_TLS_CERTDIR=/certs \
--volume ./jenkins-blue/jenkins-docker-certs:/certs/client \
--volume ./jenkins-blue/jenkins-data:/var/jenkins_home \
--publish 2376:2376 \
docker:dind --insecure-registry test.com
注意一下映射的目录是否存在。--insecure-registry test.com
参数没有配置https才需要。
3. Dockerfile
FROM jenkins/jenkins:2.426.2-jdk17
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"
- 构建docker镜像
docker build -t myjenkins-blueocean:2.426.2-1 .
- 运行jenkins
docker run --name jenkins-blueocean --restart=on-failure --detach \
--network jenkins --env DOCKER_HOST=tcp://docker:2376 \
--env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 \
--volume ./jenkins-blue/jenkins-data:/var/jenkins_home \
--volume ./jenkins-blue/jenkins-docker-certs:/certs/client:ro \
--publish 8080:8080 --publish 50000:50000 myjenkins-blueocean:2.426.2-1
通过ip:8080
(记得开放一下服务器端口),访问Jenkins,密码保存在/path/to/jenkins-blue/jenkins-data/secrets/initialAdminPassword
中。
安装Git plugin
、Pipeline
和PipelineView
。
点击New Item
添加一个多分支流水线的项目,在Branch Sources
-> Add source
-> Git
中添加我们的项目git地址。
Jenkins会扫描分支中包含Jenkinsfile的分支,进行操作。
安装Jenkins 插件
- Pipeline Utility Steps,使用其中的readJson解析json字符串。
- Git plugin
- Pipeline: Stage Step
- Pipeline: Stage View Plugin
Jenkinsfile
// 可以用来声明全局变量
import groovy.transform.Field
String buildNumber = env.BUILD_NUMBER;
String timestamp = new Date().format('yyyyMMddHHmmss');
String projectName = env.JOB_NAME.split(/\//)[0];
userInputRegistryInfo = input(
id: 'userInputRegistryInfo', message: 'Enter path of test reports:?',
parameters: [
string(description: 'Host of docker registry',
name: 'host'),
string(description: 'dockerImage of docker registry',
name: 'dockerImage')
])
host = userInputRegistryInfo.host
dockerImage = userInputRegistryInfo.dockerImage
String version = "${buildNumber}-${timestamp}-${projectName}";
node {
checkout scm;
if(params.BuildType=='Rollback') {
return rollback()
} else if(params.BuildType=='Normal'){
return normalCIBuild(version)
} else {
setScmPollStrategyAndBuildTypes(['Normal', 'Rollback']);
}
}
def setScmPollStrategyAndBuildTypes(List buildTypes) {
def propertiesArray = [
// 构建参数
parameters([choice(choices: buildTypes.join('\n'), description: '', name: 'BuildType')]),
pipelineTriggers([[$class: "SCMTrigger", scmpoll_spec: "* * * * *"]]),
// 禁止并行构建
disableConcurrentBuilds()
];
properties(propertiesArray);
}
@Field def inputAuthValue
def normalCIBuild(String version) {
stage ('test & package') {
sh('chmod +x ./mvnw && ./mvnw clean package')
}
stage('docker build') {
inputAuthValue = getInputAuth()
echo inputAuthValue.password
sh("docker login ${host} -u ${inputAuthValue.username} -p ${inputAuthValue.password}")
sh("docker build . -t ${host}/${dockerImage}:${version}")
sh("docker push ${host}/${dockerImage}:${version}")
}
stage('deploy') {
input 'deploy?'
deployVersion(version)
}
}
def deployVersion(String version) {
// 链接服务器使用docker发版
sh """ssh -o StrictHostKeyChecking=no root@${host.split(':')[0]} 'docker login ${host} -u ${inputAuthValue.username} -p ${inputAuthValue.password} && \
docker rm -f container-name && \
docker run --name container-name -d -p 8081:8080 ${host}/${dockerImage}:${version}'"""
}
def rollback() {
stage('do rollback') {
def getAllTagsUri = "/v2/${dockerImage}/tags/list";
inputAuthValue = getInputAuth()
sh("docker login ${host} -u ${inputAuthValue.username} -p ${inputAuthValue.password}")
println "http://${host}${getAllTagsUri}"
def responseJson = sh(script: "curl -u ${inputAuthValue.username}:${inputAuthValue.password} --url ${host}${getAllTagsUri}", returnStdout: true)
// {name:xxx,tags:[tag1,tag2,...]}
def response = readJSON text: responseJson
def versionsStr = response.tags.join('\n');
def rollbackVersion = input(
message: 'Select a version to rollback',
ok: 'OK',
parameters: [choice(choices: versionsStr, description: 'version', name: 'version')])
println rollbackVersion
deployVersion(rollbackVersion)
}
}
// 为Docker registry设置了认证,需要手动输入
def getInputAuth() {
def inputAuth = input(
id: 'getInputAuth', message: 'Enter username and password:?',
parameters: [
string(description: 'username of auth',
name: 'username', trim: true),
string(description: 'password of auth',
name: 'password', trim: true )
])
return inputAuth
}
Docker registry
- 安装 htpasswd生成一个登录registry用的账号密码
yum install -y httpd-tools
- 生成
mkdir -p /opt/registry-var/auth/
用以保存密码 - 生成密码保存到htpasswd中
htpasswd -Bbn username password >> /opt/registry-var/auth/htpasswd
大B - 生成
mkdir -p /opt/registry-var/config
用来映射registry的config - 启动registry
docker run -p 5001:5000 --restart=always --name=registry \
-v /opt/registry-var/config/:/etc/docker/registry/ \
-v /opt/registry-var/auth/:/auth/ \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v /opt/registry-var/:/var/lib/registry/ registry:2.8
如果没有配置https还需要修改一下vim /etc/docker/daemon.json
,
vim中按下i
变为插入模式,使用esc
输入:wq
保存内容并退出。
{
"insecure-registries": [
"xxx:port"
]
}
sudo deckerd 可以启动docker
插曲
- 服务器链接github慢,可以考虑
521github.com
,不过生产环境应该不考虑这种,可能不安全。 - xxx.pem文件使用
mv
cp
命令移动到~/.ssh/
目录下并命名为id_rsa可以实现ssh role@host
连接到服务器。 - 运行
ssh-add id_rsa.pem
时可能没有启动ssh-add
,可以运行
eval `ssh-agent -s`
启动一个ssh-agent进程,-s选项告诉ssh-agent将其相关信息输出到标准输出。
4. Docker registry如果没有配置https,可以在启动容器时在命令最后加--insecure-registry test.com
,或者使用命令vim /etc/docker/daemon.json
(见上描述)。
5. 使用ssh链接服务器如提示Warning: unprotected private key file!代表用户对私钥权限过大,可以使用命令chmod 400 ~/.ssh/id_rsa
, 400代表所有者具有只读权限,其他用户没有任何权限。如需其他权限,可自行查阅。
6. 使用root用户操作Docker容器,windowsdocker exec -ti --user root {容器名} /bin/bash
,linux可以尝试docker exec -ti --user root {容器名} sh
7. 使用PuTTY
和pem
文件链接服务器,可以在安装目录下寻找PuTTYgen
将pem文件转换为ppk。PuTTY
添加ppk文件的路径为 Connection -> SSH -> Auth -> Credentials -> Privite key file。然后点击sava
。
8. 在上述第7条配置后使用WinSCP
可以检测到配置进行利用。