Docker深入学习

Docker容器学习笔记Ⅱ(狂神说Java)

狂神说B站视频:https://www.bilibili.com/video/BV1og4y1q7M4?p=1

学习docker:https://www.runoob.com/docker/docker-tutorial.html

使用docker:https://labs.play-with-docker.com/

一、大纲

入门:

  • Docker概述

  • Docker安装

  • Docker命令

    • 镜像命令
    • 容器命令
    • 操作命令
    • ……
  • Docker镜像

精髓:

  • 容器数据卷

  • DockerFile

  • Docker网络原理

企业级:

  • IDEA整合Docker

  • 集群

    • Docker Compose
    • Docker Swarm
  • CI/CD Jenkins流水线

七、容器数据卷

1.什么是容器卷?

docker的理念回顾

将应用和环境打包成一个镜像!

数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化

MySQL,容器删除了,删库跑路!需求:MySQL数据可以存储在本地!

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!

这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!

总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!

2.使用数据卷

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[email protected]:~$ docker volume --help

Usage: docker volume COMMAND

Manage volumes

Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes

Run 'docker volume COMMAND --help' for more information on a command.
1
2
3
4
-v, --volume list Bind mount a volume
docker run -it -v 主机目录:容器内目录 -p 主机端口:容器内端口
➜ ~ docker run -it -v /home/ceshi:/home centos /bin/bash
#通过 docker inspect 容器id 查看

再来测试!

1、停止容器

2、宿主机修改文件

3、启动容器

4、容器内的数据依旧是同步的

好处:我们以后修改只需要在本地修改即可,容器内会自动同步!

3.实战:安装MySQL

思考:MySQL的数据持久化的问题

