Docker容器知识总结

Docker 核心技术

隔离性 Linux namespace

每个用户实例之间相互隔离, 互不影响。 一般的硬件虚拟化方法给出 的方法是VM,而LXC给出的方法是container,更细一点讲就是 kernel namespace。其中pid、net、ipc、mnt、uts、user等 namespace将container的进程、网络、消息、文件系统、 UTS(“UNIX Time-sharing System”)和用户空间隔离开。

  1. pid namespace。不同用户的进程就是通过pid namespace隔离开的,且不同 namespace 中可以有相同pid。所有的LXC进程在docker中的父 进程为docker进程,每个lxc进程具有不同的namespace。同时 由于允许嵌套,因此可以很方便的实现 Docker in Docker。
  2. net namespace 有了 pid namespace, 每个namespace中的pid能够相互隔 离,但是网络端口还是共享host的端口。网络隔离是通过net namespace实现的, 每个net namespace有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个container的网络就能隔离开来。 docker默认采用veth的方式将container中的虚拟网卡同host 上的一个docker bridge: docker0连接在一起。
  3. ipc namespace container中进程交互还是采用linux常见的进程间交互方法 (interprocess communication - IPC), 包括常见的信号 量、消息队列和共享内存。然而同 VM 不同的是,container 的进程间交互实际上还是host上具有相同pid namespace中的进 程间交互,因此需要在IPC资源申请时加入namespace信息 - 每 个IPC资源有一个唯一的 32 位 ID。
  4. mnt namespace 类似chroot,将一个进程放到一个特定的目录执行。mnt namespace允许不同namespace的进程看到的文件结构不同,这 样每个 namespace 中的进程所看到的文件目录就被隔离开了。 同chroot不同,每个namespace中的container 在/proc/mounts的信息只包含所在namespace的mount point。
  5. uts namespace UTS(“UNIX Time-sharing System”) namespace允许每个 container拥有独立的hostname和domain name, 使其在网络 上可以被视作一个独立的节点而非Host上的一个进程。
  6. user namespace 每个container可以有不同的 user 和 group id, 也就是说 可以在container内部用container内部的用户执行程序而非 Host上的用户。

控制组 Cgroups

cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单, 提供类似文件的接口,在 /cgroup目录下新建一个文件夹即可新建一 个group,在此文件夹中新建task文件,并将pid写入该文件,即可实 现对该进程的资源控制。groups可以限制blkio、cpu、cpuacct、 cpuset、devices、freezer、memory、net_cls、ns九大子系统 的资源,以下是每个子系统的详细说明:

  • blkio 这个子系统设置限制每个块设备的输入输出控制。例如:磁 盘,光盘以及usb等等。
  • cpu 这个子系统使用调度程序为cgroup任务提供cpu的访问。
  • cpuacct 产生cgroup任务的cpu资源报告。
  • cpuset 如果是多核心的cpu,这个子系统会为cgroup任务分配 单独的cpu和内存。
  • devices 允许或拒绝cgroup任务对设备的访问。
  • freezer 暂停和恢复cgroup任务。
  • memory 设置每个cgroup的内存限制以及产生内存资源报告。
  • net_cls 标记每个网络包以供cgroup方便使用。
  • ns 名称空间子系统。

便携性 AUFS

AUFS (AnotherUnionFS) 是一种 Union FS。 简单来说就是支持将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)的文件系统, 更进一步的理解, AUFS支持为每一个成 员目录(类似Git Branch)设定readonly、readwrite 和 whiteout-able 权限, 同时 AUFS 里有一个类似分层的概念, 对 readonly 权限的 branch 可以逻辑上进行修改(增量地, 不影响 readonly 部分的)。
通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个disk挂到同一个目录下, 另一个更常用的就是将一个 readonly 的 branch 和一个 writeable 的 branch 联合在一 起,Live CD正是基于此方法可以允许在 OS image 不变的基础上允 许用户在其上进行一些写操作。

