- 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 = noneauth-access = writepassword-db = passwdauthz-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 svnroot 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 -lCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESe84dff8aa72b 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-composechmod +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:basedocker 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.0HARBOR_BASE=/appsHARBOR_NAME=harbor.wang.orgDOCKER_VERSION="20.10.10"#DOCKER_VERSION="19.03.14"DOCKER_COMPOSE_VERSION=2.6.1#DOCKER_COMPOSE_VERSION=1.29.2DOCKER_COMPOSE_FILE=docker-compose-Linux-x86_64#HARBOR_NAME=`hostname -I|awk '{print $1}'`HARBOR_ADMIN_PASSWORD=123456HARBOR_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-releaseUBUNTU_DOCKER_VERSION="5:${DOCKER_VERSION}~3-0~${ID}-${UBUNTU_CODENAME}"color () {RES_COL=60MOVE_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_COLecho -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" ];thenif [ $VERSION_ID = "7" ];thencat > /etc/yum.repos.d/docker.repo <<EOF[docker]name=dockergpgcheck=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/EOFelsecat > /etc/yum.repos.d/docker.repo <<EOF[docker]name=dockergpgcheck=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/EOFfiyum 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 5yum -y install docker-ce-$DOCKER_VERSION docker-ce-cli-$DOCKER_VERSION \|| { color "Base,Extras的yum源失败,请检查yum源配置" 1;exit; }elsedpkg -s docker-ce &> /dev/null && $COLOR"Docker已安装,退出" 1 && exitapt 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 5apt -y install docker-ce=${UBUNTU_DOCKER_VERSION} docker-ce-cli=${UBUNTU_DOCKER_VERSION}fiif [ $? -eq 0 ];thencolor "安装软件包成功" 0elsecolor "安装软件包失败,请检查网络配置" 1exitfimkdir -p /etc/dockertee /etc/docker/daemon.json <<-'EOF'{"registry-mirrors": ["https://si7y70hh.mirror.aliyuncs.com"],"insecure-registries": ["harbor.wang.org"]}EOFsystemctl daemon-reloadsystemctl enable dockersystemctl restart dockerdocker version && color "Docker 安装成功" 0 || color "Docker 安装失败" 1echo 'alias rmi="docker images -qa|xargs docker rmi -f"' >> ~/.bashrcecho '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 1if [ ! -e ${DOCKER_COMPOSE_FILE} ];then#curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/${DOCKER_COMPOSE_FILE} -o /usr/bin/docker-composecurl -L https://get.daocloud.io/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) -o /usr/bin/docker-composeelsemv ${DOCKER_COMPOSE_FILE} /usr/bin/docker-composefichmod +x /usr/bin/docker-composeelseapt -y install docker-composefiif docker-compose --version ;then${COLOR_SUCCESS}"Docker Compose 安装完成"${END}else${COLOR_FAILURE}"Docker compose 安装失败"${END}exitfi}install_harbor(){${COLOR_SUCCESS}"开始安装 Harbor....."${END}sleep 1if [ ! -e harbor-offline-installer-v${HARBOR_VERSION}.tgz ] ;thenwget 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}/harborcp harbor.yml.tmpl harbor.ymlsed -ri "/^hostname/s/reg.mydomain.com/${HARBOR_NAME}/" harbor.ymlsed -ri "/^https/s/(https:)/#\1/" harbor.ymlsed -ri "s/(port: 443)/#\1/" harbor.ymlsed -ri "/certificate:/s/(.*)/#\1/" harbor.ymlsed -ri "/private_key:/s/(.*)/#\1/" harbor.ymlsed -ri "s/Harbor12345/${HARBOR_ADMIN_PASSWORD}/" harbor.ymlsed -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=HarborAfter=docker.service systemd-networkd.service systemd-resolved.serviceRequires=docker.serviceDocumentation=http://github.com/vmware/harbor[Service]Type=simpleRestart=on-failureRestartSec=5ExecStart=/usr/bin/docker-compose -f ${HARBOR_BASE}/harbor/docker-compose.yml upExecStop=/usr/bin/docker-compose -f ${HARBOR_BASE}/harbor/docker-compose.yml down[Install]WantedBy=multi-user.targetEOFsystemctl daemon-reloadsystemctl enable harbor &>/dev/null || ${COLOR}"Harbor已配置为开机自动启动"${END}if [ $? -eq 0 ];thenechocolor "Harbor安装完成!" 0echo "-------------------------------------------------------------------"echo -e "请访问链接: \E[32;1mhttp://${HARBOR_IP}/\E[0m"echo -e "用户和密码: \E[32;1madmin/${HARBOR_ADMIN_PASSWORD}\E[0m"elsecolor "Harbor安装失败!" 1exitfiecho "$HARBOR_IP $HARBOR_NAME" >> /etc/hosts}docker info &> /dev/null && ${COLOR_FAILURE}"Docker已安装"${END} || install_dockerdocker-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-composecurl -L https://get.daocloud.io/docker/compose/releases/download/v2.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-compose
- 赋予用户sudo权限
$ vi /etc/sudoersuser 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-certificatetar -zxvf jdk-8u45-linux-x64.tar.gzmv jdk1.8.0_45/ /usr/local/jdktar apache-maven-3.5.4-bin.tar.gzmv apache-maven-3.5.4/ /usr/local/maven
修改Maven源:
# docker pull jenkins/jenkins:ltsdocker pull jenkins/jenkins:2.375.1-ltsdocker 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 -lCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3a70a5fa86cc 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/initialAdminPassworde28b88f6c04b468aa8f08300a5d0cc86
Jenkins 使用安装推荐的插件

