学Docker(超详细)
Posted JF Coder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学Docker(超详细)相关的知识,希望对你有一定的参考价值。
文章目录
docker本质就是宿主机的一个进程,docker是通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)
博主的Docker安装教程
Docker镜像加载原理
docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。bootfs(boot file system) 主要包含bootloader和kernel,bootloader;主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就存在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
UnionFS联合文件系统一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统你那个,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层文件和目录。
docker镜像分层:
以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载;
采用这种分层结构最大的一个好处就是共享资源,比如有多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。docker
镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作 “容器层” ,“容器层” 之下的都叫镜像层。
Docker镜像都是只读的,所以无法对镜像进行操作,所以操作都是基于容器层的。当容器启动时,一个新的可写层被加载到镜像的顶部。
Docker常用的命令
docker镜像是docker容器运行时的只读模板,镜像可以用来创建docker容器
docker version #版本信息
docker info #docker系统信息和镜像(详细)
docker --help #帮助命令
docker images #查看镜像
docker search #搜索镜像
docker pull 镜像名 [:tag]版本 docker pull mysql:5.7 #下载镜像
docker rmi -f c8562eaf9d81(镜像id) #删除镜像
docker rmi -f $(docker images -aq) #删除全部的镜像
关于容器命令
Docker 利用容器来运行应用,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker
镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台。
镜像是只读的,容器在启动的时候,创建一层可写层作为最上层
- 使用下载centos测试
docker pull centos
- 新建容器启动
docker run [可选参数] image
#可选参数
--name="Name" #容器名字
-d #后台运行方式
-it #使用交互式方式运行
-p 指定容器端口 // -p 主机端口:容器端口 // -p 随机指定端口
-v #卷挂载
- 启动成功
[root@jf-server02 ~]# docker run -it centos /bin/bash
[root@2f919ced6f44 /]#
exit //退出(停止容器)
Ctrl+P+Q (不停止退出)
- 当前运行容器
docker ps
docker ps -a #最近运行容器
- 删除容器
docker rm 容器id #删除容器
docker rm -f $(docker ps-aq) #删除所有容器
- 停止重启容器
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id #强制停止
docker中容器的关系
其他常用命令
docker run -d centos #不进入容器启动,后台运行
# 但是,docker容器后台运行,就应该有前台进程;docker发现容器没有被应用就会停止运行
- 查看日志
docker logs -f -t --tail 10 镜像id or 镜像名
docker inspect centos #容器详细信息
进入当前正在运行的容器
docker exec -it 容器id /bin/bash #进入正在运行的容器,开启新的终端
docker attach 容器id #进入容器,查看正在执行的任务
docker容器文件移动复制
docker cp 容器id 容器目录 目的目录 #拷贝容器文件
docker 安装测试命令
一般用来测试,用完后就docker就自动删除容器了,docker ps查询无此容器
docker run -it --rm tomcat:9.0
一般安装使用命令(安装运行nginx)
docker run -d --name nginx02 -p 3345:80 nginx
commit镜像
源镜像是只读的,可以向docker提交自己更改过的镜像,以便下次使用
docker commit -a="demo" -m="备注做了修改" 容器id 版本信息
安装可视化工具Portainer和Rancher
Docker图形化界面管理工具
- Portainer安装
docker run -d -p 8088:9000 \\
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
- 访问地址:ip地址+:8088,选择local身份注册登录
- Rancher安装(CI/CD再用)
docker run -d --restart**=**unless-stopped -p 8080:8080 rancher/server
容器数据卷
命名的容器挂载数据卷,其他的容器通过挂载这个父容器实现数据共享,挂载数据卷的容器,我们称为数据卷容器。
docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。
通过命令行挂载的方式,命令如下:
docker run -it -v /宿主机绝对路径目录: /容器内目录 镜像名
这个命令会在宿主机和容器内分别建立两个目录,两个目录是对接的,里面的数据可以共享。如果我们不知道数据卷是否挂载成功时,可以通过以下方式来检查数据卷的挂载结果。
docker inspect 容器id #查看容器详细信息
在容器内创建test.java文件,宿主机同步
比较常见到的,将配置文件等挂载到宿主机,就可以在本地修改,容器内会自动同步;
具名和匿名挂载
- 匿名挂载
[root@jf-server02 ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
[root@jf-server02 ~]# docker volume ls #查看所有卷
DRIVER VOLUME NAME
local 4d82b139aaa331f9cc700a3bbc8f43a66172d975617cd92764d2f5ab6994104d
local 81234b75f198a59bb1a7e55d2d6ffcd0533c3b83724f14f5bda463c05a1c19e5
local fe5eb5aef188abd2e2a80827fbd03b1b4e10bfc97588b2d8151a808d16ba4010
- 具名挂载
[root@jf-server02 etc]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
1e334ae2e7aa1b9853f37b04ace7310871762e2a10987f786f977e3361cac5c2
[root@jf-server02 etc]# docker volume ls
DRIVER VOLUME NAME
local 4d82b139aaa331f9cc700a3bbc8f43a66172d975617cd92764d2f5ab6994104d
local 81234b75f198a59bb1a7e55d2d6ffcd0533c3b83724f14f5bda463c05a1c19e5
local fe5eb5aef188abd2e2a80827fbd03b1b4e10bfc97588b2d8151a808d16ba4010
local juming-nginx #具名挂载定义的别名
进入docker目录
[root@jf-server02 /]# cd /var/lib/docker/
[root@jf-server02 docker]# ls
builder containers network plugins swarm trust
buildkit image overlay2 runtimes tmp volumes
[root@jf-server02 docker]# cd volumes/
[root@jf-server02 volumes]# ls
4d82b139aaa331f9cc700a3bbc8f43a66172d975617cd92764d2f5ab6994104d
81234b75f198a59bb1a7e55d2d6ffcd0533c3b83724f14f5bda463c05a1c19e5
backingFsBlockDev
fe5eb5aef188abd2e2a80827fbd03b1b4e10bfc97588b2d8151a808d16ba4010
juming-nginx
metadata.db
如何判断是具名挂载还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径::容器内路径 #指定路径挂载
对挂载数据卷设置权限
ro
#只读 只能通过宿主机操作,容器只有读权限,操作限制
rw
#可读可写
docker run -d -p --name nginx01 -v juming-nginx:/etc/nginx:ro(设置只读权限) nginx
案例一:多个mysql实现数据共享
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d
-v /home/mysql/data:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02
--volumes-from mysql01 mysql:5.7 #挂载到 mysql01
这两个容器可以实现数据同步
DockerFile
什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。可以使用在命令行中调用任何命令。 Docker通过读取DockerFile`中的指令自动生成映像。
Dockerfile文件说明
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#
字符开头则被视为注释。可以在Docker文件中使用RUN
,CMD
,FROM
,EXPOSE
,ENV
等指令。Dockerfile 一般分为四部分:基础镜像信息
、维护者信息
、镜像操作指令
和容器启动时执行指令
#补充说明
CMD #容器启动时运行命令 !可被替代
ENTRYPOINT #容器启动运行命令 !可被追加命令
VOLUME #挂载目录
ONBUILD # 构建一个被继承dockerfile时就会运行,触发命令
使用 Dockerfile 定制镜像
docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f
标志指向文件系统中任何位置的Dockerfile。
例1:创建dockerfile1脚本
[root@jf-server02 docker-test-volume]# touch dockerfile1
[root@jf-server02 docker-test-volume]# vim dockerfile1
[root@jf-server02 docker-test-volume]# cat dockerfile1
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end-----"
CMD /bin/bash
[root@jf-server02 docker-test-volume]# pwd
/home/docker-test-volume
docker build -f /home/docker-test-volume/dockerfile1 -t centos:1.0 . # .代表当前目录
# -f dockerfile文件地址 -t 镜像名和版本
- 运行新镜像,发现dockerfile脚本匿名挂载的数据卷出现在新镜像中
[root@jf-server02 docker-test-volume]# docker run -it cabee6a5c87e /bin/bash
[root@8f271ab96163 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
例2:创建dockerfile2脚本
[root@jf-server02 dockerfile]# vim dockerfile2
[root@jf-server02 dockerfile]# cat dockerfile2
FROM centos
MAINTAINER jfcoder
ENV MYPATH /usr/local #默认工作目录
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo "---end---"
CMD /bin/bash
- 运行dockerfile2 构建新镜像
[root@jf-server02 dockerfile]# docker build -f dockerfile2 -t mycentos:01 .
[root@jf-server02 dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 01 8a53e2358d6a About a minute ago 282MB
[root@jf-server02 dockerfile]# docker run -it 8a53e2358d6a #镜像创建成功
[root@501ab4c93eed local]#
- 使用查看镜像构建过程 docker history 镜像ID
[root@jf-server02 dockerfile]# docker history 8a53e2358d6a
IMAGE CREATED CREATED BY SIZE COMMENT
8a53e2358d6a 23 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
f55702227aa1 23 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
74277d42893f 23 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
15bf8701f7d9 23 minutes ago /bin/sh -c yum -y install net-tools 14.3MB
ae0cd1e7da79 23 minutes ago /bin/sh -c yum -y install vim 58MB
3c61665ba81e 23 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
6e792da7eb66 23 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
96f5bf7a8914 23 minutes ago /bin/sh -c #(nop) MAINTAINER jfcoder 0B
300e315adb2f 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 2 months ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
发布镜像
- DockerHub
- 注册一个账号:https://hub.docker.com
- 在服务器提交镜像
[root@jf-server02 /]# docker login -u ??? #登录
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 mycentos:01 #尽量带上版本号 tag
- 阿里云
- 注册阿里云账号,找到容器镜像服务
-
登录阿里云Docker Registry
$ sudo docker login --username=用户名 registry.cn-shenzhen.aliyuncs.com #地址
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
您可以在访问凭证页面修改凭证密码。
- 从Registry中拉取镜像
$ sudo docker pull registry.cn-shenzhen.aliyuncs.com/docker-jfcoder/docker-demo:[镜像版本号]
- 将镜像推送到Registry
$ sudo docker login --username=username 容器地址 $ sudo docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/???/docker-demo:[镜像版本号] $ sudo docker push registry.cn-shenzhen.aliyuncs.com/???/docker-demo:[镜像版本号]
案例二:使用dockerfile构建Tomcat
- 准备tomcat和JDK1.8压缩包
[root@jf-server02 /]# cat dockerfile
FROM centos
MAINTAINER jfcoder
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.tar.gz /usr/local
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
#JDK环境
ENV JAVA_HOME /usr/local/jdk1.8
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#Tomcat环境
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#暴露端口
EXPOSE 8080
#启动Tomcat
CMD /usr/local/apache-tomcat-9.0/bin/startup.sh && tail -f /usr/local/apach-tomcat-9.0/bin/logs/catalina.out
-
构建镜像
编写dockerfile文件,build会自动寻找这个文件,不需要
-f
指定
docker build -t tomcatdemo .
- 启动镜像
docker run -d -p 9090:8080 --name tomcatdemo -v +需要挂载的目录
阶段小结
Docker网络
了解docker网络
- 查看本机ip信息,docker0网卡,使用桥接模式
[root@jf-server02 /]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:16:3e:0a:9a:d4 brd ff:ff:ff:ff:ff:ff
inet 172.21.148.110/20 brd 172.21.159.255 scope global dynamic eth0
valid_lft 315169625sec preferred_lft 315169625sec
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:a0:80:9b:df 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
看到三个网络信息,docker如何处理容器网络访问?使用tomcat镜像做测试!
-
看到容器启动时,docker分配给tomcat01 一个docker内部eth0@if27 ip地址
[root@jf-server02 /]# docker run -d --name tomcat01 tomcat [root@jf-server02 /]# docker exec -it tomcat01 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 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 26: eth0@if27: <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通docker容器内部,再次查看发现,docker为新容器生成新的IP网卡
[root@jf-server02 /]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:16:3e:0a:9a:d4 brd ff:ff:ff:ff:ff:ff
inet 172.21.148.110/20 brd 172.21.159.255 scope global dynamic eth0
valid_lft 315168091sec preferred_lft 315168091sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:a0:80:9b:df 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
27: veth0b3c0b2@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether 62:f3:1c:7e:65:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
所以容器在不指定网络的情况下,都是docker0网卡路由的,docker会给容器分配一个默认的可用IP地址;容器删除后,对应网桥就被删除了;
自定义网络
使用–link进行网络连接
要是容器重启,IP变化了,如何访问容器?
docker提供了
--link命令
测试--link
命令,反向无法ping通
[root@jf-server02 /]# docker run -d -P --name tomcat01 tomcat
81b9e49e91595390dfc315cc2dc874094abeae06381d749474741fd0edab4efb
[root@jf-server02 /]# docker run -d -P --name tomcat02 --link tomcat01 tomcat
eac718df71d9720a15d62f8511136b5b70303d7ea4ec0f9375dacbaf204f55d0
[root@jf-server02 /]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known
[root@jf-server02 /]# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.129 ms
查看tomcat02 hosts配置文件,看到添加了tomcat01映射
[root@jf-server02 /]# docker exec -it tomcat02 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.2 tomcat01 81b9e49e9159
172.17.0.3 eac718df71d9
自定义网络连接
(推荐使用)
[root@jf-server02 /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
3c4dcc9da21b bridge bridge local
891756e520f9 host host local
6b70477c3d00 none null local
网络模式
bridge 桥接模式(docker默认)
none 不配置网络
host 和宿主机共享网络
docker0特点,默认的桥接网络,域名无法访问,使用–link可以进行容器间的连接;
- 自定义网络demonet
[root@jf-server02 /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 demonet
[root@jf-server02 /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
3c4dcc9da21b bridge bridge local
082cd5acc532 demonet bridge local #创建成功
891756e520f9 host host local
6b70477c3d00 none null local
使用tomcat镜像测试效果
[root@jf-server02 /]# docker run -d -P --name tomcat01 --net demonet tomcat
8811a3366fddd90e465c6f46bdc87ca4ff2e726a8b587761841ca50308fdcf53
[root@jf-server02 /]# docker run -d -P --name tomcat02 --net demonet tomcat
d11cfec2e82dd40d63a31787ddf021f028c20961ff76154f2293001d29960bc8
tomcat01 ping tomcat02 可以ping通,无需使用–link,并且更完善
[root@jf-server02 /]# docker exec -it tomcat01 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.demonet (192.168.0.3): icmp_seq=1 ttl=64 time=0.077 ms
假设要跨网络操作容器,就需要使用docker network connect
连通,将此容器加到自定义网络(demonet)中;
案例三: Redis 集群部署
-
创建自定义网络
docker network create redis --subnet 172.38.0.0/16
-
通过脚本创建6个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@jf-server02 ~]# cd /mydata/
[root@jf-server02 mydata]# ls
redis
[root@jf-server02 mydata]# cd redis/
[root@jf-server02 redis]# ls
node-1 node-2 node-3 node-4 node-5 node-6 #创建成功
[root@jf-server02 redis]#
- 启动redis容器(启动六个redis,通过更改端口号,容器名,ip地址,挂载目录)
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@jf-server02 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3c1514ddc977 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:6376->6379/tcp, 0.0.0.0:16376->16379/tcp redis-6
135efe1e44dc redis:5.0.9-alpine3.11 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:6375->6379/tcp, 0.0.0.0:16375->16379/tcp redis-5
278695f5b036 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:6374->6379/tcp, 0.0.0.0:16374->16379/tcp redis-4
8c69e882b4a1 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:6373->6379/tcp, 0.0.0.0:16373->16379/tcp redis-3
4c3f9da0bfa0 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 10 minutes ago Up 10 minutes 0.0.0.0:6372->6379/tcp, 0.0.0.0:16372->16379/tcp redis-2
dfedc0fd6ab8 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 12 minutes ago Up 12 minutes 0.0.0.0:6371->6379/tcp, 0.0.0.0:16371->16379/tcp redis-1
- 进去redis-1容器,创建集群
[root@jf-server02 redis]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof nodes.conf
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
#最后按照提示选择yes创建集群
[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:331
cluster_stats_messages_pong_sent:307
cluster_stats_messages_sent:638
cluster_stats_messages_ping_received:302
cluster_stats_messages_pong_received:331
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:638
127.0.0.1:6379>
验证集群的高可用性
- 进入集群
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
- 步骤一存在redis a的值在 172.38.0.13中,关闭172.38.0.13容器,验证高可用性
[root@jf-server02 ~]# docker stop 8c69e882b4a1
8c69e882b4a1
- 然后在进入集群 get a 的值,发现172.38.0.14中存在a的值b;
/data # redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
案例四:Springboot微服务项目部署
- 构建springboot项目,打包应用,得到demo-0.0.0-SNAPSHOT.jar文件
- 编写dockerfile
- 远程上传jar包和Dockerfile文件,构建镜像,发布运行
[root@jf-server02 demodocker]# ls
demo-0.0.1-SNAPSHOT.jar Dockerfile
[root@jf-server02 demodocker]# docker build -t hello .
Sending build context to Docker daemon 17.05MB
Step 1/5 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete
fce5728aad85: Pull complete
76610ec20bf5: Pull complete
60170fec2151: Pull complete
e98f73de8f0d: Pull complete
11f7af24ed9c: Pull complete
49e2d6393f32: Pull complete
bb9cdec9c7f3: Pull complete
#运行镜像
[root@jf-server02 demodocker]# docker run -d -P --name hello-spring hello
后续:Docker Compose
Docker Swarm
CI/CD之Jenkins
推荐B站狂神说docker教程,热衷开源分享
收藏起来,谨防迷路
以上是关于学Docker(超详细)的主要内容,如果未能解决你的问题,请参考以下文章
超详细实战教程丨多场景解析如何迁移Rancher Server
超详细Docker 配置 nginxphp-fpmmysql phpmyadmin