docker 笔记

2020-10-27/2022-01-21

参考文档:
Docker 从入门到实践

Docker 安装

1.centos6.8

1yum install -y epel-release
2yum install -y docker-io
3# 配置文件 /etc/sysconfig/docker
4# 启动 docker 服务
5service docker start
6# 验证
7docker version

2.其他参考 https://docs.docker.com/engine/install/

阿里云镜像加速

https://help.aliyun.com/document_detail/60750.html

针对安装了Docker for Mac的用户,您可以参考以下配置步骤:

在任务栏点击 Docker Desktop 应用图标 -> Perferences,在左侧导航菜单选择 Docker Engine,在右侧输入栏编辑 json 文件。将

https://ln6hzcek.mirror.aliyuncs.com(自己的加速地址) 加到"registry-mirrors"的数组里,点击 Apply & Restart按钮,等待Docker重启并应用配置的镜像加速器。

Docker 命令

帮助命令

1# 查看版本
2docker version
3# docker 相关信息 
4docker info
5# 帮助命令
6docker --help

镜像命令

 1# 查看本地镜像
 2docker images
 3  -a # 列出本地所有镜像,包含中间镜像层
 4  -q # 只显示镜像 ID
 5  --digests # 显示镜像的摘要信息
 6  --no-trunc # 显示完整的镜像信息
 7  
 8# 搜索镜像
 9docker search 镜像名
10  --no-trunc # 显示完整的镜像信息
11  -s # 列出收藏数不小于指定值的镜像
12  --automated # 只列出 automated build 类型的镜像
13  
14# 下载镜像
15docker pull 镜像名[:TAG]  # 默认 tag 为 latest
16
17# 删除镜像
18docker rmi 镜像名[:TAG]/镜像 ID [镜像2名[:TAG]/镜像2 ID]
19  -f # 强制删除
20  
21# 删除全部镜像
22docker rmi -f $(docker imgages -qa)
23
24# 查看镜像构建历史
25docker history 镜像 ID

容器命令

 1# 新建并启动容器
 2docker run [OPITIONS] IMAGE [COMMAND] [ARG...]
 3  OPITIONS 说明
 4    --name="容器名称"
 5    -d # 后台运行容器,并返回容器 ID
 6    -i # 以交互模式运行容器,通常与 it 同时使用
 7    -t # 为容器重新分配一个伪输入终端,通常与 i 同时使用
 8    -P # 随机端口映射
 9    -p # 指定端口映射,有以下四种格式
10      ip:hostPort:containerPort
11      ip::containerPort
12      hostPort:containerPort
13      containerPort
14    
15# 列出当前所有正在运行的容器
16docker ps [OPITIONS]
17  -a # 列出当前所有正在运行的容器+历史上运行过的容器
18  -l # 显示最近创建的容器
19  -n # 显示最近 n 个创建的容器
20  -q # 静默模式,只显示容器编号
21  -no-trunc # 不截断输出
22  
23# 退出容器
24exit # 停止当前终端进程并退出
25ctrl+P+Q # 当前终端不停止退出
26
27# 启动容器
28docker start 容器 ID/Name
29
30# 重启容器
31docker restart 容器 ID/Name
32
33# 停止容器
34docker stop 容器 ID/Name
35
36# 强制停止容器
37docker kill 容器 ID/Name
38
39# 删除已停止的容器
40docker rm [OPITIONS] 容器 ID/Name
41  -f # 强制删除
42  
43# 一次删除多个容器
44docker rm -f $(docker ps -a -q)
45docker ps -a -q | xargs docker rm
46
47# 查看容器日志
48docker logs [OPITIONS] 容器ID
49  -t # 加入时间戳
50  -f # 跟随最新的日志打印
51  --tail n # 显示最后 n 条 
52  
53# 查看容器内运行的进程
54docker top 容器 ID
55
56# 查看容器内部细节
57docker inspect 容器 ID
58
59# 进入正在运行的容器并以命令行交互
60docker attach 容器 ID # 直接进入容器启动命令的终端,不会启动新的 bash 进程
61docker exec -it 容器 ID bashShell  # 在容器中打开新的终端,并且启动新的 bash 进程,而且可以将命令执行结果返回给宿主机
62docker exec -it 容器 ID /bin/bash # 进入容器
63
64# 从容器内拷贝文件到宿主机
65docker cp 容器 ID:容器内路径 目的主机路径
66
67# 提交容器副本使之成为一个新的镜像
68docker commit 容器 ID 要创建的目标镜像名:[标签名]
69  -m="提交的描述信息"
70  -a="作者"

镜像原理

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

Docker 镜像都是只读的
当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的都叫镜像层。
比如 tomcat,从内到外分别为 kernel、centos、jdk、tomcat,tomcat 为容器层,其他为镜像层。

Doker 容器数据卷

Docker 数据持久化有两种方式:

  • bind mount
  • Volume

bind mount

bind mount 就是常用的 -v 的方式。

1docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
2  -v # 指定数据卷,容器和宿主机数据共享,没有的话会自动新建文件夹
3
4# 查看数据卷是否挂载成功
5docker inspect 容器 ID
6
7# 容器内目录只读
8docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
  • 宿主机目录路径必须为全路径(准确的说需要以/~/开始的路径),不然 docker 会将其当做 volume 处理
  • 宿主机上的目录不存在时,docker 会自动创建该目录
  • 容器中的目录不存在时,docker 会自动创建该目录
  • 如果容器中的目录已经有内容,docker 会使用主机上的目录将其覆盖掉

volume

