学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文件中使用RUNCMDFROMEXPOSEENV等指令。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
  1. 注册一个账号:https://hub.docker.com
  2. 在服务器提交镜像
[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
  1. 推送
docker push mycentos:01 #尽量带上版本号 tag
  • 阿里云
  1. 注册阿里云账号,找到容器镜像服务
  2. 登录阿里云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> 

验证集群的高可用性

  1. 进入集群
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
  1. 步骤一存在redis a的值在 172.38.0.13中,关闭172.38.0.13容器,验证高可用性
[root@jf-server02 ~]# docker stop 8c69e882b4a1
8c69e882b4a1
  1. 然后在进入集群 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微服务项目部署

  1. 构建springboot项目,打包应用,得到demo-0.0.0-SNAPSHOT.jar文件

  1. 编写dockerfile

  1. 远程上传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

Docker Compose Swarm后续博文,点我


推荐B站狂神说docker教程,热衷开源分享

收藏起来,谨防迷路


以上是关于学Docker(超详细)的主要内容,如果未能解决你的问题,请参考以下文章

超详细实战教程丨多场景解析如何迁移Rancher Server

如何优雅地删除Docker镜像和容器(超详细)

超详细Docker 配置 nginxphp-fpmmysql phpmyadmin

Docker安装Kafka教程(超详细)

超详细的Spring框架总结,学spring,看这一篇就够了!

区块链DApp从零开始学 | 超详细 DApp创建 | 发行代币token | 宠物领养