1
# 获取mysql镜像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[[email protected] ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
a076a628af6f: Pull complete
f6c208f3f991: Pull complete
88a9455a9165: Pull complete
406c9b8427c6: Pull complete
7c88599c0b25: Pull complete
25b5c6debdaf: Pull complete
43a5816f1617: Pull complete
1a8c919e89bf: Pull complete
9f3cf4bd1a07: Pull complete
80539cea118d: Pull complete
201b3cad54ce: Pull complete
944ba37e1c06: Pull complete
Digest: sha256:feada149cb8ff54eade1336da7c1d080c4a1c7ed82b5e320efb5beebed85ae8c
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest
1
2
3
4
5
6
7
8
9
10
# 运行容器,需要做数据挂载 #安装启动mysql,需要配置密码的,这是要注意点!
# 参考官网hub https://hub.docker.com/_/mysql
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d
mysql:tag
#启动我们得
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
-- name 容器名字
1
2
[[email protected] ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf -v /home/mysql/data:/etc/mysql/data -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:latest
82f5b7eb56016504512959ec881fc4760456bb62a614ca8aaa1e4cb7d98ad4ec
1
# 启动成功之后,我们在本地使用sqlyog来测试一下

1
2
# native-连接到服务器的3306--和容器内的3306映射
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!

假设我们将容器删除 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[[email protected] mysql]# docker rm -f 82f5b7eb5601
82f5b7eb5601
[[email protected] mysql]# ls
conf data
[[email protected] mysql]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest c8562eaf9d81 8 hours ago 546MB
wiznote/wizserver latest 34c5a021e1c1 6 months ago 1.75GB
elasticsearch latest 5acf0e8da90b 2 years ago 486MB
[[email protected] mysql]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[[email protected] mysql]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f84fe6e51312 wiznote/wizserver "bash /wiz/app/entry…" 2 hours ago Created optimistic_proskuriakova
3de71bbb3db7 34c5a021e1c1 "bash /wiz/app/entry…" 2 hours ago Created nice_kalam
9517379c5255 34c5a021e1c1 "-p 80:6666" 2 hours ago Created distracted_satoshi
0ef8cabd3bb7 wiznote/wizserver:latest "bash /wiz/app/entry…" 2 months ago Exited (137) 3 hours ago WizNode

发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能。

4.具名和匿名挂载

所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data
下如果指定了目录,docker volume ls 是查看不到的。

1
2
# 匿名挂载
-v 容器内路径!
1
2
[email protected]:~$ docker run -d -P  -v /etc/nginx nginx
b60ee929f32fdbc2d0f98aad67dc85ca2e3ebe29450d02114657b87d88622e80
1
2
3
4
5
6
7
# 查看所有的volume的情况
[email protected]:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b60ee929f32f nginx "/docker-entrypoint.…" 24 seconds ago Up 21 seconds 0.0.0.0:49153->80/tcp lucid_blackwell
[email protected]:~$ docker volume ls
DRIVER VOLUME NAME
local 754e0542ce40a802a3bf79df05c44ccff9b137347153b8ce7988f49f0455b732
1
2
3
4
5
6
7
8
9
10
11
12
# 这里发现,这种就是匿名挂载,我们在 -v只写了容器内的路径,没有写容器外的路径!

# 具名挂载
[email protected]:~$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
f89ce3a25e626a69d70c2b903d5cd68b53cbe5594485e0c5b843ccc2508c28d9
[email protected]:~$ docker volume ls
DRIVER VOLUME NAME
local 754e0542ce40a802a3bf79df05c44ccff9b137347153b8ce7988f49f0455b732
local juming-nginx

# 通过 -v 卷名:容器内路径
# 查看一下这个卷

所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxxx/_data下。

如果指定了目录,docker volume ls 是查看不到的。

1
2
3
4
5
6
[email protected]:~$ docker run -d -P -v /home/nginx:/etc/nginx nginx
38c0e3bab52fc8f411e8078c17c43a39aa3a98081ab021a96e9d32855b41dc01
[email protected]:~$ docker volume ls
DRIVER VOLUME NAME
local 754e0542ce40a802a3bf79df05c44ccff9b137347153b8ce7988f49f0455b732
local juming-nginx

如何区别匿名挂载、具名挂载、指定路径挂载

1
2
3
4
5
# 三种挂载: 匿名挂载、具名挂载、指定路径挂载

-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的

拓展

ro rw 改变读写权限

1
2
3
4
5
6
ro #readonly 只读
rw #readwrite 可读可写

docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!

5.初识Dockerfile

挂载的方式二

Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!先体验一下!

通过这个脚本可以生成镜像,镜像。启动自己写的镜像。

1
2
3
4
5
6
7
# 创建一个dockerfile文件,名字可以随便 建议Dockerfile
# 文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#这里的每个命令,就是镜像的一层!
1
[email protected]:~/docker-test$ docker build -f dockerfile01 -t baixf/centos .

进入生成的镜像,查看一下卷挂载

1
docker run -it baixf/centos /bin/bash

这个卷在主机一定有一个同步目录(匿名挂载)。

baixf/centos测试一下/volume1/¥¥新建文件看同步出去了!

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

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

6.数据卷容器

多个MySQL同步数据!

1
# centos01为父容器
1
# 启动3个容器

1.启动docker01

2.启动docker02并在数据卷volume01内新建文件

3.检查docker01中的volume01中是否有这个文件。

4.新建docker03继承docker01,并查看volume01内是否有刚刚新建的文件。

5.删除docker01容器,查看docker02 d0cker03数据是否还存在。

6.此时在docker02中新建一个文件查看docker03能否同步。

以上例子所示,docker02 03共同继承docker01,如果将docker01删除,docker02 03 仍保留数据,docker02 03仍可同步数据。

多个mysql实现数据共享

1
2
3
4
5
6
7
8
➜ ~ 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=123456 --name mysql01
mysql:5.7

➜ ~ docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name
mysql02 --volumes-from mysql01 mysql:5.7

# 这个时候,可以实现两个容器数据同步!

结论:

容器之间bing的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。(病毒)

但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

八、DockerFile

1.DockerFile介绍

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

构建步骤:

1、 编写一个dockerfile文件

2、 docker build 构建称为一个镜像

3、 docker run运行镜像

4、 docker push发布镜像(DockerHub 、阿里云仓库)

但是很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!

官方既然可以制作镜像,那我们也可以!

2.DockerFile构建过程

基础知识:

1、每个保留关键字(指令)都是必须是大写字母

2、执行从上到下顺序

3、#表示注释

4、每一个指令都会创建提交一个新的镜像曾,并提交!

Dockerfile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简
单!

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

(之前是jar war包)

步骤:开发,部署,运维。缺一不可!

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

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

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

3.DockerFile常用指令

以前的话是使用别人的,,现在我们要自己做一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令,触发指
令。
COPY # 类似 ADD ,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!

4.实战测试

Docker Hub 中的99%镜像都是从FROM scratch 这个基础镜像开始的,然后配置相应的软件和配置来构建的。

创建一个自己的centos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1.编写Dockerfile文件
[email protected]:~/docker-test$ cat dockerfile02
FROM centos
MAINTAINER baixf<[email protected]>

ENV MYPATH /usr/local
WORKDIR MYPATH

RUN yum install vim
RUN yun install net-tools

EXPOSE 80

CMD echo MYPATH
CMD echo "----end----"
CMD /bin/bash
1
2
3
4
5
6
# 2、通过这个文件构建镜像
# 命令 docker build -f 文件路径 -t 镜像名:[tag] .
[email protected]:~/docker-test$ docker build -f dockerfile02 -t mycentos:1.0 .

Successfully built 031644e6e6f2
Successfully tagged mycentos:1.0

测试运行

1
# docker history 镜像id  查看镜像操作历史记录

查看官方其他镜像制作 dockerfile

1
# mysql

1
# tomcat

CMD 和 ENTRYPOINT 的区别

1
2
3
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替
代。
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# CMD测试
# dockerfile03
FROM centos
CMD ["ls","-a"]

# build
docker build -f dockerfile03 -t cmdtest .

#run【正常👍】
[email protected]:~/docker-test$ docker run cmdtest
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 追加命令【ERROR❌】
[email protected]:~/docker-test$ docker run cmdtest -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[0001] error waiting for container: context canceled
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# ENTRYPOINT 测试
# dockerfile04
FROM centos
ENTRYPOINT ["ls","-a"]

#build
docker build -f dockerfile04 -t entrypointtest .


# 追加执行【正常】👍

[email protected]:~/docker-test$ docker run entrypointtest -l
total 56
drwxr-xr-x 1 root root 4096 Jan 19 13:20 .
drwxr-xr-x 1 root root 4096 Jan 19 13:20 ..
-rwxr-xr-x 1 root root 0 Jan 19 13:20 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 15:23 bin -> usr/bin
drwxr-xr-x 5 root root 320 Jan 19 13:20 dev
drwxr-xr-x 1 root root 4096 Jan 19 13:20 etc
drwxr-xr-x 2 root root 4096 Nov 3 15:23 home
lrwxrwxrwx 1 root root 7 Nov 3 15:23 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 15:23 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:44 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 15:23 media
drwxr-xr-x 2 root root 4096 Nov 3 15:23 mnt
drwxr-xr-x 2 root root 4096 Nov 3 15:23 opt
dr-xr-xr-x 230 root root 0 Jan 19 13:20 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:45 root
drwxr-xr-x 11 root root 4096 Dec 4 17:45 run
lrwxrwxrwx 1 root root 8 Nov 3 15:23 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 15:23 srv
dr-xr-xr-x 12 root root 0 Jan 19 13:20 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:45 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:44 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:45 var

Dockerfile中很多命令都十分的相似,我们需要了解它们的区别,我们最好的学习就是对比他们然后测
试效果!

5.实战:Tomcat镜像

1.准备镜像文件 tomcat 和 jdk 的压缩包。

2.编写 Dokerfile 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM centos #
MAINTAINER baixf<[email protected]>

COPY README /usr/local/README #复制文件

ADD jdk-8u231-linux-x64.tar.gz /usr/local/ #复制解压,add会自动解压
ADD apache-tomcat-9.0.22.tar.gz /usr/local/ #复制解压,add会自动解压

RUN yum -y install vim

ENV MYPATH /usr/local #设置环境变量
WORKDIR $MYPATH #设置工作目录

ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HONE/bin

EXPOSE 8080 #设置暴露的端口

CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apachetomcat-9.0.22/logs/catalina.out # 设置默认命令

3、构建镜像

1
docker build -t diytomcat:0.1 .

4、run镜像

1
2
docker run -d -p 8080:8080 --name tomcat01 -v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs
mytomcat:0.1

5、访问测试

1
#宿主机:curl localhost:9090

6、发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了!)

