Docker 学习笔记

1.简介

Docker是一个开源的应用容器引擎;是一个轻量级容器技术;

Docker支持将软件编译成一个镜像;然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像;

运行中的这个镜像称为容器,容器启动是非常快速的。

image-20200714183144806

2.核心概念

docker主机(Host):安装了Docker程序的机器(Docker直接安装在操作系统之上);

docker客户端(Client):连接docker主机进行操作;

docker仓库(Registry):用来保存各种打包好的==软件镜像==;

docker镜像(Images):软件打包好的镜像;放在docker仓库中;好比是一个模板,可以通过这个模板创建多个容器,最终服务运行或项目运行就是在容器中

docker容器(Container):镜像启动后的==实例==称为一个容器;容器是独立运行的==一个或一组应用==/可以理解为一个简易的Linux系统

使用docker步骤:

1)、安装Docker

2)、去Docker仓库找到这个软件对应的镜像;

3)、使用Docker运行这个镜像,这个镜像就会生成一个Docker容器;

4)、对容器的启动停止就是对软件的启动停止;

安装过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1、检查内核版本,必须是3.10及以上
uname -r
2、安装docker
yum install docker
3、输入y确认安装
4、启动docker
[root@localhost ~]# systemctl start docker
[root@localhost ~]# docker -v
Docker version 1.12.6, build 3e8e77d/1.12.6
5、开机启动docker
[root@localhost ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
6、停止docker
systemctl stop docker

3.常用操作

操作 命令 说明
检索 docker search 关键字 eg:docker search redis 我们经常去docker hub上检索镜像的详细信息,如镜像的TAG。
拉取 docker pull 镜像名:tag :tag是可选的,tag表示标签,多为软件的版本,默认是latest
列表 docker images 查看所有本地镜像
删除 docker rmi image-id 删除指定的本地镜像

https://hub.docker.com/

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
1、搜索镜像
[root@localhost ~]# docker search tomcat
2、拉取镜像
[root@localhost ~]# docker pull tomcat
3、根据镜像启动容器
docker run --name mytomcat -d tomcat:latest
4、docker ps
查看运行中的容器
5、 停止运行中的容器
docker stop 容器的id
6、查看所有的容器
docker ps -a
7、启动容器
docker start 容器id
8、删除一个容器
docker rm 容器id
9、启动一个做了端口映射的tomcat
[root@localhost ~]# docker run -d -p 8888:8080 tomcat
-d:后台运行
-p: 将主机的端口映射到容器的一个端口 主机端口:容器内部的端口

10、为了演示简单关闭了linux的防火墙
service firewalld status ;查看防火墙状态
service firewalld stop:关闭防火墙
11、查看容器的日志
docker logs container-name/container-id

更多命令参看
https://docs.docker.com/engine/reference/commandline/docker/
可以参考每一个镜像的文档

启动mysql[root@iZ8vbe1ftl51c44ehxav9sZ ~]# docker run -p 3306:3306--name mysql02 -e MYSQL_ROOT_PASSWORD=qwer -d mysql

提示端口被占用,因为已经安装过mysql了

4.Run 流程和Docker原理

image-20200724111953903

底层原理

image-20200724112335014

Docker是一个Client - Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问! DockerServer接收到Docker-Client的指令,就会执行这个命令!

Docker为什么比虚拟机快?

  • Docker有比虚拟机更少的抽象层。由于docker不需要Hypervisor实现==硬件资源虚拟化==,运行在docker容器上的程序直接使用的都是==实际物理机的硬件资源==。因此在CPU、内存利用率上docker将会在效率上有明显优势。
image-20200724112738805
  • docker利用的是宿主机的内核,而不需要Guest OS。

因此,当新建一个 容器时,docker==不需要==和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是==分钟级别==的。而docker由于==直接利用宿主机的操作系统==,则省略了返个过程,因此新建一个docker容器只需要几秒钟。

5.Docker常用命令

5.1容器命令

  • docker run
image-20200725095440902
  • docker ps 列出正在运行的容器

    • -a 列出所有容器
    • -n=? 列出最近的?条容器
    • -q 只列出容器编号
  • 退出容器

    • exit 退出容器并且停止
    • ctrl + t+ q 容器退出但不停止
    • 退出后连接容器 docker attach 容器ID
  • 删除容器

    • docker rm 容器id 不能删除正在运行的容器
    • docker rm -f ${docker ps -aq}
  • 启动和停止容器操作

    • docker start 容器id 开始或停止 / run 是开启一个全新的
    • docker restart 容器id
    • docker stop 容器id

5.2后台启动容器

docker run -d 镜像名

  • 启动后发现容器会停止

  • 因为docker使用后台运行,必须要有一个==前台进程==,docker发现没有应用,就会自动停止。

    容器启动后发现自己没有提供服务,就会立刻停止

5.3日志查看

docker logs -tf --tail 10 容器id

自己编写shell脚本

1
docker run -d centos /bin/sh -c "whilt true;do echo nihao;sleep 1;done"

5.4查看容器中进程信息

docker top 容器id

docker inspect 容器id:查看容器的所有信息

5.5进入容器命令和拷贝命令

docker exec -name 容器id :进入容器后开启一个新的终端,可以在里面操作

  • docker exec -it 容器id /bin/bash

docker attach 容器id:进入容器正在执行的终端,不会启动新的进程。

拷贝命令

docker cp 容器id:/home/test.java /home:将容器中的test.java拷贝到主机的home文件夹下

后来可以使用-v 卷的技术实现自动同步。

image-20200725115434449

5.6命令小结

镜像命令

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
#查看镜像列表:
docker images
docker image ls

#导出镜像:
docker image save centos > docker-centos6.9.tar.gz
#导入镜像:
docker image load -i docker-centos6.9.tar.gz
#删除镜像:
docker image rm centos:latest

docker image rm 578c3

#搜索镜像
docker search + 镜像名字

#给源中镜像打标签:

docker tag nginx:latest 10.0.0.11:80/nginx:latest

#推送指定镜像到docker镜像源服务器

docker push 10.0.0.11:80/nginx:latest

#获取镜像 (下载) docker pull image_name

#官方pull docker pull centos:6.8(没有指定版本,默认会下载最新版) 私有仓库pull
docker pull daocloud.io/huangzhichong/alpine-cn:latest

docker history image_name #显示一个镜像的历史

docker build -t <image-name> . #*(点一定不能去掉)#使用当前目录下的Dockerfile构建镜像

容器命令

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
docker -v         #查看版本

docker info #查看docker信息

#运行容器

docker run --name 容器名 -d -p 3306:3306 mysql docker 启动容器
docker run image_name
docker run -d -p 80:80 nginx:latest
run(创建并运行一个容器)
-d 放在后台
-p 端口映射 :docker的容器端口
-P 随机分配端口
-v 源地址(宿主机):目标地址(容器)
docker run -it --name centos6 centos:6.9 /bin/bash
-it 分配交互式的终端
--name 指定容器的名字
/bin/sh覆盖容器的初始命令

docker run image_name #启动容器***

docker stop container_id #停止容器

docker kill container_name #杀死容器

docker ps (-a -l -q) #查看容器列表

docker container rm 'docker ps -a -q' #删除所有容器

docker rm -f 'docker ps -a -q` #删除所有容器

docker ps -a #查看容器列表

docker exec -it 77cd6bef4dc9 /bin/bash #进容器

docker start/stop container-id||container-name #开启/停止 指定容器id或者容器名称的容器

docker run -d -p 80:80 -v /opt/xiaoniao:/usr/share/nginx/html nginx:latest

docker logs container-name/container-id #查看容器日志

docker ps | grep ${CONTAINER_ID} #查看容器状态

docker commit ID new_image_name #镜像打包 (保存对容器的修改)
docker commit -m="提交的描述信息" -a="作者" 容器id #要创建的目标镜像名:[标签名]

docker inspect <id/container_name> #查看容器内部详情细节

docker login #登录

Ctrl+P+Q #退出而不关闭容器

5.7部署nginx

1
2
3
4
5
6
7
8
9
10
docker pull nginx
[root@iZ8vbe1ftl51c44ehxav9sZ ~]# docker run -d --name nginx01 -p 3344:80 nginx
df9f174a9ad88552391681620136f00d3e1593ca5e10232408ef5b9e560f702a

#进入容器
[root@iZ8vbe1ftl51c44ehxav9sZ ~]# docker exec -it nginx01 /bin/bash
root@df9f174a9ad8:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx


端口暴露的概念

image-20200725202446014

5.8 Portainer可视化

1
docker run -d -p 9000:9000 -p 8000:8000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
image-20200725204947063

6 Docker镜像

什么是镜像

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

所有的应用,直接打包docker镜像,就可以直接跑起来!

6.2 镜像加载原理

UnionFS联合文件系统

分层、轻量级高性能的文件系统,支持对文件系统的修改作为依次提交一次一次叠加

镜像加载原理

  • bootfs(boot file system)主要包含==bootloader==和==kernel==, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的==最底层是bootfs==。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs==转交给内核==,此时系统也会==卸载bootfs==。
image-20200726150328052
  • rootfs (root file system),在==bootfs之上==。包含的就是典型Linux系统中的/devy,/proc,/bin, /etc等标准日录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu, Centos等等。

为什么docker的centos只有几百兆?

对于一个精简的OS, ==rootfs 可以很小==,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别,因此不同的发行版可以公用bootfs。

容器不需要bootfs引导加载,所需要的加载内容基于主机,只需要加载rootfs,所以可以实现秒级启动容器。

1
2
3
4
5
6
7
8
9
10
11
[root@iZ8vbe1ftl51c44ehxav9sZ ~]# docker pull redis
Using default tag: latest
Trying to pull repository docker.io/library/redis ...
latest: Pulling from docker.io/library/redis
6ec8c9369e08: Already exists #第一层已经存在(比如centos)
efe6cceb88f8: Pull complete
cdb6bd1ce7c5: Pull complete
9d80498f79fe: Pull complete
b7cd40c9247b: Pull complete
96403647fb55: Pull complete

特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。(容器层)

容器层==之下的都是镜像层==

image-20200726151547850

6.3 提交自己的镜像

1
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
  • 类似快照,如果需要保存当前容器的状态,可以通过commit提交,获得一个镜像

7 容器数据卷

容器的持久化和同步操作,容器间也是可以数据共享的

使用数据卷

  • 直接使用命令来挂载 -v

    docker run -it -v 主机目录:容器内目录

    docker run -it -v /home/ceshi:/home centos /bin/bash

image-20200726160146987

7.1 实战:Mysql数据同步

1
2
3
4
5
6
7
8
#-d  后台运行
#-p 端口映射
#-v 卷挂载
#-e 环境配置
#--name 容器名称

[root@iZ8vbe1ftl51c44ehxav9sZ home]# 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=qwer --name mysql03 mysql
e1f2bc5534e90a1bd84f3b8a9b0ed91c7f65179a40e94771476ffe2ed9a34ebf

小插曲

navicat连接连接mysql8.0.21出现Clientdoesnotsupportauthenticationprotocol。

查询后发现 原因是因为mysql8使用了新的caching_sha2_password和sha256_password认证方式,不是mysql_native_password认证方式

1
2
3
4

use mysql;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'qwer';
flush privileges;

问题解决。

即使把容器中的mysql删除,主机上同步的mysql数据也会存在

image-20200726165854046

7.2具名挂载和匿名挂载

匿名挂载

-v 容器内路径

具名挂载

指定卷的名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@aliretain ~]# docker run -d -P --name nginx02 -v jumingnginx:/etc/nginx nginx
49ca9b43d4f21d18409d96f9af6ad60f7b6e4d07806c71552723c0a5463b8122
[root@aliretain ~]# docker volume ls
DRIVER VOLUME NAME
local 3f9a0bfa21b211508a5c309337223124320f01796c3a745c07472ab5e73c2450
local 7fce195b9f372b5eaaf56725bfa1b91ba9d0b9d668db1e1f4525963da6f4c076
local ed485135e2acd866290ea9e851334a168b83a185a443613042469fdd0ceae269
local jumingnginx #卷名称
local portainer_data

