惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
雷峰网
雷峰网
The Register - Security
The Register - Security
The Cloudflare Blog
博客园 - 【当耐特】
M
MIT News - Artificial intelligence
I
InfoQ
博客园 - 三生石上(FineUI控件)
H
Help Net Security
博客园 - 司徒正美
Vercel News
Vercel News
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
B
Blog
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
L
LangChain Blog
人人都是产品经理
人人都是产品经理
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Recorded Future
Recorded Future
小众软件
小众软件
Martin Fowler
Martin Fowler
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Apple Machine Learning Research
Apple Machine Learning Research
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - Franky
Hugging Face - Blog
Hugging Face - Blog
Y
Y Combinator Blog
V
Visual Studio Blog
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
大猫的无限游戏
大猫的无限游戏
Engineering at Meta
Engineering at Meta
N
Netflix TechBlog - Medium
V
V2EX
Blog — PlanetScale
Blog — PlanetScale

Posts on Changkun's Blog

Why High-Output Systems Are Often the First to Stop Growing Dark Forest Theory: A Formal Derivation Agents (or Humans) in Goal-Directed and Goalless Environments: On Pipelines, Priors, and the Rhythm Between Exploration and Exploitation At the Boundary of Self-Reference: From Stable Structures in Artificial Intelligence to the Self as a Recursive Model in an Open Dissipative System 2023 Reading List 2022 Reading List 2021 Reading List Are PSS/USS and RSS Actually the Same Thing? Performance Differences from Page Faults vs. Prefetching 2020 Year-End Review Migration with Zero Downtime 2020 Reading List The All in Go Stack Pointers Might Not Be Ideal for Parameters Eliminating A Source of Measurement Errors in Benchmarks Setup Wordpress in 10 Minutes 我为什么不再写博客了? 2019 年终总结 2018-2019 读书清单 Ten years of blogging Rethinking the Reflections on Communications and Trusts 2018 年终总结 Go source code study is open source Go source study: unsafe Pattern Go source study: sync.Pool Go runtime programming A Million WebSocket and Go Designing Asynchronous RESTful APIs 分布式杂谈01:CAP 理论的误解 Issues of Human-Bot Interaction 压缩法与深度网络的泛化性 Go in 1 Hour UMSLT04: The Past and Present of SGD UMSLT03: A Gentle Start of Learning Theory UMSLT02: A Breif History of Neural Networks UMSLT01: A Breif History of Regularization 不笑不足以为道 论文笔记:Generalization in Deep Learning 2017 年终总结 2017 读书清单 深度学习的泛化理论简介 删除 GitHub 上已经提交的敏感信息 硕士生涯的第一年就这样告一段落了 人肉计算(10): 系统参与激励 人肉计算(9): 陷阱的解法 别聊,一聊你就暴露 人肉计算(8): 人肉计算与数据科学中的陷阱 人肉计算(7): 社会行为分析 Hexo + GitHub + Travis CI + VPS 自动部署 人肉计算(6): 预测市场 人肉计算(5): 信用风险评级模型 读书与回报 瞎扯: 对现代企业理论与当下IT企业的商业模式和信息产业链的规律性的思考 人肉计算(4): 输入数据聚合与PageRank 又一次打整了一下博客 人肉计算(3): 输入数据聚合与链路预测 人肉计算(2): 意图博弈 GWAPs 人肉计算(1): 众包与群众智慧 对后辈同学在计算机专业上的答疑与解惑 在德国的医疗及住院体验 这可能不是一个技术博客了 实验楼楼赛第3期-Python-题解 迅速更换了 DISQUS Electron 深度实践总结 良好的编码体验的三个方面 2016 年终总结 2016 读书清单 最近在着手写的文章 微信小程序文档极致总结 谈谈过去三个月在实验楼的实习经历 Built a Desktop Client for My Blog Guacamole 源码分析与 VNC 中 RFB 协议的坑 《高速上手 C++11/14》正式发布 Docker 极速入门教程02 - 镜像与容器管理 阶段性沉默 ELK+Redis 最佳实践 终于全面启用了 HTTPS 苹果开源了LZFSE无损压缩 Hash 碰撞的一种思路 记一次完整的 Kaldi-TIMIT 示例运行 Kaldi 上的 TIMIT 例子 Kaldi 安装与部署 从科研写作谈起 Swift API 设计指南 有趣的人类 所以其实论文并没有什么鬼用 Githug 通关记录及指南 小结一下这学期的收获 2015 读书清单 2015 年终总结 负能量爆表 转眼就快两个月了 博客迁移记录 大三总结 这个世界,终究不会是我们的。 Linux 内核分析 之六:Linux 内核创建进程的过程 小说「泽缘」 Linux 内核分析 之五:system_call中断处理过程的简要分析 大创项目的标题真是每年都在考验同学们的想象力啊 Linux 内核分析 之四:使用库函数API和嵌入汇编两种方式使用同一个系统调用
Docker 极速入门教程01 - 基本概念和操作
Changkun Ou · 2016-08-07 · via Posts on Changkun's Blog