安全性 AppArmor,SELinux,GRSEC

安全永远是相对的,这里有三个方面可以考虑Docker的安全特性:

  1. 由kernel namespaces和cgroups实现的Linux系统固有的安 全标准;
  2. Docker Deamon的安全接口;
  3. Linux本身的安全加固解决方案,类如AppArmor, SELinux;

Docker 快速入门

本章节分为四个部分:

  1. Docker安装
    该部分介绍Docker在Centos7试验环境下的安装方法。

  2. Docker镜像
    该部分主要介绍 Docker利用Dockerfile来构建构建镜像文件。 通常Dcokerfile构建镜像时需要基础镜像,在文章的开始部分介 绍构建基础镜像的官方方法。随后,详细讲解Dockerfile的文件 结构,以及文件内元素的具体使用方法。

  3. Docker容器
    该部分介绍容器的一些基础使用。利用简单的docker命令行来创 建docker容器,并且在容器中安装应用等。简单介绍docker命令 行的基础使用方法,调试方法等。介绍如何管理容器内产生的数据 并将其共享和持久化,同时容器通信的管理实现也做来相关介绍。

  4. Docker基本指令和用法
    通过字典方式来整理docker命令行说明。

Docker 安装 (操作系统为CentOS7 64位)

参考官方文档安装:https://docs.docker.com/engine/install/centos/

卸载原有的环境:

$ sudo yum remove docker docker-client  docker-client-latest  docker-common  docker-latest  docker-latest-logrotate  docker-logrotate  docker-engine

安装对应的依赖环境和镜像地址:

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

直接安装docker CE

sudo yum install -y docker-ce docker-ce-cli containerd.io

启动Docker服务

sudo systemctl start docker

查看docker的版本

sudo docker version

补充:通过官方的镜像地址下载docker会比较慢,
配置阿里云的镜像地址:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker- ce/linux/centos/docker-ce.repo

yum更新下即可:

yum makecache fast

开机启动docker

sudo systemctl enable docker

默认访问的仓库是在国外所以访问速度是没法保证的。为了更好的体验,我们可以设置镜像加速:
修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值。

{
  "registry-mirrors": ["https://2lqq34jg.mirror.aliyuncs.com"]
}

添加保存之后,重启服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

至此 Docker 在CentOS下安装步骤就完成了!

Docker 镜像

镜像是 Docker 的三大组件之一。 Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地, Docker 会从镜像仓库下载(默认是 Docker Hub 公共注册服务器 中的仓库),我们也可以搭建一个本地的镜像仓库,但这不是本文的重点。本文将以镜像为中心介绍:

  • 如何构建基础镜像
  • Dockerfile的基本结构以及详解
  • 利用Dockerfile构建镜像

基础结构
Dockerfile由一行行命令语句组成,并且支持以 # 开头的注释行。一般的,Dockerfile 分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时执行指令
    例如:
FROM ubuntu

MAINTAINER docker_user docker_user@email.com

RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

CMD /usr/sbin/nginx

构建基础镜像

我将应用打包到镜像中形成我们所需的镜像,往往需要一个基础的镜像 作为我们应用服务的外部环境,那么问题来了,基础镜像从何而来?官 方推荐的是直接从官网仓库pull一个,但由于官网被墙的比较厉害, 所以这里介绍一些官方提供以及个人方法。
1.使用Debootstrap来创建Ubuntu的base image

$ sudo debootstrap raring raring > /dev/null
$ sudo tar -C raring -c . | docker import - raring
$ docker run raring cat /etc/lsb-release

2.使用scratch创建base image
在Docker registry中有一个scratch,你可以pull拉取下来,

$ sudo docker pull scratch

甚至可以自己制作:

$ tar cv --files-from /dev/null | docker import - scratch

