容器数据卷

什么是容器数据卷

docker的理念回顾
将应用和环境打包成一个镜像!

  • 数据。如果数据都在容器中,那么我们容器删除,数据就会丢失!
    需求:数据可以持久化
  • MySQL,容器删了,相当于删库跑路!
    需求:mysql数据可以存储在本地!

容器有一个数据共享的技术!Docker容器中产生的数据,同步到本地!这就是卷技术!相当于目录的挂载,将容器内的目录。挂载到linux上面。

总结:容器的持久化和同步操作!容器间也是可以数据共享的!即使容器没有运行,当然容器被干掉就不行了

面试可能会问的小问题:
挂载之后,容器的目录与宿主机的目录同步,那么实际上是同一个目录么?这时数据存储是之前的一倍还是没有变化?
个人理解,实际上并不是同一个目录,只是映射的关系,因为有两个目录了,那数据当然是之前的一倍!

使用数据卷

注意:
目录挂载有时候会出现宿主机和容器内挂载目录都被清空,那么只需要先启动容器,把容器内需要挂载的目录拷贝到宿主机,再进行挂载,具体原因暂时不清楚

方式一:直接用命令来挂载 -v

我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们修改宿主机中的内容就相当于修改了容器中的内容。

# 多个-v 可以挂载多个目录
# 主机目录:容器内目录
docker run -di -v /usr/local/guazaiceshi/:/usr/local/guazaiceshi --name=guazaiceshi --privileged=true b6973f169077 /bin/bash

# 权限不足的时候使用
--privileged=true

# 查看是否挂载成功
docker inspect 容器id
# 找Mounts,source为主机目录,Destination为容器目录

实战,同步Mysql数据

mysql数据都是在data文件夹下,只需要对data目录挂载即可

docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mysql

# 测试,连接Mysql新建一个数据库,就会发现data目录下多了一个文件夹

匿名挂载和具名挂载

# 匿名挂载,这个目录是容器内的目录
docker run -d -P -v /etc/nginx nginx

# 查看所有卷(挂载)列表
docker volume ls

# 参数
inspect # 查看卷信息 # 单个卷信息需要在后面写卷名

DRIVER    VOLUME NAME
local     4aed9b3a9616da9a1cf9decefd435062f9d74f5c34f0ff173cb4741fc1531775
local     238fd52ee900ee9be78d93cf437e265611a3438909f90c1e2ce30db84e4f97e9
local     31536dd6d44083b10e9b57df32c1124a3a4463528e65531f5103e70b86b1e96b

# 这就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径!


# 具名挂载,/代表根目录,不带/则代表配置卷的名字
docker run -d -P -v juming-nginx:/etc/nginx nginx

# local     juming-nginx

所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/卷名/data_下,这也就是同步容器内的文件夹

通过具名挂载可以方便的找到我们的一个卷,大多数情况使用具名挂载

如何确定是具名挂载还是匿名挂载,还是指定路径挂载?

-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径	# 指定路径挂载

读写权限

# ro readonly 只读
# 一旦设置了容器权限,容器内就不可更改了,只能从宿主机改变
docker run -d -P -v juming-nginx:/etc/nginx:ro nginx

docker run -d -P -v juming-nginx:/etc/nginx:rw nginx

方式二Dockerfile

DockerFile就是用来构建docker镜像的构建文件!实际上就是一个命令脚本!

通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层!

# dockerfile 文件中的内容,名字为 Dockerfile
# 指令大写
FROM centos

VOLUME["volume01","volume02"]

CMD echo "---end---"
CMD /bin/bash

# 启动命令
# -f Dockerfile文件
# -t 镜像名
docker build -f dockerfile1 -t kuangshen/centos .
# 完成之后会生成一个 kuangshen/centos 的镜像,启动镜像,容器中会有volume01 volume02两个文件夹,这两个目录就是我们生成镜像的时候自动挂载的,数据卷目录

# 宿主机挂载目录,找mounts
docker inspect 容器id

这种方式我们未来使用的很多,因为我们通常会构建自己的镜像!

假设构建镜像的时候没有挂载,就要手动镜像挂载 -v 卷名:容器内路径!

数据卷容器,–volumes-from

多个mysql同步数据!
在这里插入图片描述

