Docker

Docker是什么

简单来来说就是将应用程序部署到独立容器,每个容器相当于一个小的linux系统,通过容器进行打包成镜像,放到有Docker环境上的系统上运行。虚拟机也是属于虚拟化技术,Docker容器也是一种虚拟化技术,它是基于Go语言开发的

Docker优势

  • 更快交付/部署
  • 轻量级
  • 相互隔离,互不影响
  • 更便捷的升级和维护
  • 更高效的资源利用

Docker组成

image-20200907174531991

Docker由镜像(images),容器(container),仓库(repository)组成;

  • 镜像就像是装系统时的系统盘,包括了一些操作系统之类软件的,它是只读的.

  • 容器可以理解为提供了硬件环境,我们的沉香谷放在里面运行,可以当成一个简易的linux系统。

  • 仓库用来存放镜像,跟git很相似,我们可以从中心仓库下载镜像,也可以自建仓库。也可以把制作好的镜像上传到远程仓库。

    仓库分为公开仓库和私有仓库,最大的公开仓库是官方仓库 Dock Hub

安装Docker

环境

centos7

MobaXterm_Personal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 系统内核
[root@localhost /]# uname -r
3.10.0-1127.el7.x86_64

# 系统信息
[root@localhost /]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装

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
# 1.卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

# 2.安装`yum-utils`软件包
yum install -y yum-utils

# 3.添加软件源
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo # 国外
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #阿里云

# 4.安装docker引擎和容器
yum -y install docker-ce docker-ce-cli containerd.io

# 5.启动docker
systemctl start docker
# 6.查看docker版本

image-20200907181602044

1
2
# 7.运行hello-world测试
docker run hello-world

image-20200907181850383

1
2
3
4
# 8.查看镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB

卸载docker

1
2
3
4
# 卸载软件
yum remove docker-ce docker-ce-cli containerd.io
# 删除资源文件
rm -rf /var/lib/docker

阿里云镜像加速

  • 登录阿里云找到容器镜像服务

    image-20200907182548699

  • 镜像加速器

    image-20200907182652208

1
2
3
4
5
6
7
8
9
# 配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://a6gq0rdm.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

原理

Docker是一个Client-Server结构的同,Docker的守护进程运行在主机上。通过Socket从客户端访问

Docker为什么比VM快?

  • Docker有着比虚拟机更少的抽象层
  • Docker利用的是宿主机内核,vm需要是Guest OS

image-20200907183741446

Docker常用命令

文档

帮助命令

1
2
3
docker version # 显示docker版本信息
docker info # 显示docker系统信息
docker --help # 帮助命令

镜像命令

docker images 查看所有镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost etc]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 8 months ago 13.3kB
[root@localhost etc]# docker images --help
# REPOSITORY 镜像的仓库源
# TAG 镜像标签
# IMAGE ID 镜像id
# CREATED 镜像创建时间
# SIZE 镜像大小

# 可选项
-a,--all # 列出所有镜像
-q,--quiet # 只显示镜像id

docker search 搜索镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost etc]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9934 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3634 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 724 [OK]
percona Percona Server is a fork of the MySQL relati… 508 [OK]


# 可选项
[root@localhost etc]# docker search -h
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output

docker pull下载镜像

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
# 下载镜像 docker pull 镜像名[:tag]
[root@localhost etc]# docker pull mysql
Using default tag: latest # 默认最新
latest: Pulling from library/mysql
latest: Pulling from library/mysql
bf5952930446: Pull complete # 分层下载,docker image的核心,联合文件系统
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
3cdd8ff735c9: Pull complete
4c70cbe51682: Pull complete
e21cf0cb4dc3: Pull complete
28c36cd3abcc: Pull complete
Digest: sha256:6ded54eb1e5d048d8310321ba7b92587e9eadc83b519165b70bbe47e4046e76a
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

docker pull mysql == docker pull docker.io/library/mysql:latest

