Docker学习笔记/常用命令

安装Dcoker

sudo yum install -y yum-utils
**使用阿里镜像 **

1
2
3
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

更新yum索引
yum makecache fast
安装docker
ce为社区版 ee企业版
sudo yum install docker-ce docker-ce-cli containerd.io
启动docker
sudo systemctl start docker
通过运行hello-world 映像验证 Docker Engine 是否已正确安装
sudo docker run hello-world
使用docker version也可以查看是否安装成功 查看下载的Hello-world镜像
docker images
卸载 Docker Engine、CLI 和 Containerd 包:
$ sudo yum remove docker-ce docker-ce-cli containerd.io
主机上的映像、容器、卷或自定义配置文件不会自动删除。删除所有镜像、容器和卷:
$ sudo rm -rf /var/lib/docker $ sudo rm -rf /var/lib/containerd
/var/lib/docker为docker的默认工作路径

Docker基础命令

帮助命令

显示docker的版本信息

docker version

显示docker 的系统信息,包括镜像和容器的数量

docker info

帮助命令

docker 命令 --help
docker 官网相关的帮助文档: https://docs.docker.com/engine/reference/commandline/

镜像命令

docker images 查看所有本地的主机上的镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@zy ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE

# 因为我没有下载镜像,因为为空
REPOSITORY 镜像的仓库源
TAG 镜像标签
IMAGE ID 镜像ID
CREATED 镜像的创建时间
SIZE 镜像的大小

# 查看images命令的可选项
[root@zy ~]# docker images --help
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
-a, --all Show all images (default hides intermediate images)
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet Only show image IDs

docker search 镜像搜索

docker 镜像商店: https://hub.docker.com/
可以直接在该网站上搜索所想使用的docker的镜像,如果有就可以直接点进去,然后在点进去的页面中会告诉你如何启动这个镜像

1
2
3
4
5
6
7
8
9
10
# mysql 数据库的镜像
# 这时候会进入到以下的页面
https://hub.docker.com/search?q=mysql&type=image
# 点进最上面的下载量最多里面,会进入到以下页面
https://hub.docker.com/_/mysql
# 在该页面会告诉你如何去使用该镜像
# 所有在该网站的镜像都是这样的操作
# 在命令行查询MySQL镜像
docker search mysql
# 这时候我们从查询的结果上可以发现与在hub上面搜索的是相匹配的
1
2
3
4
5
6
7
8
9
10
11
12
# 查看docker search 的可选项
docker search --help
[root@zy ~]# docker search --help
Usage: docker search [OPTIONS] TERM
Search the Docker Hub for images Options:
-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
# 过滤查询,查询收藏大于5000的镜像
docker search MySQL --filter=STARS=5000
[root@zy ~]# docker search MySQL --filter=STARS=5000 NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 10990 [OK]

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
# 下载镜像docker pull 镜像名[:tag] 
docker pull mysql # 默认会下载最新的版本
[root@zy ~]# docker pull mysql
Using default tag: latest # 如果不写tag,默认就是laster
latest: Pulling from library/mysql
69692152171a: Already exists # 分层现在,docker image的核心 联合文件系统
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
f7fddf10c2c2: Pull complete
16415d159dfb: Pull complete
0e530ffc6b73: Pull complete
b0a4a1a77178: Pull complete
cd90f92aa9ef: Pull complete
Digest: sha256:d50098d7fcb25b1fcb24e2d3247cae3fc55815d64fec640dc395840f8fa80969 # 签名
Status: Downloaded newer image for mysql:latest docker.io/library/mysql:latest # 真实地址
# docker pull mysql 等价于 docker pull docker.io/library/mysql:latest

