安装Docker
安装
帮助文档
# 1. 卸载旧的版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2. 需要的安装包
yum install -y yum-utils
# 3. 设置镜像仓库
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外的
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 推荐使用阿里云镜像
# 更新软件包索引
yum makecache fast
# 4. 安装docker docker-ce 社区 ee 企业版
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 5. 启动docker
systemctl start docker
# 6. 查看docker是否安装成功
docker version
# 7. hello-world
docker run hello-world
# 8. 查看一下下载的这个 hello-world镜像
[root@centos-liunx-7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 12 months ago 13.3kB
了解: 卸载docker
# 1. 卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 2. 删除资源
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
# /var/lib/docker docker的默认工作路径
阿里云镜像加速
- 打开阿里云,找到镜像容器服务
- 找到镜像加速器
配置使用
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://7ux125dt.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
回顾HelloWorld流程
底层原理
Docker是怎么工作的?
Docker是一个Client - Server结构的系统,Docker的守护进程运行在主机上.通过Scoket从客户端访问!
Docker为什么比VM快?
- Docker有着比虚拟机更少的抽象层
- docker利用的是宿主机的内核, vm需要Guest OS
所以说,新建一个容器的时候,docker不需要向虚拟机一样重新加载一个操作系统内核,避免引导.虚拟机是加载Guest OS,分钟级别的,而docker是利用 宿主机的操作系统,省略了这个复杂的过程,秒级!
Docker的常用命令
帮助命令
docker version # 显示docker的版本信息
docker info # docker的系统信息,包裹镜像和容器的数量
docker 命令 --help # 万能命令
帮助文档的地址: https://docs.docker.com/engine/reference/commandline/docker/
镜像命令
docker images 查看所有本地的主机上的镜像
[root@centos-liunx-7 /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 12 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATE 镜像的创建时间
SIZE 镜像的大小
# 可选项
-a, --all 显示所有镜像
-q, --quiet 只显示镜像的ID
docker search 镜像的搜索命令
# docker search 镜像名称
[root@centos-liunx-7 /]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 13234 [OK]
mariadb MariaDB Server is a high performing open sou… 5062 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 640 [OK]
percona Percona Server is a fork of the MySQL relati… 588 [OK]
bitnami/mysql Bitnami MySQL Docker Image 77 [OK]
# 可选项
-f stars=3000 # 搜索出来的镜像就是stars大于3000的
[root@centos-liunx-7 /]# docker search mysql -f stars=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 13234 [OK]
mariadb MariaDB Server is a high performing open sou… 5062 [OK]
下载镜像 docker pull
# 下载镜像 docker pull 镜像名[:tag]
[root@centos-liunx-7 /]# docker pull mysql
Using default tag: latest # 如果不写 tag,默认就是latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete # 分层下载,docker image的核心 联合文件系统
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 for mysql:latest
docker.io/library/mysql:latest # 真实地址
# 等价于它
docker pull mysql 等价于 docker pull docker.io/library/mysql:latest
# 指定版本下载
[root@centos-liunx-7 /]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists
93619dbc5b36: Already exists
99da31dd6142: Already exists
626033c43d70: Already exists
37d5d7efb64e: Already exists
ac563158d721: Already exists
d2ba16033dad: Already exists
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
docker rmi 删除镜像
[root@centos-liunx-7 /]# docker rmi -f 镜像ID # 删除指定的容器
[root@centos-liunx-7 /]# docker rmi -f 镜像ID 容器ID 容器ID # 删除多个容器
[root@centos-liunx-7 /]# docker rmi -f $(docker images -aq) # 删除全部的容器
容器命令
说明: 我们有了镜像才可以创建容器,linux,下载一个centos镜像来测试学习
docker pull centos
新建容器并启动
docker run [可选参数] image
# 参数说明
--name="Name" 容器名字 tomcat01 tomcat02,用来区分容器
-d 后台方式运行
-it 使用交互方式运行
-p 指定容器端口 -p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口 (常用)
-p 容器端口
容器端口
-P 随机指定端口
# 测试,启动并进入容器
[root@centos-liunx-7 /]# docker run -it centos /bin/bash
[root@ab7ab1d9dc9b /]# ls # 查看容器内的centos,基础版本,很多命令是不完善的
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 从容器中退回主机
[root@ab7ab1d9dc9b /]# exit
exit
[root@centos-liunx-7 /]# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
列出所有的运行中的容器
# docker ps 命令
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器+带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号
[root@centos-liunx-7 /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab7ab1d9dc9b centos "/bin/bash" 6 minutes ago Exited (0) 2 minutes ago frosty_feistel
e19001022375 feb5d9fea6a5 "/hello" About an hour ago Exited (0) About an hour ago romantic_antonelli
退出容器
exit # 直接容器停止并退出
ctrl + p + q # 容器不停止退出
删除容器
docker rm 容器id # 删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -a -q|xargs docker rm # 删除所有的容器
启动和停止容器的操作
docker start 容器ID # 启动容器
docker restart 容器ID # 重启容器
docker stop 容器ID # 停止当前正在运行的容器
docker kill 容器ID # 强制停止当前容器
常用其他命令
后台启动容器
# 命令 docker run -d 镜像名!
[root@centos-liunx-7 ~]# docker run -d centos
# 问题docker ps,发现 centos 停止了
# 常见的坑: docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# nginx,容器启动后,发现自己没有提供服务,就会立刻定制,就是没有程序了
查看日志命令
docker logs -f -t -n 条数 容器ID
-t 显示日期+时间
-n 10 显示最近10条
查看容器中的进程信息 ps
# 命令 docker top 容器ID
[root@centos-liunx-7 ~]# docker top 293933b1a937
UID PID PPID C STIME TTY TIME CMD
root 5269 5251 0 11:46 pts/0 00:00:00 /bin/bash
[root@centos-liunx-7 ~]
查看镜像的元数据
# 命令 docker inspect 容器id
# 测试
[root@centos-liunx-7 ~]# docker inspect 293933b1a937
[
{
"Id": "293933b1a937a488e012418414479f162d5b6bec3c01d054f4f30296f2ec9f23",
"Created": "2022-10-02T03:46:19.579531063Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 5269,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-10-02T03:46:19.862987449Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/293933b1a937a488e012418414479f162d5b6bec3c01d054f4f30296f2ec9f23/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/293933b1a937a488e012418414479f162d5b6bec3c01d054f4f30296f2ec9f23/hostname",
"HostsPath": "/var/lib/docker/containers/293933b1a937a488e012418414479f162d5b6bec3c01d054f4f30296f2ec9f23/hosts",
"LogPath": "/var/lib/docker/containers/293933b1a937a488e012418414479f162d5b6bec3c01d054f4f30296f2ec9f23/293933b1a937a488e012418414479f162d5b6bec3c01d054f4f30296f2ec9f23-json.log",
"Name": "/romantic_cohen",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": [
"d959bc38ccb4a8f5f7f048538a5683e29f9091d6c7a2662b8afd0e207fdc93f8",
"9b3b78add31342988b556a4f1d50dab6e343e01922bf2d0d630cf57552c21d21"
],
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/c6552c7ff8fbafce9987c79b65f8007433b054ec7d7718627b036db45665f2e3-init/diff:/var/lib/docker/overlay2/d60d4305d3caf9a7a1b2b1a4f8cea9d0972e6672ea996ea443730d0f414b2147/diff",
"MergedDir": "/var/lib/docker/overlay2/c6552c7ff8fbafce9987c79b65f8007433b054ec7d7718627b036db45665f2e3/merged",
"UpperDir": "/var/lib/docker/overlay2/c6552c7ff8fbafce9987c79b65f8007433b054ec7d7718627b036db45665f2e3/diff",
"WorkDir": "/var/lib/docker/overlay2/c6552c7ff8fbafce9987c79b65f8007433b054ec7d7718627b036db45665f2e3/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "293933b1a937",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20210915",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "da5bbf74792f2eb5e8ad6160bb67301616f79f8f2424b19171d7ee5e8582553d",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/da5bbf74792f",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "a274ca41faf2a0e7dae8088cb5c78862a090d39535ec91c4eae676837be0a3a7",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "1db544b9e9042fcde5347650f180de98bc17f8499545c386ccc2bd19507e420f",
"EndpointID": "a274ca41faf2a0e7dae8088cb5c78862a090d39535ec91c4eae676837be0a3a7",
"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
}
}
}
}
]
[root@centos-liunx-7 ~]#
进入当前正在运行的容器
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
docker exec -it 容器id bashShell
# 测试
[root@centos-liunx-7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
293933b1a937 centos "/bin/bash" 22 minutes ago Up 22 minutes romantic_cohen
[root@centos-liunx-7 ~]# docker exec -it 293933b1a937 /bin/bash
[root@293933b1a937 /]# ps
PID TTY TIME CMD
50 pts/3 00:00:00 bash
64 pts/3 00:00:00 ps
[root@293933b1a937 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@293933b1a937 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:46 pts/0 00:00:00 /bin/bash
root 20 0 0 04:01 pts/1 00:00:00 /bin/bash
root 36 0 0 04:02 pts/2 00:00:00 /bin/bash
root 50 0 0 04:08 pts/3 00:00:00 /bin/bash
root 66 50 0 04:08 pts/3 00:00:00 ps -ef
# 方式二
docker attach 容器ID
# 测试
[root@centos-liunx-7 ~]# docker attach 293933b1a937
正在执行当前的代码...
# docker exec # 进入容器后开启一个新的终端,可以在里面操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的的主机路径
# 测试
[root@centos-liunx-7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
293933b1a937 centos "/bin/bash" 2 hours ago Up 1 second romantic_cohen
# 进入当前正在运行的容器
[root@centos-liunx-7 ~]# docker attach 293933b1a937
# 创建一个文件
[root@293933b1a937 /]# touch test.java
# 查看目录
[root@293933b1a937 /]# ls
bin etc lib lost+found mnt proc run srv test.java usr
dev home lib64 media opt root sbin sys tmp var
# 退出容器
[root@293933b1a937 /]# exit
exit
# 从容器中拷贝文件到宿主机目录中
[root@centos-liunx-7 ~]# docker cp 293933b1a937:/test.java /
[root@centos-liunx-7 ~]# cd /
# 查看宿主机目录
[root@centos-liunx-7 /]# ls
bin dev home lib64 mnt proc run srv test.java usr
boot etc lib media opt root sbin sys tmp var
[root@centos-liunx-7 /]#
# 拷贝是一个手动过程,未来我们使用 -v卷的技术,可以实现
将宿主机的文件拷贝到容器中:docker cp 宿主机路径 容器编号:容器路径
docker cp /javadxy/software/apache-tomcat-8.5.20/webapps tomcat1:/usr/local/tomcat/
重要
学习方式: 将上课的内容自己敲一遍,记录笔记
作业练习
部署Nginx
# 1. 搜索镜像 search #推荐使用hub.docker.com搜索镜像,docker hub中有详细的帮助文档和命令
[root@centos-liunx-7 ~]# docker search nginx
# 2. 下载镜像
[root@centos-liunx-7 ~]# docker pull nginx
# 3. 通过镜像运行容器
[root@centos-liunx-7 ~]# docker run -d -it --name nginx01 -p 5000:80 nginx
-d 后台运行
-it 交互模式
--name 给容器命名
-p 宿主机端口:容器端口 指定端口号
# 4. 验证nginx是否启动成功
浏览器访问 宿主IP:5000
如果是使用阿里云服务器的需要把阿里云5000端口放行
思考: 我们每次需要修改Nginx配置文件的时候都需要进入容器去修改,可以不可以直接在宿主机中直接修改一个文件,容器中的配置文件也会跟着改变?
部署Tomcat
# 官方的使用
$ docker run -it --rm tomcat:9.0
--rm # 在退出tomcat之后会将这个容器删除,一般用于测试
# 1. 搜索镜像
[root@centos-liunx-7 ~]# docker search tomcat
# 2. 下载镜像
[root@centos-liunx-7 ~]# docker pull tomcat:8.5 # 指定版本号下载
# 3. 通过镜像运行容器
[root@centos-liunx-7 ~]# docker run -d --name tomcat02 -p 8081:8080 tomcat:8.5
# 4. 测试Tomcat是否启动成功
浏览器访问 宿主IP:8081
# 发现问题,页面404,少了linux命令
# 因为阿里镜像的原因,它保证这个镜像可运行,保证镜像最小
# 页面404是因为webapps文件夹内没有文件
# 将webapps.dist中的文件拷贝到webapps中,在刷新网页
[root@centos-liunx-7 ~]# docker exec -it tomcat02 /bin/bash
root@492a85fba570:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@492a85fba570:/usr/local/tomcat# cd webapps.dist/
root@492a85fba570:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@492a85fba570:/usr/local/tomcat/webapps.dist# cd ../
root@492a85fba570:/usr/local/tomcat# cd webapps
root@492a85fba570:/usr/local/tomcat/webapps# ls
root@492a85fba570:/usr/local/tomcat/webapps# cd ../
root@492a85fba570:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@492a85fba570:/usr/local/tomcat# cd webapps
root@492a85fba570:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
root@492a85fba570:/usr/local/tomcat/webapps
思考问题: 我们每次部署Tomcat项目的时候也要进入到容器内部去部署项目,十分的麻烦.有没有一种技术,修改宿主机文件,容器内部的文件自动同步?
可视化
- portainer(先用这个)
docker run -d -p 8088:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
- Rancher(CI/CD再用)
Portainer
- 使用ip:8088进入
- 设置密码
- 选择本地
- 进入面板
镜像原理之分层理解
- 我们从Docker Hub下载的镜像是只读的
- 在使用镜像启动容器之后,我们在基于容器之后的操作(比如修改了某些文件),可以理解成在容器上面加了一层,你的每一个操作,都是在这个容器之上叠加,这个就是镜像之联合文件系统
镜像原理之文件联合系统
- 容器都是基于宿主机的内核启动的
- 比如我们下载一个mysql(有6层)
- 我们在下载一个redis,可能redis也有6层,而redis的前两层和刚才下载mysql的前两层是一样的
- Docker 就会复用mysql的前两层文件就不会再去下载
Commit镜像
## 使用Tomcat镜像启动容器
[root@centos-liunx-7 ~]# docker run -it -d -p 8080:8080 tomcat:8.5
## 发现webapps中没有文件
[root@centos-liunx-7 ~]# docker exec -it 2883d64efa26 /bin/bash
root@2883d64efa26:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@2883d64efa26:/usr/local/tomcat# cd webapps
root@2883d64efa26:/usr/local/tomcat/webapps# ls
## 将webapps.dist中的文件复制到webapps中
root@2883d64efa26:/usr/local/tomcat/webapps# cd ../
root@2883d64efa26:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@2883d64efa26:/usr/local/tomcat# ls webapps
ROOT docs examples host-manager manager
root@2883d64efa26:/usr/local/tomcat#
## 这个时候我们以后都想使用这个镜像运行,就要提交镜像
[root@centos-liunx-7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2883d64efa26 tomcat:8.5 "catalina.sh run" 5 minutes ago Up 5 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp kind_swanson
## 提交镜像
## docker commit -m="提交的消息 webapps app" -a="作者" 容器id 容器名称:版本号
[root@centos-liunx-7 ~]# docker commit -m="add webapps app" -a="yiyu" 2883d64efa26 tomcat:1.0
sha256:53fb07d89492a1afd6fe1097252122e2b6a1a658adaa9157aecef0bbe4687e3b
[root@centos-liunx-7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 1.0 53fb07d89492 2 seconds ago 683MB
nginx latest 605c77e624dd 9 months ago 141MB
tomcat 8.5 2d2bccf89f53 9 months ago 678MB
tomcat latest fb5657adc892 9 months ago 680MB
mysql latest 3218b38490ce 9 months ago 516MB
centos latest 5d0da3dc9764 12 months ago 231MB
portainer/portainer latest 580c0e4e98b0 18 months ago 79.1MB
[root@centos-liunx-7 ~]#
-a="作者"
-m="提交的消息"
这个时候我们就可以使用提交好的镜像去启动一个容器,而且启动后的容器中的tomcat是有主页面的
容器数据卷
什么是容器数据卷?
当我们使用mysql镜像创建了一个容器,之后把容器删除之后,那么我们容器中的数据就丢失了.这个时候我们可以使用数据卷,将容器内的数据和本地数据连接起来,当容器中数据改变或者本地数据改变的时候,它们都会自动同步
使用容器数据卷
## 命令 docker run -d -it -v 宿主机目录:容器内部目录
[root@centos-liunx-7 home]# docker run -d -it -v /home/ceshi:/home centos
## 查看是否挂载成功
[root@centos-liunx-7 home]# docker inspect 容器id
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
# 如果元数据中Mounts数组中有数据,表示挂载成功了
# 测试
# 在容器内部home目录下创建的文件,在宿主机/home/ceshi目录也会同步出来
# 反之,在/home/ceshi目录下创建或操作的文件,也会同步到容器内部
注意: 就算容器被关闭,在宿主机/home/ceshi目录下创建的文件依旧会同步到容器内部
实战: 安装MySQL
# 下载镜像
docker pull mysql
# 启动
# 官方的启动命令 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 我们的启动命令
-it 交互模式
-d 后台运行
-v 数据卷挂载
-e 环境配置
--name 给容器命名
[root@centos-liunx-7 ceshi]# docker run -it -d -p 3310:3306 -v /home/mysql/data:/var/lib/mysql -v /home/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
使用Navicat连接MYSQL并创建一个数据库,linux中的数据也会随之改变
当我们删除容器时,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化
具名挂载和匿名挂载
# 命令 具名挂载
# docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx nginx
-P 随机端口
[root@centos-liunx-7 data]# docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx nginx
df0f46eecd648da7709792285d70b58146c8885aab22e4bf8bd585b5e9208ed4
[root@centos-liunx-7 data]# docker volume ls
DRIVER VOLUME NAME
local 7bd9c653cd464bd8dc902b0f70b97d09a3ce6d0db5de9ac874c6072a877b8920
local 51b6c469889451450ba07cf2a781dc1c34955a0c3f3e3aa251614c41f7319e85
local 735e477cfb34b3113a458940dc3ba47db0b3ccb73d2be80f24f4bef7488115a7
local b4e659a7be46bf56c07f131c647a69b9bb3d568bbe52b3ee8fc8495f31d0a1c0
local e29d1ac89192283e4ffc5c0e9d4bf8ac19740a1c8655be3a80673bde3e6d199a
local juming-nginx
# 查看卷 docker volume ls
# 查看卷数据 docker volume inspect 卷名称
[root@centos-liunx-7 data]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-10-02T21:21:28+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
[root@centos-liunx-7 data]#
# 如何查看是具名挂载和匿名挂载,还是指定路径挂载
-v 卷名称:容器内路径 # 具名挂载
-v 容器内路径 # 匿名挂载
-v 宿主机路径:容器内路径 # 指定路径挂载
默认的挂载路径为 /var/lib/docker/volumes/xxxxx/_data
扩展
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx01 -v juming-nginx:/etc/nginx:rw nginx
# ro readonly #只读
# rw readwrite #可读可写
# 在只读的情况下不能在容器内容修改文件,只能在容器外修改
# 默认是rw(可读可写)
初识Dockerfile
Dockerfile就是用来构建docker镜像的构建文件!可以理解成一个命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本中一个个的命令,每个命令都是一层!
# 创建一个dockerfile文件,名字可以随机,建议 Dockerfile
# 文件中的内容 命令(是大写的)
FROM centos
VOLUME ["volume1","volume2"]
CMD echo "----end----"
CMD /bin/bash
命令 构建
[root@centos-liunx-7 docker-volumn-file]# docker build -f dockerfile1 -t yiyu/centos:1.0 .
-f Dockerfile文件的路径
-t 镜像名称:版本号
.构建到当前docker
使用我们自己构建的镜像创建容器
[root@centos-liunx-7 docker-volumn-file]# docker run -it 9662d35446d3 /bin/bash
[root@86f89bc561de /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume1 volume2
# 发现多了2个文件夹,这两个文件夹就是我们在构建镜像时创建的数据卷
# 使用命令 docker inspect 容器id 查看容器元数据发现已经自动挂载好了(匿名挂载)
这就实现了我们在创建容器时自动挂载数据卷,而不用使用 -v 命令手动挂载
数据卷容器
# 命令 --volumes-from 父容器id
使用刚才构建的镜像创建两个容器并在第二个容器数据卷中创建文件,第一个容器中的数据卷会自动同步
拷贝机制
多个mysql实现数据共享
[root@centos-liunx-7 ceshi]# docker run -it -d -p 3310:3306 -v /var/lib/mysql -v /etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
[root@centos-liunx-7 ceshi]# docker run -it -d -p 3310:3306 --volumes-from mysql01 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql
# 这个时候,可以实现两个容器数据共享
DockerFile
DockerFile的指令
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤: 添加其他镜像到DockerFile中. 压缩包
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFIle 这个时候会运行 ONBUILD 的指令. 触发指令
COPY # 类似ADD, 将我们的文件拷贝到镜像中
ENV # 构建的时候设置环境变量!
实战测试
创建自己的centos
[root@centos-liunx-7 dockerfile-work]# cat mydockerfile-centos
FROM centos
MAINTAINER yiyu<318334629@qq.com>
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
#构建命令
docker build -f dockerfile文件路径 -t 镜像名称: .
遇到问题: vim和net-tools安装失败
# 运行自己构建的centos
[root@centos-liunx-7 dockerfile-work]# docker run -it mycentos:0.1
[root@5a47d68eaf04 local]# pwd
/usr/local
[root@5a47d68eaf04 local]# ls
bin etc games include lib lib64 libexec sbin share src
# 可以看到运行后的工作路径是/usr/local,说明上面写的命令是没问题的
实战:Tomcat镜像
- 准备镜像文件 tomcat 压缩包,jdk的压缩包
编写dockerfile文件,官方命名
Dockerfile
,build会自动寻找这个文件FROM centos MAINTAINET yiyu<318334629@qq.com> COPY readme.txt /usr/local/readme.txt ADD jdk-8u341-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.67.tar.gz /usr/local/ RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_341 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.67 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.67 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$CATALINA_BASH/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.67/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.67/bin/ logs/catalina.ou
构建镜像
# docker build -t diytomcat .
- 启动镜像
- 访问测试
- 发布项目(由于做了卷挂载,我们之前在本地编写项目就可以发布了)
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
id="WebApp_ID" version="4.0">
</web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>hello,yiyu</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("-----my test web logs-----");
%>
</body>
</html>
发现: 项目部署成功,可以直接访问!
我们以后开发的步骤: 需要掌握Dockerfile的编写! 我们之后的一切都是使用docker镜像来发布运行
发布自己的镜像
Dockerhub
- 地址 https://hub.docker.com/ 注册自己的账号
- 确保账号可以登录
在我们服务器上提交自己的镜像
[root@centos-liunx-7 tomcatlogs]# docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username [root@centos-liunx-7 tomcatlogs]# [root@centos-liunx-7 tomcatlogs]# docker login -u chengxuyi 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 push
# push自己的镜像到服务器上 [root@centos-liunx-7 tomcatlogs]# docker push diytomcat Using default tag: latest The push refers to repository [docker.io/library/diytomcat] 3b80368c27b7: Preparing a46e380f6b0d: Preparing 009bcb6b88ee: Preparing 74ddd0ec08fa: Preparing denied: requested access to the resource is denied # 拒绝 # push镜像的问题 [root@centos-liunx-7 tomcatlogs]# docker push chengxuyi/diytomcat:11 The push refers to repository [docker.io/chengxuyi/diytomcat] An image does not exist locally with the tag: chengxuyi/diytomcat # 解决,增加一个 tag [root@centos-liunx-7 tomcatlogs]# docker tag 3962139fb78c chengxuyi/tomcat:0.9 # docker push上去即可! 自己发布的镜像尽量带上版本号 [root@centos-liunx-7 tomcatlogs]# docker push chengxuyi/tomcat:0.9 The push refers to repository [docker.io/chengxuyi/tomcat] 3b80368c27b7: Pushing 6.17MB/16.11MB a46e380f6b0d: Pushing 13.09MB/369.8MB 009bcb6b88ee: Pushed 74ddd0ec08fa: Pushing 13.13MB/231.3MB
提交的时候也是安装镜像的层级来进行提交的
阿里云镜像服务上
- 登录阿里云
- 找到容器镜像服务
- 创建命名空间
- 创建容器镜像仓库
浏览阿里云
docker push registry.cn-hangzhou.aliyuncs.com/chengxuyi/yiyu:[镜像版本号]
解决阿里云镜像无法push: CSDN
小结
Docker网络
理解Docker网络0
清空所有环境
测试
三个网络
# 问题: docker 是如何处理容器网络访问的?
# 查看容器的内部网络地址 ip addr
原理
我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker就会有一个网卡
docker0
,桥接模式,使用的技术是evth-pair
技术- 可以把docker的主网卡想成一个路由器,而每使用docker启动一个容器,docker就给给这个容器分配一个内网的IP地址
- 每启动一个容器,就会多
一对网卡
# 我们发现这个容器带来的网卡,都是一对对的 # evth-pair 就是一对的虚拟设备接口,它们都是成对出现的,一端连着协议,一端彼此相连 # 正因为有这个特效, evth-pair 充当一个桥梁,连接各种虚拟网络设备的 # PoenStac,Docker容器之间的连接,OVS的连接,都是使用 evth-pair 技术
我们来测试下centos01和centos02是否可以ping通!
[root@centos-liunx-7 /]# docker exec -it centos01 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 84: eth0@if85: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@centos-liunx-7 /]# docker exec -it centos02 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 86: eth0@if87: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever [root@centos-liunx-7 /]# docker exec -it centos01 ping 172.17.0.3 PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data. 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.129 ms 64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.085 ms 64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.102 ms 64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.104 ms 64 bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.067 ms # 结论: 容器和容器之间是可以互相ping通的
结论: centos01 和 centos02 是公用一个路由器, Docker0
所有的容器不指定网络的情况下,都是 docker0 路由的,docker会给我们的容器分配一个默认可以的IP
小结
DOcker 使用的是Linux的桥接,宿主机中是一个Docker容器的网桥 docker0
Docker中的所有的网络接口都是虚拟的.虚拟的转发效率高!
只要容器删除,对应的网桥一对就没了
--link
思考一个场景,我们编写了一个微服务,database url=ip, 项目不重启,数据ip换掉了,我们希望可以处理这个问题,可以通过名字来进行访问容器!
[root@centos-liunx-7 /]# docker exec -it tomcat02 ping tomcat01
Error: No such container: tomcat02
# 如何可以解决呢?
# 通过--link 就可以解决了网络联通问题
[root@centos-liunx-7 /]# docker run -d -it -P --name centos03 --link centos02 centos
1fccd0e0c5a2a1ea4886003d1a0021ea45fa9f1a93b0e0d263655da83f17b056
[root@centos-liunx-7 /]# docker exec -it centos02 ping centos01
ping: centos01: Name or service not known
[root@centos-liunx-7 /]# docker exec -it centos03 ping centos02
PING centos02 (172.17.0.3) 56(84) bytes of data.
64 bytes from centos02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from centos02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.217 ms
64 bytes from centos02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.076 ms
# 反向可以ping通吗?
[root@centos-liunx-7 /]# docker exec -it centos02 ping centos03
ping: centos03: Name or service not known
其实这个centos03就是在本地配置了centos02
# 查看 hosts 配置,在这里原理发现!
[root@centos-liunx-7 /]# docker exec -it centos03 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 centos02 080b56a86172
172.17.0.4 1fccd0e0c5a2
本质探究: --link就是在我们hosts配置中增加了一个172.17.0.3 centos02 080b56a86172
我们现在玩Docker已经不建议使用--link了!
自定义网络!不使用docker0
docker0问题:他不支持容器名连接访问!
自定义网络
查看所有的docker网络
网络模式
bridge: 桥接模式 docker(默认,自己创建也是用brideg模式)
none: 不配置网络
host: 和宿主机共享网络
container: 容器内网络连通(用的少!局限性很大)
测试
# 我们直接启动的命令 --net bridge ,而这个就是我们的docker0
docker run -d -P --name centos01 --net bridge centos
# docker0的特点: 默认,域名不能访问,--link可以打通连接
# 我们 可以自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16 192.168.0.2 192.168.255.255
# --gateway 192.168.0.1
[root@centos-liunx-7 /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
2eda7ce36f8f3b6c6ac6af7ae95fc593367bd9d48d637110dbbce437ac0440e7
[root@centos-liunx-7 /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
b3f10c44674d bridge bridge local
89c2b174693d host host local
2eda7ce36f8f mynet bridge local
bf454ee5fa23 none null local
[root@centos-liunx-7 /]# docker run -d -it -P --name centos-net-01 --net mynet centos
37e9334cd00053f9fcc003e58bb1e811fc11bdc9e0517301ef1920210d94fe77
[root@centos-liunx-7 /]# docker run -d -it -P --name centos-net-02 --net mynet centos
0f72e3f2d724eb2ba2e81e3ec6c4af1f1d364163e01e586a8ced56b2e8b982d0
[root@centos-liunx-7 /]# docker network inspect
"docker network inspect" requires at least 1 argument.
See 'docker network inspect --help'.
Usage: docker network inspect [OPTIONS] NETWORK [NETWORK...]
Display detailed information on one or more networks
[root@centos-liunx-7 /]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "2eda7ce36f8f3b6c6ac6af7ae95fc593367bd9d48d637110dbbce437ac0440e7",
"Created": "2022-10-04T15:05:56.551606092+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": {
"0f72e3f2d724eb2ba2e81e3ec6c4af1f1d364163e01e586a8ced56b2e8b982d0": {
"Name": "centos-net-02",
"EndpointID": "f42ecdc2792113040e91efaca8ebe68c0982cb9e30ccff51a36c2c0219cd8ca5",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"37e9334cd00053f9fcc003e58bb1e811fc11bdc9e0517301ef1920210d94fe77": {
"Name": "centos-net-01",
"EndpointID": "7bb99f5c54a3aa0a71907a0dfdcecfd9f3166a5f80e3509b9e0ad6d0907d864c",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
# 再次测试ping连接
[root@centos-liunx-7 /]# docker exec -it centos-net-01 ping centos-net-02
PING centos-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.080 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.065 ms
64 bytes from centos-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.064 ms
# 现在不使用--link也可以ping名字了
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis - 不同的集群使用不同的网络,保证集群是安全健康的
mysql - 不同的集群使用不同的网络,保证集群是安全健康的
网络连通
# 测试打通 centos03 - mynet
[root@centos-liunx-7 /]# docker network connect mynet 56d4731f695f
[root@centos-liunx-7 /]# docker exec -it centos03 ping centos-net-01
PING centos-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.241 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from centos-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.088 ms
# 连通之后就是将centos03 放到了 mynet 网络下
# 一个容器两个ip地址!
结论: 假设要跨网络操作别人,就需要使用docker network connect 连通!
实战: 部署Redis集群
shell脚本
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个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
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
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:63
79 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: e25f16e906ac90fe3e22475dcb7b7c1e51a3144e 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: a535292a5dfb31ce54f82828681d6b2472de3021 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 5b79173ce1dfc1355e57bcfc36c59ea0490da47d 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: baa3ab92abe356b23ad485c3c64528b181ca8981 172.38.0.14:6379
replicates 5b79173ce1dfc1355e57bcfc36c59ea0490da47d
S: 7fc66da4754d9d363d90e8e4248ced7c8ec094f4 172.38.0.15:6379
replicates e25f16e906ac90fe3e22475dcb7b7c1e51a3144e
S: c4dda1ab836499e84a48b26f762226b7010fec52 172.38.0.16:6379
replicates a535292a5dfb31ce54f82828681d6b2472de3021
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: e25f16e906ac90fe3e22475dcb7b7c1e51a3144e 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: baa3ab92abe356b23ad485c3c64528b181ca8981 172.38.0.14:6379
slots: (0 slots) slave
replicates 5b79173ce1dfc1355e57bcfc36c59ea0490da47d
M: a535292a5dfb31ce54f82828681d6b2472de3021 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 5b79173ce1dfc1355e57bcfc36c59ea0490da47d 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: c4dda1ab836499e84a48b26f762226b7010fec52 172.38.0.16:6379
slots: (0 slots) slave
replicates a535292a5dfb31ce54f82828681d6b2472de3021
S: 7fc66da4754d9d363d90e8e4248ced7c8ec094f4 172.38.0.15:6379
slots: (0 slots) slave
replicates e25f16e906ac90fe3e22475dcb7b7c1e51a3144e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
docker 搭建redis集群完成
我们使用docker之后,所有的技术都会慢慢的变得简单起来
SpringBoot微服务打包Docker镜像
- 构建springboot项目
- 打包应用
- 编写dockerfile
- 构建镜像
- 发布运行
以后我们使用了Docker之后,给别人交付的就是一个镜像即可!