Docker学习笔记(1)-简介与Docker基础

Docker概述

简介

Docker的出现主要是为了解决运行环境和配置的问题。通过Docker镜像将程序代码与所需要的系统环境打包成一个整体,达到程序在不同平台,不同环境上都能做到统一运行。用一句话来概括,Docker是一种容器虚拟化技术,解决了程序的运行环境和配置问题,方便持续集成,并且有助于整体发布。

Docker与虚拟机类似,但是它们在一些方面上有所不同。虚拟机可以在一种操作系统里面运行另一种操作系统,对于底层系统来说,虚拟机只是一个普通文件,对其他部分毫无影响。虚拟机首先虚拟出一套硬件,然后基于该硬件运行一个完整的操作系统,在该系统上再运行所需的应用进程。

Docker 容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统。而传统虚拟机则是在硬件层面上实现虚拟化。在Docker容器内的进程直接运行于宿主机的内核,并没有进行硬件虚拟,因此容器要比传统虚拟机更为轻便。容器不需要捆绑一整套操作系统,只需要准备好程序工作所需的相关库资源和设置即可。同时每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。与传统的虚拟机相比,Docker优势体现为启动速度快、占用体积小。

Docker 虚拟机
操作系统 与宿主机共享OS 宿主机OS上运行虚拟机OS
存储大小 镜像小,便于存储和传输 镜像庞大
运行性能 几乎没有额外性能损失 操作系统额外的CPU、内存消耗
可移植性 轻便、灵活、适用于Linux 笨重、与虚拟化技术耦合度高
面向群体 面向软件开发者 面向硬件运维者
部署速度 快速、秒级 较慢

一个常见的面试题:为什么Docker会比VM虚拟机要快?

  1. Docker有着比虚拟机更少的抽象层 由于Docker不需要Hypervisor(虚拟机)实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在CPU、内存利用率上Docker将会在效率上有明显优势。
  2. Docker利用的是宿主机的内核,而不需要加载操作系统OS内核 当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统内核,进而避免了引寻、加载操作系统内核返回等比较费时费资源的过程。当新建一个虚拟机时,虚拟机软件需要加载OS,返回新建过程是分钟级别的。而Docker由于直接利用宿主机的操作系统,省略了返回过程,因此新建一个Docker容器只需要几秒钟。

Docker的安装可以直接查看官方文档:Docker: Develop faster.Run anywhere。需要注意的是,Docker核心功能都由Docker Engine提供,但是Docker Engine需要Linux的支持,即Docker Engine能够直接安装在Linux。如果我们需要在Mac或者Windows上使用Docker的话,则需要直接安装Docker Desktop。Docker Desktop能够帮助我们在Mac和Windows构建、共享和运行容器。

关于Docker镜像加速,可以参考:Docker 镜像加速 - RUNOOB

核心概念

在Docker包含了三个重要的核心概念,分别是镜像image、容器container以及仓库repository。

  • 镜像(Image):镜像是一个只读的模板,它可以用来创建出Docker容器。镜像相当于是一个root文件系统,其中包含了一个基础操作系统所必须的root文件等。
  • 容器(Container):容器是从镜像创建而来的运行的实例。Docker使用容器来独立运行一个或一组应用。容器类似于一个虚拟化的运行环境,应用程序或者服务就运行在容器当中。容器为镜像提供了一个标准的、隔离的运行环境 ,它可以被启动、开始、停止、删除。
  • 仓库(Repository):仓库则用于集中存放镜像文件的场所,可以类比Maven仓库,Github仓库等。仓库根据访问属性可以分为公开仓库和私有仓库。Docker官方仓库地址为Docker Hub,国内的公开仓库则包括阿里云镜像仓库等。

概括来说,Docker本身是一个管理引擎。我们将应用程序和配置依赖打包形成Image镜像文件之后,通过镜像文件生成Docker容器实例再运行。同一个镜像生成可以生成多个容器实例,这些容器能够保证环境层面的相同。