发现:项目部署成功,可以直接访问!

我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!

6.发布自己的镜像

  • Dockerhub

    1.注册账号
    2.确定这个账号可以登录
    3.登录

1
2
3
4
5
6
7
8
9
10
11
[email protected]:~/docker-test$ 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
1
2
3
4
5
6
7
8
9
10
[email protected]:~/docker-test$ docker login -u baixfxyz
Password:
WARNING! Your password will be stored unencrypted in /home/pi/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

[email protected]:~/docker-test$ docker logout
Removing login credentials for https://index.docker.io/v1/

4.登陆即可,提交 push 镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[email protected]:~/docker-test$ docker push mycentos:1.0
The push refers to repository [docker.io/library/mycentos]
b2f7e775e8e8: Preparing
16764cdd1bc4: Preparing
denied: requested access to the resource is denied
# 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library

# 解决方法
# 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
$ docker build -t chengcoder/mytomcat:0.1 .
# 第二种 使用docker tag #然后再次push
$ docker tag 容器id chengcoder/mytomcat:1.0
#然后再次push
看官网 很详细https://cr.console.aliyun.com/repository/
  • 阿里云镜像服务上

看官网 很详细https://cr.console.aliyun.com/repository/

1.登录阿里云

2.找到容器镜像服务

3.创建命名空间

4.创建容器镜像

1
2
3
4
$ sudo docker login --username=白小飞23335 registry.cn-beijing.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-beijing.aliyuncs.com/aliyun-0-docker/baixf-docker:[镜像版本号]
$ sudo docker push registry.cn-beijing.aliyuncs.com/aliyun-0-docker/baixf-docker:[镜像版本号]
请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。

