文章目录
一、docker 简介
1.1 什么是虚拟化(Virtualization)
虚拟化是一种计算机资源的管理技术,用来创建模拟的(或虚拟的)计算环境,而不是物理环境,或者说,它可以将一台物理计算机“变成”多台虚拟的、逻辑上的计算机。
比如我们常用的vmware workstation、kvm虚拟机等,都是常用的虚拟化软件,通过这些软件,我们就可以在一台电脑上安装多个操作系统,如同拥有了多台电脑一样。
1.2 什么是 docker
Docker是一个用于开发、发布和运行应用程序的开放平台,是使用 go 语言开发的,并遵从 Apache2.0 开源协议。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的==容器(container)==中,然后在别的机器上快速运行,而免去搭建环境的繁琐步骤。比如,你在本地用Python开发了一个网站后台,开发测试完成后,就可以将Python3及其依赖包、Flask及其各种插件、Mysql、Nginx等打包到一个容器中,然后部署到任意你想部署到的环境。
Docker 也可以实现虚拟化的功能,比如,可以在一台机器上或者说是一个操作系统中运行多个 MySQL 容器,而且彼此之前互不干扰,如同运行在多个机器上。
1.3 容器与传统虚拟机的区别
-
传统虚拟机:
虚拟机在本质上就是在模拟一台真实的计算机设备,给人的感觉就是在管理一个个的真实的机器。每个虚拟机上都有一个完整的操作系统。因此,占用资源多,启动速度也慢,但是隔离性和安全性强。
-
容器:
容器则是模拟一个应用程序所需要的运行环境,给人的感觉就是在管理一个个的应用程序。它与虚拟机间的最大区别在于,各容器系统共享主机系统的内核。因此,占用资源少,速度快,但是隔离性和安全性稍差。
1.4 docker 的架构
Docker 使用客户端-服务器架构:
- Docker 客户端与 Docker 守护进程对话;
- Docker 守护进程负责构建、运行和分发你的 Docker 容器。
Docker 客户端和守护进程可以运行在同一个系统上,也可以运行在不同的系统上,然后通过远程连接进行交互。
**Docker 客户端和守护进程通过 UNIX 套接字或网络接口使用 REST API 进行通信。**另一个 Docker 客户端是 Docker Compose,用来处理由一组容器组成的应用程序。
-
docker 守护进程:
Docker 守护进程(dockerd)监听 Docker API 请求,并管理 Docker 对象,如图像、容器、网络和卷。一个守护进程也可以与其他守护进程通信来管理Docker 服务。
-
docker 客户端:
Docker 客户端(Docker)是用户与 Docker 交互的主要方式。当您使用docker run 等命令时,客户端会将这些命令发送给 dockerd,由 dockerd 执行。Docker客户端可以与多个守护进程通信。
-
docker 注册表:
Docker 注册表存储 Docker 镜像(images)。Docker Hub 是 docker 官方提供的一个镜像中心,任何人都可以使用,Docker 默认在 Docker Hub 上寻找镜像。但我们也可以修改为自己的私有镜像中心。
-
docker 对象(Docker objects):
-
镜像(Images):
镜像是一个只读的模板,带有创建 Docker 容器的指令,可以看作是 docker 容器的安装包。
您可以创建自己的镜像,也可以使用其他人创建并发布在镜像中心中的镜像。
-
容器(Containers):
一个容器就是一个可运行的镜像实例。通过 Docker API 和 CLI 可以创建、启动、停止、移动和删除容器。您可以将容器连接到一个或多个网络,向其添加存储,甚至根据其当前状态创建一个新的镜像。
默认情况下,容器与其他容器及其主机相对隔离,而且隔离的程度是可以控制的。
当容器被移除时,在容器中所做的所有更改都将消失,除非事先存储在持久存储中。
-
下面我们通过一个运行 docker 容器的命令来了解一下 docker 的执行流程:
$ docker run -i -t ubuntu /bin/bash
假设用的是默认的 docker registries,docker 会做以下操作:
- 如果本地没有 ubuntu 镜像,Docker 从你配置的 docker 注册表中拉取 (就是下载)镜像。
- 从镜像中生成一个新的容器。
- 为容器分配一个可读写的文件系统,作为它的最底层。这允许运行的容器在其本地文件系统中创建或修改文件和目录。
- 创建了一个网络接口让容器连接到网络,包括为容器分配一个IP地址。默认情况下,容器可以使用主机的网络连接到外部网络。
- 启动容器并执行
/bin/bash
,因为有-i
和-t
参数,所以容器是以交互方式运行并连接到您的终端,所以您可以使用键盘输入内容,同时会将结果输出到您的终端。 - 当您输入
exit
终止/bin/bash
命令时,容器将停止,但不会删除。
二、在 Ubuntu 上安装 docker
2.1 安装和换源
-
卸载旧的版本(可选):
sudo apt-get remove docker docker-engine docker.io containerd runc
删除残留的镜像、容器、配置文件等:
sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
-
第一次在新主机上安装 Docker Engine 之前,需要先设置 Docker 库。之后就可以直接从存储库中安装和更新 Docker :
sudo apt-get update sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release
-
添加 Docker 的官方GPG 密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
-
设置稳定存储库:
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
-
安装 docker engine:
sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io
-
运行 hello-world 镜像,该镜像只是为了测试安装使用,它会打印一些信息后自动退出:
sudo docker run hello-world
-
如果镜像拉取速度慢,可以跟换国内的镜像中心(以DaoCloud为例):
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io sudo systemctl restart docker # 重启 docker
查看 docker 的概要信息:
sudo docker info
2.2 以非 root 用户管理 Docker(可选)
Docker 守护进程绑定到 Unix 套接字而不是 TCP 端口。默认情况下,Unix套接字属于 root 用户,所以其他用户只能使用 sudo 来访问它。
如果你不想在 docker 命令前加上 sudo ,可以创建一个名为 docker 的 Unix 组,并向其添加用户。当 Docker 守护进程启动时,它会创建一个 Unix 套接字供 Docker 组的成员访问。
注意!docker 组授予等同于 root 用户的特权。这会影响到系统的安全,详细信息请参阅:Docker Daemon Attack Surface.
具体步骤:
-
创建 docker 用户组:
sudo groupadd docker
-
添加用户到 docker 用户组:
sudo usermod -aG docker $USER
-
重启或者运行以下命令:
newgrp docker
三、快速入门
3.1 镜像操作
-
通过镜像中心查找镜像:
到 Docker Hub,搜索想要的镜像。注意!尽量选择带有“Official Image”标志的,这说明该镜像是官方提供的。
然后按照详情页面中的说明,进行拉取和运行。
-
通过命令查找镜像:
docker search 镜像名称 docker -f is-official=true search 镜像名称 # 根据所提供的条件过滤输出,这里的条件是官方镜像
-
查看本机中已有的镜像:
docker images
输出:
REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 4 months ago 13.3kb 镜像仓库 镜像的标签 镜像ID 镜像创建时间 镜像大小 同一个仓库里可以有多个 TAG,代表这个镜像的不同版本。
-
拉取镜像:
docker pull 镜像名称 # 最新版本 docker pull 镜像名称:标签 # 指定版本
-
查看镜像详细信息:
docker inspect 镜像名称或id
-
删除镜像:
docker rmi 镜像名称或id docker rmi `docker images -a -q` # 删除所有
3.2 容器操作
-
创建并运行容器:
docker run 镜像名称 docker run -d 镜像名称 # 在后台运行容器并打印容器ID docker run -i 镜像名称 # 交互式运行 docker run -t 镜像名称 /bin/bash # 指定一个伪终端,一般和 -i 合用 docker run --name=容器名称 镜像名称 # 给容器指定一个名称 docker run -e A=a 镜像名称 # 设置环境变量
伪终端的意思是:该终端是 docker 模拟出来的终端,并不是实际的终端。
-
查看本地容器:
docker ps # 正在运行的容器 docker ps -a # 所有的容器
输出:
CONTAINER ID IMAGE COMMAND CREATES STATUS PORTS NAMES 9440fa54f841 redis “docker-entrypoint.s…” 41 seconds ago Up 40 seconds 6379/tcp redis 容器id 镜像名称 引用命令 创建时间 容器状态 暴露的端口 容器名称 -
删除容器:
docker rm 容器名称或容器id docker rm `docker ps -a -q` # 删除所有 docker rm -f 容器名称或容器id # 强制删除
-
查看容器详细信息:
docker inspect 容器名称或容器id docker inspect --format='{{.NetwoekSettings.IPAddress}}' 容器名称或容器id # 过滤出容器的 ip 地址
-
查看容器运行日志:
docker logs 容器名称或id
-
停止正在运行的容器:
docker stop 容器名称或容器id
3.3 宿主机与容器交互
-
通过命令进入容器:
docker exec -it 容器名称或id /bin/bash
exec
真正的作用是执行一个命令,/bin/bash
的位置写的就是要执行的命令。 -
通过 ssh 连接:
在容器内部安装 ssh 的服务端。
-
退出:
exit
-
拷贝文件:
docker cp 宿主机文件 容器id:目标路径 # 宿主机文件拷贝到容器 docker cp 容器id:文件 宿主机中的路径 # 容器文件拷贝到宿主机
-
目录映射:
将容器中的目录映射到宿主机(安装了该 docker 程序的主机)目录上。
docker run -v 宿主机目录:容器目录 -v 宿主机目录:容器目录…… 镜像名称
之后宿主机对该目录的修改,会影响到容器内的目录。反之亦然。
-
端口映射:
将容器中应用的端口映射到宿主机中的端口,以便从外部访问宿主机上的容器。
docker run -p 宿主机端口:容器端口 -p 宿主机端口:容器端口…… 镜像名称
之后,通过设置的宿主机端口,就能连接到容器。
3.4 容器的备份与恢复
3.4.1 备份
-
将容器保存为镜像:
docker commit 容器名称或id 镜像名称
-
将镜像打包成压缩包:
docker save -o 压缩包名称 镜像名称或id
3.4.2 恢复
-
将压缩包恢复为镜像:
docker load -i 压缩包路径