Docker是一个Client-Server架构的系统。在宿主机上会运行一个Docker守护进程,客户端通过Socket连接来访问守护进程。守护进程接受客户端的命令,同时管理运行在主机上的容器。Docker的整个后端是一个松耦合的架构,拥有众多模块,不同模块各司其职。

Hello World

安装完成之后,可以通过命令行运行docker --version或者docker info来验证,如果有相关信息打印出来,则表示Docker已经正常安装完毕了。

接下来可以运行Hello World项目来体验Docker的用法。运行命令也非常简单,只需要运行docker run hello-world即可。执行该命令之后,Docker首先会查找本地是否有对应的镜像,由于是刚完成Docker安装,自然在本地是找不到的,所以Docker会继续从Hub上搜索并拉取对应的镜像,并基于该镜像运行容器,最终会打印出下面的提示信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

常用命令

Image命令

查看Image

1
2
# 查看本地主机上的镜像
docker images [options]

该命令会列出本地主机上的镜像,镜像以列表形式展示,包括如下字段:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签版本号
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

每个镜像可能具有多个标签,表示该镜像的多个不同版本。我们可以使用REPOSITORY:TAG来唯一标识一个image,如果不指定image的版本,默认使用最新的latest版本。

该命令还可以使用相关参数:

  • -a:列出本地所有的镜像(包括历史映像层)
  • -q:只列出Image ID
1
docker system df

该命令可以查看镜像/容器/数据卷所占用的空间

搜索Image

1
2
docker search [options] image_name
# --limit x: 仅列出x个镜像

拉取Image

1
docker pull image_name[:tag]

删除Image

1
2
3
4
5
6
7
8
# 根据image id删除[-f表示强制删除]
docker rmi -f image_id

# 根据image name删除
docker rmi -f image_name:image_tag

# 删除全部image
docker rmi -f $(docker images -qa)

Container命令

创建Container

1
2
3
4
docker run [options] image [command][arg...]

# eg: 启动交互式Container,启动前台shell命令行
docker run -it ubuntu /bin/bash

该命令表示从image中创建出container,并执行相应命令command。包含如下可用参数:

  • --name="xxx":为容器指定一个名称,如果没有指定则会默认命名
  • -d:以后台模式运行容器,并返回容器ID
  • -i:以交互式模式运行容器,通常与 -t 一起使用
  • -t:为容器重新分配一个伪输入终端,通常与 -i 一起使用
  • -P:随机端口映射
  • -p:指定端口映射

通过后台运行容器的时候需要注意,要求容器运行的命令应该是一直挂起的,否则容器会运行完成命令之后直接退出,无法达到后台运行的目的。最佳的解决方案是, 将你要运行的程序以前台进程的形式运行,常见就是命令行模式。

查看Container

1
2
# 列出当前所有正在运行的容器
docker ps [options]

命令参数如下:

  • -a:列出所有的容器,包括正在运行的和历史上运行过的
  • -l:显示最近创建的容器
  • -n x :显示最近创建的x个容器
  • -q:仅显示容器编号id

还有如下命令可以查看Container相关信息,包括查看容器日志、容器进程以及容器细节

1
2
3
4
5
6
7
8
# 查看容器日志
docker logs container_id

# 查看容器内运行的进程
docker top container_id

# 查看容器内部细节
docker inspect container_id

进入Container

1
2
3
4
5
# 进入正在运行的容器,并新建命令行进行交互,这里的bashShell需要填写对应命令,例如/bin/bash
docker exec -it container_id [bashShell]

# 进入正在运行的容器,不会启动新的进程
docker attach container_id

execattach命令都可以进入正在运行的容器,但是它们有所区别:

  • attach是直接进入容器在启动的时候对应的终端,而不会启动新的进程。如果此时使用exit退出,则会导致容器的停止
  • exec是在容器中打开新的终端,启动新的进程。如果此时使用exit退出,并不会导致容器的停止

退出Container

1
2
3
4
5
# 两种退出方式
# 1、run进去容器,exit退出,容器停止
exit
# 2、run进去容器,ctrl+p+q退出,容器不停止
ctrl+p+q

