基本介绍

  Docker 是一个开源的容器引擎,可以将开的的应用以及依赖进行打包到一个可移植的镜像当中,可在 Linux 和 Windows 上运行,容器是完全使用沙箱机制,相互之间是隔离的。

版本

  • CE (Community Edition: 社区版)
  • EE (Enterprise Edition: 企业版)

特性

Docker 容器化与常用虚拟化 (Vmware、Hyper-V) 区别:

  • 虚拟机需要虚拟出硬件,以及一套完整的操作系统,然后在操作系统上运行软件,空间利用率很低,其基础的系统运行会消耗极大一部分的宿主机资源。
  • Docker 容器化是运行在宿主机上的一个服务,container 没有独立的内核,也没有独立的虚拟硬件,环境相似的 container 之间共用同一个 (linux) 内核,以节省系统开销,并且 Docker 使用了 Union File System(联合文件系统),这使得空间利用率和资源复用进一步提高。
  • Container 之间都是互相隔离的,每个容器都有自己文件系统,互不影响。

Docker 的优势:

  1. 使应用更快速的交付和部署
  2. 更便捷的升级和扩缩容
  3. 更简单的系统运维
  4. 更高效的计算机资源利用

组成

  1. 镜像 (Image)
  2. 一个只读的数据包,当中包含了虚拟环境运行的最原始的文件系统。
  3. 容器 (Container)
  4. 用来隔离虚拟环境的基础设施,它包含了程序的运行环境,和指令集。
  5. 网络 (Network)
  6. 在容器间建立虚拟网络,将数个容器包裹其中,同时与其他网络环境隔离。
  7. 数据卷 (Volume)
  8. 可以从宿主操作系统中挂载容器目录,还能够建立独立的目录存放数据,或者在容器之间共享。

    ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAACbklEQVRoQ+2aMU4dMRCGZw6RC1CSSyQdLZJtKQ2REgoiRIpQkCYClCYpkgIESQFIpIlkW+IIcIC0gUNwiEFGz+hlmbG9b1nesvGW++zxfP7H4/H6IYzkwZFwQAUZmpJVkSeniFJKA8ASIi7MyfkrRPxjrT1JjZ8MLaXUDiJuzwngn2GJaNd7vyP5IoIYY94Q0fEQIKIPRGS8947zSQTRWh8CwLuBgZx479+2BTkHgBdDAgGAC+fcywoyIFWqInWN9BSONbTmFVp/AeA5o+rjKRJ2XwBYRsRXM4ZXgAg2LAPzOCDTJYQx5pSIVlrC3EI45y611osMTHuQUPUiYpiVooerg7TWRwDAlhSM0TuI+BsD0x4kGCuFSRVzSqkfiLiWmY17EALMbCAlMCmI6IwxZo+INgQYEYKBuW5da00PKikjhNNiiPGm01rrbwDwofGehQjjNcv1SZgddALhlJEgwgJFxDNr7acmjFLqCyJuTd6LEGFttpmkYC91Hrk3s1GZFERMmUT01Xv/sQljjPlMRMsxO6WULwnb2D8FEs4j680wScjO5f3vzrlNJszESWq2LYXJgTzjZm56MCHf3zVBxH1r7ftU1splxxKYHEgoUUpTo+grEf303rPH5hxENJqDKQEJtko2q9zGeeycWy3JhpKhWT8+NM/sufIhBwKI+Mta+7pkfxKMtd8Qtdbcx4dUQZcFCQ2I6DcAnLUpf6YMPxhIDDOuxC4C6djoQUE6+tKpewWZ1wlRkq0qUhXptKTlzv93aI3jWmE0Fz2TeujpX73F9TaKy9CeMk8vZusfBnqZ1g5GqyIdJq+XrqNR5AahKr9CCcxGSwAAAABJRU5ErkJggg==)
    

镜像加速

阿里云

  1. 打开阿里云官网登录后找到 控制台 -> 容器镜像服务 -> 镜像加速器 -> (选择对应的系统) 复制加速地址

镜像加速地址

  1. 在 Docker 宿主机中执行如下代码(centos)

    
    ```
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://yourid.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    ```

常用命令

(在这之前先确保 Docker 已正确安装并启动)

基础命令

docker version          #查看docker的版本信息
docker info             #查看docker的系统信息,包括镜像和容器的数量
docker COMMAND --help   #帮助命令(可查看可选的参数)

