Docker容器学习笔记

Docker 采用了 C/S 架构,包括客户端和服务端。Docker 守护进程 (Daemon)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。容器(Docker/Podman 等)本质上是进程隔离,不是完整的虚拟机。它们直接使用宿主机的内核,只是通过 namespace 和 cgroup 做资源隔离。容器不是”打包整个 OS”,是”打包用户空间”。内核不匹配是真实风险,不是理论问题。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

Docker容器基础概念:

Image 镜像:操作系统分为 内核 和 用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。

Container 容器:容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者 绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

Registry 仓库:镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。以 Ubuntu 镜像 为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest。仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名。但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务。

 

常用命令:

获取镜像:$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

列出镜像:

列出镜像:docker image ls

查看镜像、容器、数据卷所占用的空间:docker system df

删除本地镜像:docker image rm [选项] <镜像1> [<镜像2> …]

启动容器:

新建并启动容器:docker run ubuntu:18.04 /bin/echo ‘Hello world’

启动已终止容器:docker container start

后台运行:docker run -d ubuntu:18.04 /bin/sh -c “while true; do echo hello world; sleep 1; done”

终止容器:docker container stop, 当 Docker 容器中指定的应用终结时,容器也自动终止。

进入容器:docker attach、docker exec。前者在退出容易会导致容器停止,而后者不会导致容器的停止。

导出容器:docker export 7691a814370e > ubuntu.tar

导入容器:docker import – test/ubuntu:v1.0

删除容器:docker container rm trusting_newton

Docker Hub:docker login, docker logout, docker search, docker pull, docker push

在私有仓库上传、搜索、下载镜像:

标记镜像:docker tag ubuntu:latest 127.0.0.1:5000/ubuntu:latest

上传镜像:docker push 127.0.0.1:5000/ubuntu:latest

查看镜像:curl 127.0.0.1:5000/v2/_catalog

 

当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从 registry 下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止

Docker 数据管理:

在容器中管理数据主要有两种方式:

  • 数据卷(Volumes)
  • 挂载主机目录 (Bind mounts)

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 对 数据卷 的修改会立马生效
  • 对 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。

创建数据卷:docker volume create my-vol

查看所有的数据卷:docker volume ls

查看指定数据卷:docker volume inspect my-vol

启动一个挂载数据卷的容器:

  • 在用 docker run 命令的时候,使用 –mount 标记来将 数据卷 挂载到容器里。在一次 docker run 中可以挂载多个 数据卷。
  • eg: –mount source=my-vol,target=/usr/share/nginx/html

删除数据卷:docker volume rm my-vol

 

挂载主机目录:

  • 挂载一个主机目录作为数据卷:–mount type=bind,source=/src/webapp,target=/usr/share/nginx/html
  • 挂载一个本地主机文件作为数据卷:–mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history

外部访问容器:

可以通过 -P 或 -p 参数来指定端口映射

  • 当使用 -P 标记时,Docker 会随机映射一个端口到内部容器开放的网络端口。
  • docker run -d -p 80:80 nginx:alpine: 默认会绑定本地所有接口上的所有地址。
  • docker run -d -p 127.0.0.1:80:80 nginx:alpine
  • docker run -d -p 127.0.0.1:80:80/udp nginx:alpine
  • 查看端口配置:docker port

容器互联:

  • –link
  • 新建Docker网络:docker network create -d bridge my-net
  • 运行一个容器并连接my-net网络:docker run -it –rm –name busybox1 –network my-net busybox sh

 

 

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.