Scratch镜像很赞,它简洁、小巧而且快速, 它没有bug、安全漏 洞、延缓的代码或技术债务。这是因为它基本上是空的。除了Docker 添加了点的metadata (译注:元数据为描述数据的数据)。总之它是 非常小的一个Docker镜像。
3.下载官方提提供的OS的tar文件
到OPENVZ上下载基础包然后使用docker limport 加载到本地镜 像,这里以ubuntu14.04 为例,从openvz下载一个ubuntu14.04 的模板:

wget http://download.openvz.org/template/precreated/ubuntu-14.04- x86_64.tar.gz
cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - ubuntu:base

创建镜像
编写完成 Dockerfile 之后,可以通过 docker build 命令来创 建镜像。
基本的格式为 docker build [选项] 路径,该命令将读取指定路径 下(包括子目录)的 Dockerfile,并将该路径下所有内容发送给 Docker 服务端,由服务端来创建镜像。因此一般建议放置 Dockerfile 的目录为空目录。也可以通过 .dockerignore 文件 (每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文 件。要指定镜像的标签信息,可以通过 -t 选项,例如:

$ sudo docker build -t myrepo/myapp /tmp/test1/

Dockerfile 操作建议

Docker可以读取一个Dockerfile文件来构建所需的镜像,这个文件 里包含所有所需要的指令。Dockerfile文件用特有的格式来设置镜像信息,本文包含Docker官方提供的一些践以及方法,强烈建议你去参照 这些建议。
官方建议:

  1. 一个Dockerfile文件尽量 越简洁越好 ,这意味着 它可以被停止销 毁,然后被最小化配置安装到另一个地方。
  2. 在通常情况下,最好把 Dockerfile文件放到一个空目录 ,然后,将构建 镜像所需要动文件添加到该目录。为了提高构建性能,你也可以通 过添加 .dockerignore 文件到该目录以排除文件和目录,该文件支 持排斥的模式类似于.gitignore文件。
  3. 为了 减少镜像复杂度、依赖、文件大小和构建时间 ,应该尽量避免安装多余的 不需要包,例如:你不需要在一个数据库镜像中添加一个文本编辑器。
  4. 在绝大多数情况下, 每一个镜像只跑一个process ,应用于多个容器中可 以方边应用横向扩展和重复利用容器。如果该服务依赖于其他服 务,请使用容器互联。
  5. 你需要在Dockerfile的可读性和镜像层次最小化之间取得平衡, 要有目的且非常谨慎的控制使用分层的数量。

Dockerfile 参数详解

FROM

格式为 FROM 或FROM :。

第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令(每个镜像一次)。

MAINTAINER

格式为 MAINTAINER ,指定维护者信息。

RUN

格式为 RUN 或 RUN [“executable”, “param1”, “param2”]。

前者将在 shell 终端中运行命令,即 /bin/sh -c; 后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN [“/bin/bash”, “-c”, “echo hello”],每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较 长时可以使用 \ 来换行。

CMD
支持三种格式

  1. CMD [“executable”,“param1”,“param2”] 使用 exec 执行,推荐方式;
  2. CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
  3. CMD [“param1”,“param2”] 提供给 ENTRYPOINT 的默认参数;

指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

EXPOSE

EXPOSE […]

告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P ,Docker 主机会自动分配一个端口转发到指定的端口。

ENV

ENV

指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。

ADD

ADD

该命令将复制指定的 到容器中的 。 其中可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件 (自动解压为目录)。

COPY

COPY

复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中 的 。 当使用本地目录为源目录时,推荐使用 COPY。

ENTRYPOINT
两种格式:

ENTRYPOINT [“executable”, “param1”, “param2”]
ENTRYPOINT command param1 param2(shell中执行)

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。

VOLUME

VOLUME [“/data”]

创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据 库和需要保持的数据等。

USER

USER daemon

指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以 在之前创建所需要的用户,例如: RUN groupadd -r postgres && useradd - r -g postgres postgres

WORKDIR

WORKDIR /path/to/workdir

为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。
例如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为 /a/b/c。

Docker 容器

容器是 Docker 又一核心概念。 简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环 境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运 行态环境和其他系统环境)和跑在上面的应用。本章节着重介绍了容器 的基础使用方法,以及如何管理容器的数据、如何管理容器的网络,相信你读完本章节将会有一个大致的了解。

