yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine
(2)安装docker的依赖
yum install -y yum-utils
device-mapper-persistent-data
lvm2
(3)设置docker仓库
yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo
(4)安装docker
yum install -y docker-ce docker-ce-cli containerd.io(5)启动docker
systemctl start docker(6)设置开机启动
systemctl enable docker(7)测试是否安装成功,拉取一个hello-world镜像
docker pull hello-world docker run hello-world # 可以看到有以下输出 Hello from Docker!2.配置加速器 (1)配置阿里云镜像加速器
阿里云控制台搜索 容器镜像服务
找到 镜像加速器,根据右边的命令进行操作
在centos操作以下命令
# 1.创建文件夹
mkdir -p /etc/docker
# 2.写daemon.json文件
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://dokomztn.mirror.aliyuncs.com"]
}
EOF
# 3.重新加载上面的配置文件
systemctl daemon-reload
# 4.重启docker
systemctl restart docker
二、Docker基本操作
1.镜像操作
(1)拉取镜像
# 默认拉取dockerhub上面的最新版本 docker pull tomcat # 拉取指定版本的镜像 docker pull tomcat:8(2)查看所有镜像
docker images(3)删除某一个镜像
# 根据镜像id删除,二选一即可 docker image rm imageid docker rmi -f imageid # 根据镜像名称删除,二选一即可 docker image rm 镜像名称 docker rmi -f 镜像名称 # 镜像后面可以通过 `:版本`,删除指定版本的,例如: docker rmi -f hello-world:latest(4)删除所有镜像
# 如果该镜像有运行中的容器,需要先停止基于该镜像创建的容器,否则删除会有问题 docker rmi -f $(docker image ls)2.容器操作 (1)查看所有运行中的容器
docker ps(2)查看所有的容器,包含非运行的
docker ps -a(3)根据镜像创建容器
# 以tomcat为例,-d表示后台运行,--name为容器指定名称,-p表示将容器的端口映射到宿主主机的端口 docker run -d --name my-tomcat01 -p 9090:8080 tomcat(4)进入到某一个容器
# my-tomcat01为容器名称,也可以是容器的id docker exec -it my-tomcat01 /bin/bash(5)查看容器使用情况
docker stats(6)查看容器日志
docker logs 容器名称/容器id(7)查看容器使用情况
docker inspect 容器名称/id(8)停止/启动容器
docker start 容器名称/容器id docker stop 容器名称/容器id(9)删除某一个容器
# 删除之前需要先停止该容器 docker rm 容器名称/容器id(10)删除所有容器
# 不需要停止即可删除 docker rm -f $(docker ps -aq)3.安装tomcat (1)指定拉取版本8的tomcat
docker pull tomcat:8(2)启动tomcat容器
# 创建成功之后浏览器访问宿主主机ip加端口号9090即可 docker run -d --name my-tomcat-01 -p 9090:8080 tomcat(3)tomcat启动完成之后访问404的问题
# 1.进入到tomcat的容器中 docker exec -it xxx /bin/bash # 进入到webapps,查看是否有文件 cd webapps # 如果没有的话就会出现404的问题,此时删除webapps文件夹,复制webapps.dist到webapps rm -rf webapps cp -r webapps.dist/. webapps # 重新访问即可
docker network ls 查看网路类型,有bridge、host、none三种类型
docker inspect bridge查看网卡
找到tomcat容器所对应的ip地址,一般都是以172.17.0.x的,比如是172.17.0.3
在centos里面通过 curl http://172.17.0.3:9090 也可以访问到tomcat
4.安装mysql (1)拉取mysql镜像docker pull mysql(2)创建mysql容器
# -e指定参数,docker中为mysql指定密码的参数为 `MYSQL_ROOT_PASSWORD`, # --privileged使容器内的root用户拥有真正的root权限 docker run -d --name mysql01 -p 3301:3306 -e MYSQL_ROOT_PASSWORD=123456 --privileged mysql(3)连接不上报 client does not support support authentication protocol requested by server…
# 重新修改root的密码和连接地址 alter user 'root'@'%' identified with mysql_native_password by '123456'; # 刷新 flush privileges;三、Dockerfile
docker镜像库的github地址:https://github.com/docker-library
1.根据 Dockerfile生成image镜像 (1)这里以mysql为例,从docker-library找到mysql的Dockerfile文件,直接复制一份 (2)然后 linux创建一个文件夹 mysql-imagemkdir mysql-image(3)进入到该文件夹里面,创建 Dockerfile 文件,
vi Dockerfile(4)把上面的从docker-library复制的文件粘贴到这里的Dockerfile里面,然后保存退出
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:buster-slim
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
# add gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
ENV GOSU_VERSION 1.14
RUN set -eux;
savedAptMark="$(apt-mark showmanual)";
apt-get update;
apt-get install -y --no-install-recommends ca-certificates wget;
rm -rf /var/lib/apt/lists/*;
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')";
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch";
wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc";
export GNUPGHOME="$(mktemp -d)";
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4;
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu;
gpgconf --kill all;
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc;
apt-mark auto '.*' > /dev/null;
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null;
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false;
chmod +x /usr/local/bin/gosu;
gosu --version;
gosu nobody true
RUN mkdir /docker-entrypoint-initdb.d
RUN set -eux;
apt-get update;
apt-get install -y --no-install-recommends
openssl
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
perl
xz-utils
zstd
;
rm -rf /var/lib/apt/lists/*
RUN set -eux;
# gpg: key 3A79BD29: public key "MySQL Release Engineering " imported
key='859BE8D7C586F538430B19C2467B942D3A79BD29';
export GNUPGHOME="$(mktemp -d)";
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key";
mkdir -p /etc/apt/keyrings;
gpg --batch --export "$key" > /etc/apt/keyrings/mysql.gpg;
gpgconf --kill all;
rm -rf "$GNUPGHOME"
ENV MYSQL_MAJOR 5.7
ENV MYSQL_VERSION 5.7.38-1debian10
RUN echo 'deb [ signed-by=/etc/apt/keyrings/mysql.gpg ] http://repo.mysql.com/apt/debian/ buster mysql-5.7' > /etc/apt/sources.list.d/mysql.list
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
# also, we set debconf keys to make APT a little quieter
RUN {
echo mysql-community-server mysql-community-server/data-dir select '';
echo mysql-community-server mysql-community-server/root-pass password '';
echo mysql-community-server mysql-community-server/re-root-pass password '';
echo mysql-community-server mysql-community-server/remove-test-db select false;
} | debconf-set-selections
&& apt-get update
&& apt-get install -y
mysql-server="${MYSQL_VERSION}"
# comment out a few problematic configuration values
&& find /etc/mysql/ -name '*.cnf' -print0
| xargs -0 grep -lZE '^(bind-address|log)'
| xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/'
# don't reverse lookup hostnames, they are usually another container
&& echo '[mysqld]nskip-host-cachenskip-name-resolve' > /etc/mysql/conf.d/docker.cnf
&& rm -rf /var/lib/apt/lists/*
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
&& chmod 1777 /var/run/mysqld /var/lib/mysql
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306 33060
CMD ["mysqld"]
(5)保存退出
:wq(6)根据Dockerfile文件生成一个镜像
docker build -t mysql-image .2.Dockerfile语法
# 指定基础镜像
FROM debian:buster-slim
# 运行
RUN groupadd -r mysql && useradd -r -g mysql mysql
# 设置变量的值,ENV MYSQL_MAJOR 5.7,可以通过docker run --e key=value修改,后面可以直接使用${MYSQL_MAJOR}
ENV MYSQL_MAJOR 5.7
# 设置镜像标签
LABEL
# 镜像的作者信息,即也就是Author
MAINTAINER tianqingzhao
# 数据存储在哪一个目录
VOLUME /var/lib/mysql
#将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和解压
COPY docker-entrypoint.sh /usr/local/bin/
# 将主机的文件复制到镜像内,和COPY类似,只是ADD会对压缩文件提取和解压
ADD application.yml /etc/itcrazy2016/
# 指定镜像要暴露的端口,启动镜像时,可以使用-p将该端口映射给宿主机
EXPOSE 3306 33060
# 和CMD的使用类似
ENTRYPOINT ["docker-entrypoint.sh"]
3.Dockerfile入门
(1)编写springboot工程,添加maven依赖
(2)提供一个接口org.springframework.boot spring-boot-starter-parent 2.2.0.RELEASE com.gupao dockerfile-demo 0.0.1-SNAPSHOT dockerfile-demo Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-maven-plugin
@SpringBootApplication
public class DockerfileDemoApplication {
public static void main(String[] args) {
SpringApplication.run(DockerfileDemoApplication.class, args);
}
@RestController
public class DockerController {
@GetMapping("/dockerfile")
@ResponseBody
String dockerfile(@RequestParam(defaultValue = "hello docker") String str) {
return str;
}
}
}
(3)自己编写一个Dockerfile文件
FROM openjdk:8 # 指定维护人 MAINTAINER tianqingzhao # 指定镜像名称、版本、作者 LABEL name=“dockerfile-demo” version="1.0" author="tianqingzhao" # 把centos的jar包拷贝到镜像里面 COPY dockerfile-demo-0.0.1-SNAPSHOT.jar springboot-dockerfile-demo.jar # 执行该命令启动 CMD ["java", "-jar", "springboot-dockerfile-demo.jar"](4)构建镜像
docker build -t springboot-dockerfile-demo .(5)创建容器
docker run -d --name springboot-dockerfile-demo springboot-dockerfile-demo(6)查看日志
docker logs springboot-dockerfile-demo(7)进入容器内访问
docker exec -it springboot-dockerfile-demo /bin/bash(8)请求jar包的接口接口访问成功
curl http://localhost:8080/dockerfile(9)将该容器的端口映射到centos上面,宿主主机的浏览器也可以访问
# 启动完成之后可以在我们的浏览器访问映射到centos的地址,centosip:8888/dockerfile docker run -d --name springboot-dockerfile-demo02 -p 8888:8080 springboot-dockerfile-demo四、Docker hub仓库 1.官方的Docker hub
dockerhub仓库地址:https://hub.docker.com
(1)首先注册账号和密码,注册完之后在centos登录# centos通过 `docker login` 命令登录,账号和密码输入我们在 https://hub.docker.com 注册的 docker login --username=账号 https://hub.docker.com # 给之前的sprinboot应用的镜像重新打一个标签(相当于拷贝一个副本) docker tag springboot-dockerfile-demo:latest tianqingzhao/springboot-dockerfile-demo-hub:v1.0 # 推送到hub仓库 docker push tianqingzhao/springboot-dockerfile-demo-hub:v1.0(2)等待推送完成,在dockerhub仓库就可以看到我们的镜像了 (3)推送完成之后,删除本地的镜像,从dockerhub里面拉取一下
# 先删除本地之前打好的标签 docker rmi -f tianqingzhao/springboot-dockerfile-demo:v1.0 # 拉取dockerhub仓库的 docker pull tianqingzhao/springboot-dockerfile-demo:v1.0 # 创建容器运行并访问 docker run -d --name springboot-dockerfile-demo-hub -p 8811:8080 tianqingzhao/springboot-dockerfile-demo:v1.0 # 外部浏览器访问也能成功 http://192.168.0.136:8811/dockerfile2.阿里云Docker hub (1)在 容器镜像服务 里面点击实例列表,然后创建个人版实例 (2)然后创建命名空间 qztian,创建完成之后设置仓库类型为公有 (3)创建完成之后在centos登录阿里云进行推送
# 在centos登录阿里云,这里推送到哪个地区,推送成功之后就在阿里云控制台就选择哪一个地区查看,例如我这里推送到beijing,推送成功之后就选择北京 docker login --username=tianqingzhao registry.cn-beijing.aliyuncs.com # 给springboot应用的image重新打一个标签(相当于拷贝一个副本) docker tag 镜像名称 registry.cn-beijing.aliyuncs.com/阿里云命名空间名称/推送到阿里云镜像名称:版本号 # 比如我上面创建的命名空间名称为 qztian docker tag springboot-dockerfile-demo registry.cn-beijing.aliyuncs.com/qztian/springboot-dockerfile-demo-aliyun:v1.0 # 推送到阿里云仓库 docker push registry.cn-beijing.aliyuncs.com/qztian/springboot-dockerfile-demo-aliyun:v1.0(4)推送成功之后,选择我们推送的北京地区,就可以看到我们的镜像了 (5)从阿里云镜像仓库拉取我们推送的
# 同样先删除本地的 docker rmi -f registry.cn-beijing.aliyuncs.com/qztian/springboot-dockerfile-demo-aliyun:v1.0 # 拉取阿里云仓库 docker pull registry.cn-beijing.aliyuncs.com/qztian/springboot-dockerfile-demo-aliyun:v1.0 # 创建该镜像的容器,端口号映射到centos为8899, docker run -d --name springboot-dockerfile-demo-aliyun -p 8899:8080 registry.cn-beijing.aliyuncs.com/qztian/springboot-dockerfile-demo-aliyun:v1.0 # 然后访问外部浏览器也能成功 http://192.168.0.136:8899/dockerfile3.搭建自己的Docker harbor (1)harbor基于docker-compose启动的,所以需要先安装docker-compose
# 下载 Docker-Compose版本,使用daocloud下载 curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose # 将可执行权限应用于二进制文件: chmod +x /usr/local/bin/docker-compose # 创建软链 ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 验证是否安装成功 docker-compose --version(2)下载harbor压缩包
github仓库地址:https://github.com/goharbor/harbor
下载harbor安装包,地址:https://github.com/goharbor/harbor/releases?page=1
# 连接地址 hostname: centos的ip # 密码 harbor_admin_password: Harbor123456(4)配置harbor的镜像地址
# 编辑/etc/docker/daemon.json文件
vi /etc/docker/daemon.json
# 加上该配置
"insecure-registries":["192.168.0.136:80"]
# 加完之后,配置harbor的ip以及端口,默认端口号80
{
"registry-mirrors": ["https://dokomztn.mirror.aliyuncs.com"],
"insecure-registries":["192.168.0.136:80"]
}
(5)启动harbor
./install.sh(6)停止和启动
# 停止Harbor docker-compose down -v # 启动Harbor docker-compose up -d(7)推送一个镜像到Harbor,同阿里云镜像一样,这里先要新建一个项目 (8)新建好之后在centos登录harbor并复制镜像
# 登录harbor地址,然后输入密码显示登录成功即可 docker login -u admin 192.168.0.136:80 # 给springboot应用打一个标签。这里复制出来的镜像以ip:port/项目名称/镜像名称:版本号 docker tag springboot-dockerfile-demo:latest 192.168.0.136:80/qztian/springboot-dockerfile-demo-harbor:v1.0 # 推送 docker push 192.168.0.136:80/qztian/springboot-dockerfile-demo-harbor:v1.0(9)推送完成之后进入到该项目即可看到 (10)推送完成之后同样拉取一把
# 拉取之前先删除本地之前打好的标签的镜像 docker rmi -f 192.168.0.136:80/qztian/springboot-dockerfile-demo-harbor:v1.0 # 从harbor上面拉取 docker pull 192.168.0.136:80/qztian/springboot-dockerfile-demo-harbor:v1.0 # 创建容器运行 docker run -d --name springboot-dockerfile-demo-harbor -p 8866:8080 192.168.0.136:80/qztian/springboot-dockerfile-demo-harbor:v1.0 # 外部浏览器访问该springboot应用的接口即可成功 http://192.168.0.136:8866/dockerfile五、根据container创建出image (1)拉取centos镜像
docker pull centos(2)创建centos容器
# 加上-it是希望交互式启动,否则会停止 docker run -d -it --name my-centos centos:latest(3)进入到该容器
docker exec -it my-centos /bin/bash
查看vim命令是否有,没有的话进行安装
yum install vim
安装 vim 命令的时候可能会如下错误:
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs
这是因为CentOS 官方在2020 年 12 月 8 号宣布了停止维护 CentOS Linux 的计划,并推出了 CentOS Stream 项目,CentOS Linux 8 作为 RHEL 8 的复刻版本,生命周期缩短,于 2021 年 12 月 31 日停止更新并停止维护(EOL),更多的信息可以查看 CentOS 官方公告。如果需要更新 CentOS,需要将镜像从 mirror.centos.org 更改为 vault.centos.org,参考文章:https://blog.csdn.net/weixin_43252521/article/details/124409151
# 分别执行以下命令解决上面报错问题 cd /etc/yum.repos.d/ sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* yum makecache yum update -y yum -y install vim(4)生成一个带 vim命令的centos的image
docker commit my-centos vim-centos-image
创建容器
docker run -d -it --name my-vim-centos vim-centos-image
进入容器查看是否有vim命令
docker exec -it my-vim-centos /bin/bash # 输入vim命令验证
使用commit生成的镜像不显示过程,使用Dockerfile生成的会显示每一步执行的过程,官网推荐的也是Dockerfile
六、container资源管理 1.启动一个tomcat,任何参数不配置分配默认的参数docker run -d --name tomcat01 -p 8811:8080 tomcat:8 # 查看状态 docker stats tomcat01 # 会显示一下内容 CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 258dd43c4d61 tomcat01 0.13% 60.45MiB / 2.709GiB 2.18% 656B / 0B 0B / 0B 252.使用命令监控
# 配置内容大小和cpu权重 docker run -d --name tomcat02 --memory 100M --cpu-shares 10 -p 8822:8080 tomcat:8 # 查看状态 docker stats tomcat02 # 回显示一下内容 CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS ea61e5ea38e1 tomcat02 0.12% 45.02MiB / 100MiB 45.02% 656B / 0B 0B / 0B 183.可视化监控工具
github地址:https://github.com/weaveworks/scope
(1)快速开始# 1.下载 curl -L git.io/scope -o /usr/local/bin/scope # 上面如果报 Failed to connect to 2001::6817:7dbd: Network is unreachable 错误,就使用这条命令下载 curl -L https://github.com/weaveworks/scope/releases/download/latest_release/scope -o /usr/local/bin/scope # 2.授权 chmod a+x /usr/local/bin/scope # 3.启动 scope launch centos的ip(2)启动成功之后就可以通过浏览器访问管理界面了,默认端口号4040
点击其中一个container可以查看使用情况
也可以点击image进行查看创建的container,感兴趣的自行研究
# 创建network namespace,添加网络命名空间名称为 ns1 ip netns add ns1 # 查看网络命名空间名称 ip netns list # 查看添加的网络命名空间 ip netns exec ns1 ip link show # 显示以下内容 1: lo:(2)按照以上步骤创建ns2mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 启动该网络命名空间 ip netns exec ns1 ifup lo # 再次查看 ip netns exec ns1 ip link show # 显示一下内容 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 查看物理主机 ip link show # 显示以下其中一条内容 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 发现添加的网络命名空间和物理主机的网络命名空间都为 UNKNOWN
ip netns add ns2 # 查看网络命名空间名称 ip netns list # 查看添加的网络命名空间 ip netns exec ns2 ip link show # 显示以下内容 1: lo:mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 启动该网络命名空间 ip netns exec ns2 ifup lo
接下来使这两个网络命名空间进行通信
2.veth pair:Virtual Ethernet Pair成对出现的网卡,创建出来是默认能够联通的,也就是使ns1和ns2联通
# 创建两个网卡并使它们连接 ip link add veth-ns1 type veth peer name veth-ns2 # 再次查看 ip link show # 发现它们两个已经连上了 52: veth-ns2@veth-ns1:(2)把这两个派给ns1和ns2这两个网络命名空间mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 7a:70:ac:99:cc:60 brd ff:ff:ff:ff:ff:ff 53: veth-ns1@veth-ns2: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether fe:5d:55:36:01:94 brd ff:ff:ff:ff:ff:ff
# 把网卡veth-ns1派给网络命名空间ns1 ip link set veth-ns1 netns ns1 # 派送完成之后通过 ip link show再次查看已经看不到veth-ns1这个网卡了 # 再次查看ns1这个网络命名空间 ip netns exec ns1 ip link show # 显示一下内容,说明veth-ns1这个网卡已经被派送过来了 1: lo:(3)给这两个网卡添加ip地址mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 53: veth-ns1@if52: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether fe:5d:55:36:01:94 brd ff:ff:ff:ff:ff:ff link-netnsid 0 # 同样给ns2派送网卡veth-ns2 ip link set veth-ns2 netns ns2 # 再次查看ns2这个网络命名空间 ip netns exec ns2 ip link show # 显示一下内容表示派送成功 1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 52: veth-ns2@if53: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 7a:70:ac:99:cc:60 brd ff:ff:ff:ff:ff:ff link-netnsid 0
# 给ns1这个网络命名空间的veth-ns1网卡添加ip为192.168.0.11,子网掩码为24, ip netns exec ns1 ip addr add 192.168.0.11/24 dev veth-ns1 # 启动该网络命名空间 ip netns exec ns1 ip link set veth-ns1 up # 再次查看 ip netns exec ns1 ip a # 操作ns2这个网络命名空间 ip netns exec ns2 ip addr add 192.168.0.12/24 dev veth-ns2 # 启动该网络命名空间 ip netns exec ns2 ip link set veth-ns2 up # 查看该网络命名空间 ip netns exec ns2 ip a(4)验证两个网络命名空间是否互通
# 在ns1上面去ping ns2 ip netns exec ns1 ping 192.168.0.12 # 在ns2上面去ping ns1 ip netns exec ns2 ping 192.168.0.11
看到以下表示ping通
ip a查看网络,如果报bash: ip: command not found错误,使用以下命令安装ip命令
apt update && apt install -y iproute2
进入其中一个,然后ping另外一个的ip,如果ping命令失败,使用以下命令安装ping命令
# 更新 apt-get update # 安装 apt install iputils-ping3.安装查看网桥工具 (1)安装
yum install bridge-utils
# 查看
brctl show
# 会显示以下内容
bridge name bridge id STP enabled interfaces
br-57f9401a93d6 8000.0242814bbbac no
docker0 8000.0242603a900c no veth57d3d66
veth6f9793a
veth7f8cf69
vethd979e57
(2)在centos通过ip a再次查看网络,可以找到 brctl show 命令出现的docker0的网卡信息
41: veth57d3d66@if40:(3)原理图 4.网络类型 (1)查看docker网络类型mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 92:8c:21:a1:c4:ea brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::908c:21ff:fea1:c4ea/64 scope link valid_lft forever preferred_lft forever 43: veth7f8cf69@if42: mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 96:5c:08:88:07:82 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::945c:8ff:fe88:782/64 scope link valid_lft forever preferred_lft forever 47: veth6f9793a@if46: mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 7a:05:4e:b2:7b:a6 brd ff:ff:ff:ff:ff:ff link-netnsid 2 inet6 fe80::7805:4eff:feb2:7ba6/64 scope link valid_lft forever preferred_lft forever 49: vethd979e57@if48: mtu 1500 qdisc noqueue master docker0 state UP group default link/ether ce:0a:83:9c:a3:ef brd ff:ff:ff:ff:ff:ff link-netnsid 3 inet6 fe80::cc0a:83ff:fe9c:a3ef/64 scope link valid_lft forever preferred_lft forever
# 查看 docekr network ls # 显示一下内容 57f9401a93d6 harbor_harbor bridge local 6b5feb06c2bf host host local cd6aba8f33fa none null local # docker中创建的任何容器都是基于bridge网络类型的, # host是和宿主主机一样的网络 # 查看bridge类型的 docker network inspect bridge(2)给docker 创建网络
# 创建一个网络,默认为bridge类型的 docker network create tomcat-net # 再次查看已经出现了 docker network ls # 查看创建出来的tomcat-net网络信息,它的网段已经不是172.17了,而是172.19或者其他递增的 docker network inspect tomcat-net # 创建网络并指定网段 docker network create --subnet=172.19.0.0/24 tomcat-net # 删除网络 docker network rm tomcat-net(3)创建容器并指定网络
docker run -d --name custom-net-tomcat --network tomcat-net tomcat # 再来查看该容器的网络 docker exec -it custom-net-tomcat ip a # 可以发现它就是刚刚创建的172.19开头的网段了 # 这时候用创建出来的网络去ping之前的tomcat是ping不同的 docker exec -it custom-net-tomcat ping 172.17.0.2 # 因为现在的custom-net-tomcat这个容器是新的网络,跟之前docker默认的不一样
用下面一张图来理解
接下来把tomcat01添加到tomcat-net里面
docker network connect tomcat-net tomcat01 # 添加完再次查看 docker network inspect tomcat-net # 此时已经能看到tomcat01被添加到tomcat-net这个网络里面了 # 再去查看tomcat01这个容器的网络 docker inspect tomcat01 # 此时也能看到tomcat-net这个网络了
这时候进入custom-tomcat-net这个容器里面去ping一下tomcat01这个容器,此时已经可以ping通了。
docker exec -it custom-tomcat-net /bin/bash ping 172.17.0.2
用下面一张图来理解一下
直接使用容器名称去ping两个容器的话是ping不同的,分别给他们指定网络之后可以ping通。
(1)指定网络可以ping通创建两个tomcat容器,并分别指定网络为上面创建的tomcat-net,此时再去根据容器名称ping的话是可以ping通的。
# 这这两个容器都指定网络为tomcat-net docker network connect tomcat-net tomcat01 docker network connect tomcat-net tomcat02 # 再去ping docker exec -it tomcat01 ping tomcat02(2)通过 --link 参数
# 指定tomcat01容器连接到tomcat02上面,通过dns连接 docker run -d --name tomcat01 --link tomcat02 tomcat:8 # 再次去ping可以ping通 docker exec -it tomcat01 ping tomcat02
生产中推荐使用自定义网络来进行连接。
6.解决多机网络通信问题overlay网络模式,实现的是vxlan
# 查看所有的volume docker volume ls # 查看某一个volume详情 docker volume inspect VOLUMENAME # 删除某一个volume docker vlume rm VOLUMENAME(1)以mysql为例来说明
# 拉取mysql镜像
docker pull mysql
# 创建mysql01容器
docker run -d --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 mysql
# 进入到mysql01容器
docker exec -it mysql01 /bin/bash
# 在容器里面进入到/var/lib/mysql目录
cd /var/lib/mysql
# 可以看到有以下文件
'#ib_16384_0.dblwr' '#innodb_temp' binlog.000001 binlog.index ca.pem client-key.pem ib_logfile0 ibdata1 mysql performance_schema public_key.pem server-key.pem undo_001
'#ib_16384_1.dblwr' auto.cnf binlog.000002 ca-key.pem client-cert.pem ib_buffer_pool ib_logfile1 ibtmp1 mysql.ibd private_key.pem server-cert.pem sys undo_002
# 退出容器,在centos里面查看数据持久化
# 首选查看刚创建出来的msql01的VOLUME NAME
docker volume ls
# 然后根据VOLUME NAME的值查看该volume数据存储的位置
docker volume inspect 6a19afe432358b32607297e828150308440976509b0e19b48616a60cdfd7ab7e
# 可以看到该容器的数据是存储在/var/lib/docker/volumes下面的,
[
{
"CreatedAt": "2022-05-18T01:18:31Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/6a19afe432358b32607297e828150308440976509b0e19b48616a60cdfd7ab7e/_data",
"Name": "6a19afe432358b32607297e828150308440976509b0e19b48616a60cdfd7ab7e",
"Options": null,
"Scope": "local"
}
]
# 进入到该完整目录里面,可以看到有以下文件,和在容器中查看的一样
auto.cnf binlog.000002 ca-key.pem client-cert.pem #ib_16384_0.dblwr ib_buffer_pool ib_logfile0 ibtmp1 mysql performance_schema public_key.pem server-key.pem undo_001
binlog.000001 binlog.index ca.pem client-key.pem #ib_16384_1.dblwr ibdata1 ib_logfile1 #innodb_temp mysql.ibd private_key.pem server-cert.pem sys undo_002
# 每次创建容器都会在centos的机器上面生成一个文件夹,用来保存数据
(2)给创建的容器指定volume名称
# 指定volume名称,并指定容器内存储数据目录 docker run -d --name mysql02 -v mysql02_volume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql # 再次查看 docker volume ls # 就显示我们指定的 local mysql02_volume # 删除容器之后,centos查看volume还会存在,也就是容器被删除之后,可以恢复数据,除非把centos的volume给删除了那就无法恢复 # 在mysql02这个容器中的数据存储目录里面创建一个文件,centos也会同步显示 docker exec -it mysql02 /bin/bash cd /var/lib/mysql touch test.txt # 查看已经能显示了 ls # 退出容器 exit # 在centos查看该容器对应的volume所在的路径 docker volume inspect mysql02_volume # 查看该volume所在的路径,也已经能看到 test.txt 文件了 ls /var/lib/docker/volumes/mysql02_volume/_data(3)删除mysql02容器,并进行恢复
# 首先在该容器创建一个数据库 create database tqz_test; # 查看该数据库已经被创建出来了 show databases; # 删除 docker rm -f mysql02 # 再重新创建一个容器,并指定volume docker run -d --name mysql02 -v mysql02_valume:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql # 进入到该容器查看 docker exec -it test-mysql /bin/bash mysql -u root -p show databases; # 可以发现上面创建的tqz_test数据库还存在2.Bind mounts
# 在centos创建一个文件夹 mkdir /usr/local/malls # 编辑一个html页面 vi test.html # 随便写上一段内容 Hello Bind mounts! # 创建一个tomcat01的容器,并且指定挂载centos的项目,也就是上面我们创建的页面挂载上去 docker run -d --name tomcat01 -p 9090:8080 -v /usr/local/malls/:/usr/local/tomcat/webapps/malls tomcat # 进入容器中里面,可以在tomcat的webapps目录下面看到该项目 docker exec -it tomcat01 /bin/bash # 浏览器访问可以看到我们test.html页面的内容 http://192.168.0.136:9090/malls/test.html九、搭建mysql高可用集群 1.Percona Xtradb Cluster 搭建集群
hub.docker.com搜索:percona/percona-xtradb-cluster
# 拉取pxc镜像 docker pull percona/percona-xtradb-cluster:5.7.21 # 由于镜像名称太长,给其打个tag重新起个名字 docker tag percona/percona-xtradb-cluster:5.7.21 pxc # 删除之前的镜像 docker rmi percona/percona-xtradb-cluster:5.7.21
创建pxc-net网络
# 创建网络并指定网段 docker network create --subnet=172.20.0.0/24 pxc-net # 查看网络详情 docker network inspect pxc-net
创建三个volume,分别给三个mysql容器使用
docker volume create --name v1 docker volume create --name v2 docker volume create --name v3
创建三个mysql容器
# 创建mysql01容器,映射到centos端口为3301,指定volume为v1,在容器中的存储路径为/var/lib/mysql,mysql密码为123456,集群名称为PXC,集群之间同步数据的密码为123456,指定容器的网络为pxc-net,指定ip为172.20.0.2 docker run -d --name=mysql01 -p 3301:3306 -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 --privileged --net=pxc-net --ip 172.20.0.2 pxc # 创建mysql02容器,映射到centos端口为3302,指定volume为v2,加入到mysql01里面组成集群,指定ip为172.20.0.3 docker run -d --name=mysql02 -p 3302:3306 -v v2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=mysql01 --privileged --net=pxc-net --ip 172.20.0.3 pxc # 创建mysql03容器,映射到centos端口为3303,指定volume为v3,加入到mysql01里面组成集群,指定ip为172.20.0.4 docker run -d --name=mysql03 -p 3303:3306 -v v3:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=123456 -e CLUSTER_JOIN=mysql01 --privileged --net=pxc-net --ip 172.20.0.4 pxc
通过客户端工具分别连接到三个mysql,在其中一个mysql里面创建数据库,然后创建一张表并添加数据,其他两个mysql里面也能同步到数据。
2.Haproxy 负载均衡# 拉取haproxy镜像 docker pull haproxy # 在centos机器创建一个文件夹 mkdir -p /usr/local/haproxy # 在上面的目录下创建一个haproxy.cfg配置文件 touch /usr/local/haproxy.haproxy.cfg
以下为 haproxy.cfg 配置文件内容
global #工作目录,这边要和创建容器指定的目录对应,haproxy容器的目录默认在该路径 # chroot /usr/local/etc/haproxy #日志文件 log 127.0.0.1 local5 info #守护进程运行 daemon defaults log global mode http #日志格式 option httplog #日志中不记录负载均衡的心跳检测记录 option dontlognull #连接超时(毫秒) timeout connect 5000 #客户端超时(毫秒) timeout client 50000 #服务器超时(毫秒) timeout server 50000 #监控界面 listen admin_stats #监控界面的访问的IP和端口 bind 0.0.0.0:8123 #访问协议 mode http #控制台URI相对地址 stats uri /haproxy #统计报告格式 stats realm Global statistics #控制台登陆帐户信息 stats auth admin:admin #数据库负载均衡 listen proxy-mysql #访问的IP和端口,haproxy开发的端口为3306 #假如有人访问haproxy的3306端口,则将请求转发给下面的数据库实例 bind 0.0.0.0:3306 #网络协议 mode tcp #负载均衡算法(轮询算法) #轮询算法:roundrobin #权重算法:static-rr #最少连接算法:leastconn #请求源IP算法:source balance roundrobin #日志格式 option tcplog #在MySQL中创建一个没有权限的haproxy用户,密码为空。 #Haproxy使用这个账户对MySQL数据库心跳检测 option mysql-check user haproxy #以下为三台mysql容器ip和端口号 server MySQL_1 172.20.0.2:3306 check weight 1 maxconn 2000 server MySQL_2 172.20.0.3:3306 check weight 1 maxconn 2000 server MySQL_3 172.20.0.4:3306 check weight 1 maxconn 2000 #使用keepalive检测死链 option tcpka
创建haproxy容器
docker run -it -d -p 8123:8123 -p 3306:3306 -v /usr/local/haproxy/:/usr/local/etc/haproxy --name haproxy --privileged --net=pxc-net haproxy
启动完之后浏览器访问
# centos的ip加映射到centos的端口号,后面的uri就是我们再haproxy.cfg配置的stats uri # 账户和密码使我们在haproxy.cfg配置的stats auth后面的参数 http://192.168.0.136:8123/haproxy
navicat连接数据库,需要创建一个haproxy用户,在mysql01的容器上面执行以下命令
# 进入mysql01容器 docker exec -it mysql01 /bin/bash # 进入mysql,并输入密码 mysql -u root -p # 首选执行该命令,正常情况都可以成功 CREATE USER 'haproxy'@'%' IDENTIFIED BY ''; # 如果创建失败,可以先输入一下命令 drop user 'haproxy'@'%'; flush privileges; CREATE USER 'haproxy'@'%' IDENTIFIED BY '';3.springboot项目连接高可用数据库
网络还是使用上面mysql高可用集群和haproxy的网络 pxc-net
上传springboot-mybatis.jar包
注意配置文件
# 数据源
spring:
datasource:
# 这里先使用haproxy容器的ip
url: jdbc:mysql://172.20.0.2:3306/sbm-ds?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# mybatis托管mapper文件
mybatis:
mapper-locations: classpath:mapper/*.xml
接口
@RestController
@RequestMapping(value = "/user")
public class UserController {
@Autowired
private UserService userService;
private AtomicInteger value = new AtomicInteger(0);
// 查询所有用户接口
@RequestMapping("/getList")
public R> getList(HttpServletRequest request) {
String msg = "第 " + value.incrementAndGet() + " 次调用...";
System.out.println(msg);
List users = userService.getList();
return new R<>(200, msg, users);
}
// 添加用户接口
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String add(User user) {
int result = userService.insertUser(user);
if (result >= 1) {
return "添加成功";
} else {
return "添加失败";
}
}
}
编写 Dockerfile 文件
FROM openjdk:8-jre-alpine MAINTAINER tianqingzhao LABEL name="springboot-mybatis" version="1.0" author="tianqingzhao" COPY springboot-mybatis-0.0.1-SNAPSHOT.jar springboot-mybatis.jar CMD ["java","-jar","springboot-mybatis.jar"]
基于springboot的jar包和 Dockerfile 文件构建 springboot-mybatis-image 镜像
docker build -t springboot-mybatis-image .
基于image创建容器
# 映射到centos端口号为8811,使用pxc-net的网络,容器的ip使用172.20.0.11 docker run -d --name sbm01 -p 8811:8080 --net=pxc-net --ip 172.20.0.11 springboot-mybatis-image
访问接口
# centos通过curl命令 curl http://localhost:8811/user/getList4.通过nginx负载均衡访问项目,数据库访问haproxy容器名称
整体流程:用户请求 —》 nginx —》springboot-mybatis容器项目
先删除之前的springboot-mybatis-image镜像和启动的sbm01容器
# 删除镜像 docker rmi springboot-mybatis-image:latest # 删除容器 docker rm -f sbm01
修改配置文件数据库url连接
# 数据源
spring:
datasource:
### 在同一个网络中,bridge pxc-net 容器之间不仅可以通过ip访问,而且可以通过名称
url: jdbc:mysql://haproxy/sbm-ds?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# mybatis托管mapper文件
mybatis:
mapper-locations: classpath:mapper/*.xml
打包上传重新构建image,上传之前,先删掉之前传的jar包。基于新上传的jar包重新构建镜像,Dockerfile 文件不用修改。
# 构建新的镜像 docker build -t springboot-mybatis-image . # 重新构建之后的镜像目前已推送到hub.docker.com仓库,通过以下命令可拉取 docker pull tianqingzhao/springboot-mybatis:v1.0
基于springboot-mybatis-image镜像启动三个容器
# 启动sbm01容器 docker run -d --name sbm01 -p 8811:8080 --net=pxc-net --ip 172.20.0.11 springboot-mybatis-image # 启动sbm02容器,注意修改容器名称、端口号、ip docker run -d --name sbm02 -p 8822:8080 --net=pxc-net --ip 172.20.0.12 springboot-mybatis-image # 启动sbm03容器,注意修改容器名称、端口号、ip docker run -d --name sbm03 -p 8833:8080 --net=pxc-net --ip 172.20.0.13 springboot-mybatis-image
拉取nginx镜像
docker pull nginx
编写 nginx.conf 配置文件
user nginx;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
# 访问路径为根路径
location / {
proxy_pass http://balance;
}
}
upstream balance{
server 172.18.0.20:8080;
server 172.18.0.20:8080;
server 172.18.0.20:8080;
}
include /etc/nginx/conf.d/*.conf;
}
创建nginx容器
# 容器名称为nginx,映射到centos端口号为80,把centos机器的nginx.conf挂载到容器的/etc/nginx/nginx.conf目录里面 # 使用pxc-net这个网络,ip为172.20.0.10 docker run -d --name nginx -p 80:80 -v /usr/local/nginx-image/nginx.conf:/etc/nginx/nginx.conf --network=pxc-net --ip 172.20.0.10 nginx
浏览器访问
# 该ip为centosip,由于nginx配置的为根路径,,端口号监听的80,所以直接访问ip加接口即可 http://192.168.0.136/user/getList # 可以通过docker logs 容器名称 命令查看每个容器输出情况来验证是否做到了负载均衡十、Docker-compose 1.基于Dockerfile启动一个python应用
在centos机器上面创建一个文件夹,用于存放Dockerfile和python应用的代码
# 创建文件夹 mkdir -p /usr/local/python # 进入到该文件夹 cd /usr/local/python
接下来在上面创建的文件夹写一个python应用接口,文件名称定义为 app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.n'.format(count)
继续在上面的文件夹创建 requirements.txt 文件,该文件用于标识python应用的依赖包
flask redis
编写 Dockerfile 文件
FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["flask", "run"]
根据上面的 Dockefile 文件生成镜像
docker build -t python-app-image .
拉取一个轻量级的redis镜像
docker pull redis:alpine
创建网络
# 指定网段为172.17.21.0,名称为python-net docker network create --subnet=172.21.0.0/24 python-net
基于上面构建的镜像创建容器
docker run -d --name python-app -p 5000:5000 --network python-net python-app-image
基于redis镜像创建容器
docker run -d --name redis -p 6379:6379 --network python-net redis:alpine
浏览器访问
# centos的ip加python应用的端口号 http://192.168.0.136:5000/ # 可以看到有输出,每次访问都会递增1 Hello World! I have been seen 1 times.2.docker-compose实现上面python应用
删除上面的容器、镜像、网络
docker rm -f python-app docker rmi -f python-app-image docker rm -f redis docker rmi -f redis:alpine docker network rm python-net
docker-compose是在单机上面进行多个容器的管理部署
首先安装docker-compose
# 下载 Docker-Compose版本,使用daocloud下载 curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose # 将可执行权限应用于二进制文件: chmod +x /usr/local/bin/docker-compose # 创建软链 ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose # 验证是否安装成功 docker-compose --version
编写 docker-compose.yaml 文件
version: '1'
services: # 表示定义一些容器,下面每一个service就是docker中容器的名称
python-app: # 容器名称
build: . # 从当前目录的Dockerfile进行构建
ports:
- "5000:5000" # 端口的映射,和 -p 命令一样
networks:
- python-net # 使用这个网络
redis:
image: "redis:alpine" # 从该镜像构建一个容器
networks:
- python-net
networks: # docker network create --name python-net
python-net:
driver: bridge # 创建一个python-net的网络,并指定为bridge类型的
使用 docker-compose.yaml 创建容器
# up表示启动 -d表示后台启动 # 如果有指定docker-compose.yaml文件,使用-f命令指定 docker-compose up -d
docker-compose文件详解
# service表示一个容器 # ports表示映射的端口号,相当于-p # build表示要根据Dockerfile文件构建镜像 # networks表示创建网络,service下面指定networks参数表示使用该网络 # images表示指定从指定镜像创建service # volumes表示指定数据卷,相当于-v v1:/var/lib/mysql # enviornment表示参数,相当于-e
docker-compose常见操作
# 查看版本 docker-compose version # 根据yml创建service docker-compose up # 指定yaml:docker-compose up -f xxx.yaml # 后台运行:docker-compose up #查看启动成功的service docker-compose ps # 也可以使用docker ps # 查看images docker-compose images #停止/启动service docker-compose stop/start # 删除service[同时会删除掉network和volume] docker-compose down # 进入到某个service docker-compose exec redis sh十一、docker-swarm
docker-swarm是为了解决在多机部署容器
manager-node:2200
work01-node:2201
work02-node:2202
1.安装docker-swarm进入manager
docker swarm init --advertise-addr=192.168.0.11
显示以下内容,复制圈住的内容
在其他两个worker节点执行该命令
docker swarm join --token SWMTKN-1-12nfretcz1e6jgguiifz5by9ntb2tuzdtjbc8znw9465n8nir6-93l1j9flq85rhxgvyf62ym0q7 192.168.0.11:2377
查看集群状态
docker node ls
可以看到manager-node节点的MANAGER STATUS为Leader
node类型的转换,可以将worker提升成manager,从而保证manager的高可用
# 提成节点为候选的 docker node promote worker01-node docker node promote worker02-node #降级可以用demote docker node demote worker01-node2.docker-swarm基本操作
创建一个service
docker service create --name tomcat01 tomcat
查看当前swarm的service
docker service ls
查看日志详情
docker service logs tomcat01
查看service的详情
docker service inspect tomcat01
查看容器运行在哪个节点上面
docker service ps tomcat01 # 输出以下内容,随机运行在某一个节点上面 ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS pawlnlhurroa tomcat01.1 tomcat:latest worker01-node Running Running 6 hours ago
水平扩容service
docker service scale tomcat01=3 # 查看列表 docker service ls # 查看详情 docker service ps my-tomcat # 输出一下内容 ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS pawlnlhurroa tomcat01.1 tomcat:latest worker01-node Running Running 7 hours ago xg6yne73yug2 tomcat01.2 tomcat:latest manager-node Running Running 12 minutes ago xig0y6lgaoiy tomcat01.3 tomcat:latest worker02-node Running Preparing 12 minutes ago
此时到worker01-node上:docker ps,可以发现container的name和service名称不一样
docker ps # 显示一下内容 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f8fa8f859a1f tomcat:latest "catalina.sh run" 7 hours ago Up 7 hours 8080/tcp tomcat01.1.pawlnlhurroa78izqtc21zyjm
如果某个node上的my-tomcat挂掉了,这时候会自动扩展
# [worker01-node] docker rm -f containerid # [manager-node] docker service ls docker service ps my-tomcat
删除service
docker service rm my-tomcat3.Swarm中部署一个个人博客
(1)创建一个overlay网络,用于docker swarm中多机通信
# manager节点执行 docker network create -d overlay my-overlay-net # 此时worker node查看不到 docker network ls
(2)创建mysql的service
# manager节点创建service docker service create --name mysql --mount type=volume,source=v1,destination=/var/lib/mysql --env MYSQL_ROOT_PASSWORD=examplepass --env MYSQL_DATABASE=db_wordpress --network my-overlay-net mysql:5.6 #查看service docker service ls docker service ps mysql
(3)创建wordpress的service
# 创建service [注意之所以下面可以通过mysql名字访问,也是因为有DNS解析] docker service create --name wordpress --env WORDPRESS_DB_USER=root --env WORDPRESS_DB_PASSWORD=examplepass --env WORDPRESS_DB_HOST=mysql:3306 --env WORDPRESS_DB_NAME=db_wordpress -p 8080:80 --network my-overlay-net wordpress # 查看service docker service ls docker service ps mysql # 此时mysql和wordpress的service运行在哪个node上,这时候就能看到my-overlay-net的网络
(4)测试
win浏览器访问ip[manager/worker01/worker02]:8080都能访问成功
(5)查看my-overlay-net
docker network inspect my-overlay-net
(6)为什么没有用etcd?docker swarm中有自己的分布式存储机制
4. Routing Mesh (1) Ingressdocker service create --name tomcat -p 8080:8080 --network my-overlay-net tomcat
记得使用一个自定义的overlay类型的网络
--network my-overlay-net
查看service情况
docker service ls docker service ps tomcat
访问3台机器的ip:8080测试,发现都能够访问到tomcat的欢迎页
(2) Internal之前在实战wordpress+mysql的时候,发现wordpress中可以直接通过mysql名称访问
这样可以说明两点,第一是其中一定有dns解析,第二是两个service的ip是能够ping通的
再创建一个service,也同样使用上述tomcat的overlay网络,然后来实验
docker service create --name whoami -p 8000:8000 --network my-overlay-net -d jwilder/whoami
查看whoami的情况
docker service ps whoami
在各自容器中互相ping一下彼此,也就是容器间的通信
#tomcat容器中ping whoami docker exec -it 9d7d4c2b1b80 ping whoami 64 bytes from bogon (10.0.0.8): icmp_seq=1 ttl=64 time=0.050 ms 64 bytes from bogon (10.0.0.8): icmp_seq=2 ttl=64 time=0.080 ms #whoami容器中ping tomcat docker exec -it 5c4fe39e7f60 ping tomcat 64 bytes from bogon (10.0.0.18): icmp_seq=1 ttl=64 time=0.050 ms 64 bytes from bogon (10.0.0.18): icmp_seq=2 ttl=64 time=0.080 ms
将whoami进行扩容
docker service scale whoami=3 docker service ps whoami #manager,worker01,worker02
此时再ping whoami service,并且访问whoami服务
#ping docker exec -it 9d7d4c2b1b80 ping whoami 64 bytes from bogon (10.0.0.8): icmp_seq=1 ttl=64 time=0.055 ms 64 bytes from bogon (10.0.0.8): icmp_seq=2 ttl=64 time=0.084 ms #访问 docker exec -it 9d7d4c2b1b80 curl whoami:8000 [多访问几次] I'm 09f4158c81ae I'm aebc574dc990 I'm 7755bc7da921
whoami服务对其他服务暴露的ip是不变的,但是通过whoami名称访问8000端口,确实访问到的是不同的service。
也就是说whoami service对其他服务提供了一个统一的VIP入口,别的服务访问时会做负载均衡。
(3) Stackdocker stack deploy:https://docs.docker.com/engine/reference/commandline/stack_deploy/
compose-file:https://docs.docker.com/compose/compose-file/
docker swarm中的Stack,我们直接通过前面的wordpress+mysql案例看看怎么使用咯。
新建service.yml文件
version: '3'
services:
wordpress:
image: wordpress
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
networks:
- ol-net
volumes:
- wordpress:/var/www/html
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
networks:
- ol-net
deploy:
mode: global
placement:
constraints:
- node.role == manager
volumes:
wordpress:
db:
networks:
ol-net:
driver: overlay
根据service.yml创建service
docker stack deploy -c service.yml my-service
常见操作
# 查看stack具体信息
docker stack ls
NAME SERVICES ORCHESTRATOR
my-service 2 Swarm
#查看具体的service
docker stack services my-service
ID NAME MODE REPLICAS IMAGE PORTS
icraimlesu61 my-service_db global 1/1 mysql:5.7
iud2g140za5c my-service_wordpress replicated 3/3 wordpress:latest *:8080->80/tcp
# 查看某个service
docker service inspect my-service-db
"Endpoint": {
"Spec": {
"Mode": "vip"
},
"VirtualIPs": [
{
"NetworkID": "kz1reu3yxxpwp1lvnrraw0uq6",
"Addr": "10.0.1.5/24"
}
]
}
(4)访问测试
win浏览器ip[manager,worker01,worker02]:8080



