- 4 Docker 结合 Jenkins 构建持续集成环境
- 5 Docker 结合 Consul 实现服务发现
- 6 Docker API
- 7 Docker 日志管理
4 Docker 结合 Jenkins 构建持续集成环境
4.1 持续集成是什么
持续:完成一个新功能就向下一一个环节交付,不断发现问题,解决问题。
集成:研发人员提交新代码到主干,进行构建、部署、测试,不断做集成,修正集成结果。
部署:将项目发布到测试环境、预生产环境或生产环境。
交付:将最终产品发布到预生产环境或生产环境,给用户使用。
- 持续集成 (Continuous Integration) :代码合并、构建、部署、测试都在一-起, 不断地执行这个过程,并对结果反馈。
- 持续交付 (Continuous Delivery) :将最终产品发布到生产环境,给用户使用。
- 持续部署 (Continuous Deployment) :将新需求部署到生产环境。
4.2 持续集成相关工具
Jenkins:一个开源的持续集成工具,提供软件版本发布、自动测试等一系 列流程及丰富的插件。
Maven:一个自动化构建工具,通过-段描述来管理项目的构建,比如编译、打包等逻辑流程。
SVN/Git:源代码版本管理工具。
Docker:容器化技术;打包项目环境与快速部署。
4.3 Docker + Jenkins + Maven + SVN搭建持续集成环境
Reference:https://www.cnblogs.com/xiangsikai/p/10057087.html
4.3.1 发布流程设计
:::color1 Java 环境 CI
:::
:::color1 PHP 环境 CI
:::
:::color1 发布流程设计
:::
:::color1 环境说明
:::
服务器 | IP地址 |
---|---|
Jenkins | 10.0.0.30 |
测试环境 | 10.0.0.31 |
生产环境 | 10.0.0.32 |
- 操作系统:Ubuntu16.04_x64 & CentOS 7.9.2009_x64
- Maven 3.5+
- Tomcat 8+
- JDK 1.8+
- Jenkins 2.7+
- Docker CE 17.06+
4.3.2 SVN安装配置及简单使用
# 修改主机名
$ hostnamectl set-hostname jenkins-svn-ssh
# 安装SVN软件
$ apt-get install subversion
$ mkdir -pv /home/svn
# 创建SVN仓库
$ svnadmin create /home/svn/repos
# 修改SVN配置文件
$ vi /home/svn/repos/conf/svnserve.conf
# 打开以下功能
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
# 添加SVN登录账号
$ vi /home/svn/repos/conf/passwd
[users]
test = 123456
# SVN账号的权限
$ vi /home/svn/repos/conf/authz
[repos:/]
test = rw
# 启动SVN服务
$ svnserve -d -r /home/svn
# 查看SVN进程
$ ps -ef | grep svn
root 100712 1 0 01:46 ? 00:00:00 svnserve -d -r /home/svn
# 仓库地址: svn://10.0.0.30/repos
Download SVN Client:https://tortoisesvn.net/
Download Reference:https://tortoisesvn.net/downloads.html
- 打开
TortoiseSVN Repository Browser
软件,填入相应的SVN URL
- 在 Desktop 桌面中右键找到”SVN CheckOut”,将远程SVN的 Repo 拉到本地
- 在 CheckOut 的目录下创建 index.html 默认页面
<h1>Hello world</h1>
4.3.3 Docker镜像仓库搭建
$ docker run -d \
-v /opt/registry:/var/lib/registry \
-p 5000:5000 \
--restart=always \
--name registry \
registry
# 查看资源,映射宿主机端口到容器端口
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e84dff8aa72b registry "/entrypoint.sh /etc…" 51 seconds ago Up 49 seconds 0.0.0.0:5000->5000/tcp registry
在部署节点配置Docker可信任私有仓库:
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://po13h3y1.mirror.aliyuncs.com","http://hub-mirror.c.163.com","https://mirror.ccs.tencentyun.com","http://f1361db2.m.daocloud.io"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"insecure-registries": ["10.0.0.30:5000"]
}
# 所有节点设置可信任仓库
$ systemctl daemon-reload && systemctl restart docker
# 查看当前仓库上传的镜像
$ curl http://10.0.0.30:5000/v2/_catalog
{"repositories":[]}
# 查看指定镜像的Tags版本
$ curl http://10.0.0.30:5000/v2/lnmp-nginx/tags/list
{"name":"lnmp-nginx","tags":["base"]}
- LNMP包下载地址:https://pan.baidu.com/s/1SHR6WDMXKvPlXOB1J0y5tg
- 密码:ze4f
# 解压包,进入nginx目录
unzip Dockerfile-lnmp.zip;cd Dockerfile-lnmp/nginx/
# 需要添加镜像Yum源(vim Dockerfile)
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-6.10.repo
# 构建nginx镜像容器
docker build -t 10.0.0.30:5000/lnmp-nginx:base .
####################################################################################################
# 进入php目录
cd ../php/
# 需要添加镜像Yum源(vim Dockerfile)
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-6.10.repo
# 构建php镜像如期
docker build -t 10.0.0.30:5000/lnmp-php:base .
上传基础镜像到私有仓库:
参考一键部署LNMP网站平台的配置:
# Docker Compose 存放在Git Hub,不太稳定。
# 可以也通过执行下面的命令,高速安装Docker Compose。
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# 所有节点安装
# 构建镜像
docker build -t 10.0.0.30:5000/lnmp-nginx:base .
docker build -t 10.0.0.30:5000/lnmp-php:base .
# 注:地址IP需要根据环境修改,确认执行完毕,无误。
# 推送镜像到私有仓库
docker push 10.0.0.30:5000/lnmp-nginx:base
docker push 10.0.0.30:5000/lnmp-php:base
# 报错处理:https://www.cnblogs.com/lkun/p/7990466.html
4.3.4 部署节点安装Docker与Docker- Compose及配置普通用户 sudo
注:保证所有节点都提前安装好Docker应用- 安装Docker
Install Reference:https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu
#!/bin/bash
#Description:全系列系统安装 docker harbor镜像仓库
HARBOR_VERSION=2.6.0
HARBOR_BASE=/apps
HARBOR_NAME=harbor.wang.org
DOCKER_VERSION="20.10.10"
#DOCKER_VERSION="19.03.14"
DOCKER_COMPOSE_VERSION=2.6.1
#DOCKER_COMPOSE_VERSION=1.29.2
DOCKER_COMPOSE_FILE=docker-compose-Linux-x86_64
#HARBOR_NAME=`hostname -I|awk '{print $1}'`
HARBOR_ADMIN_PASSWORD=123456
HARBOR_IP=`hostname -I|awk '{print $1}'`
COLOR_SUCCESS="echo -e \\033[1;32m"
COLOR_FAILURE="echo -e \\033[1;31m"
END="\033[m"
. /etc/os-release
UBUNTU_DOCKER_VERSION="5:${DOCKER_VERSION}~3-0~${ID}-${UBUNTU_CODENAME}"
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
install_docker(){
if [ $ID = "centos" -o $ID = "rocky" ];then
if [ $VERSION_ID = "7" ];then
cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/
EOF
else
cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name=docker
gpgcheck=0
#baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/8/x86_64/stable/
EOF
fi
yum clean all
${COLOR_FAILURE} "Docker有以下版本"${END}
yum list docker-ce --showduplicates
${COLOR_FAILURE}"5秒后即将安装: docker-"${DOCKER_VERSION}" 版本....."${END}
${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
sleep 5
yum -y install docker-ce-$DOCKER_VERSION docker-ce-cli-$DOCKER_VERSION \
|| { color "Base,Extras的yum源失败,请检查yum源配置" 1;exit; }
else
dpkg -s docker-ce &> /dev/null && $COLOR"Docker已安装,退出" 1 && exit
apt update || { color "更新包索引失败" 1 ; exit 1; }
apt -y install apt-transport-https ca-certificates curl software-properties-common || \
{ color "安装相关包失败" 1 ; exit 2; }
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt update
${COLOR_FAILURE} "Docker有以下版本"${END}
apt-cache madison docker-ce
${COLOR_FAILURE}"5秒后即将安装: docker-"${UBUNTU_DOCKER_VERSION}" 版本....."${END}
${COLOR_FAILURE}"如果想安装其它Docker版本,请按ctrl+c键退出,修改版本再执行"${END}
sleep 5
apt -y install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION}
fi
if [ $? -eq 0 ];then
color "安装软件包成功" 0
else
color "安装软件包失败,请检查网络配置" 1
exit
fi
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],
"insecure-registries": ["harbor.wang.org"]
}
EOF
systemctl daemon-reload
systemctl enable docker
systemctl restart docker
docker version && color "Docker 安装成功" 0 || color "Docker 安装失败" 1
echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrc
echo 'alias rmc="docker ps -qa|xargs docker rm -f"' >> ~/.bashrc
}
install_docker_compose(){
if [ $ID = "centos" -o $ID = "rocky" ];then
${COLOR_SUCCESS}"开始安装 Docker compose....."${END}
sleep 1
if [ ! -e ${DOCKER_COMPOSE_FILE} ];then
#curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/${DOCKER_COMPOSE_FILE} -o /usr/bin/docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-compose
else
mv ${DOCKER_COMPOSE_FILE} /usr/bin/docker-compose
fi
chmod +x /usr/bin/docker-compose
else
apt -y install docker-compose
fi
if docker-compose --version ;then
${COLOR_SUCCESS}"Docker Compose 安装完成"${END}
else
${COLOR_FAILURE}"Docker compose 安装失败"${END}
exit
fi
}
install_harbor(){
${COLOR_SUCCESS}"开始安装 Harbor....."${END}
sleep 1
if [ ! -e harbor-offline-installer-v${HARBOR_VERSION}.tgz ] ;then
wget https://github.com/goharbor/harbor/releases/download/v${HARBOR_VERSION}/harbor-offline-installer-v${HARBOR_VERSION}.tgz || ${COLOR_FAILURE} "下载失败!" ${END}
fi
[ -d ${HARBOR_BASE} ] || mkdir ${HARBOR_BASE}
tar xvf harbor-offline-installer-v${HARBOR_VERSION}.tgz -C ${HARBOR_BASE}
cd ${HARBOR_BASE}/harbor
cp harbor.yml.tmpl harbor.yml
sed -ri "/^hostname/s/reg.mydomain.com/${HARBOR_NAME}/" harbor.yml
sed -ri "/^https/s/(https:)/#\1/" harbor.yml
sed -ri "s/(port: 443)/#\1/" harbor.yml
sed -ri "/certificate:/s/(.*)/#\1/" harbor.yml
sed -ri "/private_key:/s/(.*)/#\1/" harbor.yml
sed -ri "s/Harbor12345/${HARBOR_ADMIN_PASSWORD}/" harbor.yml
sed -i 's#^data_volume: /data#data_volume: /data/harbor#' harbor.yml
#mkdir -p /data/harbor
${HARBOR_BASE}/harbor/install.sh && ${COLOR_SUCCESS}"Harbor 安装完成"${END} || ${COLOR_FAILURE}"Harbor 安装失败"${END}
cat > /lib/systemd/system/harbor.service <<EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor
[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f ${HARBOR_BASE}/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f ${HARBOR_BASE}/harbor/docker-compose.yml down
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable harbor &>/dev/null || ${COLOR}"Harbor已配置为开机自动启动"${END}
if [ $? -eq 0 ];then
echo
color "Harbor安装完成!" 0
echo "-------------------------------------------------------------------"
echo -e "请访问链接: \E[32;1mhttp://${HARBOR_IP}/\E[0m"
echo -e "用户和密码: \E[32;1madmin/${HARBOR_ADMIN_PASSWORD}\E[0m"
else
color "Harbor安装失败!" 1
exit
fi
echo "$HARBOR_IP $HARBOR_NAME" >> /etc/hosts
}
docker info &> /dev/null && ${COLOR_FAILURE}"Docker已安装"${END} || install_docker
docker-compose --version &> /dev/null && ${COLOR_FAILURE}"Docker Compose已安装"${END} || install_docker_compose
# install_harbor
- 安装Docker Compose
# curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
- 赋予用户sudo权限
$ vi /etc/sudoers
user ALL= (ALL) NOPASSWD:ALL
4.3.5 Jenkins安装
将二进制包上传到服务器并解压到工作目录,用于让Jenkins容器挂载使用。
# JDK Download:https://lupf.cn/articles/2022/02/19/1645283667689.html
# Maven Download:https://dlcdn.apache.org/maven/maven-3/3.5.4/binaries/
# wget https://dlcdn.apache.org/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz --no-check-certificate
tar -zxvf jdk-8u45-linux-x64.tar.gz
mv jdk1.8.0_45/ /usr/local/jdk
tar apache-maven-3.5.4-bin.tar.gz
mv apache-maven-3.5.4/ /usr/local/maven
修改Maven源:
# docker pull jenkins/jenkins:lts
docker pull jenkins/jenkins:2.375.1-lts
docker run -d --name jenkins -p 80:8080 -p 50000:50000 -u root \
-v /opt/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /usr/local/maven:/usr/local/maven \
-v /usr/local/jdk:/usr/local/jdk \
-v /etc/localtime:/etc/localtime \
--restart=always \
--name jenkins jenkins/jenkins:2.375.1-lts
# 查看Jenkins日志
$ docker logs -f jenkins
# 查看Jenkins的进程信息
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a70a5fa86cc jenkins/jenkins:2.375.1-lts "/usr/bin/tini -- /u…" 50 seconds ago Up 49 seconds 0.0.0.0:50000->50000/tcp, 0.0.0.0:80->8080/tcp jenkins
访问地址:http://IP
:::warning Jenkins 是类似于 Docker in Docker 的模式
:::
# 获取Jenkins的管理员密码
$ docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
e28b88f6c04b468aa8f08300a5d0cc86
Jenkins 使用安装推荐的插件
# 安装包下载:
http://mirrors.jenkins.io/war-stable/
http://maven.apache.org/download.cgi
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
# 配置JDK和Maven环境变量:
$ tar zxvf jdk-8u45-linux-x64.tar.gz
$ mv jdk1.8.0_45 /usr/locol/jdk1.8
$ tar apache-maven-3.5.0-bin.tar.gz
$ mv apache-maven-3.5.0 /usr/local/maven3.5
$ vi /etc/profile
JAVA_HOME=/usr/local/jdk1.8
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
MAVEN_HOME=/usr/local/maven3.5
PATH=$JAVA_HOME/bin:$MAVEN HOME/bin:$PATH
export JAVA_HOME CLASSPATH MAVEN HOME PATH
$ tar zxvf apache-tomcat-8.0.46.tar.gz
$ cd apache-tomcat-8.0.46/webapps
$ rm -rf./*
$ unzip /root/jenkins.war -d ROOT
# Jenkins 启动
$ .. /bin/startup.sh
4.3.6 Jenkins基本配置
:::color1 系统配置
:::
添加 SSH 远程主机的配置
Publish over SSH 配置( 生产环境的主机项目代码传到部署节点。(保存) )
测试连接( 需要在远程主机中创建相应工作目录 )
保存相应的配置即可!
:::color1 配置全局工具配置
:::
JDK 配置
Maven 配置
保存相应的配置即可!
:::color1 安装插件
:::
管理Jenkins→系统配置→管理插件→搜索git/pipeline/blue ocean
,选中点击安装。默认从国外网络下载插件,会比较慢,建议修改国内源:
$ docker exec -it jenkins /bin/bash
cd /var/jenkins_home/updates
# sed -i 's/https:\/\/updates.jenkins.io\/download/http:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' /var/lib/jenkins/updates/default.json
# sed -i 's/https:\/\/www.google.com/https:\/\/www.baidu.com/g' /var/lib/jenkins/updates/default.json
sed -i 's/https:\/\/updates.jenkins.io\/download/http:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' /var/jenkins_home/updates/default.json
sed -i 's/https:\/\/www.google.com/https:\/\/www.baidu.com/g' /var/jenkins_home/updates/default.json
$ docker restart jenkins
4.3.7 Jenkins 创建项目
系统管理 → 系统设置:主要配置workspace目录,全局环境变量,邮件通知,其他插件配置等。
系统管理 → Global Tool Confi guration:主要配置JDK、Maven等工具。
在系统设置里面先配置好SSH连接各个部署节点信息,在创建项目中使用。
4.3.7.1 测试节点:部署测试环境包( 测试节点 )
:::color1 下载测试部署压缩包
:::
- 下载地址:https://pan.baidu.com/s/1sKxJBDd1wkUhOTxhskP_Ug
- 密码:feb5
目录结构
├── config
# 生产环境配置文件
│ ├── prod.html
│ ├── prod.tar.gz
# 测试环境配置文件
│ ├── test.html
│ └── test.tar.gz
# 部署LNMP项目
├── deploy.sh
# 编排描述内容
├── docker-compose.yml
# 构建镜像
├── Dockerfile
│ ├── nginx
│ └── php
# 将容器目录数据库持久化到该目录下
├── mysql_data
# 推送镜像到线上使用
├── push_images.sh
# 记录部署时的代码版本号
├── revision.svn
# 存放项目目录
└── wwwroot
# 查看测试环境的页面
$ cat config/test.html
<h1>test</h1>
# 查看生产环境的页面
$ cat config/prod.html
<h1>prod</h1>
4.3.7.2 解压文件,脚本加入执行权限,并查看相关文件信息( 测试节点 )
# 上传test.zip脚本,解压缩
unzip lnmp.zip;cd lnmp
# 将脚本添加执行权限
chmod +x push_images.sh
脚本 deploy.sh
#!/bin/bash
# 修订版本号
REVISION=$1
# 工作环境变量环境,test传入构建dockerfile内
WORK_ENV=test
# 将当前版本写入revison文件中
echo $REVISION >./revision.svn
# 进入Dockerfile
cd Dockerfile
# 构建镜像build传入test环境
sudo docker build --build-arg work_env=$WORK_ENV -t lnmp-nginx:latest -f nginx ../
sudo docker build --build-arg work_env=$WORK_ENV -t lnmp-php:latest -f php ../
# 删除当前容器所有内容
sudo docker-compose down
# 重启初始化容器
sudo docker-compose up -d
# 脚本deploy.sh
docker-compose 脚本
# 版本号
version: '3'
# 服务管理
services:
# nginx服务
nginx:
# 镜像使用仓库内镜像
image: lnmp-nginx:latest
# 暴露端口为80
ports:
- 80:80
# 映射服务别名
links:
- php:php-cgi
depends_on:
- php
- mysql
# php服务
php:
# 镜像使用仓库内镜像
image: lnmp-php:latest
# 映射服务别名
links:
- mysql:mysql-db
# mysql服务
mysql:
# 镜像版本
image: mysql:5.6
# 暴露端口
ports:
- 3306:3306
# 映射服务数据卷
volumes:
- ./mysql_data:/var/lib/mysql
command: --character-set-server=utf8
# 指定数据库变量
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
MYSQL_USER: user
MYSQL_PASSWORD: user123
# docker-compose脚本
Dockerfile 内的 Nginx 脚本
# 指定镜像
FROM 10.0.0.30:5000/lnmp-nginx:base
# 指定管理员
MAINTAINER xiangsikai
# 接收构建参数
ARG work_env
# 更新网站目录
ADD wwwroot /usr/local/nginx/html
# 解压 接收参数传入变量的压缩包
ADD config/${work_env}.tar.gz /usr/local/nginx/html
# 声明暴露端口
expose 80
# Dockerfile 内 Nginx脚本
Dockerfile 内的 PHP 脚本
# 指定镜像
FROM 10.0.0.30:5000/lnmp-php:base
# 指定管理员
MAINTAINER xiangsikai
# 接收构建参数
ARG work_env
# 更新网站目录
ADD wwwroot /usr/local/nginx/html
# 解压 接收参数传入变量的压缩包
ADD config/${work_env}.tar.gz /usr/local/nginx/html
# 声明暴露端口
expose 9000
# Dockerfile 内 PHP脚本
push_images.sh 脚本
#!/bin/bash
# 指定镜像仓库地址
IMAGE_REPOS=10.0.0.30:5000
# 记录部署时修订版本号
REVISION=$(cat revision.svn)
# 声明生产环境
WORK_ENV=prod
# 进入Dockerfile
cd Dockerfile
# 构建镜像build传入prod环境
sudo docker build --build-arg work_env=$WORK_ENV -t $IMAGE_REPOS/lnmp-nginx:$REVISION -f nginx ../
sudo docker build --build-arg work_env=$WORK_ENV -t $IMAGE_REPOS/lnmp-php:$REVISION -f php ../
# 将镜像上传到镜像仓库
sudo docker push $IMAGE_REPOS/lnmp-nginx:$REVISION
sudo docker push $IMAGE_REPOS/lnmp-php:$REVISION
# 注:通过jenkins在svn中自动拉取传入wwwroot目录下。
# push_images.sh脚本
4.3.7.3 生产节点:部署生产环境包( 生产节点 )
目录结构
├── deploy.sh
├── docker-compose.yml
├── revision.svn
└── roll-back.sh
- 下载地址:https://pan.baidu.com/s/1SaZUubsnKJHe19ALHUfd8w
- 密码:opml
4.3.7.4 解压文件,脚本加入执行权限,并查看相关文件信息( 生产节点 )
# 解压文件,进入路径下
unzip lnmp2.zip;cd lnmp
# 加入文件执行权限
chmod +x deploy.sh roll-back.sh
deploy.sh 脚本
#!/bin/bash
# 文件赋值变量
REVISION=revision.svn
# 镜像仓库位置
IMAGE_REPOS=http://10.0.0.30:5000/v2
# 获取最新镜像tag,取最大最新版本号
LATEST_REVISION=$(curl $IMAGE_REPOS/lnmp-nginx/tags/list |\
grep -Po '(?<=")\d+(?=")' |\
awk 'BEGIN{max=0}{for(i=1;i<=NF;i++)if($i>max)max=$i}END{print max}')
# 修改版本号到docker-compose内指定构建版本
sed -i -r '/:5000/s/[0-9]+$/'$LATEST_REVISION'/' docker-compose.yml
# 标记上一个版本和当前版本
if ! grep "^$LATEST_REVISION " $REVISION &>/dev/null; then
sed -i -r '$s/([0-9]+).*/\1 Previous/' $REVISION
echo "$LATEST_REVISION Current" >> $REVISION
fi
# 重新部署docker-compose文件
sudo docker-compose down
sudo docker-compose up -d
# deploy.sh脚本
docker-compose.yml 脚本
version: '3'
services:
nginx:
image: 10.0.0.30:5000/lnmp-nginx:12
ports:
- 80:80
links:
- php:php-cgi
depends_on:
- php
php:
image: 10.0.0.30:5000/lnmp-php:12
links:
- mysql:mysql-db
mysql:
image: mysql:5.6
ports:
- 3306:3306
volumes:
- ./mysql_data:/var/lib/mysql
command: --character-set-server=utf8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
MYSQL_USER: user
MYSQL_PASSWORD: user123
# docker-compose.yml脚本
roll-backup.sh 脚本
#!/bin/bash
# 修改为上一个镜像版本
PRE_REVISION=$(awk '/Previous/{revision=$1}END{print revision}' revision.svn)
sed -i -r '/:5000/s/[0-9]+$/'$PRE_REVISION'/' docker-compose.yml
# 当前有问题的版本记录
sed -i '$d' revision.svn
sudo docker-compose down
sudo docker-compose up -d
# roll-back.sh脚本
4.3.8 管理节点:Jenkins 安装
:::color1
注:Jenkins安装需要依赖JDK环境,为了也可以部署JAVA项目同样也安装了maven。 注:Jenkins同样也需要通过Tomcat来运行 通过平台化方式管理。:::
4.3.8.1 安装 JDK 和 Maven 并配置环境变量
- JDK下载地址:https://pan.baidu.com/s/1TzyUAo3MPU0l6cUpUnzJIg
- 密码:gyxr
- Maven下载地址:https://pan.baidu.com/s/1rM_NkeclLNeAY61hA0HRAw
- 密码:k3a3
# 解压jdk
tar zxvf jdk-8u181-linux-x64.tar.gz
# 移动jdk目录
mv jdk1.8.0_181 /usr/local/jdk1.8
# 解压maven
tar zxvf apache-maven-3.6.0-bin.tar.gz
# 移动jdk目录
mv apache-maven-3.6.0 /usr/local/maven3.6
4.3.8.2 配置JDK 和 Maven 环境变量,并设置立即生效
cat >> /etc/profile <<-'EOF'
# Jenkins ENV BEGIN
JAVA_HOME=/usr/local/jdk1.8
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
MAVEN_HOME=/usr/local/maven3.6
PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
export JAVA_HOME CLASSPATH MAVEN_HOME PATH
# Jenkins ENV END
EOF
# 立刻生效
source /etc/profile
4.3.8.3 部署 Tomcat
- tomcat下载地址:https://pan.baidu.com/s/1IjaKDtUX7e_zjW5kb64Akw
- 密码:m1cz
# 解压tomcat
tar zxvf apache-tomcat-8.0.53.tar.gz
# 运行tomcat
/root/apache-tomcat-8.0.53/bin/startup.sh
# 删除目录下默认网站数据
cd apache-tomcat-8.0.53/webapps;rm -rf ./*
4.3.8.4 添加 Jenkins 资源
- Jenkins下载地址:https://pan.baidu.com/s/1sxQ8DnYl4ZS7JG0BgVWIWw
- 密码:8o8p
# 进入网站目录
cd /root/apache-tomcat-8.0.53/webapps
# 解压jenkins到指定ROOT目录
unzip /root/jenkins.zip -d ROOT
# 查看生成随机秘钥文件路径
/root/.jenkins/secrets/initialAdminPassword
4.3.8.5 Jenkins 安装
浏览器访问:http://10.0.0.30:8080
选择相关软件确认后install
- 安装ssh插件
- 安装Git插件
- 安装svn插件
初始化install 安装
根据 Jenkins 引导过程进行安装( 添加用户,确认执行Jenkins )
:::color1 若出现 Jenkins 版本过低,导致插件安装不上,需要管理员将Jenkins的版本提高。( 使用Docker部署 )
:::
# docker pull jenkins/jenkins:lts
docker pull jenkins/jenkins:2.375.1-lts
docker run -d --name jenkins -p 80:8080 -p 50000:50000 -u root \
-v /opt/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /usr/local/maven:/usr/local/maven \
-v /usr/local/jdk:/usr/local/jdk \
-v /etc/localtime:/etc/localtime \
--restart=always \
--name jenkins jenkins/jenkins:2.375.1-lts
# 查看Jenkins日志
$ docker logs -f jenkins
# 查看Jenkins的进程信息
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a70a5fa86cc jenkins/jenkins:2.375.1-lts "/usr/bin/tini -- /u…" 50 seconds ago Up 49 seconds 0.0.0.0:50000->50000/tcp, 0.0.0.0:80->8080/tcp jenkins
4.3.8 Jenkins 自动发布
4.3.8.1 WordPress 自动发布到测试环境
- 设置构建最大的保留数
- SVN 的添加( 配置SVN的凭证 )
- 在构建时进行配置( 需要配置该Server的凭证 )[ 传输 ]
- 保存后,进行 Jenkins 的构建
4.3.8.2 提交测试镜像到镜像仓库
4.3.8.3 自动发布到生产环境
5 Docker 结合 Consul 实现服务发现
5.1 Consul 是什么
Consul是:一个分布式、高可用性,在基础设施中发现和配置服务的工具。Consul 简化了分布式环境中的服务的注册和发现流程,通过 HTTP 或者 DNS 接口发现。支持外部 SaaS 提供者等。
在线演示:http://demo.consul.io/ui/ :::color1 Consul是HashiCorp公司推出的开源软件,基于 GO 语言编写,提供服务注册和发现、配置、多数据中心的高可用方案等能力,分布式一致方面采用 raft 算法实现,并且很容易和 Spring Cloud 等微服务框架集成,使用起来非常简单,具有简单、易用、可插排等特点。 简而言之,Consul 是服务网格的控制平面,Consul 提供了一种完整的服务网格解决方案。 ::: 主要功能: + 服务发现 通过DNS或HTTP接口使得消费者发现服务,应用程序可以轻松找到所依赖的服务。 + 健康检查 防止将请求转发不健康的主机。 + 键值存储 可以使用分层键/值存储,比如功能标记、动态配置等。 + 多数据中心 开箱即用,不需要复杂的配置。这就以为这不用建立抽象的逻辑来扩展多个地区。 + Web UI Consul为其用户提供了一个漂亮的Web界面,使用它可以很容易地使用和管理领事中的所有功能。:::color1
与Etcd和Zookeeper的比较:::
当我们查看此域中的其他服务发现工具时,我们有两个流行的选项。软件行业的一些主要参与者过去一直在使用它.这些工具是 Etcd 和 Zookeeper。 让我们考虑下表来比较每个工具的不同方面,我们还将了解每个内部使用的内容。属性 | Consul | Etcd | Zoo Keeper |
---|---|---|---|
用户界面 | 可用 | ![]() |
![]() |
RPC | 可用 | 可用 | ![]() |
运行状况检查 | HTTP API | HTTP API | TCP |
键值 | 3一致性模式 | 良好的一致性 | 强一致性 |
令牌系统 | 可用 | ![]() |
![]() |
语言 | Golang | Golang | Java |
5.2 Consul 集群介绍
:::color1
:::
1)Consul agent 是Consu1核心工作,分为client和server两种工作模式。默认以client模式运行,提供服务注册、健康检查、转发查询给server leader. server模式启动时使用-server选项指定,用于维护Consul集群状态 Raft协议进行选举。
2)agent必须在每个Consul节点运行,所有运行Consul agent 节点构成Consul集群。
3)官方建议Consul集群至少3或5个节点运行Consul agent server模式, client 节点不限。
4)通过join 或 rejoin 选项加入集群。一旦加入, 集群信息使用 gossip 算法同步到整个集群节点。
:::color1
Raft算法 Raft是用于管理复制日志的一致性算法.它依赖于 **CAP定理**的原理,该原理指出在存在网络分区时,必须在一致性和可用性之间进行选择.并非CAP定理的所有三个基本原理都可以在任何给定的时间点实现.必须在最好的情况下权衡其中任何两个. A Raft群集包含多个服务器,通常是奇数计数.例如,如果我们有五台服务器,它将允许系统容忍两个故障.在任何给定时间,每个服务器都处于以下三种状态之一:领导者,追随者或候选人.在正常操作中,只有一个领导者,所有其他服务器都是粉丝.这些粉丝处于被动状态,即他们自己不发出请求,只是回应领导者和候选人的请求. 下图描述了使用筏子的工作流模型算法工作 ::::
5.3 Consul 集群部署
官方文档:
下载二进制Consul包: https://www.consul.io/downloads.html
安装二进制包:
# wget https://releases.hashicorp.com/consul/1.14.2/consul_1.14.2_linux_amd64.zip
$ unzip consul_0.9.2_linux_amd64.zip
$ mv consul /usr/bin
# 官方部署文档
# Ubuntu
# wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
# echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
# sudo apt update && sudo apt install consul
# CentOS
# sudo yum install -y yum-utils
# sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
# sudo yum -y install consul
Consul Server 模式初始化集群:
# 以下命令执行为前台执行
$ consul agent \
-server \
-bootstrap \
-ui \
-data-dir=/var/lib/consul-data \
-bind=10.0.0.30 \
-client=0.0.0.0 \
-node=master
# -node 不指定则是默认主机名[ 必须是集群唯一的 ]
# 后台启动Consul
$ nohup consul agent \
-server \
-bootstrap \
-ui \
-data-dir=/var/lib/consul-data \
-bind=10.0.0.30 \
-client=0.0.0.0 \
-node=master &
# 查看Consul的成员
$ consul members
Node Address Status Type Build Protocol DC Partition Segment
master 10.0.0.30:8301 alive server 1.14.2 2 dc1 default <all>
:::color1 Consul 常用命令
:::
consul agent -dev #该命令启动只能允许本机访问
consul agent -dev -client 0.0.0.0 # 加上-client 0.0.0.0就可以其他机器进行访问了
# 进入consulserver容器
kubectl exec -it consul-server-0 -- /bin/sh
# 查看成员
consul members
# 查看版本号
consul version
# 列出所有服务
consul catalog services -http-addr=localhost:8500
# 列出consul的信息
consul info
Consul Client模式加入集群:
# Node01(10.0.0.31)节点执行
$ docker run -d \
--name=consul \
-p 8301:8301 \
-p 8301:8301/udp \
-p 8500:8500 \
-p 8600:8600 \
-p 8600:8600/udp \
--restart=always \
progrium/consul \
-join 10.0.0.30 -advertise 10.0.0.31 -client 0.0.0.0 -node=node01
# Node02(10.0.0.32)节点执行
$ docker run -d \
--name=consul \
-p 8301:8301 \
-p 8301:8301/udp \
-p 8500:8500 \
-p 8600:8600 \
-p 8600:8600/udp \
--restart=always \
progrium/consul \
-join 10.0.0.30 -advertise 10.0.0.32 -client 0.0.0.0 -node=node02
# 查看Consul的日志
$ docker logs consul
# Consul Cluster 查看端口
$ docker port consul
8301/tcp -> 0.0.0.0:8301
8600/udp -> 0.0.0.0:8600
8500/tcp -> 0.0.0.0:8500
8600/tcp -> 0.0.0.0:8600
8301/udp -> 0.0.0.0:8301
# Consul Master 节点查看成员
$ consul members
Node Address Status Type Build Protocol DC Partition Segment
master 10.0.0.30:8301 alive server 1.14.2 2 dc1 default <all>
node01 10.0.0.31:8301 alive client 0.5.2 2 dc1 default <default>
node02 10.0.0.32:8301 alive client 0.5.2 2 dc1 default <default>
# 集群就部署完毕
可以使用 Consul 的WebUI 查看 Consul 情况。默认WebUI端口为 8500
查看Consul 集群的节点的情况
范例:查看集群信息
$ consul members
Node Address Status Type Build Protocol DC Partition Segment
master 10.0.0.30:8301 alive server 1.14.2 2 dc1 default <all>
node01 10.0.0.31:8301 alive client 0.5.2 2 dc1 default <default>
node02 10.0.0.32:8301 alive client 0.5.2 2 dc1 default <default>
$ consul info | grep leader
leader = true
leader_addr = 10.0.0.30:8300
$ consul catalog services
consul
通过HTTP API 获取集群信息
curl 127.0.0.1:8500/v1/status/peers # 集群成员
curl 127.0.0.1:8500/v1/status/leader # 集群Raft leader
eurl 127.0.0.1:8500/v1/catalog/services #注册的所有服务
curl 127.0.0.1:8500/v1/catalog/services/nginx #服务信息
curl 127.0.0.1:8500/v1/catalog/nodes # 集群节点详细信息
服务注册
curl -x PUT -d \
'{"id": "jetty", "name": "service_name”, "address": "10.0.0.32”,"port”: 8080,”tags": ["test"], "checks":
[{"http": "http://10.0.0.32:8080/*, "interval": "5s"}]}' \
http://127.0.0.1:8500/v1/agent/service/register
类型 | 描述 |
---|---|
kv | 键值存储 |
agent | agent管理 |
catalog | nodes和services管理 |
health | 健康检查 |
session | session管理 |
acl | ACL管理 |
event | 用户事件 |
status | Consul系统状态 |
5.4 附录:consul 常用命令
之后每用到一个command或options,都会记录在这里。常用命令**command**:
- agent - 作用:运行一个consul agent
- join - 作用:将agent加入到consul cluster
- members - 作用:列出consul cluster集群中的members
常用选项**option**:
- -data-dir - 作用:指定agent储存状态的数据目录 - 这是所有agent都必须的 - 对于server尤其重要,因为他们必须持久化集群的状态
- -config-dir - 作用:指定service的配置文件和检查定义所在的位置 - 通常会指定为”某一个路径/consul.d”(通常情况下,.d表示一系列配置文件存放的目录)
- -config-file - 作用:指定一个要装载的配置文件 - 该选项可以配置多次,进而配置多个配置文件(后边的会合并前边的,相同的值覆盖)
- -dev - 作用:创建一个开发环境下的server节点 - 该参数配置下,不会有任何持久化操作,即不会有任何数据写入到磁盘 - 这种模式不能用于生产环境(因为第二条)
- -bootstrap-expect - 作用:该命令通知consul server我们现在准备加入的server节点个数,该参数是为了延迟日志复制的启动直到我们指定数量的server节点成功的加入后启动。
- -node - 作用:指定节点在集群中的名称 - 该名称在集群中必须是唯一的(默认采用机器的host) - 推荐:直接采用机器的IP
- -bind - 作用:指明节点的IP地址
- -server - 作用:指定节点为server - 每个数据中心(DC)的server数推荐为3或5(理想的是,最多不要超过5) - 所有的server都采用raft一致性算法来确保事务的一致性和线性化,事务修改了集群的状态,且集群的状态保存在每一台server上保证可用性 - server也是与其他DC交互的门面(gateway)
- -client - 作用:指定节点为client - 若不指定为-server,其实就是-client
- -join - 作用:将节点加入到集群
- -domain
- -dc - 作用:指定机器加入到哪一个dc中 - 例子:
选项 | 描述 |
---|---|
-advertise | 通告地址 |
-bind | 集群节点之间通信地址 |
-bootstrap | 设置服务器为bootstrap模式。在一个dc中只有一个server处于bootstrap模式。一般初始化第一台Consul时 指定,自选举为leader。 |
-bootstrap-expect | 在一个dc中期望提供server节点数目,consul会 一直等到指定的server数目才会引导整个集群,选举leader.不能与boostrap同时用。 |
-client | 设置客户端访问地址,包括RPC、DNS。默认127.0.0.1 |
-config-file | 从JSON配置文件中读取 |
-data-dir | 指定存放agent server集群状态目录,以免系统重启丢失 |
-dc | 数据中心名称,默认dc1 |
-http-port | HTTP API监听端口 |
-join | 加入一个已经启动的agent,可以指定多个agent地址 |
-node | 节点名称,必须在集群中唯一的。默认是主机名 |
-rejoin | 忽略先前的离开,再次启动后尝试加入集群 |
-server | 切换agent模式到server模式。每个集群至少有个server |
-ui | 启用内置的Web UI |
-ui-dir | Web UI的资源目录 |
5.5 Docker + Registrator + Consul 实现 Nginx 集群节点自动加入
Reference:
https://github.com/hashicorp/consul-template
https://releses.hashicorp.com/consul-template/0.19.3/consul-template_0.19.3_linux_amd64.zip
- consul-template:一个守护程序,用于实时查询consul集群数据,并更新文件系统上的任意数量的指定模板,生成配置文件,更新完成后可以选择运行任何命令。
:::color1
Consul-template 是一个守护进程,用于实时查询consul集群信息,并更新文件系统上任意数量的指定模板,生成配置文件。更新完成以后,可以选择运行shell命令执行更新操作,重新加载Nginx。Consul-Template可以查询Consul中的服务目录、Key、Key-values等。 这种强大的抽象功能和查询语言模板可以是Consul-Template 特别适合动态的创建配置文件。 例如:创建 Apache/Nginx Proxy Balancers、Haproxy Backends:::
- gliderlabs/registrator:检查容器运行状态自动注册到服务中心。
- registrator 支持服务注册有consul、etcd、SkyDNS2。
$ wget https://releases.hashicorp.com/consul-template/0.25.0/consul-template_0.25.0_linux_amd64.zip
$ unzip consul-template_0.25.0_linux_amd64.zip
$ mv consul-template /usr/bin/
$ consul-template -v
consul-template v0.25.0 (99efa642)
Node节点启动注册服务:
# 格式
$ docker run -d \
--name=registrator \
-v /var/run/docker.sock:/tmp/docker.sock \
--restart=always \
gliderlabs/registrator:latest \
consul://<Docker Host IP>:8500
# Node01(10.0.0.31) 和 Node02(10.0.0.32)执行
$ docker run -d \
--name=registrator \
-v /var/run/docker.sock:/tmp/docker.sock \
--restart=always \
gliderlabs/registrator:latest \
consul://10.0.0.31:8500
$ docker run -d \
--name=registrator \
-v /var/run/docker.sock:/tmp/docker.sock \
--restart=always \
gliderlabs/registrator:latest \
consul://10.0.0.32:8500
# 查看registrator的进程
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
788cc85312ac gliderlabs/registrator:latest "/bin/registrator co…" 19 seconds ago Up 18 seconds registrator
可以在Consul WebUI界面查看配置Service 服务状态
范例:在10.0.0.31-Node01 和 10.0.0.32-Node02启动Nginx容器测试
$ docker run -it -d -P --name nginx-node01 nginx:1.21.6-alpine
可以访问其注册的IP地址:Port端口
就可以访问其 Nginx 默认页面
# 在10.0.0.30部署Nginx
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum -y install nginx
systemctl enable --now nginx
# /etc/nginx/nginx.conf //yum方式安装后默认配置文件的路径
# /usr/share/nginx/html //nginx网站默认存放目录
# /usr/share/nginx/html/index.html //网站默认主页路径
tee > nginx.ctmpl <<EOF
upstream http_backend {
ip_hash;
# 镜像名字
{{range service "nginx"}}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
server {
listen 80;
# server_name www.nextdevops.cn;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
EOF
# 格式:
# consul-template \
# -consul-addr <Consul server>:8500 \
# -template "./nginx.ctmpl:/usr/local/nginx/conf/nginx.conf:/usr/local/nginx/sbin/nginx -s reload" \
# -log-level=info
$ consul-template \
-consul-addr 10.0.0.30:8500 \
-template "./nginx.ctmpl:/etc/nginx/conf.d/nginx.conf:/usr/sbin/nginx -s reload" \
-log-level=info
# 会追踪相应的日志(会显示服务发现的功能)
$ cat /etc/nginx/conf.d/nginx.conf
upstream http_backend {
ip_hash;
# 镜像名字
server 10.0.0.31:32770;
server 10.0.0.32:32769;
}
server {
listen 80;
# server_name www.nextdevops.cn;
server_name localhost;
location / {
proxy_pass http://http_backend;
}
}
6 Docker API
Old Docker Reference:
http://dockerone.com/article/109
http://dockerone.com/article/110
New Docker Reference:
6.1 Docker API 介绍
Docker提供了Docker Engine API与Docker daemon交互,Docker提供了Go和Python版本的SDK。本质上Docker Engine API是一个RESTful的接口,可以通过HTTP请求操作。
- Docker Registry API
- Docker Hub API
- Docker OAuth API (使用较少)
- Docker Remote API
:::color1 1. Docker Registry API
这个是docker镜像仓库的api,通过操作这套API,你可以自由的自动化、程序化的管理你的镜像仓库。2. Docker Hub API
Docker Hub API是用户管理操作的API,docker hub是使用校验和公共 namespaces 的方式来存储账户信息、认证账户、进行账户授权。API同时也允许操作相关的用户仓库和 library 仓库。3. Docker Remote API
这套API用于控制主机 Docker 服务端的 API,等价于 docker命令行客户端。 有了它,你能远程操作docker容器,更重要的是你可以通过程序自动化运维docker进程。:::
6.2 初始 Remote API
Remote API是由Docker守护进程提供的
:::color1 守护进程的默认套接字
:::
默认的情况下,Docker守护进程会绑定到一个所在宿主机的套接字,即unix:///var/run/docker.sock
:::color1 Docker守护进程的默认配置文件
:::
不同系统中,Docker守护进程的默认配置文件为:
Ubuntu、Debian系统:/etc/default/docker
Upstart系统:/etc/init/docker.conf
Red Hat、Redora系统:/etc/sysconfig/docker
对于那些使用了Systemd的发布版本:/usr/lib/systemd/docker.service
:::color1 演示机器是Ubuntu 20.04 系统版本,查看如下
:::
sudo cat /etc/default/docker
备注(重点):docker安装在桌面版ubuntu的时候,默认的配置文件/etc/default/docker里的配置是无效的(server版并无问题),导致之前的很多工作进展缓慢,这个问题在官方文档中有出现
:::color1 访问Docker API
:::
我们可以输入下面的命令来模仿一个客户端,来访问Docker守护进程
echo -e "GET /info HTTP/1.0\r\n" | sudo nc -U /var/run/docker.sock
:::color1 远程访问Remote API(改变守护进程监听地址)
:::
上面我们说了,守护进程默认绑定到unix:///var/run/docker.sock
域套接字上,那么我们只能在本地来访问这个守护进程
如果我们想要让远程来访问我们主机的Remote API,那么就需要将Docker守护进程绑定到一个网络接口上
修改方法:修改配置文件,见下面演示案例
:::color1 接口更改演示案例
:::
下面我们使用的是桌面版本的ubuntu系统,因此/etc/default/docker配置文件不生效(但是server版本不会出现这种情况)
在这种情况下我们需要修改/lib/systemd/system/docker.service文件中的ExecStart选项,默认的情况如下
sudo vim /lib/systemd/system/docker.service
下面我们修改ExecStart选项,在尾部添加如下的内容,让其监听在0.0.0.0:2375地址上
:::color1 备注:
前面还有一个-H选项,这个选项是让守护进程监听在默认的域套接字上
Docker允许守护进程监听在多个端口上,因此我们在后面又添加了一个-H,让其监听在tcp端口上
:::
首先重启Docker服务,然后再重启Docker守护进程
sudo systemctl daemon-reload
sudo service docker restart
查看一下守护进程的状态,可以看到守护进程监听在两个端口上
现在我们既可以使用当初的域套接字来访问Docker(本地访问)
sudo docker -H unix:///var/run/docker.sock info
也可以使用公开的tcp服务来访问Docker(用于外网访问)
sudo docker -H 10.0.0.100:2375 info
客户端使用的DOCKER_HOST环境变量
上面我们看到了,客户端访问Docker时都需要使用-H来指定Docker的地址,比较麻烦
Docker提供了DOCKER_HOST环境变量,设置之后客户端就会去访问DCOERK_HOST环境变量所设置的Docker,不需要每次执行命令时都要-H选项了
例如,下面将DOCKER_HOST设置为我们上面指定的Docker服务地址
sudo docker info
备注:与Docker守护进程之间的网络连接是没有经过认证的,是对外开放的。本文后面会介绍如何为网络连接加入认证功能
6.3 测试 Docker Remote API
下面我们开始使用Docker的一些API来对Docker进行测试操作;都以curl命令来连接到Docker守护进程获取信息
例如,还是获取Docker的信息,命令如下:
Docker给我返回了Docker的信息,这些信息都是以JSON格式返回的
另外,由于默认的情况下,Docker返回的JSON数据都是非常乱的,因此我们在最后使用了Python的格式化工具对结果进行了格式化处理,看起来比较整洁(文本下面都会使用这个工具命令)
curl http://10.0.0.100:2375/info | python -mjson.tool
6.4 通过 API 管理Docker 镜像
6.4.1 获取镜像列表(/images/json)
想要获取Docker的镜像列表,可以输入下面的命令,结果如下所示:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 11 months ago 141MB
redis latest 7614ae9453d1 11 months ago 113MB
结果返回了当前Docker的所有镜像,并且信息都比较详细
它们返回的结果与docker images命令非常类似
curl http://10.0.0.100:2375/images/json | python -mjson.tool
6.4.2 查看指定的镜像的信息(/images/ID/json)
我们也可以来查看指定的镜像的信息。例如:
$ docker inspect nginx
# 获取镜像的ID
$ docker inspect -f "{{.Id}}" nginx
sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85
# 将镜像运行成容器
$ docker run -it -d --name nginx-node nginx
b854eb7e61405abd265c9ab0b4508713f84340e520b258f4d9027ff3f0c5e4b7
我们有一个容器的ID为:sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85
下面我们来查看指定的镜像,就可以使用下面的命令
curl http://10.0.0.100:2375/images/sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85/json | \
python -mjson.tool
可以看到,这种做法与用”docker inspect”命令来查看某一镜像的信息是十分类似的
6.4.3 搜索镜像(/images/search?term=xxx)
还可以使用Docker API从Docker Hub上搜索指定的镜像
例如,下面从Docker Hub上搜索镜像名字中带”jamtur01”的所有镜像
curl "http://10.0.0.100:2375/images/search?term=jamtur01" | python -mjson.tool
6.5 通过API管理Docker容器
6.5.1 查看所有的容器(/containers/json?all=1)
例如当前我们的系统中有这些容器
sudo docker ps -a
可以输入下面的命令来查看所有的容器(不论是否在运行)
curl http://10.0.0.100:2375/containers/json?all=1 | \
python -mjson.tool
6.5.2 列出正在运行的容器(/containers/json)
例如当前系统中运行着一个Docker容器
sudo docker ps
可以输入下面的命令来查看当前系统中运行的容器,可以看到只有一个
curl http://10.0.0.100:2375/containers/json | \
python -mjson.tool
6.5.3 创建容器(/containers/create)
可以输入下面的命来创建一个容器。命令如下:
使用了POST请求调用了/containers/create接入点来创建容器
POST了一个JSON散列数据,其中Images指定了要创建的容器的名称
创建完成之后命令会返回创建的容器的ID(9f450c13d90034a01fe81dba5a6c75ca5686476bea231118f43f5c203775b7e2)以及可能的警告信息
curl -X POST -H "Content-Type:application/json" http://10.0.0.100:2375/containers/create -d '{ "Image":"redis:latest"}'
来查看我们新创建的容器,可以看到ID与上面.的一致
curl http://10.0.0.100:2375/containers/json?all=1 | python -mjson.tool
通过下面的命令也可以看到新创建的容器
sudo docker ps -a
备注:当然,我们可以在创建容器时指定更多的信息,例如下面添加了一个容器的主机名
curl -X POST -H "Content-Type:application/json" http://10.0.0.100:2375/containers/create -d '{ "Image":"redis:latest","Hostname":"dongshao"}'
6.5.4 启动容器
例如,我们可以输入下面的命令来启动上面我们创建的容器
curl -X POST -H "Content-Type:application/json" http://10.0.0.100:2375/containers/9f450c13d90034a01fe81dba5a6c75ca5686476bea231118f43f5c203775b7e2/start -d '{ "PublishAllPorts":true}'
7 Docker 日志管理
Docker容器日志分为两类:- Docker引擎日志(Docker本身运行的日志)
- 容器日志(各个容器内产生的日志)
7.1 Docker引擎日志
Centos系统下的docker引擎日志一般给systemd管理,可通过<font style="color:#E8323C;">journalctl -u docker.service</font>
命令查看
7.2 容器日志
1、可通过<font style="color:rgb(0, 0, 0);">docker logs [容器ID]</font>
命令显示当前运行的容器log,输出Linux下的STDOU、STDERR,生产环境中,如果应用输出到我们自己的日志文件里,使用<font style="color:rgb(0, 0, 0);">docker logs</font>
一般收集步到太多重要信息。
2、docker日志驱动
Docker ce版本,Docker logs命令仅适用于如下驱动程序:
docker inspect -f "{{ .HostConfig.LogConfig.Type }}" [Container_ID]
<font style="color:rgb(0, 0, 0);">/etc/docker/daemon.json</font>
4)日志驱动:local
local日志驱动记录从容器的STDOUT/STDERR输出,并写到主机磁盘上。默认情况下,local日志驱动为每个容器保留100M的日志信息,并启用压缩来保存
local日志驱动存储于/var/lib/docker/containers/容器id/local-logs目录下,以container.log命名,local驱动支持的选项有:
- max-size:切割之前日志的最大容量,可取值为k/m/g,默认20m
- max-file:可以存在的最大日志文件个数,如果超过最大值,则会删除旧文件,仅在max-size选项设置时有效。默认为5
- compress:对应切割日志文件是否启用压缩,默认启用
然后重启docker服务即可生效 对于指定容器设置为local驱动时,需在docker run中加—log-driver local选项即可 5)日志驱动json-file: json-file日志路径:
{
"log-driver": "local",
"log-opts": {
"max-size": "10m"
}
}
<font style="color:rgb(0, 0, 0);">/var/lib/docker/containers/容器id/容器id-json.log</font>
json-file日志驱动支持的驱动选项:
- max-size:切割之前日志的最大大小。取值单位k/m/g,默认为-1(表示无限制)
- max-file:存在的最大日志文件数,仅在max-size设置时有效,默认为1
- labels:适用于启动docker守护进程时,此守护进程接受的以逗号分隔的与日志记录相关的标签列表
- env:适用于启动docker守护进程时,此守护进程接手的以逗号分隔的与日志记录相关的环境变量列表
- env-regex:类似并兼容env。用于匹配与日志记录相关的环境变量的正则表达式。
- compress:切割的日志是否进行压缩。默认是disabled
<font style="color:rgb(0, 0, 0);">/etc/docker/daemon.json</font>
文件配置全局日志驱动为syslog:
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "udp://1.2.3.4:1111"
}
}