# 安装包下载:http://mirrors.jenkins.io/war-stable/http://maven.apache.org/download.cgihttp://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/profileJAVA_HOME=/usr/local/jdk1.8CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarMAVEN_HOME=/usr/local/maven3.5PATH=$JAVA_HOME/bin:$MAVEN HOME/bin:$PATHexport 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/bashcd /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.jsonsed -i 's/https:\/\/updates.jenkins.io\/download/http:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' /var/jenkins_home/updates/default.jsonsed -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# 进入Dockerfilecd 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# 暴露端口为80ports:- 80:80# 映射服务别名links:- php:php-cgidepends_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/mysqlcommand: --character-set-server=utf8# 指定数据库变量environment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: wordpressMYSQL_USER: userMYSQL_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# 进入Dockerfilecd 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:$REVISIONsudo 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; thensed -i -r '$s/([0-9]+).*/\1 Previous/' $REVISIONecho "$LATEST_REVISION Current" >> $REVISIONfi# 重新部署docker-compose文件sudo docker-compose downsudo docker-compose up -d# deploy.sh脚本
docker-compose.yml 脚本
version: '3'services:nginx:image: 10.0.0.30:5000/lnmp-nginx:12ports:- 80:80links:- php:php-cgidepends_on:- phpphp:image: 10.0.0.30:5000/lnmp-php:12links:- mysql:mysql-dbmysql:image: mysql:5.6ports:- 3306:3306volumes:- ./mysql_data:/var/lib/mysqlcommand: --character-set-server=utf8environment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: wordpressMYSQL_USER: userMYSQL_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.svnsudo docker-compose downsudo 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
# 解压jdktar zxvf jdk-8u181-linux-x64.tar.gz# 移动jdk目录mv jdk1.8.0_181 /usr/local/jdk1.8# 解压maventar 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 BEGINJAVA_HOME=/usr/local/jdk1.8CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarMAVEN_HOME=/usr/local/maven3.6PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATHexport JAVA_HOME CLASSPATH MAVEN_HOME PATH# Jenkins ENV ENDEOF
# 立刻生效source /etc/profile
4.3.8.3 部署 Tomcat
- tomcat下载地址:https://pan.baidu.com/s/1IjaKDtUX7e_zjW5kb64Akw
- 密码:m1cz
# 解压tomcattar 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:ltsdocker pull jenkins/jenkins:2.375.1-ltsdocker 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 -lCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3a70a5fa86cc 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 membersNode Address Status Type Build Protocol DC Partition Segmentmaster 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 consul8301/tcp -> 0.0.0.0:83018600/udp -> 0.0.0.0:86008500/tcp -> 0.0.0.0:85008600/tcp -> 0.0.0.0:86008301/udp -> 0.0.0.0:8301# Consul Master 节点查看成员$ consul membersNode Address Status Type Build Protocol DC Partition Segmentmaster 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 membersNode Address Status Type Build Protocol DC Partition Segmentmaster 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 leaderleader = trueleader_addr = 10.0.0.30:8300$ consul catalog servicesconsul
通过HTTP API 获取集群信息
curl 127.0.0.1:8500/v1/status/peers # 集群成员curl 127.0.0.1:8500/v1/status/leader # 集群Raft leadereurl 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 -vconsul-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 -lCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES788cc85312ac 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部署Nginxrpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpmyum -y install nginxsystemctl enable --now nginx# /etc/nginx/nginx.conf //yum方式安装后默认配置文件的路径# /usr/share/nginx/html //nginx网站默认存放目录# /usr/share/nginx/html/index.html //网站默认主页路径
tee > nginx.ctmpl <<EOFupstream 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.confupstream 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-reloadsudo 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 imagesREPOSITORY TAG IMAGE ID CREATED SIZEnginx latest 605c77e624dd 11 months ago 141MBredis 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}}" nginxsha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85# 将镜像运行成容器$ docker run -it -d --name nginx-node nginxb854eb7e61405abd265c9ab0b4508713f84340e520b258f4d9027ff3f0c5e4b7
我们有一个容器的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"}}