# 先用正常方式run docker01
# docker01 与 docker02 实现同步,因为构建镜像时同步的文件只有volume01 volume02,所以同步的也就只有这两个文件夹
docker run -it --name docker02 --volumes-from docker01 kuangshen/centos

# 此时三个容器对应宿主机的挂载目录是同一目录,所以宿主机的这一目录,也同步这三个容器
docker run -it --name docker03 --volumes-from docker01 kuangshen/centos

# 即使docker01容器被删除,docker02,03和宿主机的同步文件依旧存在

结论:数据卷的生命周期一直持续到没有容器使用为止!

Dockerfile

介绍

dockerfile是用来构建docker镜像的文件!命令参数脚本!

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build 构建成为一个镜像
  3. docker run运行镜像
  4. docker push 发布镜像(docker hub、阿里云镜像仓库!)

基础知识:

  1. 每个保留关键字(指令)都必须是大写字母
  2. 从上到下顺序执行
  3. ‘#’ 表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交!
    在这里插入图片描述
    dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!

docker镜像逐渐成为企业交付的标准,必须要掌握!

DockerFile:构建文件,定义了一切的步骤,源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品!

Docker容器:容器就是镜像运行起来提供服务器!

DockerFile的指令

以前的话我们就是使用别人的,现在我们知道了这些指令后,我们来练习自己写一个镜像!

FROM	# 基础镜像,一切从这里开始构建
MAINTAINER	# 镜像是谁写的,姓名+邮箱
RUN		# 镜像构建的时候需要运行的linux命令
ADD		# 步骤:例如要添加tomcat镜像,就添加tomcat这个压缩包!
COPY	# 类似ADD,将我们文件拷贝到镜像中
WORKDIR	# 镜像的工作目录
VOLUME	# 挂载的目录
EXPOSE	# 暴露端口,和-p是一个道理
CMD		# 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT	# 指定容器启动的时候要运行的命令,可以追加命令
ONBUILD	# 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令。触发指令
ENV		# 构建的时候设置环境变量

CMD和ENTRYPOINT的区别

# dockerfile 内容
FROM centos
CMD ["ls","-a"]

# 构建镜像
docker build -f dockerfile-cmd-test -t cmdtest .

# 运行容器
docker run 113e028fd125

# 运行容器后显示
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 此时追加一个-l命令,期望返回ls -al,
# 但是报错了,是因为CMD的情况下,-l 替换了 CMD ["ls","-a"],而 -l 并不是命令,就报错了
[root@localhost dockerfile]# docker run 113e028fd125 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 


# 正确的命令,略显麻烦,ENTRYPOINT就会避免这个错误
docker run 113e028fd125 ls -al

实战测试

Docker Hub 中99% 镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建
在这里插入图片描述

构建一个自己的centos

下载vim的时候有可能网络延迟下载失败,重新下载就好了

FROM centos
MAINTAINER kuangshen<24736743@11.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
# 构建镜像
# -f dockerfile文件
# -t 生成的镜像名字
docker build -f mydockerfile -t mycentos:0.1 .

查看官方构建步骤

docker history 镜像名/id

