Docker与vm的区别
左图为VMware的结构图,右侧为Docker的结构图
- 传统虚拟机是虚拟出硬件,运行一个完整的操作系统以及运行其操作系统的环境,再运行相应的应用
- 容器则是直接运行宿主机的内核,再运行想要的应用。
Docker容器优点
Docker引擎统一了基础设施环境IASS
统一了程序打包的方式(镜像)
统一了程序部署(运行)的方式(容器)
Docker容器运行逻辑
Docker容器是由docker Engine为核心运行的容器,不需要额外运行一台服务器,而是直接启用宿主机内核。
Docker容器是一个标准的C/S结构程序。通过Docker的守护进行连接,以Socket的形式打通Docker-client和Docker-server。
Docker安装部署(Centos7环境)
#卸载已有的Docker以及依赖
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#安装utils包(它提供了yum-config-manager实用程序)并设置稳定存储库。
yum install -y yum-utils
#配置docker-ce.repo的yum源(个人使用了阿里云)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#清空yum缓存
yum makecache fast
安装方式:
#1、直接安装当前yum源中最新的版本
$ sudo yum install docker-ce docker-ce-cli containerd.io
#2、查看已有版本 选择想要的版本下载
yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 3:18.09.1-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.0-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.1.ce-3.el7 docker-ce-stable
docker-ce.x86_64 18.06.0.ce-3.el7 docker-ce-stable
$ sudo yum install docker-ce- docker-ce-cli- containerd.io
启动Docker
配置镜像加速
#开启服务
$ sudo systemctl start docker
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://zvjih5co.mirror.aliyuncs.com"]
}
EOF
#重新加载Docker守护进程
sudo systemctl daemon-reload
#重新启动docker
sudo systemctl restart docker
#运行hello-world
[root@VM_0_17_centos /]# docker run hello-world
Unable to find image 'hello-world:latest' locally
#本地未能找到hello-world镜像
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
#镜像ID
Status: Downloaded newer image for hello-world:latest
#下载镜像
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Docker可视化工具
- portainer
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
#测试
crul localhost:8088
#登陆
ip:8088登录后创建用户,选择local 随后connect即可
Docker镜像讲解
什么是镜像
镜像是一种轻量化、可执行的独立软件包,用来打包软件运行环境和基础开发环境的软件,它包含了运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量、配置文件等。
未来所有的应用,直接打包生成docker镜像,就可以直接跑起来。
如何得到镜像呢?
- 远程仓库下载
- 同事朋友拷贝
- 自己制作镜像DockerFile
Docker镜像加载原理
UnionFS(联合文件系统)
下载Docker时看到一层一层的就是这个!
UnionFS:UnionFS文件系统是一种分层、轻量化并且高性能的文件系统、它支持对文件系统的修改作为一次提交来一层一层的叠加,同时可以将不同目录挂在到同一个虚拟文件系统下(Unite serverval directories into a single virtual filesystem)
Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。
特性:一次同事加载多个文件系统,但是外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
docker的镜像实际上由一层- -层的文件系统组成,这种层级的文件系统UnionFS.
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是弓|导加载kernel, Linux刚启动时会加载bootfs文件系
统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成
之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs.
rootfs (root file system) ,在bootfs之上。包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是
各种不同的操作系统发行版,比如Ubuntu , Centos等等。
commit镜像
#提交容器成为一个新的副本
docker commit
#命令类似于git
docker commit -m="描述信息" -a="作者" 容器ID 目标镜像名:[TAG]
实战测试
#启动一个默认的tomcat
docker run -it -p8080:8080 tomcat
docker exec -it 25b8dc67ca8b /bin/bash
#发现默认版本的tomcat webapps下没有任何文件。
#拷贝基本的文件进入这个目录
cp webapps.dist/* webapps
#修改后的容器,通过commit 提交为一个新的镜像。
docker commit -a="hjh" -m="add webapps app" 25b8dc67ca8b tomcat02:1.0
如果想要保存当前容器的状态,就可以通过commit提交,获得一个镜像,好比是vm中的快照
提交本地之后生成镜像。
容器数据卷
什么是容器数据卷
docker理念回顾
将应用和环境打包成一个镜像。
如果数据储存在容器中,那么把数据删除后,数据就会丢失。 需求:==数据可以持久化==
Mysql,容器删除=删库跑路了!==需求:Mysql数据可以存储在本地==
容器之间需要一个数据共享的技术!Docker容器中产生的数据,同步到本地!
卷技术=目录挂在,将容器内的目录挂在到Linux中。
使用数据卷
方式一:使用命令来挂载
docker run -it -v主机目录地址:容器内目录地址 -p 主机端口:容器内端口
测试
docker run -it -v /home/ceshi:/home centos /bin/bash
起来之后可以通过Docker inspect 查看Mounts的详细信息
宿主机文件夹生成后可以通过touch 创建文件来进行测试是否同步。
好处:以后修改只需要在本地修改即可,无需进入容器内部。
实战:mysql
Dckerhub的官方文档
#Dckerhub的官方文档中的mysql安装步骤
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#实际操作
-d 后台运行
-p 端口映射
-v 数据卷挂载,可多个挂载
-e 环境配置 此处配置了mysql密码
--name 名字
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 9cfcce23593a
#查看启动状态,
docker ps
启动成功后可以通过类似于Navicat等工具连接。连接成功说明启动成功
通过数据库工具创建数据库后,查看linux宿主机。
删除容器后,发现数据没有随着容器而被删除,这就实现了==容器持久化==
具名挂载、匿名挂载
#匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /etc/nginx/ nginx
#查看所有卷的情况
[root@VM_0_17_centos /]# docker volume ls
DRIVER VOLUME NAME
local 75f89bfb4c2ff392de15fa8896336e45c4b1792a976ce935c2f5200078e31f36
local 9589417d19a4c0d2febeed936b21c10898afe9b626ba37fe9f87b62bd1d38a90
local f327dc2fda1787f8f26c7483e6bc37e5dba9f626fdc97df2357f5af6271970fa
#这里发现,这种匿名挂载,我们在-v时,只写了容器内的路径,没有写容器外的路径。
#具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
[root@VM_0_17_centos /]# docker volume ls
DRIVER VOLUME NAME
local 75f89bfb4c2ff392de15fa8896336e45c4b1792a976ce935c2f5200078e31f36
local 9589417d19a4c0d2febeed936b21c10898afe9b626ba37fe9f87b62bd1d38a90
local f327dc2fda1787f8f26c7483e6bc37e5dba9f626fdc97df2357f5af6271970fa
local juming-nginx
所有Docker容器内的卷,没有指定目录的情况下,都会存在于/var/lib/docker/volumes/xxxxxx
/_data
通过具名挂载,可以在此处找到数据。
如何确定是具名挂载,还是匿名挂载,还是指定路径挂载?
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /容器外:容器内路径 #指定路径挂载
扩展:
#通过-V 容器内路径:ro 或者rw 改变读写权限
ro readonly #只读 这个路径只能通过宿主机来进行操作,容器内部就无法操作了。
rw readwrite #可读可写
#一旦设置了容器权限,容器对我们挂载的内容就有限定了
初识DockerFile
Dockerfile就是用来构建Docker镜像的构造文件!命令脚本!
通过这个脚本可以生成一个镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层。
#创建一个Dockerfile文件,名字可以随意,建议Dockerfile
#文件中的内容 指令都是大写的
FROM centos
VOLUME ["volume01","volume02"] #匿名挂载
CMD echo "----end----"
CMD /bin/bash
#这里的每一步都是镜像的一层
docker build -f dockerfile1 -t hjh/centos:1.0 .
docker inspect进入查看挂载目录,可编写测试文件测试。确认是否同步。
多个mysql同步数据!
数据卷容器
启动三个容器
#创建第一个数据卷容器
docker run -it --name docker01 hjh/centos:1.0
#创建第二个容器 --volumes-from通过这个参数就可以实现容器间的数据共享了
docker run -it --name docker02 --volumes-from docker01 hjh/centos:1.0
#进入数据卷创建test文件,确认两个容器互通
cd volume01
touch test.txt #发现数据互通,删除后一并删除。
#删除容器docker01之后发现依然docker02依然存在,并且可以访问。
以上测试的结果:--volumes-from参数 是以双向copy的机制完成的数据共享。
多个mysql实现数据共享
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 9cfcce23593a
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 --volumes-from mysql01 9cfcce23593a
#这时候,就可以实现2个容器数据同步了。
结论
容器之间配置信息的传递,容器的生命周期一直持续到没有容器使用为止。
但是一旦持久化到本地之后,这时候本地的数据是不会删除的。
DockerFile
dockerfile就是用来构建docker镜像的文件,命令参数脚本!
构建步骤:
1、编写一个dockerfile 文件
2、dockerbuild构建成为一个镜像
3、docker run运行镜像,生成容器
4、docker push 发布镜像(dockerhub、阿里云镜像仓库)
hub.docker.com网站上的镜像,都是由dockerFile创建的
选中某一个版本后,链接就会跳转到github上的dockerfile中。
很多官方的镜像包,都是基础包,很多功能都没有,需要自己搭建。
官方既然可以制作镜像,我们也可以制作。
DockerFile构建过程
基础知识:
1、每个保留关键字(指令)都必须是大写字母
2、指令是从上到下执行的
3、#表示注释
4、每一个指令,都会创建提交一个新的镜像层,并提交
dockerfile是面向开发的,以后要发布项目,做镜像,需要编写dockerfile文件,这个文件十分简单
Docker逐渐成为企业交付的标准,所以必须要掌握!
步骤:开发、部署、运维 缺一不可!
Dockerfile:构建文件,定义了一切步骤
Dockerimage:通过Dockerfile构建,生成的镜像,最终发布和运行的产品。原来是jar,war
Docker容器:容器就是镜像运行起来提供服务的。
DockerFile的指令
以前使用别人的,现在来自己练习写一个。
From #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的 ,一般留下姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤:tomcat镜像为例,tomcat压缩包就是要添加的内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录位置
EXPOSE #指定暴露的端口配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个生效,而且可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承的DockerFile 这个时候就会运行 ONBUILD的命令,出发命令
COPY #将文件copy到镜像中
ENV #构建的时候设置环境变量
实战测试
Docker Hub中的99%的镜像都是从 ==scratch==开始的,然后配置需要的软件和配置进行构建
#创建一个自己的centos
#1、编写dockerfile文件
FROM centos
MAINTAINER hujh<[email protected]>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "-----end----"
CMD /bin/bash
Successfully built c144f689b7c4
Successfully tagged mycentos:1.0
#2、通过这个文件构建镜像
# 命令 docker build -f dockerfile文件路径 -t 镜像名:【版本号】
#3、测试运行
之前官方的centos没有vim和net-tools等命令,通过dockerfile添加之后的镜像修改之后就可以使用了。
我们可以列出本地镜像的变更历史
平时那倒一个镜像,可以研究是怎么做的。
CMD #指定这个容器启动的时候要运行的命令,只有最后一个生效,而且可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
[root@VM_0_17_centos dockerfile]# vim dockerfile-cmd-test
--------------------------------------------------------------------------------
FROM centos
CMD ["ls","-a"]
---------------------------------------------------------------------------------------------
[root@VM_0_17_centos dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 470671670cac
Step 2/2 : CMD ["ls","-a"]
---> Running in 4d15635babb2
Removing intermediate container 4d15635babb2
---> fbc0ca213512
Successfully built fbc0ca213512
Successfully tagged cmdtest:latest
----------------------------------------------------------------------------------------
[root@VM_0_17_centos dockerfile]# docker run fbc0ca213512
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
docker run fbc0ca213512 -l 就会直接报错
如果使用ENTRYPOINT 就可以直接 -l
Dockerfile中很多命令十分相似,我们需要了解他们的区别,最好的学习方式就是对比他们测试方式
实战:Tomcat镜像
1、准备镜像文件 tomcat压缩包,jdk的压缩包!
2、编写dockerfile文件,官方明明 Dockerfile,build就会自动查找文件,不需要-f制定文件
FROM centos
MAINTAINER hjh<[email protected]>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u231-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.36.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_231
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.36
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.36
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.36/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.36/logs/catalina.out
~
~
~
~
3、构建镜像
docker build -t diytomcat .
4、启动镜像、生成容器
docker run -d -p 9090:8080 --name hjhtomcat03 -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.36/webapps/test -v /home/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.36/logs diytomcat
5、访问测试
ip:9090 进行访问
6、发布项目(由于做了卷挂载,就可以直接本地发布。)
发布镜像
#1、通过docker login登陆
[root@VM_0_17_centos tomcatconf]# docker login -u barryhu
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
#通过 docker tag 修改版本名称,作者信息
[root@VM_0_17_centos tomcatconf]# docker tag diytomcat:latest diytomcat:1.5
#通过docker push推送
[root@VM_0_17_centos tomcatconf]# docker push barryhu/diytomcat:1.5
发布阿里云镜像
1、登陆阿里云
2、根据提示做此操作
Docker网络
理解docker0
这三个网络
docker是如何处理网络访问的
容器启动时,会得到102: eth0@if103,这个是docker分配的
root@VM_0_17_centos ~]# docker exec -it 25360e9e7817 ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
102: eth0@if103: mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
linux能不能ping通容器内部?
[root@VM_0_17_centos ~]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.062 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.050 ms
linux可以ping通容器内部。
1、每启动一个docker容器,docker就会给容器分配一个IP,只要安装docker,就会有一个docker0的网卡,使用的是桥接模式,使用的技术是veth-pair技术.
2、在启动一个容器测试,发现又多了==一对==网卡。
我们发现容器带来的网卡都是一对一对的
veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段链接协议,一段彼此相连
正因为有这个特性,veth-pair可以充当桥梁,专门链接各种虚拟网络设备的
openstack,docker容器链接,ovs链接 都是使用 veth-pair技术
我们测试tomcat01和tomcat02是否ping通
[root@VM_0_17_centos ~]# docker exec -it tomcat02 ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.097 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.057 ms
容器与容器之间可以互相ping通
结论:tomcat01和tomcat02都是使用一个路由器,docker0
所有容器在不指定网络的情况下,都是使用docker0路由的,docker会给容器分配一个可用ip
255.255.0.1/16 共有65535个ip
Docker使用的是linux桥接模式,宿主机中,是一个docker容器的网桥,docker0,通信通过veth-pair连通。
docker中的所有网络接口都是虚拟的,虚拟的转发效率高。(内网传递原理)
只要对应的容器删除,对应的网桥就消失了。
思考一个场景:编写一个微服务,database url=ip:项目不重启,数据库IP换掉了,我们希望可以处理这个问题,通过名字访问
#通过 --link就可以解决连通问题
[root@VM_0_17_centos ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
3228fb9a442e4dc07325fcc36d47c2d4de29bf9513a52cedcc6ee77498d3618c
[root@VM_0_17_centos ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.18.0.3): icmp_seq=1 ttl=64 time=0.085 ms
64 bytes from tomcat02 (172.18.0.3): icmp_seq=2 ttl=64 time=0.058 ms
^C
#反向是否可以ping通?
#证明了反向不可以
[root@VM_0_17_centos ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
探究:
其实tomcat03 就是在本地配置了tomcat02的配置
查看tomcat03的hosts配置
[root@VM_0_17_centos ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3 tomcat02 56fd25e554cf #配置了host文件,把ip绑定了。
172.18.0.4 3228fb9a442e
--link的配置,原理就是添加tomcat02的映射
我们真实使用docker已经不推荐使用--link! 我们需要不适用docker0
docker0的问题:不支持容器名访问!
自定义网络
查看所有docker网络
网络模式:
bridge:桥接模式 搭桥(立交桥,天桥的形式)(自己创建也建议使用bride)
none:不配置网络
host:和宿主机共享网络
container:容器内网络连通(不建议使用,局限性很大)
#我们直接启动命令 --net bridge 默认参数
docker run -d -P --name tomcat01 --net bridge tomcat
#docker特点:默认。域名不能访问 --link打通!
#自定义网络
--driver bridge
--subnet 192.168.0.0/16 子网
--gateway 192.168.0.1 路由
[root@VM_0_17_centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
75b5a899336b0a8f825895720dd7a5d52479066c3a8a70b290e89aba58c5f7d9
[root@VM_0_17_centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
392f067ccdcb bridge bridge local
f7723aeb5bb0 host host local
75b5a899336b mynet bridge local
b7444fc6b9bb none null local
我们自己的网络就创建好了
#再次测试ping链接
[root@VM_0_17_centos ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.063 ms
^C
#现在不适用--link 也可以实现容器名互ping
[root@VM_0_17_centos ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.040 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.055 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.056 ms
^C
我们自定义的网络 docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用docker网络!
好处:
redis -不同的集群使用不同的网络,保证集群是安全健康的。
mysql -不同的集群使用不同的网络,保证集群是安全健康的。
网络连通
#测试打通tomcat01 -mynet
[root@VM_0_17_centos ~]# docker network inspect mynet
#连通之后将tomcat01 放到了mynet 网络下
#一个容器 2个ip! 阿里云服务器,公/私网
再次即可ping通。
结论:假设要跨网络操作别人,就需要docker network connect [网络名] [容器名]进行连通!
实战:部署redis集群
#1、创建网络
docker network create redis --subnet 172.38.0.0/16
#2、查看创建的网络是否存在
docker network ls
通过shell脚本生成redis相应配置文件
#循环6次
for port in $(seq 1 6); \
do \
#创建相关配置文件
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
#写入相关配置信息
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
#开始制作镜像
#-p外部访问端口暴露 --name容器名称
#-v 配置文件映射
#-d 后台运行
#--net 网络选择自己创建的redis网络
#--ip绑定ip号
#redis:5.0.9-alpine3.11 redis版本号
#redis-server /etc/redis/redis.conf 通过redis.conf启动
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf -d \
--net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建集群
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: d25022e665984fa719c26b0ab01279dc0c64e77b 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 536368935ba08be7d2ccc5000bfe6d9305361ccb 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 17b3d1309ddd707413753bf15e31a4afd717d47d 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: fd79d7aad5301138b11ef1c58d12b84f6d2ad8b0 172.38.0.14:6379
replicates 17b3d1309ddd707413753bf15e31a4afd717d47d
S: edc836a48fe536c45420bcbb5e3683059caf09ec 172.38.0.15:6379
replicates d25022e665984fa719c26b0ab01279dc0c64e77b
S: d4b0bc0ffb5ff8c79cc4e6d3bfb360a4b4b474bf 172.38.0.16:6379
replicates 536368935ba08be7d2ccc5000bfe6d9305361ccb
Can I set the above configuration? (type 'yes' to accept): yes
#测试集群
#进入容器
[root@VM_0_17_centos conf]# docker exec -it redis-1 /bin/sh
进入进群
/data # redis-cli -c
/data # set a b
在Docker stop相应储存进入的服务器后,关闭相应服务器,然后在get a
#一下内容表示集群搭建成功,3主3从
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
172.38.0.14:6379>
redis集群搭建成功~,13宕机, 14变成了新的master
我们使用了docker之后,所有的技术都会变得更简单起来!