[root@aliretain ~]# docker volume inspect jumingnginx
[
{
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/jumingnginx/_data", #文件目录
"Name": "jumingnginx",
"Options": {},
"Scope": "local"
}
]

如何确定是匿名挂载还是具名挂载

1
2
3
4
5
6
7
8
-v 容器内路径  #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径::容器内路径 #指定路径挂载

:ro read only
:rw read write
# docker run -d -P --name nginx02 -v jumingnginx:/etc/nginx:ro nginx
# docker run -d -P --name nginx02 -v jumingnginx:/etc/nginx:rw nginx

7.3 Dockerfile

用来构建docker镜像的构建文件。

1
2
3
4
5
6
7
8
9
10
#创建一个dockerfile文件   指令(大写) 参数
#每个命令

FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash
~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@aliretain docker-test-volume]# docker build -f dockerfile1 -t retain/centos:1.0 .  #不要忘记点
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM centos
---> 831691599b88
Step 2/4 : VOLUME volume01 volume02
---> Running in 9c7f72165566
---> 2756d9387024
Removing intermediate container 9c7f72165566
Step 3/4 : CMD echo "----end----"
---> Running in 6dd454b25967
---> f70a1ea26ba5
Removing intermediate container 6dd454b25967
Step 4/4 : CMD /bin/bash
---> Running in c8e930a84a76
---> f92046af7b37
Removing intermediate container c8e930a84a76
Successfully built f92046af7b37

