avatar

Docker

简介

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

https://baike.baidu.com/item/Docker/13344470?fr=aladdin

为什么需要Docker?

环境配置如此麻烦,换-一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用Docker可以消除协作编码时 “ 在我的机器上可正常工作 ” 的问题。

一次封装,处处运行

安装

Docker支持以下的CentOS版本

  • CentOS 7(64-bit)
  • CentOS 6.5 (64-bit) 或更高版本

前提条件

目前,CentOS 仅发行版本中的内核支持 Docker。
Docker运行在CentOS7上,要求系统为64位、系统内核版木为 3.10 以上。
Docker运行在Cent0S-6.5或更高的版本的CentOS.上,要求系统为64位、系统内核版本为2.6.32-431或者更高版本。

查看自己的内核

1
uname -r
1
cat /etc/redhat-release

Docker的基本组成

Docker架构图

镜像(image)

Docker镜像(Image)就是一个只读的模板。镜像可以用来创建Docker容器,一个镜像可以创建很多容器。

容器(container)

Docker利用容器(Container) 独立运行的一个或一组应用。容器是用镜像创建的运行实例。
它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等) 和运行在其中的应用程序。
容器的定义和镜像几乎一模-样,也是一堆层的统一视角, 唯一区别在于容器的最上面那一层是可读可写的。

仓库(repository)

仓库(Repository) 是集中存放镜像文件的场所。
仓库(Repository)和仓库注册服务器(Registry) 是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public) 和私有仓库(Private) 两种形式。
最大的公开仓库是Docker Hub https://hub.docker.com/
存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等

CentOS安装

安装软件包

1
2
3
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2

设置存储库

1
2
3
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

安装 Docker Engine

1
yum install docker-ce docker-ce-cli containerd.io

启动Docker

1
systemctl start docker

没报错就完事了

使用阿里云镜像加速

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

