目录
一、安装Docker
1. 安装必要的包
2. 设置镜像的仓库
3. 更新软件包的索引
4. 安装docker
5. 启动docker
6. 测试 hello-world
7. 查看的hello-world镜像
8. 卸载docker
9. 配置阿里云镜像加速
二、Docker 常用命令
镜像命令
(1)docker images
(2)docker search
(3)docker pull
(4)docker rmi -f
容器命令
(1)docker run
(2)docker ps
(3)exit
(4)docker rm
(5)docker start/stop/restart/kill
(6)docker inspect
(7)docker attach
(8)docker cp
三、Docker部署nginx
(1)搜索镜像
(2)拉取镜像
(3)查看镜像
(4)启动镜像
(5)查看容器
(6)测试访问
四、Docker 部署Tomcat
(1)搜索镜像
(2)拉取镜像
(3)查看镜像
(4)运行镜像
(5)查看容器
(6)测试访问
五、可视化工具 portainer
portainer
(1)安装
(2)访问测试
六、Docker 镜像
1. 简介
2. Docker镜像加载原理
UnionFS联合文件系统
Docker 镜像加载原理
分层理解
3. 提交镜像(commit)
七、容器数据卷
1. 简介
2. 使用数据卷
3. 安装 MySQL
(1)拉取镜像
(2)启动容器
(4)查看宿主机目录
4. 具名和匿名挂载
1. 匿名挂载
2. 具名挂载
5. 数据卷容器
八、Dockerfile
1. 简介
2. 查看官方镜像的 Dockerfile
3. Dockerfile 指令介绍
4. 实战测试
5. 制作 Tomcat 镜像
九、发布镜像
发布到 DockerHub
十、Docker流程总结
十一、Docker 网络
1. 清空环境
2. Docker0
3. 容器互联 --link
4. 网络模式
5. 自定义网络
十二、Redis集群部署
1. 新建 redis 网卡
2. 创建redis配置
3. 启动容器
4. 创建集群配置
5. 验证高可用
6. 验证负载均衡
本篇博客内容根据b站狂神说Docker教程记录,视频传送门: 狂神说Docker
一、安装Docker
1. 安装必要的包
[root@zy-host /]# yum install -y yum-utils device-mapper-persistent-data lvm2
2. 设置镜像的仓库
这里我们设置阿里云的镜像仓库
[root@zy-host /]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror
adding repo from: http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
grabbing file http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
3. 更新软件包的索引
[root@zy-host /]# yum makecache fast
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
base | 3.6 kB 00:00:00
docker-ce-stable | 3.5 kB 00:00:00
epel | 4.7 kB 00:00:00
extras | 2.9 kB 00:00:00
updates | 2.9 kB 00:00:00
4. 安装docker
[root@zy-host /]# yum install docker-ce docker-ce-cli containerd.io
查看版本信息
[root@zy-host /]# docker --version
Docker version 20.10.22, build 3a2c30b
5. 启动docker
[root@zy-host /]# systemctl start docker
6. 测试 hello-world
[root@zy-host /]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:94ebc7edf3401f299cd3376a1669bc0a49aef92d6d2669005f9bc5ef028dc333
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/
7. 查看的hello-world镜像
[root@zy-host /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 15 months ago 13.3kB
8. 卸载docker
(1)删除依赖
[root@zy-host /]# yum remove docker-ce docker-ce-cli containerd.io
(2)删除资源
[root@zy-host /]# rm -rf /var/lib/docker
9. 配置阿里云镜像加速
我使用的服务器是阿里云服务器,找到阿里云的容器镜像服务,地址容器镜像服务 (aliyun.com)
[root@zy-host /]# sudo mkdir -p /etc/docker
[root@zy-host /]# sudo tee /etc/docker/daemon.json <<-'EOF'
> {
> "registry-mirrors": ["https://g4z2eith.mirror.aliyuncs.com"]
> }
> EOF
{
"registry-mirrors": ["https://g4z2eith.mirror.aliyuncs.com"]
}
[root@zy-host /]# sudo systemctl daemon-reload
[root@zy-host /]# sudo systemctl restart docker
Docker 是怎么工作的?
Docker是一个CS架构的系统,Docker的守护进程运行在宿主机上,通过Socket从客户端访问,Docker-Sever接收到Docker-Client的指令,就会执行这个命令。
二、Docker 常用命令
官方文档地址:Reference documentation | Docker Documentation
镜像命令
(1)docker images
[root@zy-host /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 15 months ago 13.3kB
#解释
REPOSITORY #镜像的仓库源
TAG #镜像的标签
IMAGE ID #镜像的ID
CREATED #镜像的创建时间
SIZE #镜像的大小
#可选项
-a #列出所有镜像
-q #只显示镜像id
(2)docker search
网页搜索镜像:Docker Hub Container Image Library | App Containerization
命令行搜索:
[root@zy-host /]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 13652 [OK]
mariadb MariaDB Server is a high performing open sou… 5216 [OK]
(3)docker pull
下载镜像:
[root@zy-host /]# docker pull mysql
Using default tag: latest #默认最新版本
latest: Pulling from library/mysql
72a69066d2fe: Pull complete #分层下载
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 #签名
Status: Downloaded newer image
docker.io/library/mysql:latest #真实地址
#这俩等价
docker pull mysql
docker pull docker.io/library/mysql:latest
指定版本:
[root@zy-host /]# docker pull mysql:5.7
(4)docker rmi -f
删除镜像
[root@zy-host /]# docker rmi -f c20987f18b13
删除全部
[root@zy-host ~]# docker rmi -f $(docker images -a)
容器命令
注意:有了镜像才可以创建容器,下载一个centos镜像:
[root@zy-host ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
(1)docker run
新建一个容器并进入
常用参数如下:
-d:后台运行容器,并返回容器ID
-it:进入容器,交互运行
--name:给容器指定一个名称
-m:指定容器使用内存的最大值
-net:指定容器使用的网络类型
--link:链接到另一容器
-p:指定容器的端口
主机端口:容器端口(常用)
容器端口
Linux中控制台是在 /bin/bash中
[root@zy-host ~]# docker run -it centos /bin/bash
[root@06cf640f1bc2 /]#
容器内的 centOS
[root@06cf640f1bc2 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
(2)docker ps
列出在运行的容器
-a:列出所有容器,包括停止的
-f:根据条件过滤显示内容
-l:列出最近创建的容器
-n:列出最近创建的指定个数的容器
-q:只显示容器ID
-s:显示总文件大小
[root@zy-host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@zy-host ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06cf640f1bc2 centos "/bin/bash" 4 minutes ago Exited (1) 13 seconds ago naughty_mccarthy
c34f98cebb0e hello-world "/hello" 13 hours ago Exited (0) 13 hours ago wonderful_grothendieck
查看最近创建的一个容器
[root@zy-host ~]# docker ps -a -n 1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06cf640f1bc2 centos "/bin/bash" 5 minutes ago Exited (1) About a minute ago naughty_mccarthy
(3)exit
退出容器
Ctrl + P + Q 不停止退出
(4)docker rm
删除容器
删除指定容器:(运行的不能删除,可以加 -f 强制删除)
[root@zy-host ~]# docker rm 06cf640f1bc2
删除所有容器:
[root@zy-host ~]# docker rm -f $(docker ps -aq)
(5)docker start/stop/restart/kill
启动/停止/重启/杀掉 容器
(6)docker inspect
获取容器的元数据
(7)docker attach
进入容器正在执行的终端。
也可以用:docker exec(进入容器后开启一个新的终端)
[root@zy-host ~]# docker exec -it 06cf640f1bc2 /bin/bash
(8)docker cp
功能:用于容器与物理主机之间复制文件
从主机拷贝到容器:
[root@zy-host ~]# echo "拷贝测试">copy.txt
[root@zy-host ~]# cat copy.txt
拷贝测试
[root@zy-host ~]# docker cp /root/copy.txt 06cf640f1bc2:/
[root@zy-host ~]# docker attach 06cf640f1bc2
[root@06cf640f1bc2 /]# ls
bin copy.txt dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@06cf640f1bc2 /]# cat copy.txt
拷贝测试
从容器拷贝到主机:
[root@zy-host ~]# docker cp 06cf640f1bc2:/copy.txt /home
[root@zy-host ~]# ls /home
copy.txt
三、Docker部署nginx
(1)搜索镜像
[root@zy-host ~]# docker search nginx
(2)拉取镜像
[root@zy-host ~]# docker pull nginx
(3)查看镜像
[root@zy-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 12 months ago 141MB
(4)启动镜像
#名字zy-nginx
#端口映射:宿主机(8090)映射容器(80)
#镜像:nginx
[root@zy-host ~]# docker run -d --name zy-nginx -p 8090:80 nginx
4031b9eba2df4b626e86c72c69c4a97ed185ca0ac03b916c98291bda710f13ed
(5)查看容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4031b9eba2df nginx "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:8090->80/tcp, :::8090->80/tcp zy-nginx
(6)测试访问
服务器本地测试:
[root@zy-host ~]# curl http://localhost:8090
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
网页访问测试:
端口映射:
四、Docker 部署Tomcat
(1)搜索镜像
[root@zy-host ~]# docker search tomcat
(2)拉取镜像
[root@zy-host ~]# docker pull tomcat
(3)查看镜像
[root@zy-host ~]# docker images
(4)运行镜像
[root@zy-host ~]# docker run -d --name zy-tomcat -p 8888:8080 tomcat
(5)查看容器
[root@zy-host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ad622247622 tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp zy-tomcat
4031b9eba2df nginx "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 0.0.0.0:8090->80/tcp, :::8090->80/tcp zy-nginx
(6)测试访问
容器里webapps里面没有东西,所以访问404(这是因为镜像默认是最简版本)
[root@zy-host ~]# docker exec -it 75d8e820e046 /bin/bash
root@75d8e820e046:/usr/local/tomcat# ls
BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work
root@75d8e820e046:/usr/local/tomcat# cd webapps
root@75d8e820e046:/usr/local/tomcat/webapps# ls
root@75d8e820e046:/usr/local/tomcat/webapps#
解决方法:把webapps.dist内容拷贝到webapps下
root@75d8e820e046:/usr/local/tomcat# cp -r webapps.dist/* webapps
再次访问:
五、可视化工具 portainer
portainer
是一个Docker图形化管理工具,提供一个后台面板。
(1)安装
[root@zy-host ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
(2)访问测试
六、Docker 镜像
1. 简介
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含某个软件所需的所有内容,包括代码、库、环境变量和配置文件。所有的应用,可以直接打包docker镜像,就可以直接跑起来。
如何获取镜像:
(1)从远程仓库下载
(2)自己制作镜像
2. Docker镜像加载原理
UnionFS联合文件系统
UnionFS联合文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
我们pull 下载的时候,看到一层层的,就是这个。
[root@zy-host ~]# docker pull tomcat
Using default tag: latest#这里就是一层层的 pull
latest: Pulling from library/tomcat
0e29546d541c: Pull complete
9b829c73b52b: Pull complete
cb5b7ae36172: Pull complete
6494e4811622: Pull complete
668f6fcc5fa5: Pull complete
dc120c3e0290: Pull complete
8f7c0eebb7b1: Pull complete
77b694f83996: Pull complete
0f611256ec3a: Pull complete
4f25def12f23: Pull complete
Digest: sha256:9dee185c3b161cdfede1f5e35e8b56ebc9de88ed3a79526939701f3537a52324
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest
Docker 镜像加载原理
docker的镜像实际上由一层一层的文件系统组成这种层级的文件系统就是UnionFS。
分层理解
所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。
注意:
docker镜像都是只读的,容器启动时,一个新的可写层被加载到镜像的顶部。
这一层就是我们通常说的容器层,容器之下的都叫镜像层。
3. 提交镜像(commit)
docker commit 提交容器成为一个新的副本
docker commit -m="提交的信息" -a="作者" 容器id 目标镜像名:[TAG]
(1)从官方拉取 tomcat 镜像并启动
(2)在官方镜像启动的容器中,webapps下没有东西,我们把 webapps.dist的内容复制到 webapps下,我们所做的这个操作就是在容器层。然后我们把这个自定义的 tomcat 容器重新发布为镜像。命令如下:
[root@zy-host ~]# docker commit -m="my-tomcat-commit" -a="zhangyin" 75d8e820e046 zy-tomcat-image:V1.0.0
sha256:eff900203eae695b6a6eae53408c63052d294be340d2a4957c1401df129c872b
(3) 查看提交的镜像,可以看到镜像大小多了4M:
[root@zy-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zy-tomcat-image V1.0.0 eff900203eae 4 minutes ago 684MB
nginx latest 605c77e624dd 12 months ago 141MB
tomcat latest fb5657adc892 12 months ago 680MB
mysql latest 3218b38490ce 12 months ago 516MB
hello-world latest feb5d9fea6a5 15 months ago 13.3kB
centos latest 5d0da3dc9764 15 months ago 231MB
portainer/portainer latest 580c0e4e98b0 21 months ago 79.1MB
(4)运行我们自己提交的镜像,端口映射到宿主机的8081上
[root@zy-host ~]# docker run -d --name zy_tomcat_02 -p 8081:8080 zy-tomcat-image:V1.0.0
eb3b1296d057f492b307d78662e0acc9f3ff4df94a9867fb9d0edf3d5d984749
(5)网页访问测试
可以看到在8081端口可以正常显示tomcat的首页
七、容器数据卷
1. 简介
如果数据都放在容器中,如果容器被删除,数据就丢失了。为了将数据持久化,使用容器数据卷技术。将Docker 容器中产生的数据,同步到本地。也就是将容器内的目录挂载到宿主机的目录。
注意:容器间也是可以数据共享的。
2. 使用数据卷
方式一:使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
将宿主机的 /home/test 目录与 容器的 /home 挂载:
[root@zy-host ~]# docker run -it -v /home/test:/home centos /bin/bash
在容器的 /home 目录下新建一个 testfile.txt 文件:
[root@2b708cc94e25 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@2b708cc94e25 /]# cd home
[root@2b708cc94e25 home]# echo "测试目录是否挂载成功">testfile.txt
[root@2b708cc94e25 home]# ls
testfile.txt
在宿主机的 /home/test 目录下查看该文件是否同步过去:
[root@zy-host ~]# cd /home/test
[root@zy-host test]# ls
testfile.txt
[root@zy-host test]# cat testfile.txt
测试目录是否挂载成功
同样在宿主机的该文件夹下新建文件也会同步到容器的 /home中。
通过 docker inspect 查看挂载信息:
[root@zy-host test]# docker inspect 2b708cc94e25
"Mounts": [
{
"Type": "bind",
"Source": "/home/test",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
3. 安装 MySQL
考虑 MySQL 的数据持久化问题。
(1)拉取镜像
[root@zy-host test]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709
Status: Image is up to date for mysql:latest
docker.io/library/mysql:latest
(2)启动容器
端口映射到宿主机的3310端口,挂载两个目录,-e MYSQL_ROOT_PASSWORD=123456是配置MySQL的密码。
[root@zy-host ~]# 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 zy_mysql mysql:5.7
2bbd930643c108c5046e3eb4a55b46fc0d547dcba3d2245bc274c825db362b6b
(3)使用 Navicat 测试连接
端口是3310,显示连接成功。然后新建一个数据库 zy_test。
(4)查看宿主机目录
可见对应数据库文件已经同步到宿主机的 /home/mysql/data 中,这就完成了数据的持久化。
[root@zy-host data]# pwd
/home/mysql/data
[root@zy-host data]# ls
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem zy_test
如果把容器删了,对应的宿主机目录下的文件也不会丢失。
4. 具名和匿名挂载
1. 匿名挂载
-v 容器内路径
[root@zy-host data]# docker run -d -P --name nginx_01 -v /etc/nginx nginx
使用docker inspect 查看,可以看到默认挂载的宿主机的路径是:
"/var/lib/docker/volumes/ab90c532b86afc77afe7e86f33fcd92e289afede751bc1649f408665c0a81218/_data"
"Mounts": [
{
"Type": "volume",
"Name": "ab90c532b86afc77afe7e86f33fcd92e289afede751bc1649f408665c0a81218",
"Source": "/var/lib/docker/volumes/ab90c532b86afc77afe7e86f33fcd92e289afede751bc1649f408665c0a81218/_data",
"Destination": "/etc/nginx",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
进入该目录查看:
[root@zy-host _data]# pwd
/var/lib/docker/volumes/ab90c532b86afc77afe7e86f33fcd92e289afede751bc1649f408665c0a81218/_data
[root@zy-host _data]# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
2. 具名挂载
-v 卷名:容器内路径
[root@zy-host _data]# docker run -d -P --name nginx_02 -v juming_nginx:/etc/nginx nginx
5b9bb44a7bc7340d37a2cefbd055a892efba19e6d6fdf66300b6cd9857278fc3
使用 docker inspect 查看,可以看到挂载的宿主机的路径:
/var/lib/docker/volumes/juming_nginx/_data
"Mounts": [
{
"Type": "volume",
"Name": "juming_nginx",
"Source": "/var/lib/docker/volumes/juming_nginx/_data",
"Destination": "/etc/nginx",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
设置容器内部权限
#容器内部的 /etc/nginx 文件夹只读,不能修改
docker run -d -P --name nginx_02 -v juming_nginx:/etc/nginx:ro nginx
#容器内部的 /etc/nginx 文件夹只读,可以修改
docker run -d -P --name nginx_02 -v juming_nginx:/etc/nginx:rw nginx
5. 数据卷容器
容器和容器之间数据同步。
docker run -it --name my_tomcat_02 --volumes-from my_tomcat_01 tomcat
可以理解为 my_tomcat_02 继承于 my_tomcat_01
MySQL实现数据共享:
[root@zy-host ~]# 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 zy_mysql_01 mysql:5.7
[root@zy-host ~]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name zy_mysql_02 --volumes-from zy_mysql_01 mysql:5.7
八、Dockerfile
1. 简介
Dockerfile就是用来构建 docker 镜像的构建文件。
Docker 镜像的构建与定制,实际上就是构建和定制每一层的配置文件。我们可以把每一层的修改、安装、操作、构建命令都写入一个脚本,用这个脚本来构建和定制Dokcer镜像,这个脚本就是Dockerfile。
Docker 可以使用 Dockerfile 的内容来自动构建镜像。Dockerfile也是一个文件,其中有创建镜像和运行指令等一系列的命令,并且每行只支持一个运行命令。每一条命令构建一层,这条命令的内容就是描述如何构建该层。
2. 查看官方镜像的 Dockerfile
(1)在dockerhub上搜索 centos
(2)点击对应版本
3. Dockerfile 指令介绍
FROM #基础镜像,从这里开始构建
MAINTAINER #镜像是谁的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #例如 ADD jdk-8u162-linux-x64.tar.gz /usr/local/ (会自动解压)
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #指定暴露端口 跟 -p 一样
CMD #指定容器启动的时候要运行的命令,最右最后一个会生效(替换)
ENTRYPOINT #指定这个容器启动时要运行的命令,可以追加命令(追加)
ONBUILD #配置当前所创建的镜像作为其他新建镜像的基础镜像时,所执行的操
作命令。这个镜像创建后,如果其他镜像以这个镜像为基础,那么先会
执行这个镜像的ONBUILD命令。
COPY #类似ADD,将文件拷贝到镜像中
ENV #构建的时候设置环境变量
CMD 和 ENTRYPOINT的区别:
(1)CMD测试:
[root@zy-host docker]# vim dockerfile-cmd
FROM centos
CMD ["ls","-a"]
[root@zy-host docker]# docker build -f dockerfile-cmd -t cmd-test:v1.0 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 5d0da3dc9764
Step 2/2 : CMD ["ls","-a"]
---> Running in be77262e27cc
Removing intermediate container be77262e27cc
---> dcbc572de74d
Successfully built dcbc572de74d
Successfully tagged cmd-test:v1.0
[root@zy-host docker]# docker run -it dcbc572de74d
. .. .dockerenv bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
我们在docker run的时候,再加一个 -l 参数,就会报错:
[root@zy-host docker]# docker run a7261cd6e6c1 -l
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled
(2)ENTRYPOINT测试
ENTRY 不可被docker run 提供的参数覆盖
[root@zy-host docker]# vim dockerfile-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
#构建
[root@zy-host docker]# docker build -f dockerfile-entrypoint -t entry-test:V1.0 .
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos
---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in 61a19a15b9f9
Removing intermediate container 61a19a15b9f9
---> 049f36d02caf
Successfully built 049f36d02caf
Successfully tagged entry-test:V1.0
#加 -l 参数,发现没报错
[root@zy-host docker]# docker run 049f36d02caf -l
total 56
drwxr-xr-x 1 root root 4096 Jan 5 15:38 .
drwxr-xr-x 1 root root 4096 Jan 5 15:38 ..
-rwxr-xr-x 1 root root 0 Jan 5 15:38 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
4. 实战测试
自己创建一个 centos
(1)创建工作目录 /home/docker
[root@zy-host docker]# pwd
/home/docker
(2)查看基础centos的命令
可以看到 vim、clear、ifconfig等命令都没有
[root@zy-host docker]# docker run -it centos
[root@668e55dc24e1 /]# vim
bash: vim: command not found
[root@668e55dc24e1 /]# clear
bash: clear: command not found
[root@668e55dc24e1 /]# ifconfig
bash: ifconfig: command not found
(3)在基础centos镜像上增加功能,编写dockerfile文件
[root@zy-host docker]# vim zy-dockerfile
FROM centos:7
MAINTAINER zhangyin<1171900089@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH #进去容器后的工作目录
RUN yum -y install net-tools
RUN yum -y install clear
EXPOSE 80
CMD echo $MYPATH
CMD ECHO "---end---"
CMD /bin/bash
(4)通过dockerfile构建镜像
[root@zy-host docker]# docker build -f zy-dockerfile -t zy-centos:v1.0 .
(5)查看构建的镜像
[root@zy-host docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 3ec3bda8de1b 18 seconds ago 398MB
(6)启动构建的镜像
[root@zy-host docker]# docker run -it 3ec3bda8de1b
(7)查看ifconfig、clear命令
可见我们自己构建的镜像中包含 ifconfig命令。
[root@58ed4704deb2 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.9 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:09 txqueuelen 0 (Ethernet)
RX packets 8 bytes 656 (656.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
5. 制作 Tomcat 镜像
(1)准备镜像文件 tomcat压缩包,jdk压缩包,上传至 /home/tomcat目录下
[root@zy-host tomcat]# pwd
/home/tomcat
[root@zy-host tomcat]# ll
total 195500
-rw-r--r-- 1 root root 10371538 Jan 5 23:45 apache-tomcat-8.5.55.tar.gz
-rw-r--r-- 1 root root 189815615 Jan 5 23:46 jdk-8u162-linux-x64.tar.gz
(2)编写 dockerfile文件
vim Dockerfile,使用官方文件名,这样build的时候,会自动找这个文件
[root@zy-host tomcat]# vim Dockerfile
[root@zy-host tomcat]# cat Dockerfile
FROM centos
MAINTAINER zhangyin
#拷贝安装包 要求自动解压到 /usr/local目录下
ADD jdk-8u162-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.55.tar.gz /usr/local/
ADD index.jsp /usr/local/apache-tomcat-8.5.55/webapps/ROOT/
#config java and tomcat ENV
ENV JAVA_HOME /usr/local/jdk1.8.0_162
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55/
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
#config listen port of tomcat
EXPOSE 8080
#config startup command of tomcat
CMD /usr/local/apache-tomcat-8.5.55/bin/catalina.sh run
编写 index.jsp 文件:
[root@zy-host tomcat]# vim index.jsp
welcome to zy's tomcat server
(3)构建自己的镜像
[root@zy-host tomcat]# docker build -t zy_tomcat .
Sending build context to Docker daemon 200.2MB
Step 1/11 : FROM centos
---> 5d0da3dc9764
Step 2/11 : MAINTAINER zhangyin
---> Running in 3609eb121a83
Removing intermediate container 3609eb121a83
---> ce7412d3ad4b
Step 3/11 : ADD jdk-8u162-linux-x64.tar.gz /usr/local/
---> 735d6185bc52
Step 4/11 : ADD apache-tomcat-8.5.55.tar.gz /usr/local/
---> d650c35dfda6
Step 5/11 : ADD index.jsp /usr/local/apache-tomcat-8.5.55/webapps/ROOT/
---> adf8f934df5c
Step 6/11 : ENV JAVA_HOME /usr/local/jdk1.8.0_162
---> Running in 87b17a6df390
Removing intermediate container 87b17a6df390
---> f02061e054fb
Step 7/11 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
---> Running in 35270e6a0542
Removing intermediate container 35270e6a0542
---> e913b359e6a9
Step 8/11 : ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55/
---> Running in fd705d9bd675
Removing intermediate container fd705d9bd675
---> a20cee5f9341
Step 9/11 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
---> Running in 0f87eb5dbdfd
Removing intermediate container 0f87eb5dbdfd
---> bc04cb78e943
Step 10/11 : EXPOSE 8080
---> Running in e34485bd4778
Removing intermediate container e34485bd4778
---> 6dffad9497c9
Step 11/11 : CMD /usr/local/apache-tomcat-8.5.55/bin/catalina.sh run
---> Running in 7b045d73b93b
Removing intermediate container 7b045d73b93b
---> 43b48e54ac5a
Successfully built 43b48e54ac5a
Successfully tagged zy_tomcat:latest
(4)运行自定义的tomcat镜像
[root@zy-host tomcat]# docker run -it -p 8888:8080 zy_tomcat
(5)网页查看,访问8888端口
九、发布镜像
发布到 DockerHub
(1)注册账户
地址:Docker Hub
(2)登录
[root@zy-host ~]# docker login -u xxyin7
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
(3)给镜像打标签
[root@zy-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zy_tomcat latest 43b48e54ac5a 10 hours ago 630MB
[root@zy-host ~]# docker tag zy_tomcat xxyin7/zy-tomcat-01:v1.0
查看打好标签的镜像
[root@zy-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zy_tomcat latest 43b48e54ac5a 10 hours ago 630MB
xxyin7/zy-tomcat-01 v1.0 43b48e54ac5a 10 hours ago 630MB
(4)上传镜像到 Docker hub
[root@zy-host ~]# docker push xxyin7/zy-tomcat-01:v1.0
The push refers to repository [docker.io/xxyin7/zy-tomcat-01]
ada6d5b9f5e3: Pushed
f6a45e0ed8f4: Pushed
2783b006efc8: Pushing [=> ] 11.53MB/384.6MB
74ddd0ec08fa: Pushing [======> ] 28.91MB/231.3MB
十、Docker流程总结
十一、Docker 网络
1. 清空环境
为了方便测试,清空一下当前容器和镜像(非必须)
(1)清空容器
docker rm -f $(docker ps -aq)
(2)清空镜像
[root@zy-host ~]# docker rmi -f $(docker images -aq)
2. Docker0
ip addr查看,有三个网络:
lo:本机回环地址
eth0:阿里云内网地址
docker0:docker生成的网卡
[root@zy-host ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:0a:8e:fb brd ff:ff:ff:ff:ff:ff
inet 172.21.123.2/20 brd 172.21.127.255 scope global dynamic eth0
valid_lft 315223164sec preferred_lft 315223164sec
inet6 fe80::216:3eff:fe0a:8efb/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:a3:85:72:2e brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:a3ff:fe85:722e/64 scope link
valid_lft forever preferred_lft forever
docker 如何处理容器之间网络的访问?
(1)运行一个容器
[root@zy-host ~]# docker run -d -p 8081:8080 --name zy_tomcat01 tomcat
(2)docker inspect 查看
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "5d53c1211e2535b1b4821f7d02e8329174e6a85df731bd45cecc0ca7d01ddee1",
"EndpointID": "6ecf91f5d01471a6cf90ae86c5b9d06c0944aec917bdfb4af883de074975a15d",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
(3)使用宿主机 ping 容器的 IP地址
[root@zy-host ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.060 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
(4)再次查看 ip addr
[root@zy-host ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:0a:8e:fb brd ff:ff:ff:ff:ff:ff
inet 172.21.123.2/20 brd 172.21.127.255 scope global dynamic eth0
valid_lft 315222283sec preferred_lft 315222283sec
inet6 fe80::216:3eff:fe0a:8efb/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:a3:85:72:2e brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:a3ff:fe85:722e/64 scope link
valid_lft forever preferred_lft forever
83: vethc510cb3@if82: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 9e:b5:c7:63:b2:7a brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::9cb5:c7ff:fe63:b27a/64 scope link
valid_lft forever preferred_lft forever
83: vethc510cb3@if82
容器的网卡都是成对的, evth-pair 就是一对虚拟设备接口,是成对出现的。
图示:
Tomcat01 和 Tomcat02 共用的Docker0 路由器。
3. 容器互联 --link
[root@zy-host ~]# docker run -d -P --name zy_tomcat03 --link zy_tomcat02 tomcat
371e494927178d8c317f15ec10a7d2bddfe71e43ce87ebd5432773c3a3aff602
#查看zy_tomcat03 的hosts 配置,添加了 zy_tomcat02的配置
[root@zy-host ~]# docker exec -it zy_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.17.0.3 zy_tomcat02 8c07b542185a
172.17.0.4 371e49492717
4. 网络模式
bridge:桥接 docker(默认不指定使用的就是这个模式)
none:不配置网络
host:与宿主机共享网络
#这两个等价
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
5. 自定义网络
[root@zy-host ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 zynet
c95a7c3c97f739d32b84d678384022710cb7bec1aea07f8c1357cd276d8b5ab6
[root@zy-host ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
5d53c1211e25 bridge bridge local
010718f2df2f host host local
428bdf7d7822 none null local
c95a7c3c97f7 zynet bridge local
使用 docker network inspect 查看
[root@zy-host ~]# docker network inspect zynet
[
{
"Name": "zynet",
"Id": "c95a7c3c97f739d32b84d678384022710cb7bec1aea07f8c1357cd276d8b5ab6",
"Created": "2023-01-06T12:30:15.264882266+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
创建两个容器:
[root@zy-host ~]# docker run -d -P --name tomcat-net-01 --net zynet tomcat
c31a2cc2d241aafd2e9ec042989cd797b856563cbaba0815b29e0ba15dab5627
[root@zy-host ~]# docker run -d -P --name tomcat-net-02 --net zynet tomcat
945039e3b47b0b1ea5bacc7291af5d413f353d44703e72aa66dc43e1d9022cb7
[root@zy-host ~]# docker network inspect zynet
[
{
"Name": "zynet",
"Id": "c95a7c3c97f739d32b84d678384022710cb7bec1aea07f8c1357cd276d8b5ab6",
"Created": "2023-01-06T12:30:15.264882266+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"945039e3b47b0b1ea5bacc7291af5d413f353d44703e72aa66dc43e1d9022cb7": {
"Name": "tomcat-net-02",
"EndpointID": "7c271d196dca48bfa30f12a55bc080002b2b3a1a762c9998923c3c03a3e91abf",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"c31a2cc2d241aafd2e9ec042989cd797b856563cbaba0815b29e0ba15dab5627": {
"Name": "tomcat-net-01",
"EndpointID": "91b0a7dcb7d697ad6290dd1404038fef535909037966701bc8bb20f1a3d6c4b3",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
自定义的网络可以容器之间可以连接成功,不用使用 --link。
十二、Redis集群部署
1. 新建 redis 网卡
[root@zy-host ~]# docker network create redis --subnet 172.38.0.0/16
cd5c78a824cd0e642c74fd878412c56fc4bd0d19ad5970f6d7f11bc1ea37ee43
[root@zy-host ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
5d53c1211e25 bridge bridge local
010718f2df2f host host local
428bdf7d7822 none null local
cd5c78a824cd redis bridge local
c95a7c3c97f7 zynet bridge local
2. 创建redis配置
把下面内容复制到命令行执行:
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
创建后查看:
[root@zy-host redis]# pwd
/mydata/redis
[root@zy-host redis]# ls
node-1 node-2 node-3 node-4 node-5 node-6
[root@zy-host conf]# pwd
/mydata/redis/node-1/conf
[root@zy-host conf]# cat 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.11
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
3. 启动容器
[root@zy-host /]# docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
6504c9f5dd333156e2216392aaed7f9bfe3b1fc87678aa6214147112ee8a8184
启动6个:
[root@zy-host /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3bc3748e1147 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 0.0.0.0:6376->6379/tcp, :::6376->6379/tcp, 0.0.0.0:16376->16379/tcp, :::16376->16379/tcp redis-6
1e9b1e2a3113 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 30 seconds ago Up 29 seconds 0.0.0.0:6375->6379/tcp, :::6375->6379/tcp, 0.0.0.0:16375->16379/tcp, :::16375->16379/tcp redis-5
1eafe4f99a8b redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 49 seconds ago Up 48 seconds 0.0.0.0:6374->6379/tcp, :::6374->6379/tcp, 0.0.0.0:16374->16379/tcp, :::16374->16379/tcp redis-4
6130d3316d20 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:6373->6379/tcp, :::6373->6379/tcp, 0.0.0.0:16373->16379/tcp, :::16373->16379/tcp redis-3
9469494cd922 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:6372->6379/tcp, :::6372->6379/tcp, 0.0.0.0:16372->16379/tcp, :::16372->16379/tcp redis-2
6504c9f5dd33 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:6371->6379/tcp, :::6371->6379/tcp, 0.0.0.0:16371->16379/tcp, :::16371->16379/tcp redis-1
4. 创建集群配置
进入redis-1 容器进行集群配置,可以看到配置了3个主机3个从机。
[root@zy-host /]# docker exec -it redis-1 /bin/sh
/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: 4834f2bc955b4a94bf6f1e92da97bfdffaa8313f 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 5cd79157095dcc63d326bc2d51add6988ad584e8 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 112b009acf734fb8497ed175f3e09e54b08b340a 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 1b278103aae14a47fc3f915d4213545a539ca31b 172.38.0.14:6379
replicates 112b009acf734fb8497ed175f3e09e54b08b340a
S: 2f63a62e3f69e45cadfb6f50f6fd396c04ddcde2 172.38.0.15:6379
replicates 4834f2bc955b4a94bf6f1e92da97bfdffaa8313f
S: 0e07890fcc7768b4781eb8d53eb5707a488ac5d6 172.38.0.16:6379
replicates 5cd79157095dcc63d326bc2d51add6988ad584e8
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 4834f2bc955b4a94bf6f1e92da97bfdffaa8313f 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 112b009acf734fb8497ed175f3e09e54b08b340a 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 0e07890fcc7768b4781eb8d53eb5707a488ac5d6 172.38.0.16:6379
slots: (0 slots) slave
replicates 5cd79157095dcc63d326bc2d51add6988ad584e8
S: 2f63a62e3f69e45cadfb6f50f6fd396c04ddcde2 172.38.0.15:6379
slots: (0 slots) slave
replicates 4834f2bc955b4a94bf6f1e92da97bfdffaa8313f
M: 5cd79157095dcc63d326bc2d51add6988ad584e8 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 1b278103aae14a47fc3f915d4213545a539ca31b 172.38.0.14:6379
slots: (0 slots) slave
replicates 112b009acf734fb8497ed175f3e09e54b08b340a
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
查看集群信息:
/data # redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:162
cluster_stats_messages_pong_sent:165
cluster_stats_messages_sent:327
cluster_stats_messages_ping_received:160
cluster_stats_messages_pong_received:162
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:327
三主机三从机:
127.0.0.1:6379> cluster nodes
112b009acf734fb8497ed175f3e09e54b08b340a 172.38.0.13:6379@16379 master - 0 1672983332000 3 connected 10923-16383
0e07890fcc7768b4781eb8d53eb5707a488ac5d6 172.38.0.16:6379@16379 slave 5cd79157095dcc63d326bc2d51add6988ad584e8 0 1672983331000 6 connected
4834f2bc955b4a94bf6f1e92da97bfdffaa8313f 172.38.0.11:6379@16379 myself,master - 0 1672983330000 1 connected 0-5460
2f63a62e3f69e45cadfb6f50f6fd396c04ddcde2 172.38.0.15:6379@16379 slave 4834f2bc955b4a94bf6f1e92da97bfdffaa8313f 0 1672983332485 5 connected
5cd79157095dcc63d326bc2d51add6988ad584e8 172.38.0.12:6379@16379 master - 0 1672983331484 2 connected 5461-10922
1b278103aae14a47fc3f915d4213545a539ca31b 172.38.0.14:6379@16379 slave 112b009acf734fb8497ed175f3e09e54b08b340a 0 1672983331000 4 connected
5. 验证高可用
执行set命令,在redis中存值,可以看到这个值存到了 172.38.0.13的主机里面。
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
现在把13这台主机停了,验证 get a 是否还能拿到值:
[root@zy-host ~]# docker stop redis-3
redis-3
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
可以看到从172.38.0.14的从机中拿到值了。
查看集群节点:
6. 验证负载均衡
可以看到存的值会分配到不同的节点中。
172.38.0.14:6379> set name zhangyin
-> Redirected to slot [5798] located at 172.38.0.12:6379
OK
172.38.0.12:6379> set sex "男"
-> Redirected to slot [2584] located at 172.38.0.11:6379
OK