Docker 入门到精通
简介
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于Google公司推出的 Go 语言实现。
项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。
Redhat已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。
Docker 的基础是 Linux 容器(LXC)等技术。在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。
用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
1. 使用Docker的目的
1. Docker容器虚拟化的好处
在云时代,开发者创建的应用必须要能很方便地在网络上传播,也就是说应用必须脱离底层物理硬件的限制;同时必须满足“任何时间任何地点”可获取可使用的特点。
因此,开发者们需要一种新型的创建分布式应用程序的方式,快速分发部署,而这正是 Docker 所能够提供的最大优势。
Docker 提供了一种更为聪明的方式,通过容器来打包应用、解耦应用和运行平台。这意味着迁移的时候,只需要在新的服务器上启动需要的容器就可以了,无论新旧服务器是否是同一类别的平台。
这无疑帮助我们节约了大量的宝贵时间,并降低部署过程出现问题的风险。
2. Docker在开发和运维中的优势
对于开发和运维人员来说,最梦寐以求的效果可能就是一次创建和配置,之后可以在任意地方、任意时间让 应用正常运行,而 Docker 恰恰可以实现这一中级目标。
# 具体来说,在开发和运维过程中,Docker 具有以下几个方面的优势
1. 更快的交付和部署
使用 Docker,开发人员可以使用镜像来快速构建一套标准的开发环境
开发完之后,测试和运维人员可以直接使用完全相同的环境来部署代码
只要是开发测试过的代码,就可以确保在生产环境无缝运行
Docker 可以快速创建和删除容器,实现快速迭代,节约开发、测试及部署的时间
2. 更高效的利用资源
运行 Docker 容器不需要额外的虚拟化管理程序的支持
Docker 是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低
与传统的虚拟机方式相比,Docker 的性能要提高 1 ~ 2 个数量级
3. 更轻松的迁移和扩展
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑等等
同时支持主流的操作系统发行版本,这种兼容性能让用户可以在不同的平台之间轻松的迁移应用
4. 更轻松的管理和更新
使用 Dockerfile,只需要小小的配置修改,就可以替代以往大量的更新工作
所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的容器管理
3. Docker与虚拟机的比较
# 作为一种轻量级的虚拟化方式,Docker 在运行应用上跟传统的虚拟机的方式相比具有如下显著优势
1. Docker 容器启动很快,启动和停止可以实现秒级,相比传统的虚拟机方式(分钟级)要快速很多
2. Docker 容器对系统资源需求很少,一台主机上可以同时运行数千个 Docker 容器
3. Docker 通过类似 git 设计理念的操作来方便用户获取、分发和更新应用镜像,存储复用,增量更新
4. Docker 通过 Dockerfile 支持灵活的自动化创建和部署机制,可以提高工作效率,并标准化流程
2. Docker与虚拟化
Docker以及其他容器技术,都属于操作系统虚拟化范畴,操作系统虚拟化最大特点就是不需要额外的supervisor 支持
Docker虚拟化方式之所以有众多优势,跟操作系统虚拟化技术自身的设计和实现分不开
传统方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层
Docker容器时在操作系统层面实现虚拟化,直接复用本地主机的操作系统,因此更加轻量级
3. Docker概念和使用
简介
Docker中有三个核心概念
镜像、容器和仓库
因此,准确把握这三大概念对于掌握 Docker 技术尤为重要
1. 镜像(Image)
Docker 镜像(Image),启动容器的模板,就相当于是一个 root 文件系统
比如官方镜像 ubuntu:16.04 就包含了完 整的一套 Ubuntu16.04 最小系统的 root 文件系统
2. 容器(Container)
镜像(Image)和容器(Container)的关系,对外提供服务的实例
就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体
容器可以被创建、启动、停止、删除、暂停等
3. 仓库(Repository)
用来保存镜像的仓库
当我们构建好自己的镜像之后,需要存放在仓库中,当我们需要启动一个镜像时,可以在仓库中下载下来
1. Docker安装准备
1. Docker引擎是使用Docker容器的核心组件
可以在主流的操作系统和云平台上使用,包括Linux操作系统、MacOSS和Windows系统上
用户可以访问Docker官网(https://www.docker.com/get-started)去获取Docker安装包
2. 在CentOS系统上安装Docker
Docker目前支持CentOS7及以后版本。系统的要求跟Ubuntu情况类似,64位操作系统,内核至少是3.10以上
3. 安装Docker前的准备工作
# 查看系统内核版本
[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
# 查看CentOS版本
[root@localhost ~]# cat /etc/system-release
CentOS Linux release 7.9.2009 (Core)
# 安装wget
[root@localhost ~]# yum -y install wget
# 安装yum-config-manager
[root@localhost ~]# yum -y install yum-utils
2. Docker安装
1. 备份原来yum源
cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
或者
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
2. 更换 yum 源: 下载新的 CentOS-Base.repo 到 /etc/yum.repos.d/
# CentOS 6
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo
或者
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo
# CentOS 7
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
或者
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# CentOS 8
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
或者
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
3. 刷新 yum 源缓存
[root@localhost ~]# yum makecache
4. 设置 yum 源
[root@localhost ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
5. 更新 yum 源并安装 Docker-CE
[root@localhost ~]# yum makecache fast
[root@localhost ~]# yum -y install docker-ce
6. 启动Docker并设置开机自启
[root@localhost ~]# systemctl enable --now docker
或者
[root@localhost ~]# systemctl enable docker
[root@localhost ~]# systemctl start docker
7. 测试启动
[root@localhost ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 19.03.13
......
3. 生成一个Docker实例
# 示例
[root@localhost ~]# docker run -d redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
852e50cd189d: Already exists
76190fa64fb8: Pull complete
9cbb1b61e01b: Pull complete
d048021f2aae: Pull complete
6f4b2af24926: Pull complete
1cf1d6922fba: Pull complete
Digest: sha256:5b98e32b58cdbf9f6b6f77072c4915d5ebec43912114031f37fa5fa25b032489
Status: Downloaded newer image for redis:latest
WARNING: IPv4 forwarding is disabled. Networking will not work.
58daf77cf459a68934353db01f5cafad2148253ccce895956694da395ceff97e
4. 使用Docker镜像
docker 镜像是 docker 中三大概念之一,其主要作用是作为启动容器的模板。
1. 获取镜像
# 下载镜像
镜像是运行容器的模板,官方 Docker Hub 仓库已经提供了许多镜像共开发者使用
如果我们需要获取某个镜像则可以去 docker 仓库下载所需的镜像
下载镜像的格式
docker pull [仓库的URL]/[名称空间]/[仓库的名称]:[版本号]
# 示例
[root@localhost ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
852e50cd189d: Pull complete
76190fa64fb8: Pull complete
9cbb1b61e01b: Pull complete
d048021f2aae: Pull complete
6f4b2af24926: Pull complete
1cf1d6922fba: Pull complete
Digest: sha256:5b98e32b58cdbf9f6b6f77072c4915d5ebec43912114031f37fa5fa25b032489
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
'''
下载的时候,我们可以看到有若干层组成
像afb6ec6fdc1c这样的字符串是层的唯一 ID(实际上,完整的 ID 包括 256 比特, 64 个十六进制字符组成)
使用 docker pull 命令下载中会获取并输出镜像的各层信息
当不同的镜像包括相同的层的时候,本地仅存一份内容,减小存储空间
'''
2. 查看镜像
# 查看镜像
docker images <=> docker image ls
# 示例
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 74d107221092 12 days ago 104MB
# 镜像列表信息
REPOSITORY : 镜像名称
TAG : 镜像版本号
IMAGE ID : 镜像ID
CREATED : 创建时间到现在的时间
SIZE : 指镜像大小
'''
1. 镜像的 ID 信息十分重要,它唯一标识了镜像,在使用镜像 ID 的时候,一般可以使用该 ID 的前若干个字符组成的可区分串来替代完整的ID
2. TAG 信息用于标记来自同一个仓库的不同镜像,TAG 在同一个仓库中是唯一的
3. 镜像大小信息只是表示了该镜像的逻辑体积大小,实际上由于相同的镜像层本地只会存储一份,物理上占用的存储空间会小于各镜像逻辑体积之和
'''
# image 子命令
-a
列出所有(包括临时文件)镜像文件
--digests=true|false
列出镜像的数字摘要值
-q
仅显示 ID 信息
# push 推送命令
docker push [镜像名称]
# 示例
docker push registry.cn-hangzhou.aliyuncs.com/alvinos/redis:v1
3. 为镜像添加tag
# 作用
为了方便后续工作中使用特定的镜像,还可以使用 docker tag 命令来为本地的镜像添加标签
# 语法
docker tag [原镜像名称]:[版本号] [新的名称]:[新版本号]
# 示例
[root@localhost ~]# docker tag redis:latest myredis:v66
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED
nginx latest bc9a0695f571 5 days ago
redis latest 74d107221092 12 days ago
myredis v66 74d107221092 12 days ago
4. inspect命令查看详细信息
# 作用
使用 docker inspect 命令获取镜像的详细信息,包括 PID、作者、架构等等
# 语法
docker inspect [参数] [镜像ID]|[镜像名称]:[版本号]
# 示例
[root@localhost ~]# docker inspect 74d107221092
[
{
"Id": "sha256:74d107221092875724ddb06821416295773bee553bbaf8d888ababe9be7b947f",
"RepoTags": [
"redis:latest"
],
"RepoDigests": [
"redis@sha256:5b98e32b58cdbf9f6b6f77072c4915d5ebec43912114031f37fa5fa25b032489"
],
"Parent": "",
"Comment": "",
"Created": "2020-11-18T08:28:42.383873008Z",
"Container": "1a904a9885d0bdcb73bbb4899df9632a1f89a75c6bee47c55981e4834124c3cf",
"ContainerConfig": {
"Hostname": "1a904a9885d0",
"Domainname": "",
......
# 查看id
[root@localhost ~]# docker inspect -f '{{ .Id }}' 74d107221092
sha256:74d107221092875724ddb06821416295773bee553bbaf8d888ababe9be7b947f
# 查看容器主机名
[root@localhost ~]# docker inspect -f '{{ .ContainerConfig.Hostname }}' 74d107221092
1a904a9885d0
5. history命令查看镜像历史
# 语法
docker history [镜像名称]|[镜像ID]
# 示例
[root@localhost ~]# docker history redis
IMAGE CREATED CREATED BY SIZE COMMENT
74d107221092 12 days ago /bin/sh -c #(nop) CMD ["redis-server"] 0B
<missing> 12 days ago /bin/sh -c #(nop) EXPOSE 6379 0B
6. search搜索镜像
# 作用
在docker中搜索镜像主要使用Search子命令,默认只搜索Docker Hub官方镜像仓库中的镜像
# 语法
docker search [参数] [镜像名称|镜像简介]
# 选项
-f [stars=n]
过滤输出内容
stars=n
查询收藏数大于n的镜像
--limit n
只显示n条记录
--no-trunc
不截断输出结果
# 示例
# 搜索带有redis关键字的镜像
[root@localhost docker]# docker search redis
# 搜索官方提供的带有redis关键字的镜像
[root@localhost docker]# docker search -f is-official=true redis
# 搜索被收藏超过 8000 个的并且关键词包括redis的镜像
[root@localhost docker]# docker search -f stars=8000 redis
# 搜索被收藏超过8个的,关键词包括redis的镜像 搜索结果只显示3条
[root@localhost docker]# docker search -f stars=8 --limit 3 redis
# --no-trunc: 不截断输出结果
[root@localhost docker]# docker search -f stars=8 --limit 3 --no-trunc redis
# 输出参数释义
NAME : 镜像仓库源的名称
DESCRIPTION : 镜像的描述/简介
STARS : 收藏个数
OFFICIAL : 是否是官方镜像
AUTOMATED : 是否是自构建的镜像
7. 删除和清理镜像
# 简介
在 docker 中,删除镜像主要使用 rmi 子命令,清理镜像主要使用 prune 子命令
1. 使用 docker rmi 或 docker image rm 命令可以删除镜像
2. 使用一段时间之后,docker 会产生很多临时文件,以及一些没有被使用的镜像
可以通过 docker image prune 命令来进行清理
1. 删除镜像
# 语法
docker rmi [镜像ID|[镜像名称:版本号]]
# 选项
-f
强制删除镜像
ps: 如果该镜像正在使用中,强制删除,实际上是删除标签
# 示例
[root@localhost docker]# docker rmi redis
Untagged: redis:latest
Untagged: redis@sha256:5b98e32b58cdbf9f6b6f77072c4915d5ebec43912114031f37fa5fa25b032489
[root@localhost docker]# docker rmi -f redis
Untagged: redis:latest
Untagged: redis@sha256:5b98e32b58cdbf9f6b6f77072c4915d5ebec43912114031f37fa5fa25b032489
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 74d107221092 12 days ago 104MB
[root@localhost docker]# docker rmi 74d107221092
Untagged: redis:latest
Untagged: redis@sha256:5b98e32b58cdbf9f6b6f77072c4915d5ebec43912114031f37fa5fa25b032489
Deleted: sha256:74d107221092875724ddb06821416295773bee553bbaf8d888ababe9be7b947f
Deleted: sha256:d951b383737320b4e1ac7f9bb63f3919bcf25363ccb59fbb52a41e45ba70ffdd
Deleted: sha256:d3b2581a1c92973ee9a41fc00e5628047ce7e644a66240fb859b38831bd525b4
Deleted: sha256:a447231da503a58432b4d7409980139206fdf398fbde189d8a7229dd0663f472
Deleted: sha256:f786204ca260bcaef3d47ecad10821878028239072c65ceb2a1f212f275f9367
Deleted: sha256:b68afce5f52461f79be59806be00e43ea95152a0358b8dc5de9ac3f486a70d7e
Deleted: sha256:f5600c6330da7bb112776ba067a32a9c20842d6ecc8ee3289f1a713b644092f8
2. 清理镜像
# 语法
docker image prune [参数]
# 选项
-a
清理所有的镜像(ps: 未被使用)
-f
强制删除镜像,而不进行提示
# 示例
[root@localhost docker]# docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: nginx:1.17
......
[root@localhost docker]# docker image prune -a -f
8. 构建镜像
# 简介
构建镜像一般有三种情况,基于容器导入、基于本地模板导入、基于Dockerfile创建
本节主讲基于容器保存镜像和本地保存镜像导入
1. 基于容器保存镜像
# 语法
docker commit [容器ID] [参数]
# 主要参数
-a : 执行维护者(作者信息)
-m : 指定简介(提交信息)
-p : 当保存时(提交),容器停止运行
# 示例: 启动一个容器、修改并保存
[root@localhost docker]# docker run -d redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
852e50cd189d: Already exists
76190fa64fb8: Pull complete
9cbb1b61e01b: Pull complete
d048021f2aae: Pull complete
6f4b2af24926: Pull complete
1cf1d6922fba: Pull complete
Digest: sha256:5b98e32b58cdbf9f6b6f77072c4915d5ebec43912114031f37fa5fa25b032489
Status: Downloaded newer image for redis:latest
WARNING: IPv4 forwarding is disabled. Networking will not work.
58daf77cf459a68934353db01f5cafad2148253ccce895956694da395ceff97e
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58daf77cf459 redis "docker-entrypoint.s…" 33 seconds ago Up 31 seconds 6379/tcp naughty_pike
[root@localhost ~]# docker commit -a "oldboy" -m "屠龙宝刀" 58daf77cf459 redis:v1
sha256:d7362a4db0fd8cdef9e6aa3074775823eb8cdc961d2d3964f7607527f3c55ddc
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis v1 d7362a4db0fd 4 seconds ago 104MB
redis latest 74d107221092 12 days ago 104MB
2. 基于本地模板导入
用户可以将保存的镜像传到另一台机器上,另一台机器就可以直接导入
# 示例
[root@alvin-test-os ~]# cat ubuntu-18.04-x86_64-minimal.tar.gz | docker import - ubuntu:18.04