Docker
Docker入门
容器技术的发展
chroot
Namespace
2002年其Linux2.4.19开始引入的特性。可以通过三个系统调用直接操作Namespace- clone 传递不同的namespace的标志为新的(子)进程指定其所属的namespace
- unshare 允许一个进程(或线程)取消当前与其他进程(或线程)共享的执行上下文
- setns 进入文件描述符指定的namespace
- cgroups 和LXC
- Docker允许用户将容器环境打包成为一个Docker镜像进行分发,这也大大降低了用户使用的门槛
Docker的基本使用
- Docker安装:
Docker 的生命周期
- created
- running : a. running b .paused c. restarting
- removing
- dead
- exited
容器资源管理:
- CPU
- 内存
- 网络
- IO
- GPU
cgroups:
cgroups,其名称来源自控制组群(control group的简写,是Linux内核的一个功能,来用限制,控制与分离一个进程组的资源(如CPU,内存,磁盘输入输出等).容器的核心 namespace
/proc目录
/proc文件系统下的多种文件提供的系统信息不是针对某个特定进程的,而是能够在整个系统范围的上下文中使用。可以使用的文件随系统配置的变化而变化。命令procinfo能够显示基于其中某些文件的多种系统信息。以下详细描述/proc下的文件。
/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过 proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是 动态从系统内核读出所需信息并提交的。
/proc下有关于每个进程的文件夹
cgroup文件
namespace
namespace 管理的资源(可用的namespace)
Mount
PID
Network
IPC
UTS
User
Cgroups如何使用namespace:
- clone(),创建一个新的进程;但如果传递一个或多个CLONE_NEW8标志给clone,则会根据每个标志创建新的namespace 并且将紫禁城添加为其成员
- setns(),允许进程加入一个已存在的namespace中
- unshare(),允许进程(或线程)取消其执行上下文中,与其他进程(或线程)共享部分的关联。简单来说,就是可以利用此系统调用来让当前的进程(或线程)移动至一个新的namespace中。
编写容器
容器的基本属性
- 容器一定具有隔离性,具备了隔离性才能被成为容器
- 容器的资源可以被管理
- 容器可以从“镜像”启动
- 启动后的容器,可以具备网络连接
- 可以进入到容器中执行指令
- namespace 和cgroups是实现资源的隔离和管理的关键技术。其他的问题就是镜像以及网络相关的内容
1. 创建隔离环境
使用unshare 来创建隔离环境
2. 隔离主机的根目录系统
chroot可以改变进程可见的根目录。
3. 使用cgroups进行资源管理
安装cgroups工具
创建cgroups,容器的资源管理和限制是通过cgroup完成的,为了让我们的隔离环境更完善,创建一个可用于限制内存和CPU的cgroups作为演示。
使用cgcreate来创建一个新戴尔cgroups
镜像生命周期管理
docker run下载镜像行为解析
- 查找镜像
- 下载镜像
镜像操作:增
通过docker pull 或docker image pull命令来自动下载镜像 —platform参数可以执行下载的镜像的平台
加载 docker image save -o xxx.tar xxx
docker image load -i xxx.tar导入 (import)
docker export -o xxx.tar containerID
docker image import xxx.tarcommit 从正在运行的容器创建一个镜像
docker commit -a “xxx” containerID image:tagbuild
- 写一个Dockerfile
- 使用docker build 构建镜像,通过-t 指定其名称和Tag
- docker build -t xxx:xxx
- 镜像操作:查
# 查询具体名称和Tag的镜像
docker image ls xxx:tag
# 查询具有相同名称的镜像
docker image ls xxx
基于原对象对内容做修改
启动一个容器,为它新增一个文件
docker run —rm -it alpine:latest
在该容器中进行文件操作
使用commit命令将容器保存新的tag镜像
运行该tag下的镜像,文件被保存
不保留原镜像信息做修改
将容器导出为一个tar包
docker export -o xxx.tar containerID
导入该包
docker import xxx.tar alpine:some-tag
使用新的镜像启动容器
docker run alpine:some-tag sh
使用dockerfile
-
镜像操作:删
一个个删除
docker image rm xxx xxxx1 xxxx2
批量删除
docker image rm $(docker image ls alpine -q) ```
构建镜像和分发
- 本地镜像存储
Dockerfile基本介绍
Dockerfile基本格式
- 以# 开头的是注释,除了
# escape =
和# syntax =
- 指令不区分大小写,但约定使用大写
- 以# 开头的是注释,除了
Docker常用指令
FROM 指定构镜像所用的基础镜像,通常情况下使用Docker官方镜像,可以在Docker Hub上找到。每个Dockerfile必须有FROM指令,如果没有指定FROM,则会在解析DOCKERFILE时报错
RUN 指定构建过程中需要执行的操作。Docker是层级结构的,每个RUN指令都会在一个新层中执行,并将其执行结果提交为一个新的层,并用于后续Dockerfile的操作。常用的RUN指令SHELL形式的,也可以使用exec形式的,不过需要用[]括起来。
`RUN [“/usr/bin/echo”,”using exec form”]EXPOSE 标识容器运行时要监听的端口,例如EXPOSE 6379则标识暴露6379端口,也可以在docker run时通过-p 参数指定
Dockerfile 重要指令
COPY / ADD
ADD 除可用于正常拷贝文件外,还可添加URL形式的远程内容
ADD 可添加本地的tar归档文件或压缩文件,并且会被解压。如果是来自远程的内容,则不会解压
COPY 还可用于多阶段构建中,通过—from=参数传递,可以从之前阶段中拷贝内容到新的构建阶段。
在满足要求的情况下,优先使用COPY
- 构建缓存
- 减少镜像体积
ARG和ENV
- 均可用于在构建镜像过程中预定义变量
- 生命周期: ARG定义的变量只影响镜像的构建阶段,但是ENV定义的变量会存在于镜像的整个生命周期,包括使用镜像创建容器,该变量仍然可用
- ARG在构建时,可通过—build-arg进行修改和指定,但是ENV指定的变量在构建时不可修改
- 优先级: 如果ARG和ENV定义的变量相似,且ARG在ENV之前,则ENV定义的变量会覆盖ARG定义的变量
- 使用范围: ARG可优先与FROM使用,但是ENV不可以。
- 如果在构建过程中修改变量的值,则使用ARG指令,如果是想要将值保留在镜像中,甚至是之后的容器中使用的话,使用ENV更加合适。应该避免ARG和ENV指向相同的变量
ENTRYPOINT 和 CMD
- 均定义了当容器运行时,需要执行的命令
- ENTRYPOINT定义的行为,在启动容器时,需要指定—entrypoint 才能覆盖。
- CMD定义的行为,在docker run [OPTIONS] image [COMMAND] [ARG …]的[COMMAN]和[ARG…]处进行覆盖
- 当定义ENTRYPOINT后,如果CMD使用的是exec格式,即CMD[“AA”,”BB”]形式的话,则其内容会直接作为ENTRYPOINT的参数。如果CMD使用的时shell格式,即CMD AA BB的话,最终的连接形式为ENTRYPOINT sh -c aa bb。
- 建议ENTRYPOINT和CMD使用exec格式。如果是工具类镜像,直接将执行该工具的命令设为ENTRYPOINT
- 多阶段构建
- 为了能让最终产生只保留我们所需的内容,可以使用多阶段构建的方式。
- Dockerfile中存在多个FROM指令,表示不同的阶段,后阶段可以使用前阶段的产物,或镜像的内容
Docker核心特性
Docker网络基础
none网络
使用null驱动,没有网络的意思host网络
容器与主机共享网络堆栈,其hosts内容也和主机一直bridge网络
默认模式,容器在启动时,由Docker为其分配一个IP地址,并且在访问外部网络时,会通过Docker默认提供的docker0接口出去。container网络
容器共享指定容器的网络堆栈。
定制bridge网络
- 使用默认配置创建网络
docker network create 自定义网络名
即可创建新的bridge网络