7.小结

拓展命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 压缩🗜
[email protected]:~/docker-test$ docker save --help

Usage: docker save [OPTIONS] IMAGE [IMAGE...]

Save one or more images to a tar archive (streamed to STDOUT by default)

Options:
-o, --output string Write to a file, instead of STDOUT

# 加载
[email protected]:~/docker-test$ docker load --help

Usage: docker load [OPTIONS]

Load an image from a tar archive or STDIN

Options:
-i, --input string Read from tar archive file, instead of STDIN
-q, --quiet Suppress the load output

九、Docker 网络

1.理解Docker 0

清空环境!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 清空所有网络
[email protected]:~$ docker rm -f $(docker ps -aq)
5dcf3101615d
edc3cd5cbb9b
3bb8ed02e68c
53b9c300d387
ae2cfd05203b
9fcea1f7cbe0
95287e1750f5
576d355f51c8
782c0b38337d
ef483955a1ee
31ed87fa60d6
ef259865413d
38c0e3bab52f
f89ce3a25e62
b60ee929f32f
96bda453ea8b
54c30f206041
d2f86a05fc73
52a80307a7fc
31df0aa6fb9e
5a1b3e72a2e4
c86f35254ea1
e7c4a115ff36
9cbf742ee266
a535e5ba619c
f4311e01d778
e6b768a79f51
0c96b8cf9bc2
09bcaba4de1f
0eaf062ca9fb
f31980e0ab6a
792d5e8c7575
5d4de87f016f
76bd27490955
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# docker删除所有镜像