image-20200727114035190

一个命令就是一层

Dockerfile构建步骤

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

很多官方镜像都是基础包,很多功能都没有,通常需要我们自己构建镜像

7.3.1 Dockerfile构建过程

基础知识

  • 每个保留关键字(指令)都必须是大写
  • 从上到下顺序执行
  • 每一个指令都会创建提交一个新的镜像层并提交。
image-20200728195436054
  • dockerfile:构建文件,定义一切的步骤,源代码
  • DockerImages:通过Dockerfile构建生成的镜像,最终发布和运行的产品
  • Docker容器:镜像运行起来提供服务器

7.3.2 Dockerfile指令格式

1
2
3
4
5
6
7
8
9
10
11
12
FROM  			#基础镜像
MAINTAINER #姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤、tomcat镜像,添加的内容。
WORDKDIR #镜像工作目录
VOLUME #挂载目录
EXPOSE #指定暴露的端口
CMD #指定容器启动的时候需要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定容器启动时需要运行的命令,可以追加
ONBUILD #当构建一个被继承DOckerfile 这个时候就会运行ONBUILD 的指令,触发指令
COPY #类似ADD,将文件拷贝到镜像中
ENV #构建的时候设置环境变量
image-20200728195918996

7.3.3 实战 构建centos镜像