容器使用入门

使用info命令检查docker安装程序是否正常运行:

# 检查是否安装好docker
$ docker info

如果提示如下信息: command not found 或者 类似 于/var/lib/docker/repositories: permission denied 可 能安装有问题或者尝试在前面加上sudo。此外,基于docker系统配置,命令行前面应该加上sudo,来确保正常 执行命令,并且此时系统会为Administrar创建一个名叫docker的 Unix 用户组来让其他用户加入该组。
下载一个已经制作好的镜像:

docker pull ubuntu

创建一个带有交互窗口的container:

docker run -i -t ubuntu /bin/bash

-i参数表示启动了一个可以交互的容器,—t参数表示创建了一个附带 标准输入和输出的pseudo-TTY窗口 如果想要退出tty窗口,使用 Ctrl-p + Ctrl-q指令,容器将会退 出并且会持续保持一个停止的状态。如果想查看所有状态的容器,可以 使用docker ps -a 指令。
提交(保存)一个容器的状态到一个镜像文件中:
当提交(commit)容器时,docker仅保存源镜像与当前镜像的差异,如果想列出镜像,请使用docker images指令

docker commit <container> <some_name>
docker images

管理容器工作

我们用docker run指令来运行一个容器:

  • 交互容器跑在前端.
  • 守护进程跑在后台.

一些常用管理容器的命令:

  • docker ps - 列出容器
  • docker logs - 输出容器日志
  • docker stop - 停止运行容器.
    我们以docker version为例查看当前安装的docker客户端以及 deamon进程信息:
docker version

如果你想展示一些帮助信息,可以使用:

docker --help

在docker中跑一个web应用程序
现在你已经掌握了一些基础了,来深入一下吧。之前跑的一些应用没什 么实际用途,让们来跑一个web应用试试吧。 这个web应用包含里 python 应用:

docker run -d -P training/webapp python app.py

以上指令中包含两个参数:

-d 让容器在后台运行
-P 分配一个主机端口到容器端口的映射以供外部访问

training/webapp是一个构建好的镜像,里面包含了一个简单的 Python Flask web应用程序。

管理容器数据

docker管理数据的两种主要方式。 数据卷,以及数据卷容器。数据卷是在一个或多个容器,它绕过Union File System的一个专门 指定的目录。数据卷为持续共享数据提供了一些有用的功能:

  • 在创建容器时,卷被初始化。如果容器的基础映像包含指定的数据 装入点,现有的数据复制到在卷初始化新卷。
  • 数据卷可以共享和容器之间重复使用。
  • 改变数据卷将立刻生效(在所有挂载该容器中)。
  • 改变数据卷数据不会影响到容器。
  • 即使容器本身被删除。但是数据卷依然存在。
  • 数据卷的目的是持久化数据,独立于容器的生命周期。Docker因 此不会自动删除卷,当你删除一个容器,也不会“垃圾回收”直到没 有容器再使用。

添加一个数据卷
你可以在docker run时加上-v参数来添加一个数据卷,-v参数也可 以使用多次,以挂载多个数据卷

docker run -d -P --name web -v /webapp training/webapp python app.py

这条命令将在容器中的/webapp文件夹创建一个数据卷存储数据。 你也可以在构建镜像时在Dockerfile里面定义。 数据卷默认的权限时读写,你也可以定义成只读。

docker run -d -P --name web -v /opt/webapp:ro training/webapp python app.py

查找数据卷路径用docker inspect命令定位:

docker inspect web