[email protected]:~$ docker rmi -f $(docker images -aq)
Untagged: entrypointtest:latest
Deleted: sha256:3459497a6f33985afe63dc36a0f0b794defdb76c3974056c9a5f0d8ca242d112
Untagged: cmdtest:latest
Deleted: sha256:3c53210e3778da8985410fd8b337e36642a77bea744b78be417c0cc8375fc7a1
Untagged: mycentos:1.0
Deleted: sha256:031644e6e6f2aaaa19da04b0f0d16ca5bf6c2cbcb9809240f6dcaa0f69029672
Deleted: sha256:eb0c768082054902771e1f2472339e2165461b465c925e2bded425e664d7e429
Deleted: sha256:c39bd5d9475073b945d822f2cf6a6d4da5354ecda0c6c108d97809a415155188
Deleted: sha256:5bc857eb704af9e2cfabb2168a5b269a7e773fd5b11f28b9a67bf02130bf45eb
Deleted: sha256:4d7f5bac46f9282d268516aa34ac23ee2461a9fb604b859d9ccdc64f14b1d51f
Deleted: sha256:007c7aaad1025cc82b2cf930f4b9dca5fe17f752d43543a785c41461dba3891c
Deleted: sha256:fbd181bb730e6eff3ce209801fbb8eaff247a296229aad2c7be456517472872f
Deleted: sha256:2cf8bf16568fab9497bfe313623e711924ef9d517927eccd0d6abbefb62ab1c0
Untagged: baixf/centos:latest
Deleted: sha256:ddd32d4effdd7d9dd473c4dad875d6e8734b697f00278e69e4fee8a8945e4e63
Deleted: sha256:26d3ed80b9235716a6eadf283de74c16927a9e5d95e21cb5232dbe2edea7ccdf
Deleted: sha256:82319feb9890c866a0264e8f4a2e76546f3b7b73ef66c7ca1cbfd9291bccc812
Untagged: tomcat:66
Deleted: sha256:60e208f14f34aeb7a338d3d238cde22f1cb342dbd83265b71909aea146118d56
Deleted: sha256:78dacba1b96f3738579287e45619f6b266b3ef11239c1d1a9531c0dde9436f32
Untagged: tomcat:1.0
Deleted: sha256:83ac74acd5e011fa39241a5d1c4c43ad65cc9b6a68d5cbbac96db14917e6e000
Deleted: sha256:1329ab2e7df2548e6df50cb7136a5200cb6c57343293a39446f6377849118224
Untagged: redis:latest
Untagged: [email protected]:0f97c1c9daf5b69b93390ccbe8d3e2971617ec4801fd0882c72bf7cad3a13494
Deleted: sha256:aab98baa141a5336da8748325b8ef41bb387276bc8215b32070f38c27de20733
Deleted: sha256:605d5301258d50af4f8d1f6287fa8d19e298f2b3fa713d54ac0afef873a2c739
Deleted: sha256:b7dba623b62968065543ddd904ef25659953d3a23bb6d27678a311c0dc044e74
Deleted: sha256:ab1ac7683b4e74b5f6a69ab622d30c2db2311191b68c8ff870c47ce965fe916f
Deleted: sha256:fd21bb159809171cae4f0a9f25418f59c9648868d6c3f6dcf6e0d95263d14b17
Deleted: sha256:fe784928e3300261632064b45d268faa2b8cfe0bb046d04524b3314cf3b4ba86
Untagged: tomcat:latest
Untagged: [email protected]:94cc18203335e400dbafcd0633f33c53663b1c1012a13bcad58cced9cd9d1305
Deleted: sha256:688bd6a32df3e2c59d42dee0ea343a962f33308f02226ad1785d6b287ba2f33a
Deleted: sha256:b9fdf641d7fa89de59127b60302297c2c230c826ef3583e1af4ebf446033e99e
Deleted: sha256:98b2e5f6158f9689b6a1e14f1850eb9919525a77d9212058d62c0e70e46d1614
Deleted: sha256:b607261c17e5a3878e2c8f17102c8acd31cc10afe624a5593c2d0d4cffa8dc16
Deleted: sha256:549688c0055d8ccafcea97a203f59d716c30f300d55aa2519095b8925c600209
Deleted: sha256:f4c5a2eb902fc3661085c4101e454509cc20b0f9619ef506e28fe29ebaad3f10
Deleted: sha256:0f3633510041342910c1312156ea5e0f5dc0a250a76c35cd6610632fb4bf6823
Deleted: sha256:7671fe9d1ffb73c4f320db3729569ba104582370ec2f8b0d1e9b8a5738fe6ef3
Deleted: sha256:12f5d1640038ea6b949341ea394e8af61b3a684ec05b5a1e48ffd2050b6e9290
Deleted: sha256:c19a8558650d94114779314f952eb65d2baca80cdc396e3e28d8cae815201c5b
Deleted: sha256:7ce7f234bab77e0253069b93abf52000e714b9fe82ad5e3b47d60bbde097781b
Untagged: nginx:latest
Untagged: [email protected]:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
Deleted: sha256:9b016c5aa4e8f867e102fac18f0ecaed7b151c798b70354afdb54a24e76462ab
Deleted: sha256:4f68a3976989e90f271414a0b504ed7960b315bd42dad0ae8d8c2d8cf850c266
Deleted: sha256:e119254da86e1a89e11868661c511ffe6ca7a4956bb8c66c9d05d6d6dfcc37cb
Deleted: sha256:c4ca4f3b6bc0bdcc9eecf38c44af52931bd0e73fecd779625b761c07e5b300d4
Deleted: sha256:5e9255d400c476d794a592be75b3eaa460ef233ed96a970d79b46d00b93b1ce2
Deleted: sha256:5c4f3d84264daaff85b2f005a4c295693e48c0e9c3ae76e64a7f3914e94e583b
Untagged: centos:latest
Untagged: [email protected]:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Deleted: sha256:a0477e85b8aebf57d58bfa74a6598eccfd3fcc43a78c8e29c380cde2e7300a1b
Deleted: sha256:16764cdd1bc476620e90917137529491698856d33294e38e7e11b0444715eb24
Untagged: hello-world:latest
Untagged: [email protected]:31b9c7d48790f0d8c50ab433d9c3b7e17666d6993084c002c2ff1ca09b96391d
Deleted: sha256:a29f45ccde2ac0bde957b1277b1501f471960c8ca49f1588c6c885941640ae60
Deleted: sha256:167d9097a0a0c9ad3c82d85cdd3d078db0410523d29251194ef08288cb785a2a
Error: No such image: eb0c76808205
Error: No such image: c39bd5d94750
Error: No such image: 5bc857eb704a
Error: No such image: 4d7f5bac46f9
Error: No such image: 2cf8bf16568f
Error: No such image: fbd181bb730e
Error: No such image: 26d3ed80b923
Error: No such image: 82319feb9890
1
2
3
4
5
6
# 查看

[email protected]:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[email protected]:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  • 测试

三个网络

1
问题: docker 是如果处理容器网络访问的?

1
2
3
4
5
# 测试 运行一个tomcat
[email protected]:~$ docker run -d -P --name tomcat01 tomcat

# 查看容器内网络地址 ip addr 发现容器启动的时候会得到[email protected]的ip ip地址,docker分配!
[email protected]:~$ docker exec -it tomcat01 ip addr

1
# 思考:linux能否ping通这个网络
1
2
3
4
5
6
7
8
9
[email protected]:~$ 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.284 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.105 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.177 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.127 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.121 ms

# linux 可以 ping 通 docker 容器内部
  • 原理

1.我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,
就会有一个docker0桥接模式,使用的技术是veth-pair技术!

再次测试 ip addr