输入命令

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["你的加速地址"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

没报错就完事了

测试运行Hello-world

启动Docker

1
systemctl start docker

运行hello-world

1
docker run hello-world

run 作用

Docker底层原理

Docker是怎么工作的?

Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接 从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。容器,是一个运行时环境,就是我们前面说到的集装箱

为什么Docker比虚拟机快?

  • docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化, 运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
  • docker利用的是宿主机的内核,而不需要Guest OS,因此当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虑拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了这个过程,因此新建一个docker容器只需要几秒钟。

Docker常用命令

帮助命令

验证docker信息

docker version

docker安装后描述docker信息

docker info

帮助

docker –help

镜像命令

列出本地的镜像

docker images

组合: 例如 docker images -a

  • -a 列出本地所有的镜像(含中间映像层)
  • -q 只显示镜像ID
  • -qa 显示所有镜像ID
  • –digests 显示镜像的摘要信息
  • –no-trunc 显示完整的镜像信息

从Docker Hub 上查询某个 xxx 镜像

组合命令

  • -s number 用于筛选 stars 例如 docker search -s 30 tomcat ,查找 stars 数超过 30 的tomcat
  • –no-trunc 显示完整的镜像信息
  • –automated 只列出 automated build类型的镜像

下载镜像

docker pull xxx名字

组合命令

  • docker pull xxx:版本号 如果不写就是最新版 latest

删除镜像

docker rmi xxx

xxx 可以是 ID 或者 唯一镜像名

组合命令

  • docker rmi xxx:版本号 不写就是删除最新版 latest
  • docker rmi -f xxx 强制删除
  • docker rmi -f xxx1 xxx2… 一次删除多个,也可以写版本号 xxx1:latest
  • docker rmi -f $(docker images -qa) 批量删除,删除所有镜像 $()为表达式

容器命令

有镜像才能创建容器,这是根本前提


在docker上pull一个centos 进行演示

新建并启动容器

docker run

docker run [OPTIONS] IMAGE [COMMAND] [ARG….]

OPTIONS说明

  • –name=”容器新名字” 命名
  • -d 后台运行容器,并返回容器ID,也即启动守护式进程
  • -i 以交互模式运行容器,通常与 -t 同时使用
  • -t 为容器重新分配一个伪输入终端,通常与 -i 同时使用
  • -P 随机端口映射
  • -p 指定端口映射,有以下四种格式
    • ip:hostPort:containerPort
    • ip::containerPort
    • hostPort:containerPort
    • containerPort

pull好 centos 之后 使用命令 启动

1
docker run -it centos  可以是镜像ID

启动后

可以看到 @后面的字符串变了,这就相当于 你运行了一个centos容器,并打开了docker下centos的终端

通过上图可以看到docker 下的centos 目录和 虚拟机下centos目录是一样的


列出Docker运行的容器

docker ps

docker ps [OPTIONS] 不填options 的话默认显示正在运行的容器

OPTIONS说明(常用)

  • -a 列出当前所有正在运行的容器 + 历史上运行过的
  • -l 显示最近创建的容器
  • -n 显示最近 n 个创建的容器 如 docker ps -n 3
  • -q 静默模式,只显示容器编号
  • –no-trunc 显示完整信息

  • CONTAINER ID 对应终端ID
  • IMAGE 对应 镜像ID
  • COMMAND 以什么方式登录
  • CREATED 什么时候创建
  • STATUS 状态
  • PORTS 端口
  • NAMES 容器名字

退出容器

exit

使用exit后容器也会随之关闭

ctrl+P+Q

容器不停止退出


启动容器

docker start

docker start 容器ID或者容器名

获得已创建容器ID

重启


停止容器

docker stop

docker stop 容器ID或者容器名


强制停止容器

docker kill

docker kill 容器ID或者容器名


删除已停止的容器

docker rm

docker rm 容器ID

docker rmi 删除镜像, docker rm 删除容器

一次性删除多个容器

  • docker rm -f $(docker ps -a -q) 删除所有容器

  • docker ps -a -q | xargs docker rm

    | 为Linux管道符命令,xargs 可变参数

    意思是:docker ps -a -q 放回的值作为参数被xargs 接收 然后执行删除


进阶命令

启动守护式容器

docker run -d

docker run -d 容器名或者ID


查看容器日志

docker logs -f -t –tail

docker logs -f -t –tail 容器ID

  • -t 是加入时间
  • -f 跟随最新的日志打印
  • –tail 数字 显示最后多少条

使用命令循环打印日志,可以让守护式容器防止被杀

1
docker run -d centos /bin/sh -c "while true;do echo hello centos;sleep 2;done"


查看容器内运行的进程

docker top 容器ID


查看容器内部细节

docker inspect

docker inspect 容器ID


进入正在运行的容器,并已命令行交互

docker exec -it

docker exec -it 容器ID

docker attach

重新进入docker attach 容器ID

上述两个区别

  • attach 直接进入容器启动命令的终端,不会启动新的进程 在容器外对容器进行操作
  • exec 是在容器中打开新的终端,并且可以启动新的进程 进入容器后才能操作容器

从容器内拷贝文件到主机上

docker cp

docker cp 容器ID:容器内路径 目的的主机路径

Docker 镜像

是什么?

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

UnionFS(联合文件系统)

UnionFS (联合文件系统) : Union文件系统(UnionFS)是一种分层、 轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一 层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:

一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。

bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层 与我们典型的Linux/Unix系统是一样的, 包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs (root file system),在bootfs之上. 包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。roofs就是各种不同的操作系统发行版,比如Ubuntu, Centos 等等。

分层的镜像

为什么Docker 镜像要采用这种分层结构呢

最大的一个好处就是共享资源

比如: 有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

特点

Docker镜像都是只读的
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作 “容器层”, “容器层”之下的都叫”镜像层

Docker 镜像commit 操作补充

docker commit 提交容器副本使之成为一个新的镜像

docker commit -m=”提交的描述信息” -a=”作者” 容器ID 要创建的目标镜像名:[标签名]

案例演示

  1. 从Hub上下载tomcat镜像到本地并成功运行

    1
    docker run -it -p 8080:8080 tomcat
    • -p 主机端口 :docker 容器端口

    • -P 大写P 随机分配端口

    • i 交互

    • t 终端

    • 浏览器输入 localhost:8080直接访问

  2. 你可以进入 tomcat 随便改

    1
    docker exec -it 容器ID /bin/bash
  3. 改完后退出来

    1
    ctrl + p + q
  4. 提交你改完的新 tomcat

    1
    docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
  5. 然后查看镜像

  6. 完成,这就是你提交的新的镜像

Docker 容器数据卷

是什么?

能干吗?

容器持久化

容器间继承 + 数据共享

数据卷

容器内添加

直接命令添加

命令
1
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名

查看数据卷是否挂载成功
1
docker inspect 容器ID

容器和宿主机之间的数据共享

这个时候已经实现了容器与宿主机的数据共享

容器停止后,主机修改后数据是否同步

命令(带权限)
1
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名

创建好文件共享后,容器内只能读,不能写,宿主机拥有所有权限

DockerFile 添加

直接命令添加
DockerFile添加

根目录下新建mydocker文件夹并进入

备注

数据卷容器

是什么

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器

容器间传递共享(–volumes-from)

1
docker run -it --name xxx --volumes-from xxx 容器名或ID

根据一个使用DockerFile添加数据卷的镜像分别创建三个不同的容器,使用上述命令连接

例如

1
docker run -it --name aaa --volumes-from bbb 容器名或ID

连接成功之后,数据卷的内容互通

DockerFile解析

是什么

Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。

DockerFile构建过程解析

DockerFile内容基础知识

  1. 每条保留字指令都必须为大写字母,而且后面要跟随至少一个参数
  2. 指令按照从上到下顺序执行
  3. #表示注解
  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交

Docker执行DockerFile的大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令并对容器作出修改
  3. 执行类似docker commit的操作提交一个新的镜像层
  4. docker再基于刚提交的镜像运行一个新容器
  5. 执行dockerfile中的下一条指令直到所有指令都执行完成

小总结

DockerFile体系结构

保留字指令

FROM
基础镜像,当前镜像是基于那个镜像

MAINTAINER
镜像维护者的姓名和邮箱地址

RUN
容器构建时需要运行的命令

EXPOSE
当前容器对外暴露出的端口号

WORKDIR
指定在创建容器后,终端默认登录的进来的工作目录,一个落脚点

ENV
用来在构建镜像的过程中设置环境变量

ADD
将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包

COPY
类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY src dest
COPY [“src”,”dest”]

VOLUME
容器数据卷,用于数据保存和持久化工作

CMD
指定一个容器启动时要运行的命令
DockerFile中可以有多个CMD 指令,但只有最后一个生效,CMD会被docker run之后的参数替换

ENTRYPOINT

指定一个容器启动时要运行的命令

ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数,但是它指定的命令不会被最后一个替换,而是追加

ONBUILD

当构建一个被继承的DockerFile时运行命令,父镜像在被子类继承后父类镜像的onbuild被触发

小总结

案例

Base镜像(scratch)

DockerHub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的

自定义镜像mycentos

  1. 编写

    • Hub默认CentOS镜像什么情况

    • 准备编写DockerFile 文件

      • ![](Docker/准备编写DockerFile 文件.png)
    • myCentOS内容 DockerFile

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      FROM centos
      MAINTAINER duxiu<1839743406@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 "success-----------------ok"
      CMD /bin/bash
  1. 构建

    1
    docker build -f /DockerFile文件路径 -t 新镜像名字:TAG .

  2. 运行

  3. 列出镜像的变更历史

    1
    docker history 镜像ID

CMD/ENTRYPOING 镜像案例

制作CMD版可以查询IP信息的容器

在根目录下的mydocker目录下创建DockerFile3

1
2
3
FROM centos
RUN yum install -y curl
CMD {"curl,"-s","http://ip.cn"}

crul命令解释

使用CMD 执行除 curl以外的命令会报错,如

docker run myip -i

而使用ENTRYPOING 就可以执行

Docker常用安装

安装MySQL8.0.19

1
2
3
docker run -p 12345:3306 mysql -v /duxiu/mysql/conf:/etc/mysql/conf.d -v /duxiu/mysql/logs:/logs -v /duxiu/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 -d mysql:8.0.19

docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD='1234' -d mysql:8.0.19

进入容器

1
docker exec -it bd39192d9fa8 /bin/bash

执行登录命令

1
mysql -uroot -p密码

完事

安装Redis

复制redis.conf到/opt/data/redis目录下

执行下面的命令

1
docker run -p 6379:6379 --name myredis -v /opt/data/redis/redis.conf:/etc/redis/redis.conf -v /opt/data/redis/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes

将本地镜像推送到阿里云

创建容器仓库

https://cr.console.aliyun.com/repository/cn-hangzhou/huohuo/myimages/images

创建本地仓库

1
2
3
sudo docker login --username=惑惑惑惑惑惑惑惑惑惑 registry.cn-hangzhou.aliyuncs.com
sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/huohuo/myimages:[镜像版本号]
sudo docker push registry.cn-hangzhou.aliyuncs.com/huohuo/myimages:[镜像版本号]
文章作者:
文章链接: https://huohuohuohuohuohuo.github.io/2020/03/21/Docker/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论