参考【狂神说Java】Docker最新超详细版教程通俗易懂
Docker概述
Docker为什么出现
一款产品:开发-上线两套环境!应用环境,应用配置! 开发—运维。问题:我在我的电脑上可以运行!版本更新,导致服务不可用!对于运维来说,考验就十分大? 环境配置是十分的麻烦,每一个机器都要部署环境(集群Redis、ES、Hadoop.…)!费时费力。 发布一个项目(jar+(Redis MySQL jdkES)),项目能不能都带上环境安装打包! 之前在服务器配置一个应用的环境Redis MySQL jdk ES Hadoop,配置超麻烦了,不能够跨平台。 Windows,最后发布到Linux! 传统:开发jar,运维来做! 现在:开发打包部署上线,一套流程做完!
java–apk–发布(应用商店)—张三使用apk—安装即可用! java–jar(环境)—打包项目带上环境(镜像)—(Docker仓库:商店)—下载我们发布的镜像–直接运行即可!
Docker的思想就来自于集装箱! JRE–多个应用(端囗冲突)–原来都是交叉的! 隔离:Docker核心思想!打包装箱!每个箱子是互相隔离的。 Docker通过隔离机制,可以将服务器利用到极致!
Docker历史
2010年,几个搞IT的年轻人,就在美国成立了一家公司dotcloud做一些pass的云计算服务!LXC有关的容器技术! 他们将自己的技术(容器化技术)命名就是Docker! Docker刚刚诞生的时候,没有引起行业的注意!dotCloud,就活不下去开源开发源代码!2013年,Docker开源!Docker越来越多的人发现了docker的优点!火了,Docker每个月都会更新一个版本!2014年4月9日,Docker1.0发布! Docker为什么这么火?十分的轻巧! 在容器技术出来之前,我们都是使用虚拟机技术! 虚拟机:在window中装一个Vmware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重! 在容器技术出来之前,我们都是使用虚拟机技术! 虚拟机:在window中装一个Vmware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重!虚拟机也是属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!
vmware linux centos原生镜像,相当于一个虚拟电脑 可以实现隔离,开多个虚拟机 占用内存几个G 启动时间几分钟
docker 可以隔离,是(最核心的环境 + jdk + mysql) 很小 几个M 运行时间秒级
Docker 基于go语言开发
Docker能干什么
之前的虚拟机技术 虚拟机技术缺点 1、资源占用十分多 2、冗余步骤多 3、启动慢
容器化技术不是模拟一个完整的操作系统
比较Docker和虚拟机技术的不同:
- 传统虚拟机,虚拟出一套硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就轻便了
- 每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响。
容器化技术的优点
- 应用更快速的交付和部署
传统:一堆帮助文档,安装程序 Docker:打包镜像发布测试,一键运行 - 更便捷的升级和扩缩容
使用了Docker之后,我们部署应用就和搭积木一样! 项目打包为一个镜像,扩展服务器A!服务器B - 更简单的系统运维
在容器化之后,我们的开发,测试环境都是高度一致的。 - 更高效的计算资源利用:
Docker是内核级别的虚拟化,可以再一个物理机上可以运行很多的容器实例!服务器的性能可以被压榨到极致。
Docker架构图
安装Docker
安装准备
Linux要求内核3.0以上
[root@localhost ~]
3.10.0-1160.el7.x86_64
[root@localhost ~]
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
安装
帮助文档:https://docs.docker.com/engine/install/
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
yum install -y yum-utils
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install docker-ce docker-ce-cli containerd.io
systemctl start docker
docker version
docker run hello-world
[root@localhost ~]
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/
# 8.查看一下下载的镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 3 months ago 13.3kB
了解:卸载docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
阿里云镜像加速
1、登录阿里云找到容器服务
https://cr.console.aliyun.com/cn-shenzhen/instances/mirrors
2、配置使用
回顾helloworld流程
Docker底层原理
docker是怎么工作的?
Docker是一个Client-Server结构的服务器,Docker的守护进程运行在主机上,通过Socket从客户端访问!Docker-Server接收到Docker-Client指令,就会执行这个命令。
docker为什么比VM快?
1、Docker有着比虚拟机更少的抽象层 2、docker利用的是宿主机的内核,vm需要是Guest os 所以说,新建一个容器的时候,docker不需要想虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载 GuestOS,分钟级别的,而docker是利用宿主机的操作系统吗,省略了这个复杂的过程,秒级!
Docker的常用命令
帮助命令
docker version
docker info
docker xxx --help
帮助文档:https://docs.docker.com/reference/ https://docs.docker.com/engine/reference/commandline/docker/
镜像命令
https://docs.docker.com/engine/reference/commandline/images/ 查看镜像
docker images 查看所有本地主机上的镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 4 months ago 13.3kB
镜像的仓库源 标签 镜像ID 镜像创建时间 镜像大小
帮助命令
使用docker images --help 查看images参数命令
常见参数
-a :列出本地所有镜像
-q :只列出镜像ID
–digests :显示镜像的摘要信息
–no trunc :显示完整的镜像信息
-s :列出收藏数不小于指定值的镜像
在仓库中搜索镜像
docker search 搜索镜像
#过滤docker search 中的信息
docker search tomcat --filter=STARS=3000 过滤收藏大于3000的tomcat镜像
docker search mysql
下载镜像
docker pull 下载镜像
docker pull 镜像名[:tag],如果不写tag,默认是latest
docker pull mysql
docker pull mysql:5.7
docker pull tomcat:9
9: Pulling from library/tomcat
d960726af2be: Pull complete
e8d62473a22d: Pull complete
Digest: sha256:71703331e3e7f8581f2a8206a612dbeedfbc7bb8caeee972eadca1cc4a72e6b1
Status: Downloaded newer image for tomcat:9
docker.io/library/tomcat:9
#等价于
docker pull tomcat:9
docker pull docker.io/library/tomcat:9
删除镜像
docker rmi -f 镜像id #删除指定的镜像
docker rmi -f 镜像id 镜像id 镜像id 镜像id #删除指定的镜像
docker rmi -f $(docker images -aq) #删除全部的镜像
$(docker images -aq) 表示取 docker images -aq 得到的内容作为参数
docker rm 是删除容器
其他
docker history 镜像id 查看镜像的构建命令
容器命令
说明:我们有了镜像才可以创建容器,linux,下载一个centos镜像测试学习 先下载一个centos虚拟机
docker pull centos
docker run 在新容器中运行命令,该docker run命令首先creates在指定映像上创建一个可写容器层,然后starts使用指定的命令
运行容器镜像
docker run [可选参数] [image镜像]
#参数说明
--name="Name"
-d
-it
-p
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
-P
测试
[root@localhost ~]# docker run -it centos /bin/bash #在指定镜像上创建一个可写容器层
-it 表示交互操作 centos /bin/bash 表示交互控制台
[root@21b5801833c3 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 后台运行tomcat,-p 表示是把需拟机的8888端口映射到容器中的8080端口
[root@localhost /]# docker run -d -p 8888:8080 c43a65faae57
f0119f0207f3f5f5db72
[root@localhost /]# docker ps 查看运行中的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f0119f0207f3 c43a65faae57 "catalina.sh run" 16 minutes ago Up 16 minutes 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp trusting_shannon
# 启动并进入容器
# [root@localhost /]# docker run -it c43a65faae57 /bin/bash
# 进入已启动容器
[root@localhost /]# docker exec -it f0119f0207f3 /bin/bash
[root@aabc66e4ef0d:/]# 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@aabc66e4ef0d:/]# exit
exit
列出所有运行的容器
docker ps [参数]
-a, --all #列出当前正在运行的容器 + 带出历史运行过的容器
-n, --last int -n=? #?指历史记录,1表示-a的第一列,以此类推
-q, --quiet #只显示容器id
启动和停止容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
退出容器
exit #容器直接退出
ctrl + P + Q #容器不停止退出
删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器
docker rm -rf 容器id #强制删除,可以删除正在运行的容器
docker rm -f $(docker ps -aq) #删除所有运行中和历史的容器,会删除正在运行的容器
docker ps -a -q|xargs docker rm #删除所有的容器
其他常用命令
[root@localhost /]# docker run -d centos -d表示后台启动容器
6f114cdff4d934d0a2f005baeaeb86f
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 后台启动centos,docker ps 发现centos 停止了
# 原因:
docker容器使用后台运行,必须有一个前台的进程,docker发现没有前台应用,就会自动停止
如:nginx,启动后发现自己没有提供服务,就会立即停止,就没有程序了
查看日志
#自己编写一段脚本,并后台运行
[root@localhost /]# docker run -d centos /bin/sh -c "while true;do echo kuangshen;sleep 1;done"
85d460f6
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
85d460f6ad96 centos "/bin/sh -c 'while t…" 5 seconds ago Up
-tf #显示日志
--tail number #要显示日志条数
[root@localhost /]# docker logs -tf --tail 10 85d460f6ad96
查看容器中的进程信息ps
docker top 容器id
[root@localhost /]# docker top 85d460f6ad96
UID PID PPID C STIME TTY TIME CMD
root 110110 110090 0 15:23 ? 00:00:00 /bin/sh -c while true;do echo kuangshen;sleep 1;done
root 128910 110110 0 15:37 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
查看镜像的元数据
docker inspect 容器id #返回有关 Docker 对象的详细信息
进入当前运行的容器
# 方式一
# 我们通常使用的容器都是后台方式运行的,进入容器,修改一些配置
docker exec -it 容器id bash or shell
[root@localhost /]# docker exec -it 85d460f6ad96 /bin/bash
[root@85d460f6ad96 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@85d460f6ad96 /]# ps -ef 显示运行中的进程
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:23 ? 00:00:01 /bin/sh -c while true;do echo kuangshen;sleep 1;done
root 1607 0 0 07:50 pts/0 00:00:00 /bin/bash
# 方式二
docker attach 容器id
[root@localhost /]# docker attach 85d460f6ad96
正在执行的代码……
# 二者的区别
# docker exec #进入容器后开启一个新的线程,可以执行里面的操作
# docker attach #进入容器正在执行的终端,不会启动新的进程
从容器内拷贝内容到主机上
[root@localhost home]# docker run -it centos /bin/bash
[root@3fa32928910b /]# cd home
[root@3fa32928910b home]# touch test.java 新建test.java文件
[root@3fa32928910b home]# ls
test.java
[root@3fa32928910b home]# exit
exit
可以拷贝停止运行的容器
[root@localhost home]# docker cp 3fa32928910b:/home/test.java /home
[root@localhost home]# ls
admin test.java
小结
作业
部署nginx
[root@localhost home]# docker search nginx 搜索镜像
[root@localhost home]# docker pull nginx 下载镜像
[root@localhost home]# docker run -d --name nginx01 -p 3344:80 nginx:9 启动镜像
# 后台启动 容器名 主机端口:容器端口 镜像:下载的nginx的版本号,默认是latest,如果存在的nginx不是最新的,会自动pull latest版本
-d 后台运行
--name 给容器起名
-p 宿主机端口:容器内部端口
87558db1c082123f6cbb50bc311f033253fc6722c0fbd678f42d9b7c925e0606
[root@localhost home]# docker ps 查看运行中的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
87558db1c082 nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:3344->80/tcp, :::3344->80/tcp nginx01
容器id 镜像名称 别名
[root@localhost home]# curl localhost:3344 本机测试3344端口
[root@localhost ~]# docker exec -it nginx01 /bin/bash 进入容器
root@87558db1c082:/# whereis nginx 查看nginx配置文件
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@87558db1c082:/# cd /etc/nginx
root@87558db1c082:/etc/nginx# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
端口暴露的概念
问题思考:我们每次改动nginx配置文件,都需要进入容器内部,十分麻烦,我要是可以在容器外部提供一个映射路径,达到修改容器名,容器内部就可以自动修改
部署tomcat
[root@localhost ~]# docker pull tomcat 可以直接docker run 就会自动下载
[root@localhost ~]# docker run -d -p 3355:8080 --name tomcat01 tomcat
d21f60cdaf09e1fcb8dc0a770492bf76c3f989ce9d4dc7c6e5b9d435faf328f0
[root@localhost ~]# docker exec -it tomcat01 /bin/bash
root@d21f60cdaf09:/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
#有webapps和webapps.dist两个文件,webapps里没有特权指令文件,webapps.dist才是我们要的指令文件
root@d21f60cdaf09:/usr/local/tomcat/webapps# ls
root@d21f60cdaf09:/usr/local/tomcat/webapps# cd ..
root@d21f60cdaf09:/usr/local/tomcat# cd webapps.dist/
root@d21f60cdaf09:/usr/local/tomcat/webapps.dist# ls
ROOT docs examples host-manager manager
root@d21f60cdaf09:/usr/local/tomcat/webapps.dist# cd ..
root@d21f60cdaf09:/usr/local/tomcat# cp -r webapps.dist
发现问题:1、linux命令太少了,2、没有webapps,阿里云镜像原因,默认是最小镜像,所有不必要的都剔除。保证最小可运行环境
可视化工具portainer
什么是portainer
Docker图形化管理工具,提供一个后台面板供我们操作
[root@localhost ~]# docker run -d -p 8088:9000 \
> --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
#打开宿主机的浏览器 http://ip:8088
镜像讲解
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含某个软件所需的所有内容,包括代码、库、环境变量和配合文件。
如何得到镜像
1、从远程仓库下载
2、朋友拷贝
3、自己制作一个镜像dockerfile
Docker镜像加载原理
分层理解
特点 假如一个容器只有6个层级,使用pull拉取到主机,当容器被run时,它新增一个可写层到镜像层之上,所有的操作都是基于容器层的,可被打包发送。
commit镜像
docker commit 提交容器成为一个新的副本
# 命令与Git原理类似
docker commit -m="提交的描述信息" -a="作者名" 容器id 目标镜像名:[tag]
实战测试
[root@localhost ~]
root@a05714b681c2:/usr/local/tomcat
root@a05714b681c2:/usr/local/tomcat
root@a05714b681c2:/usr/local/tomcat/webapps
ROOT docs examples host-manager manager
[root@localhost ~]
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS(空) NAMES
dfc031405614 tomcat "/bin/bash" 4 minutes ago Exited (0)4 minutes ago
[root@localhost ~]
sha256:e0ecdc9573dc
[root@localhost ~]
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat01 1.0 e0ecdc9573dc 12 seconds ago 667MB
[root@localhost ~]
root@2cb5b3cb89b6:/usr/local/tomcat
ROOT docs examples host-manager manager
root@2cb5b3cb89b6:/usr/local/tomcat
[root@localhost ~]
root@43aa9e29ed29:/usr/local/tomcat
总结
docker run 跟镜像id,是基于镜像创建了一个容器 docker run 跟容器id,是进入创建的容器
# 可以进入各层的容器
# 1、首先要start开启要进入的容器id
# 2、docker exec -it 容器id /bin/bash
# 3、发现上层容器有着下层容器的修改内容,容器删除,数据丢失
容器数据卷
什么是容器数据卷
docker的理念回顾:将应用和环境打包成一个镜像! 数据?如果数据都在容器中,那么我们的容器删除,数据就会丢失。需求:数据可以持久化! MySQL,容器删了,删库跑路,需求:mysql数据可以存储在本地。 容器之间可以有一个数据共享的技术,docker容器中产生的数据,同步到本地! 这就是卷技术!目录的挂载,将我们容器内的目录挂载到linux上面 总结:容器的持久化和同步操作,容器间也可以数据共享的!
使用数据卷
方式一:直接使用命令来挂载,-v
docker run -it -v 主机目录:容器目录 镜像名 命令行界面
[root@localhost ~]# docker run -it -v /home/ceshi:/home centos01:1.0 /bin/bash
[root@localhost home]# ls
admin ceshi
启动之后,docker inspect 容器id 查看容器的详细信息
测试文件的同步
# docker容器
[root@deda031e3e44 home]# ls
[root@deda031e3e44 home]# touch test.java
[root@deda031e3e44 home]# ls
test.java
# 虚拟机
[root@localhost ceshi]# ls
test.java
# 可以双向操作
mysql实战操作
思考:mysql数据持久化的问题
[root@localhost ~]# docker search mysql
[root@localhost ~]# docker pull mysql:5.7
# 运行容器需要数据挂载,安装启动mysql是要配置密码。
# 官方测试 $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
[root@localhost ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/home/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# -d:后台运行 -p:端口映射 -v:卷挂载 -e:环境配置 --name:容器名字
[root@localhost home]# cd mysql
[root@localhost mysql]# ls
conf data
[root@localhost mysql]# cd conf
[root@localhost conf]# ls
[root@localhost conf]# cd ../data
[root@localhost data]# ls
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem
使用mysql访问工具,添加新的数据库,再次cd data 会出现新增的数据库
[root@localhost data]# docker rm -f mysql01 #将容器删除,数据还在,实现了数据持久化功能
mysql01
[root@localhost data]# ls
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem
具名挂载和匿名挂载
匿名挂载 -v 容器内路径
# -P 随机映射端口
docker run -d -P --name nginx01 -v 容器内路径
[root@localhost home]# docker run -d -P --name nginx01 -v /etc/nginx nginx
93feb2845f4
查看所有的volume的情况,所有的卷
[root@localhost home]# docker volume ls
DRIVER VOLUME NAME
local 842f43951064
local 036770a8e232
# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径
具名挂载
# 通过 -v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:容器内路径
[root@localhost home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
e4cff6b0fdb21
[root@localhost home]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
查看一下这个卷,对应的容器外部地址
[root@localhost home]# docker volume inspect juming-nginx
所有docker容器内的卷,没有指定目录的情况下都是在==/var/lib/docker/volumes_data==
我们通过具名挂载可以方便找到我们的一个卷,大多数情况在使用具名挂载
如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 自定义卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
拓展
# 通过 -v 容器内路径:ro rw 改变读写权限
ro(只读) rw(可读可写)
# 一旦设置了容器权限,容器对我们挂载出来额内容就有限定了
[root@localhost home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
[root@localhost home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的
初始dockerfile
dockerfile 就是用来构建docker镜像的构建文件,命令脚本,使用docker build
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层
# 自己手写一个镜像
# 创建dockerfile,名字可以随机,建议dockerfile
# 文件中的内容 指令(大写) 参数
[root@localhost docker-test-volume]# cat dockerfile
#这里的每一个命令,就是镜像的一层
FROM centos
VOLUME ["/volume01","/volume02"]
CMD echo "----end------"
CMD /bin/bash
# 生成镜像,docker build -f 镜像文件 -t 镜像名:[tag] 当前目录(用 . 表示当前目录)
[root@localhost docker-test-volume]# docker build -f dockerfile -t syw/centos:1.0 .
[root@localhost docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
syw/centos 1.0 572699bf1784 3 minutes ago 209MB
[root@localhost docker-test-volume]# docker run -it d230fdb6f988
[root@f0919d2736d4 /]# ls -l
total 0
...
# 生成镜像时自动挂载的数据卷,这个卷和外部有一个同步的目录
drwxr-xr-x 2 root root 6 Jul 16 16:02 volume01
drwxr-xr-x 2 root root 6 Jul 16 16:02 volume02
数据卷同步
这种方式以后用的很多,我们通常会构件自己的镜像,假设创建镜像时没有挂载卷,就要手动挂载卷 -v 卷名:容器内路径
在容器中,卷目录下创建的文件,会在外部有同步的文件
在卷中新建文件
[root@c2f68340ea32 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var volume01 volume02
[root@c2f68340ea32 /]# cd volume01
[root@c2f68340ea32 volume01]# touch test01.txt
[root@c2f68340ea32 volume01]# ls
test01.txt
查看容器的元数据信息
[root@localhost ~]# docker inspect c2f68340ea32
..........找到mounts部分,查看容器内卷挂载的外部路径
"Mounts": [
{
"Type": "volume",
"Name": "b95f402df171463d2fb1d33730d76a29ea14a46c675f49bb5f1dd7c9ee1e5d48",
"Source": "/var/lib/docker/volumes/b95f402df171463d2fb1d33730d76a29ea14a46c675f49bb5f1dd7c9ee1e5d48/_data",
"Destination": "/volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "24b9d703c3ba734e82df6f2798f778c051530f07f9b09b4ad8fcc181d3fa8c55",
"Source": "/var/lib/docker/volumes/24b9d703c3ba734e82df6f2798f778c051530f07f9b09b4ad8fcc181d3fa8c55/_data",
"Destination": "/volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
查看外部同步的内容
[root@localhost ~]# cd /var/lib/docker/volumes/b95f402df171463d2fb1d33730d76a29ea14a46c675f49bb5f1dd7c9ee1e5d48/_data
[root@localhost _data]# ls
test01.txt
数据卷容器
多个mysql同步数据
通过 syw/centos:1.0 镜像 创建并启动一个 叫docker01的容器
[root@localhost /]# docker run -it --name docker01 syw/centos:1.0
[root@9998f8ab8c5a /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
通过 syw/centos:1.0 镜像 创建并启动一个 叫docker02的容器
启动的时候 进行挂载,继承docker01
[root@localhost /]# docker run -it --name docker02 --volumes-from docker01 syw/centos:1.0
# 子容器 挂载 父容器 镜像
#进入docker01容器,创建文件,测试是否同步到docker02
[root@localhost /]# docker attach docker01
[root@9998f8ab8c5a /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@9998f8ab8c5a /]# cd volume01
[root@9998f8ab8c5a volume01]# touch docker01
#退出docker01,进入docker02,发现容器间同步数据
[root@localhost /]# docker attach docker02
[root@7238a4895cdc /]# cd volume01
[root@7238a4895cdc volume01]# ls
docker01
创建docker03容器,继承docker01 如果删除了docker01,继承docker01的依旧挂载了父容器
小结:
关键命令 --volumes-from 只要子容器挂载到父容器上就可以实现容器间的数据互相同步,
第三个容器的数据也可以同步到第一、第二个容器中,可以同步多个容器
就算删除docker01,docker02依然可以访问这个文件
这是容器间的拷贝的概念
容器之间的信息的传递,数据卷容器的生命周期一直持续到没有容器为止,但是一旦持续化到了本地,删除容器,本地的信息是不会被删除的
dockerfile
dockerfile 就是用来构建docker镜像的构建文件,命令脚本参数
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像
官方的做法
很多官方镜像都是基础包,很多功能没有(jdk+mysql+redis),我们通常会搭建自己的镜像,官方既然可以搭建镜像,我们自己也可以!
dockerfile搭建过程
基础知识
1、每个保留关键字(指令)都是必须是大写字母
2、执行从上到下顺序执行
3、#表示注释
4、每个指令都会创建提交一个新的镜像层,并提交
dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单
Docker镜像逐渐成为企业交付的标准,必须掌握
dockerfile:构建文件,定义了一切步骤,源代码
Dockerimages:通过dockerfile构建生成的镜像,最终发布和运行的产品
docker容器:容器就是镜像运行起来的服务器
dockerfile指令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像运行的时候需要运行的命令
ADD #步骤,tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露端口配置
CMD #指定这个容器启动的时候需要运行的命令,只有最后一个命令会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候需要运行的命令,可以追加命令
ONBUILD #当构建一个被继承dockerfile 这个的时候就会运行ONBUILD的指令
COPY #类似ADD,我们文件拷贝到镜像中
ENV #构建的时候设置环境变量
实战测试
Docker Hub中99%的镜像都是从这个基础镜像 scratch 过来的,FROM scratch 然后配置需要的软件和配置来进行构建的
创建一个自己的dockerfile,增加官方centos没有的功能,如vim,net-tools
编写dockerfile文件
[root@localhost dockerfile]# vim mydockerfile-centos
FROM centos #基于centos创建
MAINTAINER syw<2502708421@qq.com>
ENV MYPATH /usr/local #运行时,进入容器的默认工作目录,pwd查看
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(表示tag) 镜像名:[tag版本号]
[root@localhost dockerfile]# docker build -f mydockerfile-centos -t mycentos:1.0 .
注意最后有个点
查看镜像的构建命令
docker history 创建的dockerfile镜像id
CMD和ENTRYPOINT的区别
CMD #指定这个容器启动的时候需要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候需要运行的命令,可以追加命令
CMD中 替换 的含义
# 编写dockerfile文件
[root@localhost dockerfile]# vim CMDtest
FROM centos
CMD ["ls","-a"] #展示当前目录所有结构
# 构建镜像
[root@localhost dockerfile]# docker build -f CMDtest -t centoscmd . #镜像名一定为小写
# run ,发现 ls -a 命令生效了
[root@localhost dockerfile]# docker run b3f0497ff150
.
..
.dockerenv
bin
dev
etc
home #正常运行
# 想追加一个命令的时候 -l ,实现 ls -al
[root@localhost dockerfile]# docker run b3f0497ff150 -l
"docker run" requires at least 1 argument.
See 'docker run --help'.
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
#出现报错,因为CMD把ls -a 替换成了 -l (CMD中的替换的含义)
ENTRYPOINT中 追加 的含义
# 编写dockerfile
[root@localhost dockerfile]# vim ENTRYPOINTtest
FROM centos
ENTRYPOINT ["ls","-a"]
# 构建镜像
[root@localhost dockerfile]# docker build -f CMDtest -t centoscmd .
[root@localhost dockerfile]# docker run 43aa1c125f19 -l
WARNING: IPv4 forwarding is disabled. Networking will not work.
total 0
drwxr-xr-x 1 root root 6 Jul 17 07:35 .
drwxr-xr-x 1 root root 6 Jul 17 07:35 ..
-rwxr-xr-x 1 root root 0 Jul 17 07:35 .dockerenv
# 追加一个命令 -l ,实际上执行的是 ls -al,并没有像cmd替换了-a命令
最好的学习就是对比
tomcat实战
1、准备文件,把文件上传到本地
[root@localhost tomcat]# pwd
/home/admin/build/tomcat
[root@localhost tomcat]# ls
apache-tomcat-9.0.50-deployer.tar.gz jdk-8u181-linux-x64.tar/2.gz
2、编写dockerfile文件,官方命名Dockerfile,build会自动寻找这个文件,就不需要-f指定了
FROM centos
MAINTAINER admin<2502708421@qq.com>
COPY readme.txt /usr/local/readme.txt 拷贝readme.txt 到容器内 /usr/local/readme.txt
ADD jdk-8u181-linux-x64.tar.gz /usr/local #ADD 自动解压到/usr/local
ADD apache-tomcat-9.0.50-deployer.tar.gz /usr/local
RUN yum -y install vim #安装vim
#配置环境变量
ENV MYPATH /usr/local #配置环境变量目录
WORKDIR $MYPATH #工作目录
ENV JAVA_HOME /usr/local/jdk1.8.0_181 #java的环境变量
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.50-deployer
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.50-deployer
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
# && 表示添加执行命令
CMD /usr/local/apache-tomcat-9.0.50-deployer/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.50-deployer/bin/logs/catalina.out
3、构造镜像
[root@localhost tomcat]# docker build -t diytomcat .
4、启动镜像
挂载了文件目录,挂载了日志目录
[root@localhost tomcat]# docker run -d -p 9090:8080 --name sywtomcat -v /home/admin/build/tomcat/test:/usr/local/apache-tomcat-9.0.50-deployer/webapps/test -v /home/admin/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.50-deployer/logs diytomcat
[root@localhost tomcat]# docker exec -it 3679e0964ee /bin/bash
在本地的/home/admin/build/tomcat/test目录下编写jsp文件,文件就可以自动同步到容器中,在宿主机浏览器测试,ip:映射端口号就可以访问tomcat服务器返回的jsp文件了。
5、发布项目(由于做了卷挂载,我们直接可以在本地编写项目,就可以发布了)
我们以后的开发步骤,需要掌握dockerfile的编写,我们以后的一切都是使用docker镜像来发布运行的
发布自己的镜像
1、注册https://hub.docker.com/账号
2、在服务器上提交自己的镜像
[root@localhost ~]# 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@localhost ~]# docker login -u 账号名
[root@localhost ~]# docker push syw/tomcat:5.0
The push refers to repository [docker.io/syw/tomcat]
eb0d038a8c91: Preparing
ed5c187d1a57: Preparing
d9aae75ea5b5: Preparing
2653d992f4ef: Preparing
denied: requested access to the resource is denied #虚拟机不允许发到docker hub上,因为要翻墙
发布自己的镜像
1、注册https://hub.docker.com/账号
2、在服务器上提交自己的镜像
[root@localhost ~]# 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@localhost ~]# docker login -u 账号名
[root@localhost ~]# docker push syw/tomcat:5.0
The push refers to repository [docker.io/syw/tomcat]
eb0d038a8c91: Preparing
ed5c187d1a57: Preparing
d9aae75ea5b5: Preparing
2653d992f4ef: Preparing
denied: requested access to the resource is denied #虚拟机不允许发到docker hub上,因为要翻墙
发布到阿里云
找到容器镜像服务 创建镜像时,公有(别人可以访问),私有(只有自己访问),公网地址:可以通过该地址可以访问自己当前的仓库。
创建容器镜像
注意:密码需要在访问凭证那里设置,并用访问凭证密码在终端登录
补充:
docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称
docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像
docker save保存的是镜像,docker export保存的是容器
docker网络
理解docker网络
清空所有环境
docker rmi -f $(docker images -aq)
获取当前ip地址
[root@localhost ~]# ip addr #docker0网卡 它作为桥梁,使得容器间可以互相通信
docker是如何处理容器访问网络的?下面生成一个容器进行测试
[root@localhost ~]# docker run -d -P --name tomcat01 tomcat
#查看容器的内部网络容器地址 ip addr ,发现容器启动的时候会得到一个etho ip地址,docker发配的
[root@localhost ~]# docker exec -it tomcat01 ip addr
上面命令相当于 docker exec -it tomcat01 进入容器,但是没有打开交互命令行/bin/bash 直接执行 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
6: eth0@if7: <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
#思考:linux能不能ping通容器内部
[root@localhost ~]# 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.199 ms
原理 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就有一个网卡docker0,桥接模式,使用的技术是evth-pair技术
启动了一个容器后再次测试 ip addr
[root@localhost ~]# ip addr #与上面 6: eth0@if7 成对出现
发现又启动一个容器之前,多了一个262 与容器内的网卡6相似 再启动一个容器,再次 ip addr ,又多了一个网卡 容器内部 ip addr 发现和容器外部的网卡成对出现
# 我们发现这个容器带来的网卡都是一对对的
# evth-pair 就是一对虚拟设备接口,它们都是成对出现的,一段连着协议,一段彼此相连
# 正因为这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备
# OpenStack,docker容器间的连接,OVS的连接,都是使用evth-pair 技术
测试容器tomcat01、tomcat02 是否可以ping通
docker exec -it tomcat02 ping 172.18.0.2
说明容器和容器之间是可以通信的
原理图
结论:tomcat01和tomcat02是共用一个路由器,docker0 所有容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip
Docker使用的是linux的桥接,宿主机是一个docker容器的网桥 只要容器删除了,对应的网桥就没有了,ip addr 中对应的网卡也没了
–link(不适用当前)
思考一个场景,我们编写了一个微服务,database url=ip: ,项目不重启,数据库ip换掉,我们希望可以处理这个问题,可以名字来进行访问容器。不用网络地址可以ping通
[root@localhost ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known
如何解决这个问题?
# 添加了--link 实现容器名ping通,不需要通过网路ip
[root@localhost ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
tomcat03 --link tomcay02 表示将tomcat03 link 到tomcat02
[root@localhost ~]# docker exec -it tomcat03 ping tomcat02
64 bytes from tomcat02 (172.17.0.3): icmp_seq=74 ttl=64 time=0.134 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=75 ttl=64 time=0.156 ms
# 反向不能ping通
docker inspect 容器id 其实这个tomcat03就是在本地配置了tomcat02的配置
[root@localhost ~]# 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.17.0.3 tomcat02 d8351e39a3c7 这里
172.17.0.4 e93babbd67a8
本质探究:–link就是我们在hosts配置中增加了一个 172.17.0.3 tomcat02 d8351e39a3c7 的配置 现在docker已经不建议用–link 主要用自定义网络,不适合docker0(不支持容器名连接访问)
自定义网络(容器互联)
查看所有的docker网络
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6b4e58745ca8 bridge bridge local
6e037e8fa416 host host local
437a79a1bd1a none null local
网络模式
bridge:桥接docker (默认,自己创建的网络也是用bridge 模式)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通(用的少,局限很大)
测试
# 我们直接启动命令,--net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat #等同于上一个命令
# docker0特点,默认,域名不能访问,--link 可以打通!
# 自定义网络
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
--driver : 创建一个网络 bridge:桥接的默认模式
--subnet : 创建子网 16 表示可以创建65536个子网 从192.168.0.0 到 192.168.255.255
--gateway : 默认路由
mynet : 网络名称
e9f5bbedbd719f2a83e86151898e63ee0b046ffc4d13de64f64791f1781904d4
#注意:不可以与自己的终端连接同一网段和网关,否则产生冲突
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6b4e58745ca8 bridge bridge local
6e037e8fa416 host host local
e9f5bbedbd71 mynet bridge local
437a79a1bd1a none null local
自己的网络就创建好了,后期就可以把自己的服务放到自己的网络里 查看元数据
启动两个容器
[root@localhost ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
968477f8b2330669ca9dfed713f1ad277d413dc8216246dcfc8b72c118322e7f
[root@localhost ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
2ff8d58d4d34c2e52a41247b115e6a6ef4d3dffa69f61e7afabdee960e1f55ef
[root@localhost ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "e9f5bbedbd719f2a83e86151898e63ee0b046ffc4d13de64f64791f1781904d4",
"Created": "2021-07-18T16:31:54.338626301+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": {
"2ff8d58d4d34c2e52a41247b115e6a6ef4d3dffa69f61e7afabdee960e1f55ef": {
"Name": "tomcat-net-02",
"EndpointID": "81f1f522143adfb96e2e521ec8b43fbc5c1cd52acd9061433e6003a5e527ecd0",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"968477f8b2330669ca9dfed713f1ad277d413dc8216246dcfc8b72c118322e7f": {
"Name": "tomcat-net-01",
"EndpointID": "07e62fb9172718b3ba337074ca1b6bdf757fb33c0103159f9f1a711f4927611c",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
发现不使用–link都可以ping通
[root@localhost ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
[root@localhost ~]# docker exec -it tomcat-net-01 ping tomcat-net-02
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络 好处: Redis 不同的集群使用不同的网络,保证集群是安全和健康的 mysql 不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
通过打通容器和网卡mynet 实现连通不同网卡下的容器 测试打通 tomcat01(属于172.17.0.0/16) -mynet
生成tomcat01容器
[root@localhost ~]# docker run -d -P --name tomcat01 tomcat
c3054639c41f17
测试两个不同网段的容器连接
[root@localhost ~]# docker network connect mynet tomcat01
[root@localhost ~]# docker network inspect mynet
查看,发现将tomcat01容器连通到了mynet网卡,容器和网络打通了
# 一个容器两个ip地址,类似阿里云服务器:公网ip 私网ip
实现了跨网段用名称进行通信
[root@localhost ~]# docker exec -it tomcat01 ping tomcat-net-01
tomcat02 和mynet是依旧没有连通的
[root@localhost ~]# docker exec -it tomcat02 ping tomcat-net-01
结论:假设要跨网段操作别人,就需要使用docker network connect 连通
实战:部署Redis集群
测试六台服务器的集群,r-m3宕机,r-s3替补
# 创建redis网卡
[root@localhost ~]# docker network create redis --subnet 172.38.0.0/16
95d43efc681975cab5da8d8c6344438ee0654dd2f31592afe7552be930c385ab
# 通过脚本创建六个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@localhost ~]# cd /mydata
[root@localhost mydata]# ls
redis
[root@localhost mydata]# cd redis/
[root@localhost redis]# ls
node-1 node-2 node-3 node-4 node-5 node-6
# 启动六个redis
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf;
# 启动第一个
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
#进入其一个redis
[root@localhost redis]# docker exec -it redis-1 /bin/sh
/data #
创建集群的配置
/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: 60438cf4aecf3b0e8a61f69f36084608eabea0ef 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 4cd57656a08a2c49a132b8187480f74c99c1759b 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 1686c456274f1429eb74222b1eb5e55e641bb983 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: cd8444d88e3a9cb494ce84edfdc163757f3b61dd 172.38.0.14:6379
replicates 1686c456274f1429eb74222b1eb5e55e641bb983
S: e706e3562994488db2dc94cb5aa0d02ee2f64f9d 172.38.0.15:6379
replicates 60438cf4aecf3b0e8a61f69f36084608eabea0ef
S: e543c17775f8e48cd9019bd3535dc3e8a5a54ff1 172.38.0.16:6379
replicates 4cd57656a08a2c49a132b8187480f74c99c1759b
Can I set the above configuration? (type 'yes' to accept): yes #问是否要配置是哪 个主机,三个从机,回答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: 60438cf4aecf3b0e8a61f69f36084608eabea0ef 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: e706e3562994488db2dc94cb5aa0d02ee2f64f9d 172.38.0.15:6379
slots: (0 slots) slave
replicates 60438cf4aecf3b0e8a61f69f36084608eabea0ef
M: 1686c456274f1429eb74222b1eb5e55e641bb983 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 4cd57656a08a2c49a132b8187480f74c99c1759b 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: cd8444d88e3a9cb494ce84edfdc163757f3b61dd 172.38.0.14:6379
slots: (0 slots) slave
replicates 1686c456274f1429eb74222b1eb5e55e641bb983
S: e543c17775f8e48cd9019bd3535dc3e8a5a54ff1 172.38.0.16:6379
slots: (0 slots) slave
replicates 4cd57656a08a2c49a132b8187480f74c99c1759b
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
/data # redis-cli -c #redis-cli 连接的是单机,-c 可以连接到集群
127.0.0.1:6379> cluster nodes
测试
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
#将redis-3服务停止,在redis-4中get到
172.38.0.13:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
Springboot微服务打包Docker镜像
构建项目,打包 打包后进入目录,命令行测试jar包是否可以运行 编写dockerfile文件 发布docker 将发布的内容上传到服务器 build构建镜像 运行镜像,curl测试
其他
忘记一个命令是什么,可以docker ex 然后按tab键,会提示相关的命令
|