2.在启动一个容器测试,发现又多了一对网络

1
2
3
4
5
6
[email protected]:~$ docker run -d -P  --name tomcat02 tomcat
327db62f9f2ada6eca1c8b15419ddeaee534096208d12301a38804d964f69f5d

[email protected]:~$ docker exec -it tomcat01 ip addr

[email protected]:~$ docker exec -it tomcat02 ip addr

1
2
3
4
我们发现这个容器带来网卡,都是一对对的
veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术

3、我们来测试下tomcat01和tomcat02是否可以ping通

1
2
3
[email protected]:~$ docker exec -it tomcat01 ping 172.17.0.3

[email protected]:~$ docker exec -it tomcat01 ping 172.17.0.2

结论:tomcat01和tomcat02公用一个路由器,docker0。

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

拓展:计算机网络

255.255.0.1/16 域 局域网!

00000000.00000000.00000000.00000000

255.255.0.0 - 255.255.255.255 255*255-2

小结: Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0

Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)

只要容器停止或者删除,对应的网桥一对就没了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[email protected]:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
327db62f9f2a tomcat "catalina.sh run" 34 minutes ago Up 34 minutes 0.0.0.0:49154->8080/tcp tomcat02
14c6b9b831c4 tomcat "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:49153->8080/tcp tomcat01
[email protected]:~$ docker stop 327db62f9f2a
327db62f9f2a
[email protected]:~$ 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
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether dc:a6:32:32:3f:f3 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.103/24 brd 192.168.1.255 scope global dynamic noprefixroute eth0
valid_lft 7037sec preferred_lft 7037sec
inet6 fe80::8074:3558:bc0f:6a10/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000
link/ether dc:a6:32:32:3f:f5 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.101/24 brd 192.168.1.255 scope global dynamic noprefixroute wlan0
valid_lft 7083sec preferred_lft 7083sec
inet6 fe80::b147:6e97:3e61:9203/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:d1:83:a7:72 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
inet6 fe80::42:d1ff:fe83:a772/64 scope link
valid_lft forever preferred_lft forever
5: docker_gwbridge: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:a8:dd:7b:50 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global docker_gwbridge
valid_lft forever preferred_lft forever
7: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 72:e0:76:05:2c:0d brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 169.254.138.46/16 brd 169.254.255.255 scope global noprefixroute veth42162a4
valid_lft forever preferred_lft forever
inet6 fe80::70e0:76ff:fe05:2c0d/64 scope link
valid_lft forever preferred_lft forever

思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ping不通
[email protected]:~$ docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known


# 运行一个tomcat03 --link tomcat02
[email protected]:~$ docker run -d -P --name tomcat03 --link tomcat02 tomcat
31110eb8ef9e9202e40c0fdb4c8522ee39cef4df1929fba4390b7e1614db8bfa

# 用tomcat03 ping tomcat02 可以ping通
[email protected]:~$ docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.630 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.167 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.142 ms


# 用tomcat02 ping tomcat03 ping不通
[email protected]:~$ docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看docker network --help
[email protected]:~$ docker network --help

Usage: docker network COMMAND

Manage networks

Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.
1
2
3
4
5
6
[email protected]:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
421f2c2a5ec7 bridge bridge local
eb4bd4907eff docker_gwbridge bridge local
06a3c9e409f6 host host local
e129f1c57a68 none null local

探究: docker network inspect 网络id 网段相同

1
docker inspect 421f2c2a5ec7

1
docker inspect tomcat03

查看tomcat03里面的/etc/hosts发现有tomcat02的配置

1
docker exec tomcat03 cat /etc/hosts

本质探究:–-link 本质就是在hosts配置中添加映射

现在使用 Docker 已经不建议使用 –link 了!

自定义网络,不适用 docker0!

docker0 问题:不支持容器名连接访问!

3.自定义网络

  • 查看所有的docker网络
1
2
3
4
5
6
[email protected]:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
421f2c2a5ec7 bridge bridge local
eb4bd4907eff docker_gwbridge bridge local
06a3c9e409f6 host host local
e129f1c57a68 none null local

网络模式

bridge :桥接 docker(默认,自己创建也是用bridge模式)

none :不配置网络,一般不用

host :和宿主主机共享网络

container :容器网络连通(用得少!局限很大)

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat

# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦!

# 我们可以 自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

[email protected]:~$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
3a84276ed04cc6fd1cc499a9b63b7d4957b83a599a7d65e8bd483cad5cd4200b

[email protected]:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
421f2c2a5ec7 bridge bridge local
eb4bd4907eff docker_gwbridge bridge local
06a3c9e409f6 host host local
3a84276ed04c mynet bridge local
e129f1c57a68 none null local