启停Container

1
2
3
4
5
6
7
8
9
10
11
# 启动已停止运行的容器
docker start 容器ID或者容器名

# 重启容器
docker restart 容器ID或者容器名

# 停止容器
docker stop 容器ID或者容器名

# 强制停止容器
docker kill 容器ID或容器名

删除Container

1
2
3
4
5
# 删除已停止的容器
docker rm 容器ID

# 删除所有容器
docker rm -rf $(docker ps -a -q)

Container文件导出

1
2
# 将容器内的文件拷贝到宿主机上
docker cp 容器ID:容器内路径 目的主机路径

Container导入与导出

1
2
3
4
5
# 容器导出,将容器整体内容导出为一个tar归档文件
docker export container_id > xxx.tar

# 容器导入,从归档文件创建出对应的镜像
cat xxx.tar | docker import image_name:tag

总结

Docker相关的主要围绕Image、Container、Repository以及相关的文件进行,下面是Docker基础命令的图形化总结,上面仅介绍了一些基础的常用命令,还有其他相关命令会在后面的笔记中介绍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
attach    Attach to a running container                 # 当前 shell 下 attach 连接指定运行镜像 
build     Build an image from a Dockerfile              # 通过 Dockerfile 定制镜像
commit    Create a new image from a container changes   # 提交当前容器为新的镜像
cp        Copy files/folders from the containers filesystem to the host path   #从容器中拷贝指定文件或者目录到宿主机中
create    Create a new container                        # 创建一个新的容器,同 run,但不启动容器
diff      Inspect changes on a container's filesystem   # 查看 docker 容器变化
events    Get real time events from the server          # 从 docker 服务获取容器实时事件
exec      Run a command in an existing container        # 在已存在的容器上运行命令
export    Stream the contents of a container as a tar archive   # 导出容器的内容流作为一个 tar 归档文件
history   Show the history of an image                  # 展示一个镜像形成历史
images    List images                                   # 列出系统当前镜像
import    Create a new filesystem image from the contents of a tarball # 从tar包中的内容创建一个新的镜像
info      Display system-wide information               # 显示系统相关信息
inspect   Return low-level information on a container   # 查看容器详细信息
kill      Kill a running container                      # kill 指定 docker 容器
load      Load an image from a tar archive              # 从一个 tar 包中加载一个镜像[对应 save]
login     Register or Login to the docker registry server    # 注册或者登陆一个 docker 源服务器
logout    Log out from a Docker registry server          # 从当前 Docker registry 退出
logs      Fetch the logs of a container                 # 输出当前容器日志信息
port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT    # 查看映射端口对应的容器内部源端口
pause     Pause all processes within a container        # 暂停容器
ps        List containers                               # 列出容器列表
pull      Pull an image or a repository from the docker registry server   # 从docker镜像源服务器拉取指定镜像或者库镜像
push      Push an image or a repository to the docker registry server    # 推送指定镜像或者库镜像至docker源服务器
restart   Restart a running container                   # 重启运行的容器
rm        Remove one or more containers                 # 移除一个或者多个容器
rmi       Remove one or more images       # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
run       Run a command in a new container              # 创建一个新的容器并运行一个命令
save      Save an image to a tar archive                # 保存一个镜像为一个 tar 包[对应 load]
search    Search for an image on the Docker Hub         # 在 docker hub 中搜索镜像
start     Start a stopped containers                    # 启动容器
stop      Stop a running containers                     # 停止容器
tag       Tag an image into a repository                # 给源中镜像打标签
top       Lookup the running processes of a container   # 查看容器中运行的进程信息
unpause   Unpause a paused container                    # 取消暂停容器
version   Show the docker version information           # 查看 docker 版本号
wait      Block until a container stops, then print its exit code   # 截取容器停止时的退出状态值

Docker学习笔记(1)-简介与Docker基础
http://example.com/2023/07/08/Docker学习笔记-1-简介与Docker基础/
作者
EverNorif
发布于
2023年7月8日
许可协议