Docker Hub中99%镜像都是从这个基础镜像过来的==FROM scratch== ,I然后配置需要的软件和配置来进行的构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM centos
MAINTAINER retain<772392403@qq.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

#构建镜像,会自动下载安装vim和net-tools
docker build -f mydockerfile-centos -t mycentos:1.0 .

image-20200728202648400

可以使用docker history 容器id 查看dockerfile文件对应的命令

image-20200728202940380

7.3.4 CMD 和 ENTRYPOINT区别

CMD:

1
2
3
4
5
6
7
8
FROM centos
CMD ["ls","-a"]

#build
#run后发现运行了ls -a命令

但是如果在docker run 容器 -l
-l替换了-a,但是-l并不是命令,所以会报错

ENTRYPOINT:

1
2
3
4
5
6
7
8
FROM centos
ENTRYPOINT ["ls","-a"]

#build
#run后发现运行了ls -a命令

但是如果在docker run 容器 -l
在-a后面追加了-l,即ls -al命令,可以执行

7.3.5 实战 构建tomcat镜像

准备压缩包

image-20200729192821165

编写dockerfile文件

命名时写Dockerfile,build的时候会自动寻找该文件而不用指定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FROM centos
MAINTAINER retain<772392403@qq.com>

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

ADD apache-tomcat-9.0.37.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.37
ENV PATH $PATH:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.37/bin/logs/catalina.out

构建镜像

docker build -t mytomcat .

image-20200729194258054
1
2
3
启动tomcat,挂载webapps和logs
[root@aliretain tomcat]# docker run -d -p 9090:8080 --name retaintomcat -v /home/build/tomcat/test:/usr/local/apache-tomcat-9.0.37/webapps/test -v /home/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.37/logs diytomcat
659b79a61c2cc15e9b2aaa563c7b034fdca9afcaeb7f8740bb376d0deef54662

7.3.6 发布镜像到DockerHUB

image-20200729195950691

登录DockerHub发布镜像

docker push 镜像名:版本号

7.4 数据卷容器

多个mysql同步数据

1
2
3
4
docker run -it --name docker01 retain/centos:1.0
#启动docker01 centos
docker run -it --name docker02 --volumes-from docker01 retain/centos:1.0
#启动docker02 挂载到docker01
image-20200728193837856
image-20200728193912158

实现了多个容器间的数据同步

容器之间配置信息的传递,数据卷容器的生命周期一直持续到==没有容器使用==为止。 但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

即使删除一个容器,另外的容器数据也仍然存在。

image-20200729200722781

8 Docker网络

image-20200730203410112
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
[root@aliretain ~]# docker exec -it tomcat03 ip addr

#tomcat容器内ip地址
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
50: eth0@if51: <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 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever

#主机能ping通容器内ip
[root@aliretain ~]# 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.142 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.084 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.077 ms
^C
--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms

原理

我们每启动一个docker容器,docker就会给==docker容器分配一个ip==,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术!