我们自己的网络就创建好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
[email protected]:~$ docker run -d -P --name tomcat-net-01 --net mynet tomcat
b650b67f860b9e1db725b185d018430fa5cd101691933a28d6791937bc7112eb
[email protected]:~$ docker run -d -P --name tomcat-net-02 --net mynet tomcat
8fc5140b4d55da708a13f8777f3fe18a9c627c1ed3c72f6b55134b4113f02e08
[email protected]:~$ docker inspect mynet
[
{
"Name": "mynet",
"Id": "3a84276ed04cc6fd1cc499a9b63b7d4957b83a599a7d65e8bd483cad5cd4200b",
"Created": "2021-01-20T16:11:39.555402615+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": {
"8fc5140b4d55da708a13f8777f3fe18a9c627c1ed3c72f6b55134b4113f02e08": {
"Name": "tomcat-net-02",
"EndpointID": "9ddc507c5a7c61cc8bfb4309ef99e2bbd512c95711ca24d1f7f56d82aa0ac2ff",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"b650b67f860b9e1db725b185d018430fa5cd101691933a28d6791937bc7112eb": {
"Name": "tomcat-net-01",
"EndpointID": "91231509fd2ff4c96a09cd558b7ef438ff4b1c7d76881417119473a43dee3878",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]

自定义网络可以互相ping通

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#在自定义的网络下,服务可以互相ping通,不用使用–link

[email protected]:~$ docker exec -it tomcat-net-01 ping 192.168.0.3
docker exec -it tomcat-net-01 ping tomcat-net-02PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.619 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.215 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.148 ms
64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.186 ms

[email protected]:~$ docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.230 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.238 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.285 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.163 ms

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

好处:

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

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

4.网络连通

1
2
3
4
5
6
7
8
9
10
11
12
13
# 在docker0启动tomcat01

[email protected]:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8fc5140b4d55 tomcat "catalina.sh run" 26 minutes ago Up 26 minutes 0.0.0.0:49158->8080/tcp tomcat-net-02
b650b67f860b tomcat "catalina.sh run" 26 minutes ago Up 26 minutes 0.0.0.0:49157->8080/tcp tomcat-net-01
[email protected]:~$ docker run -d -P --name tomcat01 tomcat
163d7c78f25272bd6f9caed9310cd9ee89f17e6b262a400191f14c62d44e202e
[email protected]:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
163d7c78f252 tomcat "catalina.sh run" 6 seconds ago Up 4 seconds 0.0.0.0:49159->8080/tcp tomcat01
8fc5140b4d55 tomcat "catalina.sh run" 27 minutes ago Up 27 minutes 0.0.0.0:49158->8080/tcp tomcat-net-02
b650b67f860b tomcat "catalina.sh run" 27 minutes ago Up 27 minutes 0.0.0.0:49157->8080/tcp tomcat-net-01

1
2
3
4
5
6
# 测试打通 tomcat01 - mynet

[email protected]:~$ docker network connect mynet tomcat01

# 查看mynet
[email protected]:~$ docker network inspect mynet

1
2
3
# 连通之后就是将tomcat01放到了mynet网络下
# 一个容器两个ip
# 公网ip 私网ip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 测试tomcat01与tomcat-net-01是否ping通

[email protected]:~$ docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.414 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.225 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.305 ms
64 bytes from tomcat-net-01.mynet
[email protected]:~$ docker exec -it tomcat-net-01 ping tomcat-01
ping: tomcat-01: Name or service not known
[email protected]:~$ docker exec -it tomcat-net-01 ping tomcat01
PING tomcat01 (192.168.0.4) 56(84) bytes of data.
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.251 ms
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=2 ttl=64 time=0.381 ms
64 bytes from tomcat01.mynet (192.168.0.4): icmp_seq=3 ttl=64 time=0.157 ms

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

5.实战:部署Redis集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 创建网卡
docker network create redis --subnet 172.38.0.0/16

# 通过脚本创建六个redis配置
for port in $(seq 1 6);\
do \
sudo mkdir -p /mydata/redis/node-${port}/conf
sudo touch /mydata/redis/node-${port}/conf/redis.conf
sudo 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

# 通过脚本运行六个redis
for port in $(seq 1 6);\
do \
docker run -p 637${port}:6379 -p 1667${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
done

# 随便进入一个
docker exec -it redis-1 /bin/sh
#redis默认没有bash

# 创建集群
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
[email protected]:/# for port in $(seq 1 6);\
> do \
> sudo mkdir -p /mydata/redis/node-${port}/conf
> sudo touch /mydata/redis/node-${port}/conf/redis.conf
> sudo 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


[email protected]:/# for port in $(seq 1 6);\
> do \
> docker run -p 637${port}:6379 -p 1667${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
> done
66269c755eaee88688ea01efd231b9c57872c230a1bec940124ea9e2aea2c99a
7e8b48f50e8b74e45ed97a134866ba0a30845afe67a493bd2d083232ad17780f
874c17ffc961098ee3902018b1d8bdfb7e7589b227e3eeaced667fa50cc8e2a2
dc14eb2816a645926bc78d8a2a203f5b885574f0c87f87ab04a3f9deab9270db
fe1f79c3536c674fb758229c103a23e306ca6ecee1b736119c59c386f76f29af
1de56ee718ed60fbd71a8af241a36b60cb4f55422838b68ff15315be04154c08


[email protected]:/# 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
>>> 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: a33d8e303927c7f9d0a3d12137f0174504f0c1a3 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: 81d1c6db29f3e041285968f2e1648eeaa648441c 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 67dff49fc0e891df591fac841b07ec62851edf7c 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 218238df71f0b8baf0ca4fd47c18a9aabeb4abd4 172.38.0.14:6379
replicates 67dff49fc0e891df591fac841b07ec62851edf7c
S: b8175dbdf99e75577df2c6c575f6d62f364323aa 172.38.0.15:6379
replicates a33d8e303927c7f9d0a3d12137f0174504f0c1a3
S: d6fcb4f6de9dc0d9ffb6461624b0a882150028e3 172.38.0.16:6379
replicates 81d1c6db29f3e041285968f2e1648eeaa648441c
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.....
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: a33d8e303927c7f9d0a3d12137f0174504f0c1a3 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 81d1c6db29f3e041285968f2e1648eeaa648441c 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: d6fcb4f6de9dc0d9ffb6461624b0a882150028e3 172.38.0.16:6379
slots: (0 slots) slave
replicates 81d1c6db29f3e041285968f2e1648eeaa648441c
S: 218238df71f0b8baf0ca4fd47c18a9aabeb4abd4 172.38.0.14:6379
slots: (0 slots) slave
replicates 67dff49fc0e891df591fac841b07ec62851edf7c
M: 67dff49fc0e891df591fac841b07ec62851edf7c 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: b8175dbdf99e75577df2c6c575f6d62f364323aa 172.38.0.15:6379
slots: (0 slots) slave
replicates a33d8e303927c7f9d0a3d12137f0174504f0c1a3
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

docker搭建redis集群完成!

拓展:redis玩一玩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 进入集群模式 -c:集群 无参:单机模式

/data # redis-cli -c
127.0.0.1:6379>

# 查看集群信息
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:521
cluster_stats_messages_pong_sent:507
cluster_stats_messages_sent:1028
cluster_stats_messages_ping_received:502
cluster_stats_messages_pong_received:521
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1028

172.38.0.13:6379> cluster nodes # 查看节点数目
d6fcb4f6de9dc0d9ffb6461624b0a882150028e3 172.38.0.16:[email protected] slave 81d1c6db29f3e041285968f2e1648eeaa648441c 0 1611137999000 6 connected
81d1c6db29f3e041285968f2e1648eeaa648441c 172.38.0.12:[email protected] master - 0 1611137999000 2 connected 5461-10922
218238df71f0b8baf0ca4fd47c18a9aabeb4abd4 172.38.0.14:[email protected] slave 67dff49fc0e891df591fac841b07ec62851edf7c 0 1611137998000 4 connected
67dff49fc0e891df591fac841b07ec62851edf7c 172.38.0.13:[email protected] myself,master - 0 1611137998000 3 connected 10923-16383
a33d8e303927c7f9d0a3d12137f0174504f0c1a3 172.38.0.11:[email protected] master - 0 1611138000096 1 connected 0-5460
b8175dbdf99e75577df2c6c575f6d62f364323aa 172.38.0.15:[email protected] slave a33d8e303927c7f9d0a3d12137f0174504f0c1a3 0 1611137999092 5 connected

# slave是从节点 master是主节点

127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379 # 当前处理的数据存在了节点为13.6379 master节点
OK

# 选举机制
# 高可用机制体现👇

我们使用docker之后,所有的技术都会慢慢变得简单起来!

十、SpringBoot微服务打包Docker镜像

1.构建SpringBoot项目

2.打包运行

1
mvn package

3.编写dockerfile

1
2
3
4
5
6
7
8
9
FROM java:8

COPY *.jar /app.jar

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

EXPOSE 8080

ENTRYPOINT ["java","-jar","app.jar"]
  1. 构建镜像
1
2
3
4
# 1.复制jar和Dockerfile到服务器

# 2.构建镜像
docker build -t xxxxx:xx .

5.发布运行 以后我们使用了Docker之后,给别人交付就是一个镜像即可!

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

mmexport1612022824914

参考


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!