镜像命令

docker images  #查看本地所有的镜像

# 字段解释:
1.REPOSITORY  仓库源
2.TAG  标签
3.IMAGE ID
4.CREATED 创建时间
5.SIZE

# option参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id

镜像搜索

docker search imgname

# 字段解释:
1.NAME 
2.DESCRIPTION 镜像描述
3.STARS
4.OFFICIAL 官方镜像
5.AUTOMATED

# option说明
-f, --filter filter     过滤器
      --format string   
      --limit int       
      --no-trunc

#eg(搜索nginx大于1000start的镜像):
docker search nginx --filter=STARS=1000

镜像下载

# 下载nginx镜像
docker pull nginx     # 默认为latest

# 指定版本(1.20.2)下载
docker pull nginx:1.20.2

镜像删除

# 删除单个镜像
docker rmi -f imgId

# 删除多个镜像
docker rmi -f imgId1 imgId2 ...

# 删除所有镜像(表达式)
docker rmi -f $(docker images -aq)

容器命令

# 创建一个容器
docker run [option] image

# option说明
--          容器名
-d                     后台运行
-it                    使用交互方式运行
-p                     端口
    -p ip:宿主机端口:容器端口
    -p 宿主机端口:容器端口
    -p 容器端口
    
# 进入容器
docker run -it nginx /bin/bash

# 退出容器
exit #停止并退出容器
Ctrl+P+Q #不停止容器退出

# 列出运行的容器
docker ps
    -a   # 列出所有容器
    -n=? # 最近创建的容器
    -q   # 容器Id

# 删除容器
docker rm containerId     #不能删除正在运行的容器(强制删除 rm -f)

# 删除所有容器
docker rm -f $(docker images -aq)

# 结合linux命令删除所有容器
docker ps -a -q|xargs docker rm

# 启动或停止容器
docker start contaId    #启动容器

docker restart contaId     #重启容器

docker stop contaId     #停止容器

docker kill contaId     #强制停止容器

# 查看容器中的进程
docker top contaId

# 查看容器的配置
docker inspect contaId  

# 进入容器命令
docker exec -it contaId /bin/bash    #开启一个新的终端

docker attach contaId                 #进入正在执行的终端

# 数据拷贝操作
docker cp contaId:容器内部路径  宿主机路径        #将容器内的文件拷贝到宿主机

docker cp 宿主机路径 contaId:容器内路径        #宿主机文件拷贝到容器内部

日志命令

# 查看容器日志
docker logs
      --details        显示详细的日志信息
  -f, --follow         输出日志
      --since string   Show logs since timestamp
  -n, --tail string    显示日志行数
  -t, --timestamps     显示时间戳
      --until string   Show logs before a timestamp

# eg(输出该容器的日志信息):
docker logs -tf contaId

docker logs --tail num contaId #num为要显示的日志条数

Docker 深入解析

Docker 镜像原理

​ Docker 的镜像是由一层一层的文件系统组成,这种分层的文件系统就是 UFS 联合文件系统。UFS 主要体现在镜像容器上,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。UFS 是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。不同容器之间可以共享一些基础的文件系统层,再加上自己独有的改动层,可以大大提高存储效率。

分层概念理解:

​ 分层的概念主要围绕一个系统文件复用的过程,简单点说就是资源共享,假设有多个镜像是基于同一个基础镜像构建而来,那么宿主机只需要保留一份基础镜像即可,容器运行的时候在内存中加载一份镜像,就可以为所有容器提供服务,这好比你的多个应用程序基于同一个版本的 SDK 开发,那么在宿主机上只需要装一个该版本的 Runtime 就可以为这些应用提供服务。并且 Docker 的镜像每一层都可以被共享。

fslayer.jpg

# 可通过inspect命令查看镜像的分层信息
docker image inspect imgName    #在Rootfs中的部分

注意

在 Docker 中会将多个镜像的组合对外展示为统一的文件系统,每次往基础镜像中添加额外的镜像层时,镜像始终保持是当前所有镜像的组合。镜像始终呈现出一种堆叠的状态。

镜像提交 (commit)

# 使用commit提交一个新的镜像版本
docker commit -m='描述信息'  -a='作者' contaid imgName:[TAG]

Dockerfile

命令详解