启动一个容器就会多一个==网卡==

image-20200730204442717

evth-pair就是==一对的虚拟设备接口==,他们都是成对出现的,一端连着协议,一端彼此相连,所以因为这个特性,evth-pair==充当一个桥梁==,连接各种虚拟网络设备。

容器互ping

image-20200730211526612

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

桥接

image-20200730211909993

docker中网络接口都是虚拟的,虚拟的转发效率高。容器删除,对应的网桥就没有了

在数据库源指定时,database:ip ,如果ip换掉了,项目不重启,怎么可以通过名字来访问容器,而不是指定ip?

1
2
3
4
5
6
docker exec -it tomcat01 ping tomcat02 #直接ping名字
ping: tomcat01: Name or service not known
#使用--link
docker run -it -d -P --name tomcat03 --link tomcat02 tomcat
docker exec -it tomcat03 ping tomcat02
#可以ping通!,但反向不能ping通,即tomcat02不能ping通tomcat03

原理

image-20200730213220189

hosts文件中指定了映射

==已经不建议使用--link了,不支持容器名进行访问!==

8.3 自定义网络

image-20200731102409058
  • bridge:桥接模式
  • none:不配置网络
  • host:和宿主机共享网络
  • container:容器网络连通(局限性大)

一般直接启动的是docker0,特点是域名不能访问 --link可以打通连接

创建网络

1
2
3
4
5
6
7
8
9
10
11
#创建网络	桥接模式 	子网ip	网关
[root@aliretain ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

8322db6b6c963255b0ebcbc783defd82ae9262482aeb6a65a7e817e913aad336
[root@aliretain ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
ffb38a869657 bridge bridge local
df03c2ae6b23 host host local
8322db6b6c96 mynet bridge local #创建的网络
2accbd25fb04 none null local

测试互ping

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
#启动tomcat-net-01
[root@aliretain ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
59abaeb32d035c1a78062d9b7180f07a1471df9ec432913c452f6f7b01fe8f48
#启动tomcat-net-02
[root@aliretain ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
a3759f673b277d2898aaab0f18f41b0b438f7664f9889e79ce5d23a3a440fc5c

#tomcat—net-01 通过名字 ping tomcat-net-02
[root@aliretain ~]# 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.119 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.100 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.100 ms
^C
--- tomcat-net-02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.100/0.106/0.119/0.012 ms

#tomcat—net-02 通过名字 ping tomcat-net-01
[root@aliretain ~]# docker exec -it tomcat-net-02 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.096 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.105 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.124 ms
^C
--- tomcat-net-01 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2ms
rtt min/avg/max/mdev = 0.096/0.108/0.124/0.014 ms

好处与坏处

好处

  • redis、mysql-不同的集群使用不同的网络,保证集群是安全的

8.4 网络连通

image-20200731104748338

tomcat01和tomcat-net-01==处在不同网段==下,一般情况下不能直接ping通。操作是将==tomcat01容器与mynet网卡连接==。

docker network connect:连接一个容器到一个网络

1
docker network connect mynet tomcat01
image-20200731104500399

连通后将tomcat01放到了mynet网络下(一个容器,两个ip)

8.5 实战:部署Redis集群

image-20200731105014214
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
#设置redis网卡
[root@aliretain ~]# docker network create redis --subnet 172.38.0.0/16
e4ec6584fe6cb183efe732d0c4fdf68b70bb460079de47e112846c9512efa3f9
#通过脚本创建六个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-enab1ed 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

docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

#redis-1
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:latest redis-server /etc/redis/redis.conf; \
#redis-6
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:latest redis-server /etc/redis/redis.conf; \

#结果
[root@aliretain /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4137249a0879 redis:latest "docker-entrypoint..." 3 seconds ago Exited (1) 2 seconds ago redis-6
2b50ed79c7c6 redis:latest "docker-entrypoint..." 22 seconds ago Exited (1) 20 seconds ago redis-5
cb45a0262b4d redis:latest "docker-entrypoint..." 39 seconds ago Exited (1) 38 seconds ago redis-4
848f3139bbd2 redis:latest "docker-entrypoint..." About a minute ago Exited (1) About a minute ago redis-3
1ee0d5ea5712 redis:latest "docker-entrypoint..." 2 minutes ago Exited (1) 2 minutes ago redis-2
5c4195d1acbb redis:latest "docker-entrypoint..." 2 minutes ago Exited (1) 2 minutes ago redis-1
[root@aliretain /]#


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