Published at发布于:   |   PV/UV: /   |   Reading阅读: 2 min

序言

为什么写这个系列

我加入了一家以 Docker 为技术栈核心的公司,如果走出去说自己不会 Docker,就显得有点不合适了。早在大三的时候就已经听说 Docker 技术的火爆,只是当时一心研究 iOS,并没有对此技术有太多在意,到了现在已经不得不研究了。

实习的这几个月,做的事情比较多,每周只能花很少的时间来了解 Docker 这一门技术,这也是我需要花很长时间才能完成这个系列的原因。网上关于 Docker 的资源、教程已经数不胜数,为什么我还要再写这样一个系列。这里面的原因有以下几点:

  1. 资源再多教程再多,也是别人的。别人写出来的东西是按照别人的思路进行,随着 Docker 技术的发展,我在学习 Docker 这门技术的过程中,发现了当下其实有更好更快捷的路径从新手直接入门整套技术;
  2. 自己写成了文章之后,才能够发现自己对这门技术究竟还有那些不懂不明白的地方;
  3. 装逼

为什么读这个系列

这个系列与其他网上的资源相比有以下几个特点:

  1. 只适用于有 Linux 基本基础的人,有很多教程都尝试向一些 Linux 基础薄弱的人由浅至深介绍 Docker,但实际上他们花了很大篇幅在介绍 Linux 本身上,却忽略了很多 Docker 的重要特性。
  2. 高速,无废话。Docker 的命令错综复杂,很多的书籍、教程反复针对同一个命令反复介绍,废话奇多。读者需要从中甄别这些无用信息,从而浪费大量时间。

好了,说了不废话还是废话了这么长,开始吧。

建立以 Docker 为核心的概念

容器技术与 Docker 架构

容器通过对操作系统的资源访问进行限制,构建成独立的资源池,让应用运行在一个相对隔离的空间里,同时容器间也可以进行通信。容器技术对比虚拟化技术,容器比虚拟化更轻量级,对资源的消耗小很多。容器操作也更快捷,启动和停止都要比虚拟机快。但Docker容器需要与主机共享操作系统内核,不能像虚拟机那样运行独立的内核。

Docker 则是一个基于 Linux 容器(LXC, Linux Container) 技术构建的容器引擎。Docker 支持将应用打包进一个可以移植的容器中,重新定义了应用开发,测试,部署上线的过程。

使用 Docker,可以快速构建一个应用程序服务器、一个消息总线、一个持续集成测试环境,升值为生产或开发快速复制一套复杂的应用程序栈,可以说是让开发者成为 DevOps 的必备技能之一。

Docker 是一个 C/S 架构的程序,Docker 客户端通过向守护进程发出请求,守护进程和 Docker 容器将请求处理完成后返回响应的结果。由于 Docker 是基于 LXC 产生的,因此在其他(Mac/Windows)上不具备这样的技术时,Docker 依然能够运行则是得益于一个虚拟的宿主机,因此整个 Docker 的架构在 Linux 和其他平台上的架构略有不同,但随着如今 Docker 技术的发展,作为 Docker 的用户,我们完全不需要操心这一切,只需心中有下图即可:

此外,Docker 提供了一个命令行工具及一整套 RESTful API 让用户与守护进程进行交互,也就是我常说的 Docker API,这使得我们能够基于 Docker 来开发 Docker 相关的应用。

