-
Notifications
You must be signed in to change notification settings - Fork 0
/
dockerxi-lie-yi.html
350 lines (296 loc) · 20.6 KB
/
dockerxi-lie-yi.html
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="CatsAction" />
<meta property="og:type" content="article" />
<meta name="twitter:card" content="summary">
<meta name="keywords" content="Docker, containers, Docker, " />
<meta property="og:title" content="Docker系列(一) - 概念及入门"/>
<meta property="og:url" content="./dockerxi-lie-yi.html" />
<meta property="og:description" content="Docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的 cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。 Docker和VM 虚拟机本质是模拟出一台计算机,再在模拟的机器上运行其他系统。而容器只是对进程做了隔离和资源控制,直接运行于宿主的内核。下面表格简单对比了Docker和VM。 对比项 Docker VM 是否需要模拟硬件 不需要 需要 是否拥有自己的内核 Docker容器没有自己OS系统内核,运行于宿主系统内核之上 VM上运行的系统独立于宿主OS系统,拥有自己的内核 是否可以运行不同于宿主的OS系统 Docker的镜像准确的说不是OS,只是一个容器运行依赖的集合,即rootfs,依赖于宿主内核运行 VM可以运行不同于宿主的OS系统,比如在MacOS上运行Ubuntu 启动是否需要完整的OS引导流程 不需要,宿主OS已经完成 需要,每个Guest OS都需要经MBR启动 下面的两幅图,很好的展示了传统虚拟机和Docker与宿主机的关系。 Docker特点 轻小。由于不需要模拟硬件,相当于传统虚拟机小很多。 资源耗费小。容器只是利用Linux隔离技术,单机可以运行几千个容器。 部署快速方便。所有容器共享宿主系统内核,部署只需要打包依赖的库和应用本身。当需要迁移部署的时候 …" />
<meta property="og:site_name" content="CatsAction's blog" />
<meta property="og:article:author" content="CatsAction" />
<meta property="og:article:published_time" content="2019-01-22T00:00:00+08:00" />
<meta name="twitter:title" content="Docker系列(一) - 概念及入门">
<meta name="twitter:description" content="Docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的 cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。 Docker和VM 虚拟机本质是模拟出一台计算机,再在模拟的机器上运行其他系统。而容器只是对进程做了隔离和资源控制,直接运行于宿主的内核。下面表格简单对比了Docker和VM。 对比项 Docker VM 是否需要模拟硬件 不需要 需要 是否拥有自己的内核 Docker容器没有自己OS系统内核,运行于宿主系统内核之上 VM上运行的系统独立于宿主OS系统,拥有自己的内核 是否可以运行不同于宿主的OS系统 Docker的镜像准确的说不是OS,只是一个容器运行依赖的集合,即rootfs,依赖于宿主内核运行 VM可以运行不同于宿主的OS系统,比如在MacOS上运行Ubuntu 启动是否需要完整的OS引导流程 不需要,宿主OS已经完成 需要,每个Guest OS都需要经MBR启动 下面的两幅图,很好的展示了传统虚拟机和Docker与宿主机的关系。 Docker特点 轻小。由于不需要模拟硬件,相当于传统虚拟机小很多。 资源耗费小。容器只是利用Linux隔离技术,单机可以运行几千个容器。 部署快速方便。所有容器共享宿主系统内核,部署只需要打包依赖的库和应用本身。当需要迁移部署的时候 …">
<title>Docker系列(一) - 概念及入门 ·
CatsAction's blog
</title>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="./theme/image/logo.ico" />
<link rel="stylesheet" type="text/css" href="./theme/css/elegant.prod.css" media="screen">
<link rel="stylesheet" type="text/css" href="./theme/css/custom.css" media="screen">
</head>
<body>
<div id="content">
<div class="navbar navbar-static-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="./"><span class=site-name>CatsAction's blog</span></a>
<div class="nav-collapse collapse">
<ul class="nav pull-right top-menu">
<li >
<a href=
.
>Home</a>
</li>
<li ><a href="./categories.html">Categories</a></li>
<li ><a href="./tags.html">Tags</a></li>
<li ><a href="./archives.html">Archives</a></li>
<li><form class="navbar-search" action="./search.html" onsubmit="return validateForm(this.elements['q'].value);"> <input type="text" class="search-query" placeholder="Search" name="q" id="tipue_search_input"></form></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span1"></div>
<div class="span10">
<article itemscope>
<div class="row-fluid">
<header class="page-header span10 offset2">
<h1>
<a href="./dockerxi-lie-yi.html">
Docker系列(一)
<small class="subtitle">
概念及入门
</small>
</a>
</h1>
</header>
</div>
<div class="row-fluid">
<div class="span8 offset2 article-content">
<p>Docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的 cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。</p>
<h5>Docker和VM</h5>
<p>虚拟机本质是模拟出一台计算机,再在模拟的机器上运行其他系统。而容器只是对进程做了隔离和资源控制,直接运行于宿主的内核。下面表格简单对比了Docker和VM。</p>
<table>
<thead>
<tr>
<th align="left">对比项</th>
<th align="left">Docker</th>
<th align="left">VM</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">是否需要模拟硬件</td>
<td align="left">不需要</td>
<td align="left">需要</td>
</tr>
<tr>
<td align="left">是否拥有自己的内核</td>
<td align="left">Docker容器没有自己OS系统内核,运行于宿主系统内核之上</td>
<td align="left">VM上运行的系统独立于宿主OS系统,拥有自己的内核</td>
</tr>
<tr>
<td align="left">是否可以运行不同于宿主的OS系统</td>
<td align="left">Docker的镜像准确的说不是OS,只是一个容器运行依赖的集合,即rootfs,依赖于宿主内核运行</td>
<td align="left">VM可以运行不同于宿主的OS系统,比如在MacOS上运行Ubuntu</td>
</tr>
<tr>
<td align="left">启动是否需要完整的OS引导流程</td>
<td align="left">不需要,宿主OS已经完成</td>
<td align="left">需要,每个Guest OS都需要经MBR启动</td>
</tr>
</tbody>
</table>
<p>下面的两幅图,很好的展示了传统虚拟机和Docker与宿主机的关系。</p>
<p><img alt="dockers_vm" src="./images/dockers_virtualization.png">
<img alt="dockers_docker" src="./images/dockers_docker.png"></p>
<h4>Docker特点</h4>
<ul>
<li>轻小。由于不需要模拟硬件,相当于传统虚拟机小很多。</li>
<li>资源耗费小。容器只是利用Linux隔离技术,单机可以运行几千个容器。</li>
<li>部署快速方便。所有容器共享宿主系统内核,部署只需要打包依赖的库和应用本身。当需要迁移部署的时候,也只需要转发很小的文件。</li>
<li>采用分层机构。容器运行于镜像之上,镜像给容器运行提供只读的依赖资源,容器对文件的修改只会体现在本层,不影响下层的镜像。</li>
<li>C/S结构,分为客服端和服务端。即Docker CLI和Docker daemon。它们之间基于REST API沟通。</li>
<li>采用数据卷(data volumes)。数据卷让容器运行的应用程序和数据分离,即静动分离。不依赖于数据的容器方便发布成镜像给其它需要的容器。</li>
<li>模块化和分布式。容器之间可以创建网络通信,因此可以把应用本身,存储,缓存,消息队列分开部署。 </li>
</ul>
<h4>术语解释</h4>
<h6>镜像</h6>
<p>提供容器运行时所需的程序、库、资源、配置。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
采用分层构建模式,上层依赖的下层做修改。基于UnionFS技术。</p>
<h6>容器</h6>
<p>容器可以理解成镜像的实例,它是一个操作系统的进程。多个容器基于Cgroup和Namespace技术隔离。利用虚拟的网络接口(veth pair)进行通信。</p>
<h6>数据卷</h6>
<p>Docker的哲学是应用和动态数据分离。数据卷让容器可以挂载容器外部的目录或者文件到容器目录。这样应用程序写入数据的时候,实际上就是写入外部对应的目录或文件。这样做的好处是方便分发,而且基于现有容器生成镜像时,其上的层不需要关心数据。</p>
<h6>仓库</h6>
<p>仓库是镜像的托管站。官方仓库是Docker Hub,可以很方便的复用已经构建好的镜像启动一个容器。比如<code>docker run ubuntu:18.04 /bin/echo 'Hello world'</code>就是从官方仓库克隆镜像ubuntu:18.04启动一个容器。</p>
<h6>Docker Engine</h6>
<p>Docker Engine是一个C/S结构的应用,它由Docker CLI、Docker Daemon和一个REST API组成。
<center><img alt="docker_engine" src="./images/docker_engine.png"></center>
<center>Docker Engine结构图</center></p>
<h6>Dockerfile</h6>
<p>Dockerfile是Docker构建镜像的一个文件,里面包含了构建镜像的一些列Docker指令。Dockerfile保证了镜像构建的透明和可重复,而且避免Docker commit构建时写入容易数据。下面是一个简单Dockerfile例子。</p>
<div class="highlight"><pre><span></span><span class="k">FROM</span> <span class="s">nginx</span>
<span class="k">RUN</span> <span class="nb">echo</span> <span class="s1">'<h1>Hello, Docker!</h1>'</span> > /usr/share/nginx/html/index.html
</pre></div>
<p>FROM指令指定已经存在的Docker镜像。RUN指令用来执行shell命令,可以用来安装依赖包等。</p>
<h6>镜像构建上下文(Context)</h6>
<p>上面的Dockerfile写好后,可以执行<code>docker build -t nginx:v3 .</code>构建镜像。-t参数给构建的镜像打标签,“.”就是构建时的上下文。Docker采用C/S模式,构建镜像时Docker指令是运行在Docker Daemon(Docker守护进程)。引入上下文,使得ADD,COPY等需要复制文件的指令有了参考位置。构建镜像时,上下文会通过Docker Remote API打包传给Docker Daemon,通过这种保证了一些列文件的依赖,让Docker Daemon共享本地文件。</p>
<div class="highlight"><pre><span></span><span class="k">COPY</span> ./package.json /app/
</pre></div>
<p>上面的COPY指令,复制的是上下文的package.json到构建镜像的/app目录,而不是Dockerfile文件目录。</p>
<h4>简单使用</h4>
<p>下面通过一些基本例子,演示Docker容器创建,数据卷创建和使用及容器之间的网络通信。<br></p>
<h6>运行一个容器</h6>
<p>首先我们启动一个容器</p>
<div class="highlight"><pre><span></span>docker run -d -it --name nginx_test nginx
</pre></div>
<p>-d:后台运行
-it:启动终端</p>
<p>执行<code>docker ps</code>查看运行中进程</p>
<p><img alt="dockers_docker" src="./images/docker_ps.jpg"></p>
<p>可以看到我们的容器已经在运行,容器名ngix_test<br>
执行<code>docker stop nginx_test</code>停止刚才的容器。执行<code>docker rm nginx_test</code>删除刚才的容器。</p>
<h6>访问本地目录</h6>
<p>执行下面的命令挂载本地的~/nginx_test到容器的/data目录。容器的/data目录会自动创建,本地机器的必须存在命令才能执行成功。</p>
<div class="highlight"><pre><span></span>docker run -d --name nginx_test --mount <span class="nv">type</span><span class="o">=</span>bind,source<span class="o">=</span>/Users/xufan/nginx_data,target<span class="o">=</span>/data nginx
</pre></div>
<p>执行命令<code>docker exec -it nginx_test bash</code>进入容器,可以看到/data目录以及存在,重新打开一个终端,看看本地的~/nginx_data目录也多了一些文件。</p>
<div class="highlight"><pre><span></span>root@01818c8eb399:/# ls
bin boot data dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@01818c8eb399:/# <span class="nb">cd</span> data/
root@01818c8eb399:/data# ls
root@01818c8eb399:/data# <span class="nb">echo</span> <span class="s2">"helo docker"</span> > test.txt
</pre></div>
<p>同样,在本地的~/nginx_data新建文件,容器的/data也会相应的更新。</p>
<h6>访问网络</h6>
<p>运行容器的时候,可以通过-p参数指定本地端口到容器端口的映射。。</p>
<div class="highlight"><pre><span></span>docker run -d -it -p <span class="m">8080</span>:80 --name nginx_test2 nginx
</pre></div>
<p>上面命令将本地端口8080端口映射到容器80端口,浏览器访问http:127.0.0.1:8080就能看到Nginx的欢迎界面。</p>
<h6>容器之间通信</h6>
<div class="highlight"><pre><span></span>docker network create -d bridge my-net
docker run -it --rm --name busybox1 --network my-net busybox sh
docker run -it --rm --name busybox2 --network my-net busybox sh
</pre></div>
<p>去busybox1 ping busybox2验证网络的互通。</p>
<h4>技术原理</h4>
<p>对于Docker使用的Namespace,Cgroup,UnionFS技术,放到下篇再写。(<a href="./dockerxi-lie-er.html">技术原理</a>)</p>
<hr />
<aside>
<nav>
<ul class="articles-timeline">
<li class="previous-article">« <a href="./rabbitmqxi-lie-di-san-pian.html"
title="Previous: RabbitMQ系列第三篇 - 分布式部署">RabbitMQ系列第三篇 <small class="subtitle">分布式部署</small></a></li>
<li class="next-article"><a href="./dockerxi-lie-er.html"
title="Next: Docker系列(二) - 技术原理(UnionFS,Namespace,Cgroup)">Docker系列(二) <small class="subtitle">技术原理(UnionFS,Namespace,Cgroup)</small></a> »</li>
</ul>
</nav>
</aside>
</div>
<section id="article-sidebar" class="span2">
<h4>Published</h4>
<time itemprop="dateCreated" datetime="2019-01-22T00:00:00+08:00"> 1
22, 2019</time>
<!---->
<h4>Category</h4>
<a class="category-link"
href="./categories.html#docker-ref">Docker</a>
<h4>Tags</h4>
<ul class="list-of-tags tags-in-article">
<li><a href="./tags.html#containers-ref">containers
<span>2</span>
</a></li>
<li><a href="./tags.html#docker-ref">Docker
<span>6</span>
</a></li>
</ul>
<h4>Stay in Touch</h4>
<div id="sidebar-social-link">
<a href="mailto:[email protected]" title="My Email Address" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="Mail" role="img" viewBox="0 0 512 512"><rect width="512" height="512" rx="15%" fill="#328cff"/><path d="m250 186c-46 0-69 35-69 74 0 44 29 72 68 72 43 0 73-32 73-75 0-44-34-71-72-71zm-1-37c30 0 57 13 77 33 0-22 35-22 35 1v150c-1 10 10 16 16 9 25-25 54-128-14-187-64-56-149-47-195-15-48 33-79 107-49 175 33 76 126 99 182 76 28-12 41 26 12 39-45 19-168 17-225-82-38-68-36-185 67-248 78-46 182-33 244 32 66 69 62 197-2 246-28 23-71 1-71-32v-11c-20 20-47 32-77 32-57 0-108-51-108-108 0-58 51-110 108-110" fill="#fff"/></svg>
</a>
<a href="https://github.com/boyaziqi" title="catsaction Github Repository" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="GitHub" role="img" viewBox="0 0 512 512"><rect width="512" height="512" rx="15%" fill="#1B1817"/><path fill="#fff" d="M335 499c14 0 12 17 12 17H165s-2-17 12-17c13 0 16-6 16-12l-1-50c-71 16-86-28-86-28-12-30-28-37-28-37-24-16 1-16 1-16 26 2 40 26 40 26 22 39 59 28 74 22 2-17 9-28 16-35-57-6-116-28-116-126 0-28 10-51 26-69-3-6-11-32 3-67 0 0 21-7 70 26 42-12 86-12 128 0 49-33 70-26 70-26 14 35 6 61 3 67 16 18 26 41 26 69 0 98-60 120-117 126 10 8 18 24 18 48l-1 70c0 6 3 12 16 12z"/></svg>
</a>
<a href="https://www.linkedin.com/feed/" title="My LinkedIn" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="LinkedIn" role="img" viewBox="0 0 512 512" fill="#fff"><rect width="512" height="512" rx="15%" fill="#0077b5"/><circle cx="142" cy="138" r="37"/><path stroke="#fff" stroke-width="66" d="M244 194v198M142 194v198"/><path d="M276 282c0-20 13-40 36-40 24 0 33 18 33 45v105h66V279c0-61-32-89-76-89-34 0-51 19-59 32"/></svg>
</a>
</div>
<h4>Friendship Links</h4>
<ul class="list-of-tags tags-in-article">
<li>
<a href="https://leetcode-cn.com/" title="力扣中国站点" target="_blank" rel="nofollow noopener noreferrer">
LeetCode
</a>
</li>
<li>
<a href="https://coolshell.cn/about" title="陈皓酷壳" target="_blank" rel="nofollow noopener noreferrer">
CoolShell
</a>
</li>
<li>
<a href="https://yikun.github.io/" title="姜毅坤博客" target="_blank" rel="nofollow noopener noreferrer">
Yikun
</a>
</li>
<li>
<a href="https://www.nowcoder.com/" title="牛客网" target="_blank" rel="nofollow noopener noreferrer">
牛客网
</a>
</li>
</ul>
</section>
</div>
</article>
</div>
<div class="span1"></div>
</div>
</div>
</div>
<footer>
<div>
<span class="site-name">CatsAction's blog</span> - It's a wonderful world
</div>
<div id="fpowered">
Powered by: <a href="http://getpelican.com/" title="Pelican Home Page" target="_blank" rel="nofollow noopener noreferrer">Pelican</a>
Theme: <a href="https://elegant.oncrashreboot.com/" title="Theme Elegant Home Page" target="_blank" rel="nofollow noopener noreferrer">Elegant</a>
</div>
</footer> <script src="//code.jquery.com/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script>
function validateForm(query)
{
return (query.length > 0);
}
</script>
<script>
(function () {
if (window.location.hash.match(/^#comment-\d+$/)) {
$('#comment_thread').collapse('show');
}
})();
window.onhashchange=function(){
if (window.location.hash.match(/^#comment-\d+$/))
window.location.reload(true);
}
$('#comment_thread').on('shown', function () {
var link = document.getElementById('comment-accordion-toggle');
var old_innerHTML = link.innerHTML;
$(link).fadeOut(200, function() {
$(this).text('Click here to hide comments').fadeIn(200);
});
$('#comment_thread').on('hidden', function () {
$(link).fadeOut(200, function() {
$(this).text(old_innerHTML).fadeIn(200);
});
})
})
</script>
</body>
<!-- Theme: Elegant built for Pelican
License : MIT -->
</html>