# 指定版本下载
[root@localhost etc]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bf5952930446: Already exists
8254623a9871: Already exists
938e3e06dac4: Already exists
ea28ebf28884: Already exists
f3cef38785c2: Already exists
894f9792565a: Already exists
1d8a57523420: Already exists
5f09bf1d31c1: Pull complete
1591b28581e8: Pull complete
96ef942f7603: Pull complete
2e009731422e: Pull complete
Digest: sha256:1a83136153b238b659b0887ceb4e08275473af1eab2e67de4c22b37c5f4130cd
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi删除镜像

1
2
3
4
5
6
7
8
[root@localhost etc]# docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 d589ea3123e0 2 days ago 448MB
mysql latest 3646af3dc14a 2 days ago 544MB
hello-world latest bf756fb1ae65 8 months ago 13.3kB
[root@localhost etc]# docker rmi -f 3646af3dc14a 通过id删除
[root@localhost etc]# docker rmi -f id id id 删除多个镜像
[root@localhost etc]# docker rmi -f $(docker images -aq) 删除全部镜像

容器命令

有了镜像才可以创建容器,下载一个centos

1
docker pull centos

新建容器并启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
docker run [可选参数] image 

# 参数说明
--name="Name" 容器名字
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-P 指定容器端口 8080:8080
-P 主机端口:容器端口
-P 容器端口
-P ip:主机端口:容器端口
-p 随机指定端口

# 测试
## 启动并进入容器
[root@localhost etc]# docker run -it centos /bin/bash
[root@dc22cdc304ab /]# ls # 查看容器内的centos
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr

# 从容器中退出
[root@115f580f95bd /]# exit
exit
[root@localhost /]#

列出所有的运行容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# docker ps #列出当前正在运行的容器
-a # 列出当前正在运行的容器+历史运行过得容器
-n=? #显示最近创建的容器
-q # 只显示容器编号