# 指定版本下载
docker pull mysql:5.7
[root@zy ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
69692152171a: Already exists # 会发现这个已存在
1651b0be3df3: Already exists
951da7386bc8: Already exists
0f86c95aa242: Already exists
37ba2d8bd4fe: Already exists
6d278bb05e94: Already exists
497efbd93a3e: Already exists
a023ae82eef5: Pull complete
e76c35f20ee7: Pull complete
e887524d2ef9: Pull complete
ccb65627e1c3: Pull complete
Digest: sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi 删除镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看存在的镜像 
[root@zy ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
postgres latest 293e4ed402ba 4 weeks ago 315MB
mysql 5.7 2c9028880e58 4 weeks ago 447MB
mysql latest c0cdc95609f1 4 weeks ago 556MB

# 删除镜像
[root@zy ~]# docker rmi -f 容器id
# 删除指定的镜像
[root@zy ~]# docker rmi -f 容器id1 容器id2 容器id3
# 删除多个指定的镜像
[root@zy ~]# docker rmi -f $(docker images -aq) # 删除全部镜像

容器命令

当我们有了镜像,才可以创建容器

新建容器并启动

1
2
3
4
5
6
7
8
9
10
11
docker run [可选参数] image 

# 常用参数名
--name='Name' # 创建容器的名字,可以用来区分容器
-d # 后台交互方式运行
-it # 使用交互方式运行,进入容器查看内容
-p # 指定容器端口 -p 8080:8080
-p ip:端口: 容器端口
-p 主机端口: 容器端口
-p 容器端口
-P # 随机指定端口

列出容器

1
2
3
4
5
docker ps # 列出当前运行的容器 
# 可选参数
-a # 列出当前运行的容器与历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号

退出

1
2
3
# 如果docker容器在启动的时候没有加 -d 参数 
exit # 会直接停止容器并退出
Ctrl + P + Q # 容器不停止,并退出

删除容器

1
2
3
docker rm 容器id           # 删除指定的容器, 不能删除正在运行的容器,可以强制删除 rm -f  
docker rm $(docker ps -aq) # 删除所有的容器
docker ps -a -q | xargs docker rm # 删除所有的容器

启动与停止容器

1
2
3
4
docker start 容器id  # 启动容器 
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器

其他命令

查看日志

1
2
3
docker logs -f -t --tail 容器id 
-ft # 显示日志
--tail number # 要显示的日志条数

查看容器中的进程信息

1
2
3
4
5
6
7
8
9
10
# 命令docker top  容器id 
[root@zy ~]# docker top e2c680cd2fe7
UID PID PPID C STIME TTY TIME CMD
polkitd 6774 6753 0 Jun12 ? 00:00:01 postgres
polkitd 6868 6774 0 Jun12 ? 00:00:00 postgres: checkpointer
polkitd 6869 6774 0 Jun12 ? 00:00:02 postgres: background writer
polkitd 6870 6774 0 Jun12 ? 00:00:02 postgres: walwriter
polkitd 6871 6774 0 Jun12 ? 00:00:01 postgres: autovacuum launcher
polkitd 6872 6774 0 Jun12 ? 00:00:01 postgres: stats collector
polkitd 6873 6774 0 Jun12 ? 00:00:00 postgres: logical replication launcher

查看镜像元数据

1
2
docker inspect 容器id 
[root@zy ~]# docker inspect e2c680cd2fe7

进入容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 方式1 
docker exec -it 容器id /bin/bash
[root@zy ~]# docker exec -it e2c680cd2fe7 /bin/bash
root@e2c680cd2fe7:/# ls
bin boot dev docker-entrypoint-initdb.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@e2c680cd2fe7:/#

# 方式2
docker attach 容器id
[root@zy ~]# docker attach e2c680cd2fe7

# 区别
# docker exec # 进入容器后开启一个新的终端,可以在里面进行操作(常用)
# docker attach # 进入容器正在执行的终端,不会开启新的进程

从容器拷贝文件到主机上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
docker cp 容器id:容器内路径  目录路径 
[root@zy ~]# docker exec -it e /bin/bash
root@e2c680cd2fe7:/# ls
bin boot dev docker-entrypoint-initdb.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@e2c680cd2fe7:/# cd /home/
root@e2c680cd2fe7:/home# ls
root@e2c680cd2fe7:/home# mkdir python
root@e2c680cd2fe7:/home# cd python/
root@e2c680cd2fe7:/home/python# vi test.py bash: vi: command not found
root@e2c680cd2fe7:/home/python# touch test.py
root@e2c680cd2fe7:/home/python# ls test.py root@e2c680cd2fe7:/home/python# pwd /home/python
root@e2c680cd2fe7:/home/python# exit
exit

[root@zy ~]# ls
anaconda-ks.cfg original-ks.cfg
[root@zy ~]# docker cp e2c680cd2fe7:/home/python/test.py .
[root@zy ~]# ls
anaconda-ks.cfg original-ks.cfg test.py
# 拷贝可以用了在启动容器的时候因为没有进行卷挂载,然后因为修改配置文件导致容器无法启动后,
#无法进入到容器中进行容器中进行文件的修改,这时候可以将文件拷贝到宿主机,修改后再放回去。

可视化

Docker 图形化界面管理工具!提供了一个后台面板供我们操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@zy ~]# docker run -d -p 8888:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer 
Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete
49d59ee0881a: Pull complete
a2300fd28637: Pull complete
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
730b0b2e9bd7442fdbb5221153edf09ef534a028d7b16b4878344ee9ff01b982

[root@zy ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
730b0b2e9bd7 portainer/portainer "/portainer" 9 seconds ago Up 9 seconds 0.0.0.0:8888->9000/tcp, :::8888->9000/tcp nifty_shirley
e2c680cd2fe7 postgres "docker-entrypoint.s…" 23 hours ago Up 13 minutes 5432/tcp postgres

这时候我们可以通过 ip:8888 进行访问,首此访问需要设置密码,然后选择local,然后点击Connect即可

镜像

UnionFS联合文件系统

image.png

commit镜像

1
2
docker commit #提交容器称为一个新的副本 
docker commit -m "提交的描述信息" -a"作者" 容器id 目标镜像名:[TAG]

容器数据卷

将容器内的目录挂载的服务器上面
使用命令来挂载
docker run -it -v 主机目录:容器目录

容器数据卷的概念

docker 的理念:

  • 将应用于环境打包成一个镜像
  • 数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据持久化
  • MySQL,容易删除,删库跑路! 需求:MySQL 数据可以存储在本地!

容器之间有一个可以数据共享的技术! Docker 容器中产生的数据,同步到本地!
这就是卷技术! 目录的挂载,将容器中的目录,挂载在 Linux 上面!
总结:容器的持久化和他同步操作!容器间也是可以数据共享的

使用数据卷

1
2
3
4
#直接使用命令来挂载 -v
docker run -it -v 主机目录: 容器内目录
# 测试
docker run -it -v /home/ceshi:/home centos /bin/bash

容器之间的同步是双向的,我们以后只需要在本地修改即可,容器自动同步

具名和匿名挂载

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

# 查看所有的 volumn 的情况
docker volume ls

# 这里发现,这种就是匿名的,我们在 -v 只写了容器内的路径,没有容器外的路径

# 具名挂载

docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

docker volume ls
DRIVER VOLUME NAME
local juming-nginx

# 通过 -v 卷名:容器内路径
# 查看一下这个卷
docker volume insepect juming-nginx
..

#所有容器的卷,没有指定目录的情况下都是在: /var/lib/docker/volumes/xxx/data#我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用 具名挂载

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

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

1
2
3
4
5
6
7
8
# 通过 -v 容器内路径: 
ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写
# 一旦这个设置了容器权限,容器对我们挂载出来的就有限定了!
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -O --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# ro 只要看到 ro接说明这个路径只能通过宿主机来操作,容器内部是无法操作的!

Dockerfile

Dockerfile 就是用来构建 docker 镜像的构建文件!命令脚本!
通过编写一个脚本,可以生成一个镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层
touch dockerfile

1
2
3
4
5
6
7
8
# 创建一个 dockerfile 文件,名字随意,建议 dockerfile 
# 文件的内容 指令(大写 参数
FROM centos

# 挂在卷
VOLUME ["volume01","volume02"]
CMD echo "-----end------"
CMD /bin/bash

构建 dockerfile

1
2
3
4
docker build -f ./dockerfile -t Gorit/centos:1.0 . 

# 可以看到我们自己的镜像
docker images

查看一下卷载的路径这种方式我们未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时没有挂在卷,要手动镜像挂在 -v 卷名: 容器内路径!

创建第一个 Dockerfile

构建步骤:

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

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

DockerFile 的构建过程

基本知识

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

dockerfile 是面向开发的,我们以后发布项目,作镜像,就需要编写 dockerfile 文件,这个文件十分简单
步骤:开发,部署,上线运维 缺一不可
Docker 镜像已经逐渐成为企业交付的标准,必须掌握!!!
DockerFile:构建文件,定义了一切的步骤
DockerImages:通过 DockerFile 构建生成的镜像,最终要发布和运行的产品,原来是 jar,war
Docker 容器:容器就是镜像运行起来提供服务的

DockerFile 的指令

image.png
image.png

实战测试

Docker Hub 中 99% 镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件进行构建
创建一个自己的CentOS:

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
# 编写 dockerfile 的文件
FROM centos

MAINTAINER CodingGoirt<gorit@qq.com>

# 配置环境变量
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 执行安装命令
RUN yum -y install vim
RUN yum -y install net-tools # ifconfig

EXPOSE 80

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

# 通过文件构建镜像
# 命令 docker build -f mydockerfile-centos -t mycemtos:0.1 .

#8 writing image sha256:d77323e0cfbddd8088a616b4005c0d2ee5d21bfa5cf771f776dbbb4e273f1835 done
#8 naming to docker.io/library/mycemtos:0.1 done
#8 DONE 0.6s


# 测试运行
docker run -it mycemtos:0.1

# 可以看到默认路径在 /usr/local
# 可以使用 vim 命令了
# 可以打开 ifconfig 了

我们可以列出本地进行变更的历史

  • docker history imageID

我们拿到一个镜像,可以研究是怎么做的

CMD 和 ENTIRPOINT 的区别

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


FROM centos
ENTRYPOINT ["ls","-a"]

# 两者构建,在运行,效果是一样的

# 但是如果运行
docker run imageId -l # 前者原本的命令会被覆盖,后者是被追加在原有的命令

实战 Tomcat 镜像

  1. 准备镜像文件 tomcat 压缩包,jdk 压缩包

  2. 编写 DockerFile 文件

  3. 访问镜像

    发布镜像

    DockerHub

  4. 地址 https://hub.docker.com/ ,并注册一个可以登录的账号

  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
    $ docker login --help
    Log in to a Docker registry or cloud backend.
    If no registry server is specified, the default is defined by the daemon.

    Usage:
    docker login [OPTIONS] [SERVER] [flags]
    docker login [command]

    Available Commands:
    azure Log in to azure

    Flags:
    -h, --help help for login
    -p, --password string password
    --password-stdin Take the password from stdin
    -u, --username string username

    Global Flags:
    --config DIRECTORY Location of the client config files DIRECTORY (default "C:\\Users\\伟\\.docker")
    -c, --context string context
    -D, --debug enable debug output in the logs
    -H, --host string Daemon socket(s) to connect to

    Use "docker login [command] --help" for more information about a command.

    $ docker login -ucodinggorit
    Password:
    Login Succeeded
    docker push gorit/diytomcat:1.0
  7. 登录后可以提交镜像了

  8. docker push

阿里云镜像

  1. 登录阿里云

  2. 找到容器镜像服务

  3. 创建命名空间

  4. 创建容器镜像

  5. 根据 阿里云提供的方式拉取推

    Docker 网络

    docker0

    初始化 docker 环境

    1
    docker rmi -f $(docker images -aq)

    Linux 下获取 ip地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    ip addr
    # 随机启动一个

    docker run -d -P --name tomcat01

    PS C:\Users\伟> docker exec -it tomcat01 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
    2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
    link/tunnel6 :: brd ::
    12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
    valid_lft forever preferred_lft forever

    # 思考 ,linux 能不能 ping 通容器内部
    #可以#

    # linx 可以 ping 通 docker 容器内部

    原理

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

  7. 在启动一个容器测试的时候,发现又多了一个网卡

    1
    2
    3
    4
    # 我们发现这个容器带来的网卡,都是一对对的
    # evth-path 就是一堆虚拟的设备接口,他们都是成对的出现,一段连着协议,一段彼此相连
    # 正因为有这个特性,evth-path 充当一个桥梁,链接各种虚拟网络设备
    # OpenStac,Docker 容器之间的连接,OVS 连接,都是使用 evth-pair 技术
  8. 测试 tomcat01 和 tomcat02 是否可以ping 通

    • 容器和容器之间是可以互相 ping 通的

结论:
tomcat01 和 tomcat02 是公用个路由器:docker0,所有的容器不指定网络的情况,都是 docker 容器会给我们分配一个默认可用的 ip
小结
Docker 中的所有的网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件!)
只要容器删除,对应网桥一对就没了!

解决两个独立的 docker 项目不能互相 ping 的问题

1
2
3
4
docker run -d -P --name tomcat03 --link tomcat02 tomcat
docker exec -it tomcat03 ping tomcat02

# 反向可以 ping 通吗? 不可以,需要配置

可以通过 insepect 可以看到很多东西

自定义网络

查看所有 docker 网络

1
2
3
4
5
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
de74c8203497 bridge bridge local
550920e46e30 host host local
105ce7ef023f none null local

网络模式:桥接 docker (默认)
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
24
25
26
27
28
29
30
31
32
33
34
35
# 我们直接启动的命令 --net bridge,而这个就是我们的 docker0
docker run -d -P --name tomcat01 tomcat
docker -d -P --name tomcat01 --net bridge tomcat

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

# --driver bridge 桥接
# --subnet 192.168.0.0/16
# --gateway
PS C:\Users\伟> docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 我们的网络就创建好了
c81d519694cb79a3b84dda1e20b0ce76521fcd7dbd9f25ff9db38c4717dc4ec1
PS C:\Users\伟> docker network ls
NETWORK ID NAME DRIVER SCOPE
de74c8203497 bridge bridge local
550920e46e30 host host local
c81d519694cb mynet bridge local
105ce7ef023f none null local

# 启动
docker run -d -P --name tomcat-net-01 --net mynet tomcat

$ docker run -d -P --name tomcat-net-01 --net mynet tomcat
29efa1bcdb47c157b3737caa313aba619ef7c521f75babe6fff606443d7b0af5
$ docker run -d -P --name tomcat-net-02 --net mynet tomcat
29c71809d2ba670ea7ccc9d64e64a784b813458273187584aca030d6cc7af0cc
$ 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.115 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.108 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.067 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.088 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=5 ttl=64 time=0.077 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=6 ttl=64 time=0.046 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=7 ttl=64 time=0.052 ms

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

好处:
redis - 不同的集群使用不同的网络,保证集群是安全和健康的
mysql - 不同的集群使用不同的网络,保证集群是安全和健康的
网络连通

1
2
3
4
5
6
7
8
9
10
11
12
13
# 测试连通
docker netword connect mynet tomcat01

# 连通之后,就是将 tomcat01 放了 mynet 网络下

# 一个容器两个 ip 地址
# 云服务器:公网 ip 私有 ip

# 01 连通
docker exec -it tomcat01 ping tomcat-net-01

# 02 是依然打不通的
docker exec -it tomcat02 ping tomcat-net-01
  • 假设要跨网络操作别人,就需要使用 docker network connect 连通

    实战 部署 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
    # 通过脚本创建六个 redis 欧配置
    for port in $(seq 1 6);\
    do \
    mkdir -p /mydata/redis/node-${port}/conf
    touch /mydata/redis/node-${port}/conf/redis.conf
    cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
    port 6379
    bind 0.0.0.0
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    cluster-announce-ip 172.38.0.1${port}
    cluster-announce-port 6379
    cluster-announce-bus-port 16379
    appendonly yes
    EOF
    done

    # 开启一个服务
    docker run -p 6371:6379 -p 16371:16379 --name redis-1 \

    # 。。。

    # 创建集群
    redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 ... --cluster-replicas 1

    Spring Boot打包

    1、构建 SpringBoot 项目
    2、打包应用

  • 将打包出来的应用放在 项目根路径

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"]

4、构建镜像

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
$ docker build -t gorit-docker-springboot .
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 159B done
#1 DONE 0.0s

#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.1s

#3 [internal] load metadata for docker.io/library/java:8
#3 DONE 5.7s

#4 [1/2] FROM docker.io/library/java:8@sha256:c1ff613e8ba25833d2e1940da0940...
#4 DONE 0.0s

#5 [internal] load build context
#5 transferring context: 45B
#5 transferring context: 47B done
#5 DONE 0.0s

#6 [2/2] COPY *.jar /app.jar
#6 CACHED

#7 exporting to image
#7 exporting layers done
#7 writing image sha256:79a6d059fd2b32a8f79e8c1466ffa2c610f03c42059ea591b80beb3c5b2a1ef1 done
#7 naming to docker.io/library/gorit-docker-springboot done
#7 DONE 0.0s

5、查看镜像

1
2
3
4
5
6
7
8
9
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gorit-docker-springboot latest 79a6d059fd2b 6 minutes ago 660MB
mytomcat01 1.0 833d7bcc1b04 10 hours ago 653MB
tomcat latest 625b734f984e 41 hours ago 648MB

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83badbffcc4d gorit-docker-springboot "java -jar /app.jar …" 12 seconds ago Up 11 seconds 0.0.0.0:32768->8080/tcp docker-springboot-web

Docker Compose

官方文档:https://docs.docker.com/compose/

简介

传统方式打包项目:

  1. Docker
  2. DockerFile build run 手动操作,单个容器
  3. 微服务,100个微服务,依赖关系

使用 Docker Compose 来轻松高效的管理容器 定义运行多个容器

Docker Compose 官方介绍

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. To learn more about all the features of Compose, see the list of features.

  • 使用 YAML 文件 来配置你的 app 服务
  • 使用一个 single command

Compose works in all environments: production, staging, development, testing, as well as CI workflows. You can learn more about each case in Common Use Cases.
Using Compose is basically a three-step process:
使用步骤

  1. Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
    1. 创建 DockerFile 可以使你的 app 在任何地方运行
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
    1. 定义一个 docker-compose.yml 文件
  3. Run docker-compose up and Compose starts and runs your entire app.
    1. 运行 docker-compose 命令
    2. 启动项目

作用:项目编排
Compose 是 Docker 官方开源项目,需要安装!!!

Docker-Compose 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
version: "3.9"  # optional since v1.27.0 
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {
}

Compose: 重要概念

  • 服务 service,容器,应用。(web,redis,mysql…)
  • 项目 project,一组关联的容器,博客,web,mysql

    安装 Docker Compose

  1. Linux 下载

    1
    2
    3
    4
    5
    # 下载
    sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

    # 设置权限
    sudo chmod +x /usr/local/bin/docker-compose
  2. windows 下载, 下载 Docker Desktop 貌似就能自带了

官方安装步骤
安装好之后,在shell 窗口输入
docker-compose —version,可以看到安装信息就可以了

开始体验

官网做了一个统计页面访问次数的 python 应用,用到了

  • python
  • redis
  1. 启动 app.py
  2. Dockerfile 应用打包为镜像
  3. Docker-compose yaml 文件(定义整个服务,需要的环境 redis,web 等等)
  4. 启动 docker-compose up
    1
    2
    3
    4
    5
    docker-compose up # 启动

    docker-compose down # 停止

    docker-compose stop # 暴力停止

流程

  1. 创建网络
  2. 执行 Docker-compose.yml
  3. 启动服务
    1. composetest_web_1 is up-to-datecomposetest_redis_1 is up-to-date

以前都是单个 docker run 启动容器
通过 docker-compose 编写 YAML 配置文件,可以通过 compose 一键启动所有服务,停止
docker-compose

Docker 小结

  1. Docker 镜像,run => 容器

  2. DockerFile 构建镜像(服务打包)

  3. docker-compose、 启动项目(编排,多个微服务环境)

  4. Docker 网络

    yaml 规则

    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
    # 3 层

    version: "" # 版本
    services: # 服务
    服务1:web
    # 服务配置
    images
    build
    network
    ...
    服务2: redis
    ...
    服务3: redis

    # 从下网上才为顺序
    version: "3.9"
    services:
    web:
    build: .
    ports:
    - "5000:5000"
    volumes:
    - .:/code
    environment:
    FLASK_ENV: development
    redis:
    image: "redis:alpine"

    docker-compose 搭建开源博客

    https://docs.docker.com/compose/wordpress/
    博客

  5. 下载程序,安装数据库,配置…

  6. compose 应用,=> 一键启动

  7. 下载项目(docker-compose.yaml)

  8. 如果需要文件, Dockerfile

  9. 文件准备齐全(直接一键启动)

前台启动
docker -d
docker-compose -d

微服务实战

  1. 编写自己的微服务
  2. dockerfile 构建镜像
  3. docker-compose.yml 编排项目
  4. 丢到服务器
  5. 启动

小结:
未来项目中只要有 docker-compose 文件,按照这个规则,启动编排容器
公司:docker-compose 直接启动
网上开源项目:docker-compose

假如项目要重新部署打包:
docker-compose up —build # 重新构建

总结

工具、服务、容器
项目 compose:三层

  • 工程:project
  • 服务 服务
  • 容器 运行实例! docker k8s, 容器