指令时效说明
FROMxxx指定该镜像的基础镜像
FROM centos:8
MAINTAINERxxx镜像的署名信息
MAINTAINER "Geek created"
RUN构建镜像时执行镜像构建时需要运行的命令
RUN ls -l
CMD运行容器时执行容器启动时要运行的命令(只有最后一个会生效)
CMD ["ls", "-l"]
ENTRYPOINT运行容器时执行容器启动时要运行的命令,可追加命令
ENTRYPOINT ["install.sh", "run"]
EXPOSExxx暴露容器的端口号
EXPOSE 80
WORKDIRxxx工作目录
WORKDIR /path/to/workdir
ADDxxx拷贝文件添加到容器中,tar 文件会自动解压 (网络压缩资源不会被解压),可以访问网络资源
ADD txt.tff /web
ENV运行容器时执行环境变量
ENV MYPATH /usr/local
COPYxxx复制文件到容器
COPY mycss.css /source
VOLUMExxx挂载目录
VOLUME ["/web/static", "/web/root"]
EMTRYPOINT容器启动时执行首次启动时需要执行的命令
EMTRYPOINT ["/docker-entrypoint.sh"]
ONBUILDxxx当该镜像为基础镜像再次构建新的镜像时,会触发执行
ONBUILD ADD . /app/src

镜像构建

# 注意最后有个点(特指上下文路径,即Dockerfile所在路径)
docker build -t myapp:v1 .

注意

有些指令在功能上都差不多,但也是有区别的:

  • RUNCMDENTRYPOINT执行脚本的指令

    
    *   三个指令都是执行脚本
    *   `RUN`是在创建镜像时执行,使用`docker build`命令时执行,在一个 Dockerfile 里面可以有多个`RUN`
    *   `CMD`和`ENTRYPOINT`是在运行容器时执行,即使用`docker run`命令时执行,这两个指令在 Dockerfile 中都只有最后一条被执行
    *   `CMD`在使用`docker run`时可以加参数将 Dockerfile 中的`CMD`覆盖
    *   `ENTRYPOINT`在 Dockerfile 中出现后就一定会在`docker run`时被执行,不必担心会被其他参数所覆盖。
  • ADDCOPY拷贝文件到容器

    
    *   `ADD`拷贝文件(夹)时可以指定本地文件、远程 URL 地址,如果拷贝的是`tar`压缩文件时将会被自动解压成文件夹
    *   `COPY`拷贝文件(夹)时不可以指定远程 URL 地址,不会自动解压成文件夹,在拷贝本地文件时建议使用`COPY`
    

优化

  1. 组合运行语句:合并相同类型构建语句,可以有效减少镜像分层;
  2. 利用镜像构建缓存:时间同步,基础软件安装等固定内容在镜像前部分处理,镜像重新构建时会使用缓存,节省时间;
  3. 清理中间产物:注意安装过程中使用的软件和压缩包在一定要同一层里清理,否则仍然会占用镜像空间;
  4. 构建语句优化:比如 ADD 在处理本地文件时可以直接解压缩,起到 COPY + RUN tar 的作用;
  5. 优化基础镜像源:国内高校和大型 IT 企业都有创建镜像站,选择一个稳定更新及时的镜像站可以有效缩短构建时间;

Docker Compose

简介

在实际的生产环境中一个项目大多是由多个容器运行起来,这样做还有个好处就是一个容器 down 掉,不会影响到其他服务。Compose 是用于运行多容器 Docker 应用程序的工具。通过使用 YML 文件来配置应用程序需要的所有服务。

docker-compose.yml 文件

version: '2'
services:
  web:
    image: dockercloud/hello-world
    ports:
      - 8080
    networks:
      - front-tier
      - back-tier

  redis:
    image: redis
    links:
      - web
    networks:
      - back-tier

  lb:
    image: dockercloud/haproxy
    ports:
      - 80:80
    links:
      - web
    networks:
      - front-tier
      - back-tier
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock 

networks:
  front-tier:
    driver: bridge
  back-tier:
driver: bridge
  • version: 指定 compose 版本
  • service: 使用到的容器集合

    
    *   image: 容器使用的镜像
    *   links: 链接到另一个容器
  • networks:加入的网络
  • devices: 设备映射列表
  • labels: 向容器添加元数据
  • build: 指定镜像,可以基于一份 Dockerfile

最后修改:2023 年 02 月 14 日
如果觉得我的文章对你有用,请随意赞赏