[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
115f580f95bd centos "/bin/bash" 2 minutes ago Exited (0) 2 minut es ago amazing_vaughan
dc22cdc304ab centos "/bin/bash" 6 minutes ago Exited (0) 3 minut es ago unruffled_satoshi
6831b24d8b06 bf756fb1ae65 "/hello" About an hour ago Exited (0) About a n hour ago zealous_blackburn
[root@localhost /]# docker ps -a -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
115f580f95bd centos "/bin/bash" 3 minutes ago Exited (0) 3 minutes ago amazing_vaughan
[root@localhost /]# docker ps -aq
115f580f95bd
dc22cdc304ab
6831b24d8b06

退出容器

1
2
3
4
5
6
7
8
exit # 停止容器并退出
Ctrl+P+Q # 容器不停止退出


[root@9c647327935f /]# docker ps[root@localhost /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c647327935f centos "/bin/bash" 45 seconds ago Up 45 seconds nervous_elgamal
[root@localhost /]#

删除容器

1
2
3
docker rm 容器id	#删除指定容器
docker rm -f $(docker ps -ap) # 删除所有容器
docker ps -a -q|xargs docker rm

启动和停止容器的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker start 容器id	# 启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止容器
docker kill 容器id #强制停止容器


[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
427a0b73db5e centos "/bin/bash" 48 seconds ago Exited (127) 35 seconds ago romantic_booth
[root@localhost /]# docker start 427a0b73db5e
427a0b73db5e
[root@localhost /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
427a0b73db5e centos "/bin/bash" About a minute ago Up 7 seconds romantic_booth
[root@localhost /]# docker stop 427a0b73db5e
427a0b73db5e

常用其他命令

后台启动容器

1
2
3
4
5
6
7
8
[root@localhost ~]# docker run -d centos
e42dc17c4ded0270fbdce2d0697804787986319854edbda5f2fe2bf49a184d35
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e42dc17c4ded centos "/bin/bash" 43 seconds ago Exited (0) 24 seconds ago agitated_hoover
427a0b73db5e centos "/bin/bash" 15 hours ago Exited (0) 15 hours ago romantic_booth

# docker容器使用后台运行,就必须要一个前台进程,docker发现没有前台应用就会自动停止

查看日志

1
2
[root@localhost ~]# docker logs -f -t --tail 10 e42dc17c4ded
10条日志

查看进程信息

1
docker top 容器id

查看镜像元数据

1
docker inspect 容器id

进入当前正在运行的容器

1
2
3
4
5
6
7
# 我们通常都是使用后台方式启动运行的,需要进入容器,修改一些配置

# 进入容器后开启新终端
docker exec -it 容器id bashShell

# 进入容器当前正在执行终端
docker attach 容器id

拷贝容器内文件到主机上

1
2
3
4
5
6
# docker cp 容器id:容器内路径 目的主机路径

[root@localhost ~]# docker cp e1b8972855ac:/22.java ./
[root@localhost ~]# ls
11.java 22.java anaconda-ks.cfg custom

image-20200908183940536

Docker练习

安装Nginx

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
# 1.docker search nginx 搜索镜像
# 2.docker pull nginx 下载镜像
[root@localhost ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
latest: Pulling from library/nginx
bf5952930446: Pull complete
cb9a6de05e5a: Pull complete
9513ea0afb93: Pull complete
b49ea07d2e93: Pull complete
a5e4a503d449: Pull complete
Digest: sha256:b0ad43f7ee5edbc0effbc14645ae7055e21bc1973aee5150745632a24a752661
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

# 3 测试
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 4bb46517cac3 3 weeks ago 133MB
centos latest 0d120b6ccaa8 4 weeks ago 215MB
# -d 后台启动 --name 给容器命名 -p宿主机端口:容器内部端口
[root@localhost ~]# docker run -d --name nginx098 -p 3344:80 nginx
bb9437232f7143a92dc3797b2535489d731b4e4882e53265001c39634089aa23
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb9437232f71 nginx "/docker-entrypoint.…" 23 seconds ago Up 11 seconds 0.0.0.0:3344->80/tcp nginx098

[root@localhost ~]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

安装Tomcat

1
2
3
4
5
6
7
8
9
# 官方
docker run -it --rm tomcat:9.0 # 我们之前的启动都是后台,停止容器后还可以查到,docker run -it --rm 一般用来测试 用完即删的(删除容器不会删除镜像)

# 正常启动
docker run -d -p 8090:8080 --name tomcat1 tomcat

# http://192.168.45.121:8090/测试访问没有问题
# 进入容器 [root@localhost ~]# docker exec -it 61722710fb57 /bin/bash
# linux命令少了,webapps里面没有文件,阿里云镜像的原因,剔除了不必要的东西,保证最小可运行环境

Portainer—Docker可视化

1
2
3
4
5
docker run -d -p 9000:9000 \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name prtainer-test \
docker.io/portainer/portainer

测试访问:http://192.168.45.121:9000/

image-20200908193715245

image-20200908193920508

Docker镜像

是什么?

Docker镜像加载原理

docker镜像是有一层一层的文件系统组成,这种层级的文件系统叫联合文件系统(UnionFS)

分层

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# docker pull redis:5.0.9
5.0.9: Pulling from library/redis
bf5952930446: Already exists # 已经存在的层
911b8422b695: Pull complete
093b947e0ade: Pull complete
2e4ea19ac656: Pull complete
62403d50d101: Pull complete
3a097fa7018a: Pull complete
Digest: sha256:ab3998e18bfaa570fad08c884ffbcc7861f59caf736a5a0c1ad5383c4d863958
Status: Downloaded newer image for redis:5.0.9
docker.io/library/redis:5.0.9

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

这一层就是容器层,容器之下的都叫镜像层

Commit镜像

1
2
docker commit 提交容器为一个新的副本
docker commit -m=“message” -a=“author” 容器id 目标镜像名:[tag]

image-20200908204958201

1
如果想要保存当前的容器状态,就可以通过commit来提交。获得一个自己的镜像,好比快照

容器数据卷

什么是容器数据卷

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

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

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

使用数据卷

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

1
2
3
4
5
6
7
8
9
10
docker run -it -v 主机目录:容器目录

[root@localhost ~]# docker run -it -v ~/custom:/home centos /bin/bash
[root@77979c56cacc /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@77979c56cacc /]# cd home/
[root@77979c56cacc home]# ls
redis-5.0.9.tar.gz

# docker inspect 77979c56cacc查看信息

image-20200908211208164

文件(目录)同步

image-20200908211601262

image-20200908212348444

好处:以后只需要在本地修改就可以同步到容器

安装MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
 # 获取镜像
docker pull mysql:5.7

# 运行容器,挂载
# 需要配置密码
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
docker run -d -p3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7

#启动成功后在本地测试下

image-20200908213923422

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 在本地测试创建一个数据库,测试映射是否ok
[root@localhost mysql]# ls data/
auto.cnf ibdata1 private_key.pem
ca-key.pem ib_logfile0 public_key.pem
ca.pem ib_logfile1 server-cert.pem
client-cert.pem ibtmp1 server-key.pem
client-key.pem mysql sys
ib_buffer_pool performance_schema
[root@localhost mysql]# ls data/
auto.cnf ibdata1 private_key.pem
ca-key.pem ib_logfile0 public_key.pem
ca.pem ib_logfile1 server-cert.pem
client-cert.pem ibtmp1 server-key.pem
client-key.pem mysql sys
ib_buffer_pool performance_schema `test`

假设容器删除,挂载到本地的数据卷没有丢失,实现了容器数据持久化功能

具名挂载和匿名挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看所有volume的情况
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 235cc62983d27076c03fd5b9511265b4092a518a2a5857e44168a55f7e4a2931
local 436029b616a3b523f5b8563144c2afed69062547abc7dc5cafd46a9084b383c2
# 这种就是匿名挂载

#具名挂载
[root@localhost ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
293c0e013dba80a42ff854b0ea5019a28233197f16ab12a1cd2230c517d321a1
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local 235cc62983d27076c03fd5b9511265b4092a518a2a5857e44168a55f7e4a2931
local 436029b616a3b523f5b8563144c2afed69062547abc7dc5cafd46a9084b383c2
local juming-nginx
# 通过 -v 卷名:容器内路径
查看一下这个卷

image-20200908215629171

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

通过具名挂载可以方便找到卷

image-20200908215938787

1
2
3
4
# 确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载

初识DockerFile

Dockerfile 就是用来构建docker镜像的构建文件

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

1
2
3
4
5
6
7
8
9
10
11
12
# 创建一个dockerfile文件,名字可以随机
# 文件中的指令都是大写,参数

FROM centos

VOLUME ["volume01","volume02"]

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

# 每个命令都是镜像的一层

image-20200909132947855

1
启动容器

image-20200909133503940

这个卷外部一定有一个同步的目录(匿名挂载 )

通过容器id查看一下

image-20200909135448191

测试是否同步了

image-20200909135631398

image-20200909135640791

如果需要手动挂载镜像 -v 卷名:容器内路径

数据卷容器

多个容器间实现数据共享

1
2
3
4
5
# 通过自己创建的镜像来创建三个容器
docker run -it --name docker01 7fb29b29a668
docker run -it --name docker02 --volumes-from docker01 7fb29b29a668
docker run -it --name docker03 --volumes-from docker01 7fb29b29a668
# 通过--volumes-from实现容器间共享
1
# 测试删除docker01容器,docker02和03的数据还在

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

DockerFile

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

构建步骤:

  • 编写dockerfile文件
  • docker build构建镜像
  • docker run 运行镜像
  • docker push 发布

DockerFile构建过程

基础知识:

  1. 每个保留关键字都是大写字母
  2. 执行从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建提交一个新的镜像层,并提交

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

DockerFile指令

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

DockerFile-centos

image-20201001212639866

默认centos很多命令是没有的

自定义dockerfile并构建

image-20201001213043994

image-20201001213031239

image-20201001212825836

可以看到我们配置的生效

image-20201001213309793

还可以列出某个镜像的变更历史

CMD和ENTRYPOINT区别

测试CMD

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
# 编写dockerfile文件
[root@localhost ~]# vim dockerfile-test-cmd
FROM centos

CMD ["ls","-a"]

# 构建镜像
[root@localhost ~]# docker build -f dockerfile-test-cmd -t cmdtest .
Sending build context to Docker daemon 2.031MB
Step 1/2 : FROM centos
---> 0d120b6ccaa8
Step 2/2 : CMD ["ls","-a"]
---> [Warning] IPv4 forwarding is disabled. Networking will not work.
---> Running in 8614ac972b4e
Removing intermediate container 8614ac972b4e
---> a30c685ac1a8
Successfully built a30c685ac1a8
Successfully tagged cmdtest:latest

# 运行 ls -a 生效
[root@localhost ~]# docker run a30c685ac1a8
WARNING: IPv4 forwarding is disabled. Networking will not work.
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

# 想追加一个命令 -l ls -al
[root@localhost ~]# docker run a30c685ac1a8 -l
WARNING: IPv4 forwarding is disabled. Networking will not work.
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.

# cmd指令下 -l 替换了CMD ["ls","-a"]命令,-l

DockerFile制作tomcat

1.准备tomcat和jdk压缩包

image-20201001214207778

2.编写dockerfile文件,官方命名Dockerfile

image-20201001214302834

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FROM centos
MAINTAINER aurora<23155203@qq.com>
COPY readme.txt /usr/local/readme.txt

ADD jdk-8u144-linux-x64.tar.gz /usr/local # ADD会自动解压
ADD apache-tomcat-9.0.37.tar.gz /usr/local

RUN yum -y install vim

ENV MYPATH /usr/local # 一进入就是此目录
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_144
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
ENV PATH $PATH:$JAVA_HOME/bin:$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

3.构建镜像

1
docker build -t mytomcat .

4.运行容器

1
docker run -d -p 8081:8080 --name tomcat1 -v /home/aurora/build/tomcat/test:/usr/local/apache-tomcat-9.0.37/webapps/test -v /home/aurora/build/tomcat/logs/:/usr/local/apache-tomcat-9.0.37/logs c13b0d8d127c

5.发布项目测试

image-20201001230710235

image-20201001231119938

通过卷挂载 ,本地项目已经同步到容器了

image-20201001231205071

image-20201001231239032

日志信息也同步过来了

发布镜像

1.登录阿里云

找到容器镜像服务

image-20201002092447739

2.创建命名空间

image-20201002092539292

创建镜像仓库

image-20201002092601585

3.阿里云教程

image-20201002092623940

4.push

image-20201002092702006

image-20201002092711265

Docker 网络

Docker0

image-20201002093141004

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
[root@aurora ~]# docker run -d -p 8080:8080 f796d3d2c195
de57956557a2d041ed84f5344bd27ef36a0277bf02d16218873c6af4e3e056a9

# 查看容器网络
[root@aurora ~]# docker exec -it de57956557a2 ip a
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
50: eth0@if51: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever



# Linux能ping通docker容器内部
[root@aurora ~]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.089 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.083 ms
64 bytes from 172.18.0.2: icmp_seq=4 ttl=64 time=0.080 ms

每运行一个docker容器,docker就会给容器分配一个ip,只要安装了docker,就会有一个网卡docker0,使用的是桥接模式,veth-pair技术

测试ip a

image-20201002094130120

又多了一个网卡

在启动一个容器测试,发现又多了一个网卡

image-20201002094245205veth-pair 就是一对虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连

测试两个tomcat容器是否可以ping通

image-20201002094800738

结果是可以的

所有的容器不指定网络的情况下,都是docker0路由的,docker会给容器分配可用ip

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
[root@aurora ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7e15416c5f39 f796d3d2c195 "catalina.sh run" 2 minutes ago Up 2 minutes 8080/tcp tom2
abfa3e4a85a3 f796d3d2c195 "catalina.sh run" 2 minutes ago Up 2 minutes 8080/tcp tom1

# 发现容器间无法通过名字ping通
[root@aurora ~]# docker exec -it tom1 ping tom2
ping: tom2: Name or service not known

# --link 连接后可以通过名字ping
[root@aurora ~]# docker run -d --name tom3 --link tom1 f796d3d2c195
573a523b5bc039a830d64f7b3a55aa6a3e933e019d55a28b4c460f65108e215f
[root@aurora ~]# docker exec -it tom3 ping tom1
PING tom1 (172.18.0.2) 56(84) bytes of data.
64 bytes from tom1 (172.18.0.2): icmp_seq=1 ttl=64 time=0.147 ms
64 bytes from tom1 (172.18.0.2): icmp_seq=2 ttl=64 time=0.118 ms
64 bytes from tom1 (172.18.0.2): icmp_seq=3 ttl=64 time=0.109 ms
64 bytes from tom1 (172.18.0.2): icmp_seq=4 ttl=64 time=0.110 ms


# 反向是无法ping通的
[root@aurora ~]# docker exec -it tom1 ping tom3
ping: tom3: Name or service not known

查看tom3的hosts配置

image-20201002102044491

可以发现tom3的hosts里面对tom1的ip做了解析,我们可以通过名字或容器id来连通

image-20201002102214210

但是在tom1里面并没有,所以就无法反向ping通。

现在不建议使用–link

自定义网络,不使用docker0

docker0 不支持容器名访问

自定义网络

查看所有docker网络

image-20201002102601010

网络模式

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
docker run -d -P --name tom1 f796d3d2c195
docker run -d -P --name tom1 --net bridge f796d3d2c195

# 直接启动时,默认有--net bridge,就是docker0

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


# 自定义网卡
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
[root@aurora ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 aurora_net
6d13d57495764d26aad369986410b3bab24bd1585bc24a319e35bf78401ab534
[root@aurora ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
6d13d5749576 aurora_net bridge local
839665245f94 bridge bridge local
bd58428d04c0 host host local
a544d905bb5c none null local

image-20201002103631393

使用自定义网络启动两个tomcat测试

1
2
docker run -d -P --name tom1-net --net aurora_net f796d3d2c195
docker run -d -P --name tom2-net --net aurora_net f796d3d2c195

image-20201002103906759

可以看到docker为两个容器分配了ip

再次测试ping连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@aurora ~]# docker exec -it cc6a778c809f ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.156 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.100 ms
^C
--- 192.168.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.100/0.128/0.156/0.028 ms


# 不使用--link就可以ping通名字了
[root@aurora ~]# docker exec -it cc6a778c809f ping tom2-net
PING tom2-net (192.168.0.3) 56(84) bytes of data.
64 bytes from cc6a778c809f (192.168.0.3): icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from cc6a778c809f (192.168.0.3): icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from cc6a778c809f (192.168.0.3): icmp_seq=3 ttl=64 time=0.073 ms
64 bytes from cc6a778c809f (192.168.0.3): icmp_seq=4 ttl=64 time=0.062 ms
64 bytes from cc6a778c809f (192.168.0.3): icmp_seq=5 ttl=64 time=0.080 ms
^C
--- tom2-net ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.023/0.061/0.080/0.021 ms

好处:
集群时不同的集群使用不同的网络,保证集群是安全的

网络连通

image-20201002104955275

测试tom1连通到tom1-net

1
2
3
4
5
docker network connect aurora_net tom1

docker network inspect aurora_net # 查看网卡情况
# 发现docker直接把tom1加到aurora_net网卡了

image-20201002105527380

查看tom1的ip

image-20201002105659600

发现tom1有两个ip了

1
2
3
4
5
6
7
8
9
10
11
12
# 连通ok

[root@aurora ~]# docker exec -it 55909059da41 ping 46843aae707c
PING 46843aae707c (192.168.0.2) 56(84) bytes of data.
64 bytes from tom1-net.aurora_net (192.168.0.2): icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from tom1-net.aurora_net (192.168.0.2): icmp_seq=2 ttl=64 time=0.123 ms
64 bytes from tom1-net.aurora_net (192.168.0.2): icmp_seq=3 ttl=64 time=0.095 ms
^C
--- 46843aae707c ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2ms
rtt min/avg/max/mdev = 0.072/0.096/0.123/0.023 ms

部署Redis集群

SpringBoot微服务打包Docker镜像

创建项目,编写controller

image-20201002152841798

Docker Compose

Docker Compose高效管理容器,定义运行多个容器

评论