安装

https://docs.docker.com/engine/install/centos/

  • 卸载旧版本

    1
    2
    3
    4
    5
    6
    7
    8
    sudo yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine
  • 安装包与镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 安装包
    sudo yum install -y yum-utils
    # 镜像仓库,可使用官方文档或阿里云的镜像
    sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

    sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 安装

    1
    2
    3
    4
    # 可以先更新软件包索引
    yum makecache fast
    # 安装
    sudo yum install docker-ce docker-ce-cli containerd.io
  • 启动及基本操作

    1
    2
    3
    4
    5
    6
    # start启动
    sudo systemctl start docker
    # 运行hello-world,若没有对应镜像会先拉取镜像
    sudo docker run hello-world
    # 查看镜像
    docker images
  • 卸载

    1
    2
    3
    4
    5
    # 卸载
    sudo yum remove docker-ce docker-ce-cli containerd.io
    # 手动删除资源,/var/lib/docker默认路径
    sudo rm -rf /var/lib/docker
    sudo rm -rf /var/lib/containerd
  • 使用阿里云给容器镜像加速

    https://cr.console.aliyun.com/cn-chengdu/instances/mirrors

    使用对应的命令配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
    "registry-mirrors": ["https://wl2q99bq.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
  • 镜像启动流程

    • docker现在本地查找镜像,有就直接使用
    • 本地镜像查找不到,就去Docker Hub上下载镜像
    • 查找到了就下载并使用,官方查找不到则报错

基本命令

官网命令:https://docs.docker.com/engine/reference/commandline/docker/

镜像命令

  • docker images 查看镜像

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [root@localhost /]# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    hello-world latest d1165f221234 6 months ago 13.3kB
    # 字段解释
    REPOSITORY 镜像仓库源
    TAG 镜像标签
    IMAGE ID 镜像id
    CREATED 创建时间
    SIZE 镜像大小
    # 相关命令
    Options:
    -a, --all # 显示全部镜像
    -f, --filter # 根据条件过滤输出
    -q, --quiet # 只显示镜像ID
  • docker search 搜索镜像

    和直接去Docker Hub官网搜索一致。

  • 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 可下载对应版本
    # 默认最新版本下载
    [root@localhost /]# docker pull mysql
    Using default tag: latest
    latest: Pulling from library/mysql
    a330b6cecb98: Pull complete # 分层下载
    9c8f656c32b8: Pull complete
    88e473c3f553: Pull complete
    062463ea5d2f: Pull complete
    daf7e3bdf4b6: Pull complete
    1839c0b7aac9: Pull complete
    cf0a0cfee6d0: Pull complete
    1b42041bb11e: Pull complete
    10459d86c7e6: Pull complete
    b7199599d5f9: Pull complete
    1d6f51e17d45: Pull complete
    50e0789bacad: Pull complete
    Digest: sha256:99e0989e7e3797cfbdb8d51a19d32c8d286dd8862794d01a547651a896bcf00c
    Status: Downloaded newer image for mysql:latest
    docker.io/library/mysql:latest # 真实地址

    # 指定版本下载
    [root@localhost /]# docker pull mysql:5.7
    5.7: Pulling from library/mysql
    # 分层下载,以前下过的组件就不用二次下载了,节省空间
    a330b6cecb98: Already exists
    9c8f656c32b8: Already exists
    88e473c3f553: Already exists
    062463ea5d2f: Already exists
    daf7e3bdf4b6: Already exists
    1839c0b7aac9: Already exists
    cf0a0cfee6d0: Already exists
    fae7a809788c: Pull complete
    dae5a82a61f0: Pull complete
    7063da9569eb: Pull complete
    51a9a9b4ef36: Pull complete
    Digest: sha256:d9b934cdf6826629f8d02ea01f28b2c4ddb1ae27c32664b14867324b3e5e1291
    Status: Downloaded newer image for mysql:5.7
    docker.io/library/mysql:5.7
  • docker rmi 删除镜像(remove images)

    1
    2
    3
    4
    # 指定id删除镜像
    [root@localhost /]# docker rmi -f <镜像对应ID>
    # 查出所有的id,然后删除所有镜像
    [root@localhost /]# docker rmi -f $(docker images -aq)

容器命令

拥有镜像后才能创建容器,使用centos镜像来进行实验

  • 下载镜像:docker pull centos

  • docker run 新建容器并启动

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    docker run <参数> <镜像>
    # 参数
    --name = "name" # 容器名字自定义
    -d # 在后台运行
    -it # 使用交互方式运行,进入容器查看内容
    -p # 指定容器端口 -p 8080端口
    -p ip:主机端口:容器端口
    -p 主机端口:容器端口
    -p 容器端口
    容器端口
    -P # 大写P,随机指定端口

    [root@localhost /]# docker run -it centos /bin/bash
    [root@a0e3c05e1120 /]#
  • docker ps 查看所有运行的容器

    1
    2
    3
    4
    5
    # docker ps <参数>
    # 默认展示正在运行的容器
    -a # 可查看所有运行过的容器
    -n=x # 列出最近创建的x个容器、
    -q # 只显示ID
  • 退出容器

    1
    2
    exit			# 容器停止并退出
    ctrl + P + Q # 容器不停止退出
  • docker rm 删除容器

    1
    2
    docker rm <容器ID>	# 删除指定ID,运行中的不能删除,可使用rm -f
    docker rm -f $(docker ps -aq) # 全部删除
  • 启动与停止容器的操作

    类似linux命令,这里启动可以启动以前运行过的

    1
    2
    3
    4
    docker start ID
    docker restart ID
    docker stop ID
    docker kill ID

常用命令

  • docker run 后台启动容器

    注意后台启动容器时,必须要有一个前台进程,若docker发现没有应用,则自动停止

    1
    2
    3
    4
    docker run -d <镜像名>

    # 可以写一个脚本,然后后台运行
    docker run -d centos /bin/sh -c "while true;do echo tang;sleep 1;done"
  • docker logs 查看日志

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    docker logs <参数> <容器>
    # 参数
    -f # 跟踪日志输出
    -t # 显示日志的时间戳
    --since # 自某个时间开始的所有日志
    --tail # 只列出最新的n条日志

    # 可以用上面的循环脚本进行日志测试
    # 发现-f后日志会持续输出内容但是没有时间
    # -t会输出当前的全部内容有时间但不跟踪
    # --since和--tail后面必须加相关条件进行信息筛选
  • docker top 查看容器中进程信息

    可以根据查询的进程号杀死进程

    1
    2
    3
    4
    docker top <容器ID>
    # UID 用户ID
    # PID 进程ID
    # PPID 父进程ID
  • docker inspect 查看容器源数据

    可以查看容器的相关信息

    1
    docker inspect <容器ID>
  • docker exec / attach 进入当前正在运行的容器

    1
    2
    3
    4
    # 进入容器,然后开启一个新的终端
    docker exec -it <容器ID> /bin/bash
    # 进入容器正在执行的终端
    docker attach <容器ID>
  • docker cp 容器拷贝文件到主机

    1
    2
    3
    # 在容器中创建文件,然后在主机中使用cp命令
    # 将容器对应的文件拷贝到主机的指定目录
    docker cp <容器ID>:<文件路径> <主机路径>

使用练习

1
2
3
4
5
docker search nginx
docker pull nginx
docker run -d -p 8888:80 nginx # 使用8888替换默认80端口
curl lcoalhost:8888 # 测试访问对应地址端口
docker exec -it <ID> /bin/bash # 可以进入容器

本机访问对应ip和端口也可以访问nginx容器,需要提前关闭防火墙开放端口。

可视化面板

安装可视化工具:portainer

1
docker run -d -p 8088:9000 --restart=always -v var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

运行测试,主机访问8088端口:http://192.168.158.131:8088/

Docker

镜像(分层复用)

Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的配置参数,如匿名卷、环境变量、用户等,镜像不包含动态数据,构建后内容不会被改变。

Docker设计时,使用Union FS技术,使其成为一个分层存储架构。镜像由多层文件系统联合组成。Docker镜像可拆分成多个层次,两个不同镜像其中相同层次的文件是可以复用的。一层层构建镜像时,后一层是在前一层的基础上完成的,每一层构建完后不在发生改变,后一层的任何改变只会发生在自己这一层。也就说若后一层删除前一层的文件,只是在当前层标记文件删除,使得文件不显示,其实在前一层上数据并没有改变。

容器

可以说容器是镜像运行时的实体,镜像与容器可以类比面向对象里的类与实例。容器是可以进行创建、启动、停止、删除等操作的。

镜像一般是只读的,启动一个容器就是在镜像的最外层加上一个可读写层,镜像就像一个安装包,启动容器后才能对内部进行操作。

仓库

仓库就是集中存储镜像文件的地方,很容易联想到Maven仓库。

官方镜像仓库搜索地址:https://hub.docker.com/

提交镜像

1
2
3
4
# 官方的tomcat进行过简化,webapps文件夹是空的
# 我们可以将基本信息拷贝进去,然后提交这个修改过的镜像
# 提交后相当于新生成了一个镜像
docker commit -a="作者" -m="描述信息" <容器ID> 自定义镜像名

容器数据卷(持久化与同步)

我们希望Docker的数据是可以持久化的,但我们修改了容器内的数据,如果不生成一个新容器,删除容器后修改的数据就消失了,为了将数据持久化,我们要使用容器数据卷。卷就是目录或文件,存在于一个或多个容器中,但不属于Union FS(联合文件系统),不是分层架构的,可以进行数据的持久化或数据共享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 运行容器,使用-v命令进行目录挂载
# -v <主机目录>:<容器目录>
docker run -it -v /home/ceshi:/home centos /bin/bash

# 通过inspect命令查看容器信息,Mounts就是卷挂载的信息
# Source:主机目录,Destination:容器目录
docker inspect <容器ID>
···
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
···

通过以上操作,两个目录就完成了同步操作,其内容完全一致。

同理我们操作一下mysql,且使用本地数据库操作工具可以对该数据库连接。

而且将数据库删除后,我们data中的数据依旧存在。

1
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=123456 --name mysql01 mysql:5.7

Dockerfile

创建镜像

Dockerfile是一个用来构建镜像的文本文件。其包含构建镜像所需的指令与说明。相当于一个命令脚本,使用脚本生成镜像。

1
2
3
4
5
6
7
8
9
# 在指定目录下,写一段简单脚本
# 我的路径/home/dockerfile-test/dockerfile01
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "--------END--------"

CMD /bin/bash

有了脚本后,就可以使用docker build命令创建镜像,末尾有个 . 不要忘了

1
2
3
4
# docker build命令创建镜像
# -f 脚本路径
# -t 镜像名:版本号
docker build -f /home/dockerfile-test/dockerfile01 -t tang/centos:1.0 .

运行自己创建的镜像,在根目录下可以发现脚本中写好的卷:volume01、volume02,但这里是匿名挂载,需要通过inspect查看主机对应生成的随机文件夹名称。

1
docker run -it tang/centos:1.0 /bin/bash

卷数据同步(–volumes-from)

将不同容器的挂载卷的数据同步,如两个不同容器的mysql使用同一个数据库。当然删除其中一个容器,其他容器内的卷数据不会消失。

1
2
3
4
5
# 我们这里只是要使用同一个数据库,可使用匿名挂载
# 第二个mysql使用--volumes-from和第一个mysql进行卷数据同步
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

docker run -d -p 3310:3306 --name mysql02 --volumes-from mysql:5.7

Dockerfile指令

我们写dockerfile脚本时常用的指令。

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM			# 基础镜像
MAINTAINER # 镜像作者
RUN # 镜像构建时要执行的命令
ADD # 将文件添加到镜像中
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 配置端口
CMD # 容器启动时要运行的命令,可被替代
ENTRYPOINT # 容器启动时要运行的命令,可追加命令
ONBUILD # 该命令下的内容只对当前镜像的子镜像生效
COPY # 类似ADD,将文件拷贝到镜像
ENV # 构建时配置环境变量
LABEL # 为镜像指定标签

实战

  • 编写dockerfile脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    FROM centos
    MAINTAINER aidianfirst<AVG--lover>

    # 设置默认的工作目录
    ENV MYPATH /usr/local
    WORKDIR $MYPATH

    # 自行添加命令,原生centos命令很少
    RUN yum -y install vim
    RUN yum -y install net-tools

    EXPOSE 80

    CMD echo $MYPATH
    CMD echo ----------END-----------
    CMD /bin/bash
  • docker build命令构建镜像

    1
    docker build -f myDockerfile -t mycentos:1.0 .
  • 启动容器

    1
    2
    # 启动我们自定义的镜像后,我们就可以使用自行添加的命令了
    docker run -it mycentos:1.0

CMD 与 ENTRYPOINT区别

cmd:命令只能被替换,不能拼接。

entrypoint:命令可以被拼接。

1
2
3
4
5
6
7
8
9
10
# 使用CMD,启动容器后就会执行ls -a命令
FROM centos
CMD ["ls","-a"]

# 若我们启动时在结尾添加新指令
# 希望容器启动后执行ls -al,但CMD只能命令替换
# 也就是将原本的ls -a替换为 -l,这不是一个命令会报错
docker run e457b67ad5eb -l
# 需要写成一个完整命令对CMD的命令进行替换,而不是拼接
docker run e457b67ad5eb ls -al
1
2
3
4
5
6
# 使用ENTRYPOINT
FROM centos
ENTRYPOINT ["ls","-a"]

# 使用命令行启动,发现可以进行命令拼接
docker run -it fe4bf4cb9f12 -l

Docker流程一图看懂

pull下载镜像、run启动容器、Dockerfile编写镜像脚本,build一个脚本生成镜像,save/load打包传输。

26.png

Docker网络

docker是如何处理容器网络访问的?(ip)

使用 ip addr 命令可以查看虚拟机的网络,然后我们可以发现有一个叫docker0的网络。我们启动一个容器,进入配置文件查看ip,然后用本机ping这个ip,发现网络是通的。

1
2
3
4
5
docker run -d -P --name tomcat01 tomcat
docker exec -it tomcat01 /bin/bash
cat /etc/hosts
# 172.17.0.2 78c064e8db0a
ping 172.17.0.2 # 网络是通的
  • 启动docker容器,docker会为容器分配一个ip,且安装docker后会生成一个网卡docker0,使用的是桥接模式,技术是veth-pair。
  • 每次启动容器都会新建一个网卡,成对出现的。使用veth-pair充当桥梁连接虚拟网络设备。其中容器之间也可以相互ping。
  • 我们不同容器可以使用ip进行连接。

–link(run启动时)

其实就是在/etc/hosts配置文件中声明了,名称对应的ip,所以我们后续可直接使用名字连接,不使用ip。

1
2
3
4
# 启动一个test2的tomcat,使用--link指令将其与test1连通
# 可直接使用ping test1,2与1不适用ip九年连通,但link是单向的
# 想要1与2连通,我们需要对test1也进行声明
docker run --name test2 --link test1 tomcat