Volume 是被 docker 管理的,docker 下所有的 volume 都在宿主机上的指定目录 /var/lib/docker/volumes 下。

 1# 创建 volume
 2docker volume create volumeName
 3
 4# 查看所有容器卷
 5docker volume ls 
 6
 7# 将 volume 挂载到容器目录
 8docker run -it -v volumeName:/mydata 镜像名
 9
10# 查看 volume
11docker volume inspect volumeName
12
13# 可见 volume 位于 /var/lib/docker/volumes/volumeName/_data
14
15# 删除自定义数据卷
16docker volume rm volumeName

此时,如果 volumeName 不存在,那么 docker 会自动创建 volumeName,然后再挂载。

1# 也可以不指定 host 上的 volume
2docker run -it -v /mydata tomcat

此时 docker 将自动创建一个匿名的 volume,并将其挂载到 container 中的 /mydata 目录。匿名 volume 在 host 机器上的目录路径类似于:/var/lib/docker/volumes/300c2264cd0acfe862507eedf156eb61c197720f69e7e9a053c87c2182b2e7d8/_data

与 bind mount 不同的是,如果 volume 是空的而 container 中的目录有内容,那么 docker 会将 container 目录中的内容拷贝到 volume 中,但是如果 volume 中已经有内容,则会将 container 中的目录覆盖。

DockerFile 添加

dockerfile 相当于对镜像源码级的描述。

出于可移植和分享的考虑,用 -v 主机目录:容器目录 这种方法不能够直接在 Dockerfile 中实现。
由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。

 1vim /mydocker/Dokerfile
 2
 3# volume test
 4FROM centos   # 基于 centos
 5VOLUME["/dockerVolumeContainer1", "/dockerVolumeContainer2", "/dockerVolumeContainer3"]
 6CMD each "finished, -success"
 7CMD /bin/bash
 8
 9# 容器卷默认位置
10/var/ib/docker/volumes/很长的字符串/_data
11
12# 构建镜像
13docker build -f /mydocker/Dockerfile -t rainsheep/centos .
14  -f # dokerfile 文件位置
15  -t # 镜像名
16  . # 镜像在哪个目录

数据卷共享

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

1# 新建一个容器
2docker run -it --name dc01 rainsheep/centos
3# 容器 dc02 的数据卷和 dc01 共享
4docker run -it --name dc02 --volumes-from dc01 rainsheep/centos 
5# 容器 dc03 的数据卷和 dc01 共享
6docker run -it --name dc03 --volumes-from dc01 rainsheep/centos 
7# 删除容器 dc01
8docker rm dc01
9# 发现 dc02 和 dc03 数据还能共享,就像加入了群聊一样

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

Docker 容器网络

  • 所有 docker 容器共用一个网关

  • 网桥为每一个 docker 分配一个 IP

  • 容器之间可以通过 IP 进行通信

  • 外部网络没办法通过 IP 地址访问到容器内部,只能通过端口映射来访问

  • 四种网络模式

    Docker网络模式 配置 说明
    host模式 –network=host 容器和宿主机共享Network namespace。mac 系统无法使用。
    container模式 -network=container:容器名或者 ID 容器和另外一个容器共享Network namespace。
    none模式 –network=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
    bridge模式 –network=bridge (默认为该模式)

DockerFile

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

编写 Dockerfile 文件 → docker build → docker run

scratch 为源镜像

dockerfile 内容基础知识

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

docker 执行 dockerfile 的大致流程

  • docker 从基础镜像运行一个容器
  • 执行每一条指令并对容器做出修改
  • 执行类似 docker commit 的操作提交一个新的镜像层
  • docker 再基于刚刚提交的镜像运行一个新容器
  • 执行 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之 后的命令参数替换
      • docker run -it centos ls -l 则原 dockerfile 中的 CMD 会被替换掉
    • CMD <命令>
    • CMD ["可执行命令","参数 1","参数 2"...],例如CMD ["curl", "-s", "http://ip.cn"]
    • 参数列表格式:CMD ["参数 1","参数 2"...],指定了在 ENTERYPOINT 指令后,使用 CMD 指定具体的参数
  • ENTRYPOINT

    • 指定一个容器启动时要运行的命令
    • ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动命令及参数
    • docker run 之后的参数会被当做参数传递给 ENTRYPOINT, 之后形成新的命令组合
  • ONBUILD: 当构建一个被继承的 Dockerfile 时运行命令,父镜像在被子继承后父镜像的 onbuild 被触发

Docker 问题汇总

docker 修改容器时间

1# 进入容器执行,后重启容器
2ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
3# 或者宿主机执行,后重启容器
4docker cp  /usr/share/zoneinfo/Asia/Shanghai 容器ID:/etc/localtime

改完之后,发现 tomcat 时间仍然不对,是因为 docker 中的 java 应用获取时间是从 timezone 中获取,因此进入 docker,修改timezone

1echo "Asia/Shanghai" > /etc/timezone

Alpine Linux 操作系统

介绍

Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过 https://pkgs.alpinelinux.org/packages 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。

Alpine Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB),且拥有非常友好的包管理机制。官方镜像来自 docker-alpine 项目。

目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。

使用

目前,大部分 Docker 官方镜像都已经支持 Alpine 作为基础镜像,可以很容易进行迁移。

例如:

  • ubuntu/debian -> alpine
  • python:3 -> python:3-alpine
  • ruby:2.6 -> ruby:2.6-alpine

由于在国内访问 apk 仓库较缓慢,建议在使用 apk 之前先替换仓库地址为国内镜像。

1RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories \
2      && apk add --no-cache <package>
评论
发表评论
       
       
取消