挂载一个主机目录作为数据卷
挂载主机目录为数据卷,必须参照 -v hostPATH:containerPATH 这种格式 路径必须为绝对路径,以保证容器的 可移植性。

docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

上面的命令加载主机的 /src/webapp 目录到容器的 /opt/webapp 目录
docker数据卷的权限是读写,你也可以指定只读:

docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py

挂载一个数据文件作为数据卷
-v 标记也可以从主机挂载单个文件到容器中

docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash

管理容器通信

容器与宿主机器采用端口映射的方式通信
之前的例子:

docker run -d -P training/webapp python app.py

我们也可以指定端口映射:

docker run -d -p 80:5000 training/webapp python app.py

-p参数还有其他指定方法:

ip:hostPort:containerPort 映射指定IP的指定端口
ip::containerPort 映射指定IP任意端口
hostPort:containerPort 映射所有主机IP的指定端口

Docker 常用基本指令及用法

镜像命令

镜像命令说明
docker images列出本地主机上的镜像
docker search 镜像名称从 docker hub 上搜索镜像
docker pull 镜像名称从docker hub 上下载镜像
docker rmi 镜像名称删除本地镜像

docker images
在这里插入图片描述

镜像表格信息说明

选项说明
REPOSITORY表示镜像的仓库源
TAG镜像的标签
IMAGE ID镜像ID
CREATED镜像创建时间
SIZE镜像大小
参数说明
-a列出本地所有的镜像
-q只显示镜像ID
–digests显示镜像的摘要信息
–no-trunc显示完整的镜像信息

docker search
docker hub是Docker的在线仓库,我们可以通过docker search 在上面搜索我们需要的镜像

参数名称描述
–no-trunc显示完整的描述信息
–limit分页显示
-f过滤条件 docker search -f STARS=5 tomcat

Docker pull
从Docker hub 上下载镜像文件

Docker rmi

删除方式命令
删除单个docker rmi -f 镜像ID
删除多个docker rmi -f 镜像1:TAG 镜像2:TAG
删除全部docker rmi -f $(docker images -qa)

容器命令

创建并启动一个容器的命令

docker run [OPTIONS] IMAGE [COMMAND]

OPTIONS中的一些参数

options说明
–name“容器新名字”: 为容器指定一个名称
-d后台运行容器,并返回容器ID,也即启动守护式容器
-i以交互模式运行容器,通常与 -t 同时使用
-t为容器重新分配一个伪输入终端,通常与 -i 同时使用
-P随机端口映射
-p指定端口映射

我们要查看当前正在运行的容器有哪些,可以通过ps 命令来查看:

docker ps [OPTIONS]
OPTIONS说明
-a列出当前所有正在运行的容器+历史上运行过的
-l显示最近创建的容器
-n显示最近n个创建的容器
-q静默模式,只显示容器编号
–no-trunc不截断输出

我们启动了一个容器后,如何退出容器

退出方式说明
exit容器停止退出
ctrl+p+q容器不停止退出

启动容器:

docker start 容器ID或者容器名称

重启容器:

docker restart 容器id或者名称

停止容器:

docker stop 容器ID或者名称

还可以通过强制停止方式处理:

docker kill 容器ID或者名称

删除容器:
有时候容器使用完成就没有作用了,我们想要删除掉容器,这时可以通过rm命令

docker rm 容器ID 
docker rm -f $(docker ps -qa) 
docker ps -a -q | xargs docker rm

其他命令

查看容器运行的日志:

docker logs -t -f --tail 3 容器ID

查看容器中运行的进程:

docker top 容器ID

查看容器细节:

docker inspect 容器ID

进入运行的容器:

进入方式说明
exec在容器中打开新的终端,并且可以启动新的进程
attach直接进入容器启动命令的终端,不会启动新的进程

文件复制:
我们有时需要从容器中拷贝内容到宿主机中

docker cp 容器ID:容器内路径 目的地路径
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值