学习 Docker 需要先在脑子里建立三大基本概念,分别是:仓库、镜像、容器。

仓库(Registry)

仓库的概念和 git 里的仓库几乎完全一样。一个 Docker 仓库就相当于一个 Git 的代码仓库。DockerHub 的地位就如同 GitHub,用于托管和保存用户的镜像,因此用户可以在 DockerHub 上注册账号,管理或开源自己的镜像。

镜像(Image)

镜像是构建 Docker 的基础,就如同操作系统安装的 .iso 镜像一样,Docker 镜像就是这种类似物。镜像通过 Union 文件系统产生了层式的结构,从最基础的镜像,像盖房子一样一层层堆叠,从而完成整个镜像的构建。

容器(Container)

容器是从 Docker 镜像创建运行出来的一个实例(Instance),可以理解为一个虚拟的 Linux 环境。Docker 容器如同虚拟机,支持启动、停止、删除。每个容器之间互相隔离,隔离性弱于虚拟机。

隔离的效果由 CGroupsNamespaces 实现,CGroups (Control Group, Linux 内核特性之一) 对 CPU、内存、磁盘资源等访问进行限制,而 Namespaces 提供了环境的隔离。

安装 Docker

安装 Docker 的方法在现在已经变得非常的简单了,这里不再叙述,下面是各个平台的安装方法:

值得一提的是,现在(Docker v1.12) Mac 上的 Docker 已经不再需要使用 Docker ToolBox 了,只需要下载 Docker for Mac,就能够在 命令行工具中使用了:

基本操作

首先要获得一个镜像,我们才能开始 Docker 的相关学习。

1
2
3
$ docker images           # 查看当前镜像
$ docker search ubuntu    # 搜索镜像
$ docker pull ubuntu      # 拉取一个镜像

拿到镜像后,我们可以开始进行一些基本的操作了。

1
2
3
4
5
6
7
8
$ # 运行 docker 容器
$ docker run ubuntu echo "hello docker" 
$ # 查看运行的容器列表, 
$ # docker 在执行完命令后会主动停止, 
$ # 所以使用 -a 参数可以查看到已经停止的容器. 此外, -l 可以查看最后一次启动的容器, -q 只查看容器 ID
$ docker ps 
$ # 对于 run 命令可以使用 -it 参数进入 bash 来保持容器运行
$ docker run -i -t ubuntu /bin/bash

docker run-i (interactive) 参数保证了容器中的 STDIN 开启,要让交互式 shell 长期运行,就必须要开启持久的标准输入;-t (tty) 指定让 Docker 创建一个伪 tty 终端。

在 Docker 中,涉及到磁盘、网络、设备等 Linux 特权命令都无法执行,因此我们不能够执行诸如 reboot 之类的命令,可以通过 exit 退出 bash。

如果希望退出后依然保持容器运行,可以使用 Ctrl+pCtrl+q 两组快捷键,然后使用 docker attach 能够再次进入 bash。

1
2
3
$ docker start <id>     # 根据 ID 启动一个容器
$ docker stop <id>      # 根据 ID 停止一个容器
$ docker restart <id>   # 根据 ID 重启一个容器

1
2
$ docker inspect <id>   # 查看容器或镜像内部信息
$ docker top <id>       # 查看容器中运行进程等信息

1
2
$ docker rm  <id>        # 删除容器
$ docker rmi <id>        # 删除镜像

初识 Dockerfile

Dockerfile 用于编写一个镜像,下面创建了一个新的 Docker 镜像:

1
2
from ubuntu:latest          # 基于 ubuntu:latest 
ENV HOSTNAME=changkun       # 设置 HOSTNAME 环境变量

通过 docker build 构建新镜像:

1
$ docker build -t changkun .

其中 -t changkun 指定了镜像的名字, . 标志从当前目录查找 Dockerfile。

删除我们刚才创建的镜像:

注意: 删除 Docker 镜像时,尽管可以使用 -f 参数强制删除镜像,为了养成良好的运维习惯,应该先使用 docker rm 删除容器后,再删除镜像。

延伸阅读