[root@localhost dockerfile]# docker history mysql
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
c8562eaf9d81   6 weeks ago   /bin/sh -c #(nop)  CMD ["mysqld"]               0B        
<missing>      6 weeks ago   /bin/sh -c #(nop)  EXPOSE 3306 33060            0B        
<missing>      6 weeks ago   /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B        
<missing>      6 weeks ago   /bin/sh -c ln -s usr/local/bin/docker-entryp…   34B       
<missing>      6 weeks ago   /bin/sh -c #(nop) COPY file:a209112a748b68e0…   13.1kB    
<missing>      6 weeks ago   /bin/sh -c #(nop) COPY dir:2e040acc386ebd23b…   1.12kB    
<missing>      6 weeks ago   /bin/sh -c #(nop)  VOLUME [/var/lib/mysql]      0B        
<missing>      6 weeks ago   /bin/sh -c {   echo mysql-community-server m…   411MB     
<missing>      6 weeks ago   /bin/sh -c echo 'deb http://repo.mysql.com/a…   55B       
<missing>      6 weeks ago   /bin/sh -c #(nop)  ENV MYSQL_VERSION=8.0.23-…   0B        
<missing>      7 weeks ago   /bin/sh -c #(nop)  ENV MYSQL_MAJOR=8.0          0B        
<missing>      7 weeks ago   /bin/sh -c set -ex;  key='A4A9406876FCBD3C45…   2.61kB    
<missing>      7 weeks ago   /bin/sh -c apt-get update && apt-get install…   52.2MB    
<missing>      7 weeks ago   /bin/sh -c mkdir /docker-entrypoint-initdb.d    0B        
<missing>      7 weeks ago   /bin/sh -c set -eux;  savedAptMark="$(apt-ma…   4.17MB    
<missing>      7 weeks ago   /bin/sh -c #(nop)  ENV GOSU_VERSION=1.12        0B        
<missing>      7 weeks ago   /bin/sh -c apt-get update && apt-get install…   9.34MB    
<missing>      7 weeks ago   /bin/sh -c groupadd -r mysql && useradd -r -…   329kB     
<missing>      7 weeks ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      7 weeks ago   /bin/sh -c #(nop) ADD file:422aca8901ae3d869…   69.2MB

实战tomcat镜像

  1. 准备镜像文件 tomcat 压缩包(tomcat官网的包下core的),jdk的压缩包!
  2. 编写dockerfile文件,官方命名为Dockerfile,build会自动寻找这个文件,不需要 -f 指定了
# 下载centos镜像,本地有的话直接提取
FROM centos
MAINTAINER kuangshen<24736743@qq.com>

COPY readme.txt /usr/local/readme.txt

# 添加到该目录,ADD命令是会解压的
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.43.tar.gz /usr/local/

# 安装vim,-y 同意
RUN yum -y install vim

# 工作目录,进入容器就是这个目录,默认是/
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 配置环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.43
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.43
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

# 暴露端口
EXPOSE 8080

# 输出日志
CMD /usr/local/apache-tomcat-9.0.43/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.43/bin/logs/catalina.out
  1. 构建镜像、运行容器
# 构建镜像,注意别忘了最后那个 .
docker build -t diytomcat .

docker run -d -p 9090:8080 --name kuangshentomcat -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.43/webapps/test -v /home/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.43/logs diytomcat
# 就可以访问tomcat了

发布自己的镜像

Dockerhub
因为是国外的,所以会很慢,虚拟机几乎不会成功,涉及到翻墙了

docker login -u 账号 -p 密码

# 自己发布的镜像,尽量带版本
docker push kuangshen/镜像名:版本

# 如果上面的报错,改一下镜像名和版本试试
docker tag 镜像id kuangshen/镜像名:版本

阿里云镜像

  1. 在阿里云找容器镜像服务
  2. 创建命名空间,相当于一个大文件夹,镜像仓库就是放命名空间的文件
$ sudo docker login --username=林夕qazokmzjl registry.cn-beijing.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-beijing.aliyuncs.com/lxstudy/dockertest:[镜像版本号]
$ sudo docker push registry.cn-beijing.aliyuncs.com/lxstudy/dockertest:[镜像版本号]

阿里云镜像参考官方文档,很详细https://cr.console.aliyun.com/cn-beijing/instances/repositories

Jenkins下用DockerFile自动部署Java(SpringBoot)项目

FROM java:8   #java1.8基础镜像
VOLUME /tmp   #创建/tmp目录并持久化到Docker数据文件夹,因为Spring Boot使用的内嵌Tomcat容器默认使用/tmp作为工作目录
MAINTAINER test  #作者名称
ADD web-0.0.1-SNAPSHOT.jar test/test_web0.jar #复制jar到test下且重命名为test_web0.jar
EXPOSE 8506   #容器开放端口
ENTRYPOINT ["java","-jar","-Djava.security.egd=file:/dev/.urandom","test/test_web0.jar"].
#容器执行命令

删除、重载镜像容器等操作shell,这样做感觉不是太好,以后有更好的办法在解决

#!/bin/bash -l
docker stop test_web0;       #停止容器
docker rm test_web0;        #删除容器
docker rmi test/test_web0;      #删除镜像
cd /usr/local/wwwroot/test_web/test_web0;   #进入目录
docker build -t test/test_web0.;     #构建镜像 .为当前目录的dockerfile
docker run -t -d --name test_web0-p 192.168.2.1:8506:8506 test/test_web0; #创建容器

下面这个更专业看起来

这个jar包应该是Jenkins自动会打成jar包的,然后放到本地,也可以选择上传到服务器

d1=$(date "+%Y%m%d%H%M")
name="robot-test"
appName=$name$d1
port=29000
 
mkdir -p /home/$name
cd /home/$name
 
cp /usr/local/soft/jenkins/jenkins-data/workspace/robot-test/robot-api/target/robot-api-yskj0.01-releases.jar app.jar
 
docker rm -f $(docker ps | grep $name | awk '{print $1}')
docker rmi -f $(docker images | grep $name | awk '{print $3}')

cat > Dockerfile << EOF
FROM java:8
EXPOSE $port
 
#复制代码包到镜像内
ADD app.jar /app.jar
ENV TZ=Asia/Shanghai
RUN bash -c 'touch /app.jar'
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENTRYPOINT ["java","-jar","-D user.timezone=GMT+08","/app.jar"]
EOF
 
docker build -t $name:${ImageVersion} .
 
mkdir -R /logs/robotApi
docker run --name $appName -d -v /logs/robotApi/:/logs/robotApi/ -p $port:$port $name:${ImageVersion}

docker网络

理解Docker 0

如果发现docker 0 没有ip地址的话

# 执行下面命令时需要关闭所有容器
vi /etc/docker/daemon.json

# 添加,bip就是docker0启动后的IP地址
# 这个ip为什么这么配,不太懂
{

"bip": "192.168.200.1/24"

}

systemctl restart docker

在这里插入图片描述

lo是本地回环地址
docker0是docker0地址

docker是如何处理容器网络访问的

在这里插入图片描述
发现容器启动的时候会得到一个 eht0@if60 ip地址,docker分配的!

思考:linux 能不能ping通容器内部
可以的
两个容器之间是否可以ping通
可以,

这其实就是个 桥接模式 ,都是通过 “路由器” 来联通的
在这里插入图片描述

结论:tomcat01 和 tomcat02 都是公用的一个路由器,docker 0

所有容器不指定网络的情况下,都是docker 0路由的,docker会给我们的容器分配一个默认的可用ip

计算机原理

255.255.0.1/16

二进制
00000000.00000000.00000000.00000000
转换为十进制
255.255.255.255

16位截止到第二个255,固定也就是255.255

255.255.0.0

IP共有 255 * 255 - 0.0.0.0(回环地址) - 255.255.255.255
大约65535

原理

  1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡 docker 0

桥接模式,使用的技术是 evth-pair 技术!

启动tomcat容器之后,发现又多了一个网卡

我们发现容器带来的网卡,都是一对对的,例如上面的59和60
evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
openStac,Docker容器之间的连接,都是使用 evth-pair 技术

小结

只要容器删除,对应网桥一对就没了!
在这里插入图片描述

– link(不推荐使用)

我们需要的是自定义网络!而不是docker 0!
docker 0问题:不支持容器名连接访问!

思考一个场景,我们编写了一个微服务,访问数据库的时候是ip+什么什么,此时数据库ip重启ip变化了,我们希望可以处理这个问题,就像springCloud的feign访问服务是用的服务的名字,并不是服务的Ip。

# 如果正常启动tomcat01 tomcat02是ping不通的
docker run -d -P --name tomcat03 --link tomcat02 tomcat

# 此时是可以ping通的,但是反向是不通的
docker exec -it tomcat03 ping 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 f903762057df
172.17.0.4      602851931fe2

# 当你访问 tomcat02 它就会去找172.17.0.3

自定义网络

在这里插入图片描述
docker网络模式

bridge:桥接 docker(默认,自己创建也使用bridge模式)
none:不配置网络
host:主机模式,和宿主机共享网络
container:容器内网络连通!(用的少!局限很大)

# 我们之前启动的默认是有这个命令的 --net bridge,而这个就是我们的docker01
docker run -d -P --name tomcat01 --net bridge tomcat

# docker0特点:默认的,域名不能访问,--link可以打通连接!

# 我们可以自定义一个网络!
# --driver bridge 默认的,桥接
# --subnet 子网掩码
# --gateway 网关
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
1e8941d2482253013134cc77cd8c9d3d181ba32d24b9cc174479388d5e903fcf
[root@localhost ~]# docker network ls
NETWORK ID     NAME                     DRIVER    SCOPE
10959e1aeab4   bridge                   bridge    local
69e0e0ea8669   docker-compose_default   bridge    local
db0129761cb6   host                     host      local
1e8941d24822   mynet                    bridge    local
2389fd756942   none                     null      local
8b28db849e71   somenetwork              bridge    local
# 到这为止我们的网络就创建好了
[root@localhost ~]# docker inspect mynet
[
    {
        "Name": "mynet",
        "Id": "1e8941d2482253013134cc77cd8c9d3d181ba32d24b9cc174479388d5e903fcf",
        "Created": "2021-03-11T10:02:19.687427947+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

测试

docker run -d -P --name tomcat-net-01 --net mynet tomcat

docker run -d -P --name tomcat-net-02 --net mynet tomcat

docker inspect mynet
 "Containers": {
            "85f3fb81e713650c33d9ba8c8e3b42eb8cdf2232927007d4016dc144f8af8289": {
                "Name": "tomcat-net-01",
                "EndpointID": "e6c21f9d150b1491273388c78e6f6dd766726d1de27cb02d8c26526ecd964d57",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "a4d1b0c70f463b1741c95e191893c713d1dfd74cb0a1d7ac83e72a89012a9c70": {
                "Name": "tomcat-net-02",
                "EndpointID": "652eb7795d357179ffef341fe51d6b02a837ad2edf60fa0dfba02ac06ff7a1b4",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },

# 以下都是可以ping通的
docker exec -it tomcat-net-01 ping 192.168.0.3
docker exec -it tomcat-net-01 ping tomcat-net-02
docker exec -it tomcat-net-02 ping tomcat-net-01

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!

好处:

不同的集群使用不同的网络,保证集群是安全和健康的

例如mysql集群的网络是192.161.0.0
redis集群的网络是192.162.0.0

网络连通(不同网段)

在这里插入图片描述
tomcat-01是ping不通tomcat-net-01的,因为它们不在同一网段。

Docker0 和 mynet 两个网卡之间也是不可能被打通的。

但是tomcat-01可以加入到mynet的网段中,也就是一个容器两个ip地址!

# 默认就是docker0 的桥接模式
docker run -d -P --name tomcat02 tomcat

# 自定义网络 mynet
docker run -d -P --name tomcat-net-01 --net mynet tomcat

# 将tomcat01加入到mynet网段中
docker network connect mynet tomcat01

[root@localhost ~]# docker inspect mynet
"Containers": {
            "85f3fb81e713650c33d9ba8c8e3b42eb8cdf2232927007d4016dc144f8af8289": {
                "Name": "tomcat-net-01",
                "EndpointID": "e6c21f9d150b1491273388c78e6f6dd766726d1de27cb02d8c26526ecd964d57",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "a4d1b0c70f463b1741c95e191893c713d1dfd74cb0a1d7ac83e72a89012a9c70": {
                "Name": "tomcat-net-02",
                "EndpointID": "652eb7795d357179ffef341fe51d6b02a837ad2edf60fa0dfba02ac06ff7a1b4",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "c2fdeff32c042f0b53aff9f3dfd582ff6fb48aa8b15bb20d2cafe117e486f6ac": {
                "Name": "tomcat01",
                "EndpointID": "46beeb303272d7ec0de96a413f85f1aba182c33081a7b016aad81c3574e24f1a",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            }
        },

结论:
假设要跨网络操作别人,就需要使用 docker network connect 连通!

实战:部署redis集群

在这里插入图片描述

docker network create redis --subnet 172.38.0.0/16

# 通过脚本创建6个redis配置

# 通过for循环,循环6次
for port in $(seq 1 6); \
do \
# 创建redis配置文件
mkdir -p /mydata/redis/node-${port}/conf
# 创建redis config 配置
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



# 按照这个修改规律启动6个节点
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 6372:6379 -p 16372:16379 --name redis-2 -v /mydata/redis/node-2/data:/data -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 进去是/data目录,有appendonly.aof nodes.conf
docker exec -it 13 sh

# 创建集群
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

# 连接集群
redis-cli -c

# 查看集群节点,都正常
127.0.0.1:6379> cluster nodes
c116ed5ba6643ddb5bff08a1dc3c30bf5ac66876 172.38.0.14:6379@16379 slave 4f252038c097cd6266a3f811c49ba9b42f30b428 0 1615433327000 4 connected
9757ebf1f6417508647756f6b37c40bf6b4a7493 172.38.0.11:6379@16379 myself,master - 0 1615433326000 1 connected 0-5460
79265c600c7893f337ccd70ce067f703f9e26852 172.38.0.15:6379@16379 slave 9757ebf1f6417508647756f6b37c40bf6b4a7493 0 1615433327000 5 connected
890099a84f443c2b58bdfce60b3b70441dc75553 172.38.0.16:6379@16379 slave 6fcf5d2fe9f16d626e7ed0273b97d06bc3f8d0ed 0 1615433327000 6 connected
4f252038c097cd6266a3f811c49ba9b42f30b428 172.38.0.13:6379@16379 master - 0 1615433327241 3 connected 10923-16383
6fcf5d2fe9f16d626e7ed0273b97d06bc3f8d0ed 172.38.0.12:6379@16379 master - 0 1615433328270 2 connected 5461-10922
# 设置key value,get a会看到是哪个节点,然后去把该节点的docker stop,
127.0.0.1:6379> set a b
172.38.0.13:6379> get a

# crtl + c退出
redis-cli -c
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"b"
172.38.0.14:6379> cluster nodes
6fcf5d2fe9f16d626e7ed0273b97d06bc3f8d0ed 172.38.0.12:6379@16379 master - 0 1615433676076 2 connected 5461-10922
c116ed5ba6643ddb5bff08a1dc3c30bf5ac66876 172.38.0.14:6379@16379 myself,master - 0 1615433675000 7 connected 10923-16383
890099a84f443c2b58bdfce60b3b70441dc75553 172.38.0.16:6379@16379 slave 6fcf5d2fe9f16d626e7ed0273b97d06bc3f8d0ed 0 1615433674537 6 connected
4f252038c097cd6266a3f811c49ba9b42f30b428 172.38.0.13:6379@16379 master,fail - 1615433499124 1615433497065 3 connected
79265c600c7893f337ccd70ce067f703f9e26852 172.38.0.15:6379@16379 slave 9757ebf1f6417508647756f6b37c40bf6b4a7493 0 1615433675259 5 connected
9757ebf1f6417508647756f6b37c40bf6b4a7493 172.38.0.11:6379@16379 master - 0 1615433674229 1 connected 0-5460

# 此时主节点挂掉,数据仍然可以在从节点获取,实现了高可用

docker 搭建redis集群完成!
我们使用了docker之后,所有的技术都会慢慢的变得简单起来!

springboot微服务打包Docker镜像

  1. 构建springboot项目并打包
    构建好之后写个hello world本地测试成功并打包,再用java -jar jar包名.jar 来进行测试jar包

idea -> settings -> plugins 安装docker,写Dockerfile的时候会有提示
2. 编写dockerfile

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

# 容器启动时要运行的命令
ENTRYPOINT ["java","-jar","/app.jar"]
  1. 构建镜像并发布运行
# --net是因为默认的docker 0网卡启动后,
# 用inspect查询 docker 0,其中的container并没有启动的kuangshen666,原因未知
# 看网上有两种解决方式,一种是重新配置网卡
# 这里使用更简单的,使用自定义网络
docker run -d -P --net mynet kuangshen666

curl localhosT:49165/test

以后我们使用了docker之后,给别人交付的就是一个镜像即可!

到这儿,如果只是一个单纯的开发者,docker的知识其实掌握的差不多了,后面就是企业级开发,更偏向运维一些,例如k8s,不过暂时不打算接触,远没到那个级别

到这儿已经比大多数市面上的教程要更详细更多了,这是狂神在视频里说的,我自己就是培训班出来的,他说的是真的,感谢狂神

转载自:
https://www.bilibili.com/video/BV1og4y1q7M4?from=search&seid=18423066343999250308

部分内容参考自:
https://www.cnblogs.com/liyuchuan/p/13435883.html
https://www.jb51.net/article/194333.htm

刘十三懂了,小学同学最多愚蠢,大学同学很有可能猥琐。

云边有个小卖部
张嘉佳

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