此篇记录使用Docker的一些基本概念和操作。

虚拟机和容器

虚拟机 -> 模拟整个计算机,容器 -> 只提供操作系统级别的虚拟化。
Docker本质上就是一种管理容器的平台软件。Docker是对运行特定应用所需的全部程序(包括操作系统在内)的一种轻量级虚拟化。
Docker引擎由Docker客户端、Docker守护进程以及不同的Docker容器组成,这些容器为Docker镜像的实例。
Docker镜像可以通过Dockerfile创建,并且镜像还能够存储在Docker注册中心(registy)中。

Docker 架构

  1. Docker 采用的是 Client/Server 架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。
  2. 客户端和服务器可以运行在一个 Host 上,客户端也可以通过 socket 或 REST API 与远程的服务器通信。

Docker 的核心组件

  1. Docker 客户端:client
  2. Docker 服务器:Docker daemon
  3. Docker 镜像:Image
  4. Registry
  5. Docker 容器:Container

Docker的三个基本概念

镜像(Image)

  • 由一组文件系统(多层文件系统)联合组成。
  • 镜像是静态的定义,类似于一个只读模板。
  • 有好几种不同的方法可以创建Docker镜像,其中一种就是在一个名为Dockerfile的文件里包含一系列指令。
  • 容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。
  • 只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。

容器(Container)

  • 容器是镜像运行时的实体。
  • 容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。容器使软件具备了超强的可移植能力。
  • 容器可以被创建、启动、停止、删除、暂停等。
  • 容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。
  • 容器在运行时会为读写准备一个临时存储层,称为容器存储层。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
  • 容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

仓库(Repository)

  • 一个集中的存储、分发镜像的服务。
  • 可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
  • 最常使用的 Registry 公开服务是官方的 Docker Hub( https://hub.docker.com ), 这也是默认的 Registry,并拥有大量的高质量的官方镜像。Docker Hub提供公开和私有的Docker镜像,但私有的Docker镜像需要付费才能使用。

Docker架构

  1. Docker client客户端:Docker的客户端向Docker Daemon发起请求。
  2. Docker Daemon守护进程:Docker是C/S架构的程序,Docker的客户端向守护进程发起请求,守护进程处理完成后返回结果。Docker客户端既可以在本地访问守护进程,也可以通过 socket 或 REST API 远程访问守护进程。
  3. Docker Image镜像:Docker 容器运行时的只读模板。
  4. Docker Container容器:Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。
  5. Docker Registry仓库:Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库
  6. Docker Network网络:Docker网络用来保证容器之间,以及容器的内外部通信。

安装 Docker

Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费),EE 即企业版,强调安全,付费使用。

Docker 命令

  1. 验证安装正确

docker version
docker info

  1. 运行一个 Nginx 服务器

docker run -d -p 80:80 --name webserver nginx

  • 服务运行后访问 http://localhost ,如果看到了 "Welcome to nginx!" 说明 Docker 安装成功。
  • 要停止 Nginx 服务器并删除执行下面的命令:

docker stop webserver
docker rm webserver

  1. 从 Docker 镜像仓库获取镜像的命令是 docker pull。其命令格式为:

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

  • 具体的选项可以通过 docker pull --help 命令看到。
  • Docker 镜像仓库地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
  • 仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。
  • 从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。
  1. 运行容器的命令

docker run
例如:
docker run hello-world
docker run -it ubuntu bash
docker run -i -t centos

  1. 列出镜像

docker image ls
docker image ls -a
docker image ls xxxxx

  1. 查看镜像、容器、数据卷所占用的空间

docker system df

  1. 删除无用的虚悬镜像

docker image prune

  1. 删除本地镜像

docker image rm [选项] <镜像1> [<镜像2> ...]
docker rmi IMAGE_NAME|IMAGE_ID

  1. 其它

-d 让容器在后台运行
-p 指定端口映射,格式为主机(宿主)端口:容器端口
--restart 重启模式,设置 always,每次启动 Docker 都会启动 Nginx 容器。

例如:

docker run -d -p 80:80 nginx // 启动nginx容器,并映射到宿主机的80端口
访问 http://localhost 进行验证
docker ps -n 5 // 查看容器list及状态
docker stop [CONTAINER ID] // 停止nginx容器

Dockerfile

Dockerfile的基本指令有十三个。下面介绍常用的几个:

FROM

所有Dockerfile的第一个指令都必须是 FROM,用于指定一个构建镜像的基础源镜像,如果本地没有就会从公共库中拉取,没有指定镜像的标签会使用默认的latest标签,如果需要在一个Dockerfile中构建多个镜像,可以使用多次。

MAINTAINER

描述镜像的创建者,名称和邮箱。

RUN

RUN命令是一个常用的命令,启动某个镜像。执行完成之后会成为一个新的镜像,通常用于运行安装任务从而向映像中添加额外的内容。

COPY

复制本机文件或目录,添加到指定的容器目录中。

WORKDIR

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

ENTRYPOINT

在启动容器的时候提供一个默认的命令项。

docker安装redis

搜索镜像

docker search redis

加载redis镜像

docker pull redis

启动redis容器

docker run -p 6379:6379 -v $PWD/data:/data -d redis redis-server --appendonly yes --requirepass "123456"

查看运行的容器

docker ps

设置自启

docker update --restart=always [容器id]

进入redis镜像

docker exec -it 容器ID redis-cli

创建Docker映像

docker build -t docker-xxx:0.1 .

或者

docker build

Docker远程访问

docker的远程访问一般占用2375端口。

Docker其它管理

  1. Docker ps/top/stats 是原生的命令行监控工具。除了命令行,Docker 也提供了 stats API,用户可以通过 HTTP 请求获取容器的状态信息。
  2. Docker logs 是原生的日志工具。另外还有 logspout 对日志提供了路由功能,它可以收集不同容器的日志并转发给其它工具进行后处理。

Docker可视化管理工具

1. UI For Docker

docker pull uifd/ui-for-docker
docker run -it -d --name docker-web -p 9500:9000 -v /var/run/docker.sock:/var/run/docker.sock docker.io/uifd/ui-for-docker
然后通过浏览器访问 http://127.0.0.1:9500 即可。

2. Portainer

docker volume create portainer_data
docker run -d -p 9500:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
然后通过浏览器访问 http://127.0.0.1:9500 即可。

Docker实现原理

Docker的实现依赖Linux底层三大基础能力:
1、chroot & pivot_root 模拟:模拟文件系统
2、namespace 隔离:隔离进程
3、CGroup 限制:限制资源访问量