CICD
是持续集成(Continuous Integration)和持续部署(Continuous Deployment)的简称。CD还有一层 Continuous Delivery 持续交付的意思。
降低时间成本、降低出错概率。在快速的产品迭代中还可以保持很高的质量。
-
时间成本的降低是相对而言,不是有了
CICD
就一定降低时间成本。CICD
的搭建也需要时间成本,同时无形当中也拔高了人力成本。所以上不上CICD
需要考虑当下和上CICD
后的运维时间成本和运维复杂度。
代码编写 → 代码构建 → 单元测试 → 质量管理 → 打包与归档 → 集成测试 → 部署测试环境 → 部署预生产环境 → 验收测试 → 部署生产环境 → 运维与监控
推送代码到 Gitlab
→ Gitlab`通知 `Jenkins
→ Jenkins
触发构建(单元测试、代码质量、打包归档) → 推送镜像到 test
库 → Harbor
通知 Jenkins
镜像接收完成 → Jenkins
把应用部署到 k8s
→ 邮件通知
Note
|
镜像命名规则 → 项目名-分支名-版本名。测试环境初始版本镜像命名不要用latest,统一用0.0.1(k8s拉取问题、字面意思问题)。 |
正式环境的升级工作只能手动触发或定时触发。预生产环境的构建和部署可以联动,生产环境的构建和部署推荐断开。
Jenkins
触发构建 → 获取最近代码版本(Tag) → 开始构建(单元测试、代码质量、打包归档) → 推送镜像到 official
库 → Harbor
通知 Jenkins
镜像接收完成 → Jenkins
把应用部署或更新到 k8s
→ 邮件通知
-
构建最新版本的应用
Jenkins
触发构建 → 获取最近代码版本(Tag) → 开始构建(单元测试、代码质量、打包归档) → 推送镜像到 official
库 → 邮件通知。
-
构建指定版本的应用
Jenkins
触发构建 → 获取最近代码版本(Tag) → 开始构建(单元测试、代码质量、打包归档) → 推送镜像到 official
库 → 邮件通知。
CAAS
是 Containers as a Service 的缩写。
jenkins
是基于 Java
开发的一种持续集成工具。
-
docker - https://hub.docker.com/_/jenkins
-
docker-github - https://github.com/jenkinsci/docker
$ sudo docker search jenkinsci/blueocean
$ sudo docker pull jenkinsci/blueocean:1.23.0
$ sudo docker images
$ sudo mkdir -p /opt/n5/jenkins/bin/jenkins-1.23.0/data
$ sudo chown -R 200 /opt/n5/jenkins/bin/jenkins-1.23.0/data
$ sudo docker run \
-u root \
-d \
-p 8080:8080 \
-p 50000:50000 \
--name jenkins \
--restart=always \
-v /opt/n5/jenkins/bin/jenkins-1.23.0/data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkinsci/blueocean:1.23.0
$ sudo docker pull jenkins/jenkins:2.277.4-lts-centos7
$ sudo docker images
$ sudo mkdir -p /opt/n5/jenkins/bin/jenkins-2.277/data
$ sudo chown -R 200 /opt/n5/jenkins/bin/jenkins-2.277/data
$ sudo docker run \
-u root \
-d \
-p 8090:8080 \
--name jenkins2.277.4 \
--restart=always \
-v /opt/n5/jenkins/bin/jenkins-2.277/data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:2.277.4-lts-centos7
获取登录密码
$ sudo docker logs jenkins-blueocean
输出
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
50de1ecbe1654d4b975da8dc894cf0ae (1)
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
-
登录密码
登录 jenkins
http://192.168.41.34:8080
安装插件,可以通过官网(需要连接外网)或者设置代理进行自动安装,也可以通过手动安装插件,点击系统管理 → 管理插件 → 高级 → 上传插件。
-
登录
Jenkins
安装SSH Agent Plugin
和SSH Build Agents plugin
插件,系统管理 → 管理插件。-
SSH Agent Plugin
This plugin allows you to provide SSH credentials to builds via a ssh-agent in Jenkins -
SSH Build Agents plugin
Allows to launch agents over SSH, using a Java implementation of the SSH protocol. -
SSH Pipeline Steps
-
-
添加节点,系统管理 → 节点管理 → 新建节点
-
登录
GitLab
插件Access Tokens
,账号 → Settings → Access Tokens。
-
如果
jenkins
和Gitlab
在同一台机器上,admin
角色登录Gitlab
,设置Gitlab
的Outbound requests
勾选允许所有请求。
-
登录
Jenkins
安装GitLab
插件,系统管理 → 管理插件。 -
设置
GitLab
信息,系统管理 → 系统设置 → Gitlab。
增加 Credentials
-
Harbor
的Post
内容
{
"method" : "POST",
"path" : "/",
"headers" : {
"Host" : [ "192.168.41.35:1080" ],
"User-Agent" : [ "Go-http-client/1.1" ],
"Content-Length" : [ "384" ],
"Content-Type" : [ "application/json" ],
"Accept-Encoding" : [ "gzip" ]
},
"keepAlive" : true,
"secure" : false,
"body" : {
"type" : "pushImage",
"occur_at" : 1620398885,
"operator" : "admin",
"event_data" : {
"resources" : [ {
"digest" : "sha256:50c3e028b6015527fd6a3c55d0054c4044d330dc8b1e86eb13a52df15a1713d3",
"tag" : "1.0.0",
"resource_url" : "192.168.41.32/test/test-jenkins:1.0.0"
} ],
"repository" : {
"date_created" : 1620398885,
"name" : "test-jenkins",
"namespace" : "test",
"repo_full_name" : "test/test-jenkins",
"repo_type" : "public"
}
}
}
}
-
通过
$.type
取到type
的值赋值给type
。
-
$type_$repo_full_name
的值与^pushImage_test/test-jenkins$
正则能匹配上则执行。
-
设置
token
,请求的地址需要带上token
才会触发。
引导路径 → 项目 → 特定项目 → Webhooks
-
登录
Jenkins
安装SSH Credentials Plugin
和SSH plugin
插件,系统管理 → 管理插件。-
SSH Credentials Plugin
Allows storage of SSH credentials in Jenkins -
SSH plugin
This plugin executes shell commands remotely using SSH protocol.
-
-
设置
SSH remote hosts
-
选择凭据
Credentials
,如果未插件,则新插件一个Credentials
。Credentials
的类型有Username with password
或X.509 Client Certificate
登录 Jenkins 安装 Email Extension Plugin 插件,系统管理 → 管理插件。
Email Extension Plugin
allows you to configure every aspect of email notifications.
-
在
Jenkins
上设置Jenkins
的地址和管理员邮箱地址,系统管理 → 系统设置。
-
设置
Extended E-mail Notification
,系统管理 → 系统设置。
-
设置邮件的模板,系统管理 → 系统设置。
-
设置邮件的触发
-
在
Task
的构建后操作中配置发送邮件。
Gitlab > jenkins > git > maven > docker image > harbor
# 构建目录
WORK_SPACE="/opt/n5/cicd/bin/docker/data"
# MAVEN的仓库目录
MAVEN_REPO=/opt/n5/maven/bin/.m2
# 项目
PROJECT_NAME=test-jenkins
PROJECT_SPACE=${WORK_SPACE}"/"${PROJECT_NAME}
# 如果存在构建目录,就删除
if [ -e ${PROJECT_SPACE} ] ; then
echo "file "${PROJECT_SPACE}" exists"
rm -rf ${PROJECT_SPACE}
fi
mkdir -p ${PROJECT_SPACE}
# 构建目录
WORK_SPACE="/opt/n5/cicd/bin/docker/data"
# MAVEN的仓库目录
MAVEN_REPO=/opt/n5/maven/bin/.m2
# 项目
PROJECT_NAME=test-jenkins
PROJECT_SPACE=${WORK_SPACE}"/"${PROJECT_NAME}
GIT_SPACE=${PROJECT_SPACE}"/git"
GIT_NAME=${PROJECT_NAME}"-GIT"
docker run -i \
--rm \
--name ${GIT_NAME} \
-v "${GIT_SPACE}":/git \
alpine/git \
clone http://192.168.41.31:180/ludongrong/test-jenkins.git
#删除容器
docker ps -a | grep ${GIT_NAME} | awk '{print $1}' | xargs -I {} docker rm {}
# 构建目录
WORK_SPACE="/opt/n5/cicd/bin/docker/data"
# MAVEN的仓库目录
MAVEN_REPO=/opt/n5/maven/bin/.m2
# 项目
PROJECT_NAME=test-jenkins
PROJECT_SPACE=${WORK_SPACE}"/"${PROJECT_NAME}
GIT_SPACE=${PROJECT_SPACE}"/git"
MAVEN_SPACE=${GIT_SPACE}"/"${PROJECT_NAME}
MAVEN_NAME=${PROJECT_NAME}"-MAVEN"
# 如果不存在maven的仓库目录,就创建
if [ ! -e ${MAVEN_REPO} ] ; then
echo "file "${MAVEN_REPO}" not exists"
mkdir -p ${MAVEN_REPO}
chown -R 200 ${MAVEN_REPO}
fi
docker run -i \
--rm \
--name ${MAVEN_NAME} \
-v "${MAVEN_SPACE}":/usr/src/git \
-v "${MAVEN_REPO}":/root/.m2 \
-w /usr/src/git \
192.168.41.32/test/maven33:3.6.3 mvn clean install
#删除容器
docker ps -a | grep ${MAVEN_NAME} | awk '{print $1}' | xargs -I {} docker rm {}
# 构建目录
WORK_SPACE="/opt/n5/cicd/bin/docker/data"
# MAVEN的仓库目录
MAVEN_REPO=/opt/n5/maven/bin/.m2
# 项目
PROJECT_NAME=test-jenkins
# 项目端口
TARGET_PORT=8081
# 版本号
VERSION=1.0.0
PROJECT_SPACE=${WORK_SPACE}"/"${PROJECT_NAME}
GIT_SPACE=${PROJECT_SPACE}"/git"
MAVEN_SPACE=${GIT_SPACE}"/"${PROJECT_NAME}
TARGET_SPACE=${MAVEN_SPACE}"/target"
cd ${TARGET_SPACE}
# 创建Dockerfile文件
cat << EOF > Dockerfile111
FROM kdvolder/jdk8
MAINTAINER ${PROJECT_NAME}
VOLUME /tmp
LABEL app="${PROJECT_NAME}" version="${VERSION}" by="${PROJECT_NAME}"
COPY ${PROJECT_NAME}.jar ${PROJECT_NAME}.jar
EXPOSE ${TARGET_PORT}
CMD -Xmx100m -Xms100m -jar -Duser.timezone=GMT+08 ${PROJECT_NAME}.jar
ENTRYPOINT java
EOF
# 创建Dockerfile文件
cat << EOF > Dockerfile
FROM tomcat:8.5.65-jdk8-corretto
ADD ./springmvcdemo.war /usr/local/tomcat/webapps/
EXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
EOF
#删除容器
docker ps -a | grep ${PROJECT_NAME} | awk '{print $1}' | xargs -I {} docker rm {}
#删除镜像
docker images | grep ${PROJECT_NAME} | awk '{print $3}' | xargs -I {} docker rmi -f {}
#创建镜像
docker build -t ${PROJECT_NAME}:${VERSION} .
# 构建目录
WORK_SPACE="/opt/n5/cicd/bin/docker/data"
# MAVEN的仓库目录
MAVEN_REPO=/opt/n5/maven/bin/.m2
# 项目
PROJECT_NAME=test-jenkins
# 项目端口
TARGET_PORT=8081
# 版本号
VERSION=1.0.0
# 组织
ORG_NAME=test
PROJECT_SPACE=${WORK_SPACE}"/"${PROJECT_NAME}
docker login -u admin -p Harbor12345 192.168.41.32
docker tag ${PROJECT_NAME}:${VERSION} 192.168.41.32/${ORG_NAME}/${PROJECT_NAME}:${VERSION}
docker push 192.168.41.32/${ORG_NAME}/${PROJECT_NAME}:${VERSION}
#删除容器
docker rm -f $(docker ps -a | grep "${PROJECT_NAME}" | awk '{print $1}')
#删除镜像
docker images | grep ${PROJECT_NAME} | awk '{print $1}' | xargs -I {} docker rmi -f {}
rm -rf ${PROJECT_SPACE}
jenkins > docker pull > docker stop > docker rmi > docker run
# 构建目录
WORK_SPACE="/opt/n5/cicd/bin/docker/data"
# MAVEN的仓库目录
MAVEN_REPO=/opt/n5/maven/bin/.m2
# 项目
PROJECT_NAME=test-jenkins
# 项目端口
TARGET_PORT=8081
# 项目日志
LOG_PATH="/opt/n5/logs/"${PROJECT_NAME}
# 版本号
VERSION=1.0.0
# 组织
ORG_NAME=test
HARBOR_URL=192.168.41.32
#删除同名容器
docker_id=$(docker ps | grep "${PROJECT_NAME}" | awk '{print $1}')
if [ "${docker_id}" != "" ]; then
docker rm -f ${docker_id}
fi
#删除镜像
docker images | grep ${PROJECT_NAME} | awk '{print $3}' | xargs -I {} docker rmi -f {}
# 登录Harbor
docker login -u admin -p Harbor12345 ${HARBOR_URL}
# 拉取镜像
docker pull ${HARBOR_URL}/${ORG_NAME}/${PROJECT_NAME}:${VERSION}
docker run -itd -p ${TARGET_PORT}:8080 \
--name ${PROJECT_NAME}-${VERSION} \
-v ${LOG_PATH}:/usr/local/tomcat/logs \
${HARBOR_URL}/${ORG_NAME}/${PROJECT_NAME}:${VERSION}
bamboo
是持续集成、部署和交付的商业软件。
内容 | bamboo | jenkins |
---|---|---|
Built-in Git branching workflows |
support |
not support |
Built-in deployment Projects |
support |
not support |
Built-in Jira Software integration |
support |
not support |
Built-in Bitbucket Server integration |
support |
not support |
REST APIs |
support |
support |
Test Automation |
support |
Supported through plugins |
Easy Enterprise-grade permissions |
support |
Supported through plugins |
GitLab
是开源的代码托管软件。
sudo yum install -y curl policycoreutils-python openssh-server
sudo systemctl enable sshd
sudo systemctl start sshd
sudo firewall-cmd --permanent --add-service=http
sudo systemctl reload firewalld
rpm -i gitlab-ce-10.1.4-ce.0.el7.x86_64.rpm
修改配置
$ vim /etc/gitlab/gitlab.rb
unicorn['port'] = 8082
nginx['listen_port'] = 82
git_data_dirs({
"default" => {
"path" => "/data/git-data",
"failure_count_threshold" => 10,
"failure_wait_time" => 30,
"failure_reset_time" => 1800,
"storage_timeout" => 30
}
})
重启 gitlab
$ gitlab-ctl reconfigure
$ gitlab-ctl restart
$ sudo docker search gitlab
$ sudo docker pull gitlab/gitlab-ce:12.9.4-ce.0
$ sudo docker images
$ sudo mkdir -p /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/config
$ sudo chown -R 200 /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/config
$ sudo mkdir -p /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/logs
$ sudo chown -R 200 /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/logs
$ sudo mkdir -p /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/data
$ sudo chown -R 200 /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/data
$ export GITLAB_HOME=/opt/n5/gitlab/bin/gitlab-12.9.4-ce.0
$ sudo docker run --detach \
--hostname 192.168.41.31 \ (1)
--publish 443:443 \ (2)
--publish 80:80 \ (3)
--publish 122:22 \ (4)
--name gitlab \ (5)
--restart always \ (6)
--volume $GITLAB_HOME/config:/etc/gitlab \
--volume $GITLAB_HOME/logs:/var/log/gitlab \
--volume $GITLAB_HOME/data:/var/opt/gitlab \
gitlab/gitlab-ce:12.9.4-ce.0
-
指定容器域名,未知功能:创建镜像仓库的时候使用到
-
443(主机端口):443(容器端口),提供https服务
-
80(主机端口):80(容器端口),提供http服务
-
122(主机端口):22(容器端口),提供ssh服务
-
指定容器名称
-
容器运行中退出时(不是手动退出),自动重启
$ sudo docker exec -it gitlab /bin/bash
$ vi /etc/gitlab/gitlab.rb
或者直接修改 /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/config/gitlab.rb
为了让 GitLab
向您的用户显示正确的克隆链接。
For HTTP
external_url 'http://192.168.41.31'
或者
For HTTPS (notice the https)
external_url 'https://192.168.41.31'
$ sudo docker restart gitlab
-
查看过程
$ sudo docker logs -f gitlab
-
查看过程
After starting a container you can visit http://localhost/ or http://192.168.59.103
-
重启失败
$ cd /opt/n5/gitlab/bin/gitlab-12.9.4-ce.0/logs/unicorn
$ rm -rf *
$ sudo docker restart gitlab
访问【http://192.168.41.31:180/】>> 输入密码。