-
Notifications
You must be signed in to change notification settings - Fork 0
/
container-design-ii.html
486 lines (367 loc) · 34.8 KB
/
container-design-ii.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
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: dark)"><meta name="generator" content="Hexo 7.0.0-rc1">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha256-HtsXJanqjKTc8vVQjO4YMhiqFoXkfBsjBWcX91T1jr8=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
<script class="next-config" data-name="main" type="application/json">{"hostname":"www.hwchiu.com","root":"/","images":"/images","scheme":"Gemini","darkmode":true,"version":"8.17.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"Searching...","empty":"We didn't find any results for the search: ${query}","hits_time":"${hits} results found in ${time} ms","hits":"${hits} results found"}}</script><script src="/js/config.js"></script>
<meta name="description" content="本文延續前篇文章關於 Open Container Initiatives 的討論,前篇文章討論了關於 OCI 內的兩大標準,分別是 Runtime 以及 Image 這兩項關於 Container 的標準,而本篇文章則是會介紹如了相關的標準之外,目前有什麼相關的解決方案與工具與這兩個標準息息相關,同時對於 Docker 本身會怎麼利用這些標準來完成 COntainer 的運行">
<meta property="og:type" content="article">
<meta property="og:title" content="淺談 Container 實現原理, 以 Docker 為例(II)">
<meta property="og:url" content="https://www.hwchiu.com/container-design-ii.html">
<meta property="og:site_name" content="Hwchiu Learning Note">
<meta property="og:description" content="本文延續前篇文章關於 Open Container Initiatives 的討論,前篇文章討論了關於 OCI 內的兩大標準,分別是 Runtime 以及 Image 這兩項關於 Container 的標準,而本篇文章則是會介紹如了相關的標準之外,目前有什麼相關的解決方案與工具與這兩個標準息息相關,同時對於 Docker 本身會怎麼利用這些標準來完成 COntainer 的運行">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="https://i.imgur.com/WL7hKSD.png">
<meta property="og:image" content="https://i.imgur.com/yYRFdUK.png">
<meta property="og:image" content="https://i.imgur.com/Nxzr0Tn.png">
<meta property="og:image" content="https://i.imgur.com/wDbs54G.png">
<meta property="article:published_time" content="2019-09-17T23:17:58.000Z">
<meta property="article:modified_time" content="2023-06-23T05:16:12.608Z">
<meta property="article:author" content="Hwchiu">
<meta property="article:tag" content="Docker">
<meta property="article:tag" content="ITHOME">
<meta property="article:tag" content="Container">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.imgur.com/WL7hKSD.png">
<link rel="canonical" href="https://www.hwchiu.com/container-design-ii.html">
<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"en","comments":true,"permalink":"https://www.hwchiu.com/container-design-ii.html","path":"container-design-ii.html","title":"淺談 Container 實現原理, 以 Docker 為例(II)"}</script>
<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>淺談 Container 實現原理, 以 Docker 為例(II) | Hwchiu Learning Note</title>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-54006186-1"></script>
<script class="next-config" data-name="google_analytics" type="application/json">{"tracking_id":"UA-54006186-1","only_pageview":false}</script>
<script src="/js/third-party/analytics/google-analytics.js"></script>
<noscript>
<link rel="stylesheet" href="/css/noscript.css">
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
<div class="headband"></div>
<main class="main">
<div class="column">
<header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="Toggle navigation bar" role="button">
<span class="toggle-line"></span>
<span class="toggle-line"></span>
<span class="toggle-line"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<i class="logo-line"></i>
<p class="site-title">Hwchiu Learning Note</p>
<i class="logo-line"></i>
</a>
<p class="site-subtitle" itemprop="description">kubernetes, sdn, linux,devops</p>
<img class="custom-logo-image" src="/uploads/hwchiu.jpg" alt="Hwchiu Learning Note">
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger" aria-label="Search" role="button">
</div>
</div>
</div>
<nav class="site-nav">
<ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>Home</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>About</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>Tags</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>Archives</a></li><li class="menu-item menu-item-sitemap"><a href="/sitemap.xml" rel="section"><i class="fa fa-sitemap fa-fw"></i>Sitemap</a></li>
</ul>
</nav>
</header>
<aside class="sidebar">
<div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
<ul class="sidebar-nav">
<li class="sidebar-nav-toc">
Table of Contents
</li>
<li class="sidebar-nav-overview">
Overview
</li>
</ul>
<div class="sidebar-panel-container">
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%89%8D%E8%A8%80"><span class="nav-number">1.</span> <span class="nav-text">前言</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#OCI-Implementation"><span class="nav-number">2.</span> <span class="nav-text">OCI - Implementation</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Runtime"><span class="nav-number">2.1.</span> <span class="nav-text">Runtime</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Image"><span class="nav-number">2.2.</span> <span class="nav-text">Image</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Docker"><span class="nav-number">3.</span> <span class="nav-text">Docker</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Docker-UI-x2F-Commands"><span class="nav-number">3.1.</span> <span class="nav-text">Docker UI/Commands</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Docker-Engine"><span class="nav-number">3.2.</span> <span class="nav-text">Docker Engine</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Containerd"><span class="nav-number">3.3.</span> <span class="nav-text">Containerd</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Containerd-Shim"><span class="nav-number">3.4.</span> <span class="nav-text">Containerd-Shim</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Summary"><span class="nav-number">3.5.</span> <span class="nav-text">Summary</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Reference"><span class="nav-number">4.</span> <span class="nav-text">Reference</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%80%8B%E4%BA%BA%E8%B3%87%E8%A8%8A"><span class="nav-number">5.</span> <span class="nav-text">個人資訊</span></a></li></ol></div>
</div>
<!--/noindex-->
<div class="site-overview-wrap sidebar-panel">
<div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
<img class="site-author-image" itemprop="image" alt="Hwchiu"
src="/uploads/avatar.jpg">
<p class="site-author-name" itemprop="name">Hwchiu</p>
<div class="site-description" itemprop="description">kubernetes/SDN/DevOps</div>
</div>
<div class="site-state-wrap animated">
<nav class="site-state">
<div class="site-state-item site-state-posts">
<a href="/archives/">
<span class="site-state-item-count">352</span>
<span class="site-state-item-name">posts</span>
</a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/">
<span class="site-state-item-count">115</span>
<span class="site-state-item-name">tags</span></a>
</div>
</nav>
</div>
<div class="links-of-author animated">
<span class="links-of-author-item">
<a href="https://github.com/hwchiu" title="GitHub → https://github.com/hwchiu" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
</span>
<span class="links-of-author-item">
<a href="mailto:sppsorrg@gmail.com" title="E-Mail → mailto:sppsorrg@gmail.com" rel="noopener me" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
</span>
<span class="links-of-author-item">
<a href="https://twitter.com/hw_chiu" title="Twitter → https://twitter.com/hw_chiu" rel="noopener me" target="_blank"><i class="fab fa-twitter fa-fw"></i>Twitter</a>
</span>
<span class="links-of-author-item">
<a href="https://www.facebook.com/technologynoteniu" title="FB Page → https://www.facebook.com/technologynoteniu" rel="noopener me" target="_blank"><i class="fab fa-facebook fa-fw"></i>FB Page</a>
</span>
<span class="links-of-author-item">
<a href="https://www.youtube.com/channel/UCoYY8K9fbfDtTY7m68UCATA/videos" title="YouTube → https://www.youtube.com/channel/UCoYY8K9fbfDtTY7m68UCATA/videos" rel="noopener me" target="_blank"><i class="fab fa-youtube fa-fw"></i>YouTube</a>
</span>
<span class="links-of-author-item">
<a href="https://instagram.com/hwchiu" title="Instagram → https://instagram.com/hwchiu" rel="noopener me" target="_blank"><i class="fab fa-instagram fa-fw"></i>Instagram</a>
</span>
</div>
</div>
</div>
</div>
</aside>
</div>
<div class="main-inner post posts-expand">
<div class="post-block">
<article itemscope itemtype="http://schema.org/Article" class="post-content" lang="en">
<link itemprop="mainEntityOfPage" href="https://www.hwchiu.com/container-design-ii.html">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/uploads/avatar.jpg">
<meta itemprop="name" content="Hwchiu">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Hwchiu Learning Note">
<meta itemprop="description" content="kubernetes/SDN/DevOps">
</span>
<span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
<meta itemprop="name" content="淺談 Container 實現原理, 以 Docker 為例(II) | Hwchiu Learning Note">
<meta itemprop="description" content="本文延續前篇文章關於 Open Container Initiatives 的討論,前篇文章討論了關於 OCI 內的兩大標準,分別是 Runtime 以及 Image 這兩項關於 Container 的標準,而本篇文章則是會介紹如了相關的標準之外,目前有什麼相關的解決方案與工具與這兩個標準息息相關,同時對於 Docker 本身會怎麼利用這些標準來完成 COntainer 的運行">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
淺談 Container 實現原理, 以 Docker 為例(II)
</h1>
<div class="post-meta-container">
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2019-09-18 07:17:58" itemprop="dateCreated datePublished" datetime="2019-09-18T07:17:58+08:00">2019-09-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2023-06-23 13:16:12" itemprop="dateModified" datetime="2023-06-23T13:16:12+08:00">2023-06-23</time>
</span>
<span class="post-meta-item" title="Views" id="busuanzi_container_page_pv">
<span class="post-meta-item-icon">
<i class="far fa-eye"></i>
</span>
<span class="post-meta-item-text">Views: </span>
<span id="busuanzi_value_page_pv"></span>
</span>
</div>
<div class="post-description">本文延續前篇文章關於 Open Container Initiatives 的討論,前篇文章討論了關於 OCI 內的兩大標準,分別是 Runtime 以及 Image 這兩項關於 Container 的標準,而本篇文章則是會介紹如了相關的標準之外,目前有什麼相關的解決方案與工具與這兩個標準息息相關,同時對於 Docker 本身會怎麼利用這些標準來完成 COntainer 的運行</div>
</div>
</header>
<div class="post-body" itemprop="articleBody"><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>前一天的文章中,我們探討了關於 <code>Open Container Initiatives(OCI)</code> 的概念,並且探討了關於 <code>Runtime Spec</code> 以及 <code>Image Spec</code> 的規範與規格。</p>
<p>今天則是要探討對於一個開發者來說,如果要開發一個能夠滿足 <code>OCI</code> 標準的解決方案,則有什麼相關的函式庫,工具可以使用來減少重複打造輪子的情況。<br>一旦我們可以掌握這方便的概念,之後再研究 <code>Docker</code>, <code>Kubernetes</code> 等解決方案時就會有更清晰的輪廓。</p>
<h1 id="OCI-Implementation"><a href="#OCI-Implementation" class="headerlink" title="OCI - Implementation"></a>OCI - Implementation</h1><p>如同前言所述, <code>OCI</code> 本身包含了 <code>Runtime</code> 以及 <code>Image</code> 兩個規範,而 <code>Runtime</code> 尤其重要,畢竟其規範了 <code>Container</code> 的生命週期操作以及相關的設定。</p>
<h2 id="Runtime"><a href="#Runtime" class="headerlink" title="Runtime"></a>Runtime</h2><p><code>OCI</code> 官方基於 <code>Runtime 規範</code> 實現了一個解決方案,稱為 <a target="_blank" rel="noopener" href="https://github.com/opencontainers/runc">RunC</a>, 根據其官方文件的說明</p>
<blockquote>
<p>runc is a CLI tool for spawning and running containers according to the OCI specification.</p>
</blockquote>
<p>這意味者藉由這套工具,並且搭配適宜的設定,就可以輕鬆的創建出一個符合<code>OCI</code> 標準的 <code>Container</code> 運行。 但是單純的 <code>CLI</code> 工具並不一定適合所有的開發者,部分的開發者可能只希望擁有一套能夠符合 <code>OCI</code> 標準的相關函示庫可以使用,這時候要可以使用 <a target="_blank" rel="noopener" href="https://github.com/opencontainers/runc/tree/master/libcontainer">libcontainer</a>這套由官方維護並且以 <code>golang</code> 撰寫的函示庫,根據其說明文件</p>
<blockquote>
<p>Libcontainer provides a native Go implementation for creating containers with namespaces, cgroups, capabilities, and filesystem access controls. It allows you to manage the lifecycle of the container performing additional operations after the container is created.</p>
</blockquote>
<p>透過這個函式庫,開發者可以輕鬆的撰寫出滿足整個 <code>container</code> 的生命週期,同時也能夠創建相關的 <code>namespace/cgroups</code> 等的程式碼,並且將心力專注在更上層的服務提供。</p>
<p>除了 <code>runC</code> 這套實現方案之外,官方<br><a target="_blank" rel="noopener" href="https://github.com/opencontainers/runtime-spec/blob/master/implementations.md">GitHub</a> 可以看到目前官方收錄的所有 <code>Runtime Spec</code> 的實現方案,這些方案有些由 <code>OCI</code> 組織本身維護,有些由其他組織維護。</p>
<p>其中特別有趣的就是這些實現方案目前分為兩大類,分別是 <code>Runtime (Container)</code> 以及 <code>Runtime (Virtual Machine)</code>.</p>
<p>其中 <code>Container</code> 就是我們一直在探討的 <code>Container</code> 而 <code>Virtual Machine</code> 這類型則是透過 <code>Virtual Machine</code> 相關的技術去完成虛擬化的環境,但是同時又符合 <code>OCI</code> 的標準。 這意味者使用者可以創建 <code>Contaienr</code> 來使用,但是其底層是以 <code>Virtual Machine</code> 的技術創建出來的。</p>
<p>這相關的概念其實不難想像,畢竟 <code>Container</code> 一直以來被認為不夠安全,畢竟其部分功能都是依賴 <code>Host</code> 上的 <code>Kernel</code> 來實現,其隔離能力沒有 <code>Virtual Machine</code> 這麼明確。<br>所以如何打造一個速度又快,安全度又高的虛擬化環境一直以來都是一個探討的議題。</p>
<p>該清單中的 <code>google/gvisor</code> 以及 <code>kata-containers</code> 都算是滿知名的專案<br>有興趣的讀者可以自行研究這些技術底層並看看各大專案是希望如何實現<code>高效能,高安全</code> 的虛擬化環境。</p>
<h2 id="Image"><a href="#Image" class="headerlink" title="Image"></a>Image</h2><p><code>Image</code> 的部分也有相對應的工具可以使用,一樣由<a target="_blank" rel="noopener" href="https://github.com/opencontainers/image-tools">官方 GitHub</a> 進行維護,該文件中會介紹如何搭配 <code>skopeo</code> 等工具來完成一個關於 <code>Image</code> 相關的案例。<br>此外,也有其他的專案如 <a target="_blank" rel="noopener" href="https://github.com/containers/buildah">buildah</a> 也針對 <code>OCI Image</code> 的部分提供一些解決方案</p>
<blockquote>
<p>Buildah - a tool that facilitates building Open Container Initiative (OCI) container images</p>
</blockquote>
<h1 id="Docker"><a href="#Docker" class="headerlink" title="Docker"></a>Docker</h1><p>對於 <code>Open Container Initiative (OCI)</code> 有基本概念之後,接下來就要探討作為 <code>OCI</code> 重大貢獻者的 <code>docker</code> (libcontainer, image spec…etc),是如何在其架構中透過何種方式跟來創建基於 <code>OCI</code> 介面的 <code>Container</code>.</p>
<p>下圖是一個滿棒的架構圖,當有了 <code>OCI</code> 的概念後再來看這張圖會覺得親切許多。</p>
<p><img src="https://i.imgur.com/WL7hKSD.png"><br>(圖片擷取自:<a target="_blank" rel="noopener" href="https://blog.docker.com/2016/04/docker-engine-1-11-runc/">blod.docker.com - docker-engine-1-11-runc</a>)</p>
<p>這張圖片的右半部分標出了四個不同層級的概念,分別是</p>
<ul>
<li>Docker UI/Commands</li>
<li>Docker Engine</li>
<li>Containerd</li>
<li>Runc</li>
</ul>
<h2 id="Docker-UI-x2F-Commands"><a href="#Docker-UI-x2F-Commands" class="headerlink" title="Docker UI/Commands"></a>Docker UI/Commands</h2><p>大家最為熟悉的 <code>docker</code> 指令其實在整個 <code>Docker</code> 的架構中扮演了所謂了 <code>client</code> 的角色,負責將使用者的需求(指令)打包,並且與後方的 <code>server</code> 溝通</p>
<p>這邊除了常用的 <code>docker run/build/image/exec/attach...etc</code> 等直接使用的 CLI 工具外,也是有相關的函式庫可以供開發者使用,將自己的應用程式直接與 <code>Docker Server</code> 連動來溝通。</p>
<p>在預設的情況下,<code>docker</code> 指令都會透過 <code>unix socket</code> 與本地的 <code>docker engine</code> 溝通,這個部分可以透過環境變數來描述,譬如</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">export DOCKER_HOST=tcp://192.168.0.123:2376</span><br><span class="line">docker run</span><br></pre></td></tr></table></figure>
<h2 id="Docker-Engine"><a href="#Docker-Engine" class="headerlink" title="Docker Engine"></a>Docker Engine</h2><p>當系統內安裝 <code>Docker</code> 後,你可以透過系統指令 <code>ps</code> 觀察到系統上會有一個名為 <code>dockerd</code> 的程序</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">root 2487 0.6 2.2 694888 90000 ? Ssl 22:26 0:11 dockerd -G docker --exec-root=/var/snap/docker/384/run/docker --data-root=/var/snap/docker/common/var-lib-docker --pidfile=/var/snap/docker/384/run/docker.pid --config-file=/var/snap/docker/384/config/daemon.json --debug</span><br></pre></td></tr></table></figure>
<p>這個 <code>server</code> 就是所謂的 <code>docker engine</code>, 所有的 <code>docker client</code> 都會將指令送到這個 <code>engine</code> 進行相關整理。這一層級相對於 <code>OCI</code> 的層級還是算高,偏向上層的應用,所以特色還是以 <code>Docker</code> 自己的特色為主。</p>
<h2 id="Containerd"><a href="#Containerd" class="headerlink" title="Containerd"></a>Containerd</h2><p>當 <code>Docker Engine</code> 收到指令後就會將指令往後傳送到 <code>containerd</code> 進行處理。</p>
<p>相對於 <code>Docker Engine</code>, <code>containerd</code> 則更面向 <code>OCI</code> 標準,向上提供 <code>gRPC</code> 接口供 <code>Docker Engine</code> 使用,向下則是根據需求創建符合 <code>OCI</code> 標準的 <code>Container</code>.</p>
<p>就如同昨天所述, <code>Runtime spec</code> 目前有眾多的實現方案可以選擇,而最知名且由 <code>OCI</code> 組織維護的就是 <code>runc</code>.</p>
<p>所以 <code>Containerd</code> 本身也會透過這些現有的解決方案來創建符合 <code>OCI</code> 標準的 <code>Container</code>.</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">root 2571 0.6 0.8 558432 35808 ? Ssl Sep12 0:39 docker-containerd --config /var/snap/docker/384/run/docker/containerd/containerd.toml</span><br></pre></td></tr></table></figure>
<h2 id="Containerd-Shim"><a href="#Containerd-Shim" class="headerlink" title="Containerd-Shim"></a>Containerd-Shim</h2><p>此外,為了滿足一些軟體設計上的需求,<code>containerd</code> 並沒有直接呼叫 <code>runc</code>,反而是中間會在填補一層所謂的 <code>containerd-shim</code>, <code>containerd</code> 會創建一個獨立的 process <code>containerd-shim</code> 並由其呼叫 <code>runc</code> 來真正創建 <code>container</code>.</p>
<p>根據下列 <a target="_blank" rel="noopener" href="https://github.com/crosbymichael/dockercon-2016/blob/master/Creating%20Containerd.pdf">dockercon-2016</a> 相關的演講,我們可以歸納出下列為什麼需要 <code>containerd-shim</code> 的理由</p>
<ul>
<li><p>daemonless</p>
<ul>
<li>將 <code>container</code> 運行與 <code>docker</code> 分開,這意味者 <code>docker</code> 升級的過程中這些運行的 <code>container</code> 並不會被影響,可以繼續使用。 因為 <code>docker engine/containerd</code> 目前都是屬於 <code>docker</code> 套件的程式。</li>
</ul>
</li>
<li><p>re-parenting</p>
<ul>
<li>當 <code>runc</code> 創建出 <code>container</code> 後可以直接讓 <code>runc</code> 離開,並且把其程序的 <code>process</code> 交由更上層的祖父去管理,這個情況中我們就可以讓 <code>containerd-shim</code> 去管理。此外假設當 <code>containerd</code> 意外重啟後,則新的 <code>containerd-shim</code> 可以交由 <code>init</code> 去管理,藉此做到系統更新而不影響現存的 <code>container</code></li>
</ul>
</li>
<li><p>tty/stdin 為了處理 <code>container</code> 本身的輸入問題,則會用 <code>FIFO</code> 這種 <code>IPC</code>的方式再 <code>parent & child process</code> 中溝通。所以我們將 <code>parent</code> 的重責大任就交給了 <code>containerd-shim</code> 上</p>
</li>
</ul>
<p>關於 <code>re-parenting</code> 的演變可以直接參閱該份投影片,如下<br><img src="https://i.imgur.com/yYRFdUK.png"><br>(圖片擷取自:<a target="_blank" rel="noopener" href="https://github.com/crosbymichael/dockercon-2016/blob/master/Creating%20Containerd.pdf">dockercon-2016</a>)<br><img src="https://i.imgur.com/Nxzr0Tn.png"><br>(圖片擷取自:<a target="_blank" rel="noopener" href="https://github.com/crosbymichael/dockercon-2016/blob/master/Creating%20Containerd.pdf">dockercon-2016</a>)</p>
<p>由上面的概念可以知道,每個 <code>containerd-shim</code> 都會對應到一個 <code>container</code>, 因此當透過 <code>docker run</code> 的方式來運行容器後,系統就會產收一個 <code>container-shim</code> 相關的應用程式. 可以使用以下範例創建多個容器,然後觀察相關的 <code>containerd-shim</code> 的狀態</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">sudo docker run -d hwchiu/netutils</span><br><span class="line">sudo docker run -d hwchiu/netutils</span><br><span class="line">sudo docker run -d hwchiu/netutils</span><br><span class="line">sudo docker run -d hwchiu/netutils</span><br><span class="line">ps auxw | grep docker-containerd-shim | <span class="built_in">wc</span> -l</span><br><span class="line">ps auxw | grep docker-containerd-shim</span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">root 11732 0.0 0.1 7380 4420 ? Sl 18:17 0:00 docker-containerd-shim -namespace moby -workdir /var/snap/docker/common/var-lib-docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/a12e5594d0d666759c51b2420db0e361649a39b43aa6b5e928382c69381be0a0 -address /var/snap/docker/384/run/docker/containerd/docker-containerd.sock -containerd-binary /snap/docker/384/bin/docker-containerd -runtime-root /var/snap/docker/384/run/docker/runtime-runc -debug</span><br></pre></td></tr></table></figure>
<h2 id="Summary"><a href="#Summary" class="headerlink" title="Summary"></a>Summary</h2><p>此外,上述所有的元件在最後於 <code>docker</code> 的環境中都有重新命名,包含了</p>
<ol>
<li>containerd -> docker-containerd</li>
<li>containerd-shim -> docker-containerd-shim</li>
</ol>
<p>用下列架構圖來重新說明一次 <code>Docker</code> 內部的構造以及是如何創建出符合 <code>OCI</code> 標準的容器<br> <img src="https://i.imgur.com/wDbs54G.png"></p>
<h1 id="Reference"><a href="#Reference" class="headerlink" title="Reference"></a>Reference</h1><ul>
<li><a target="_blank" rel="noopener" href="https://blog.docker.com/2017/08/what-is-containerd-runtime/">https://blog.docker.com/2017/08/what-is-containerd-runtime/</a></li>
<li><a target="_blank" rel="noopener" href="http://alexander.holbreich.org/docker-components-explained/">http://alexander.holbreich.org/docker-components-explained/</a></li>
<li><a target="_blank" rel="noopener" href="https://github.com/crosbymichael/dockercon-2016/blob/master/Creating%20Containerd.pdf">https://github.com/crosbymichael/dockercon-2016/blob/master/Creating%20Containerd.pdf</a></li>
<li><a target="_blank" rel="noopener" href="https://ops.tips/blog/run-docker-with-forked-runc/#forking-runc">https://ops.tips/blog/run-docker-with-forked-runc/#forking-runc</a></li>
<li><a target="_blank" rel="noopener" href="https://medium.com/tiffanyfay/docker-1-11-et-plus-engine-is-now-built-on-runc-and-containerd-a6d06d7e80ef">https://medium.com/tiffanyfay/docker-1-11-et-plus-engine-is-now-built-on-runc-and-containerd-a6d06d7e80ef</a></li>
</ul>
<h1 id="個人資訊"><a href="#個人資訊" class="headerlink" title="個人資訊"></a>個人資訊</h1><p>我目前於 Hiskio 平台上面有開設 Kubernetes 相關課程,歡迎有興趣的人參考並分享,裡面有我從底層到實戰中對於 Kubernetes 的各種想法</p>
<p>線上課程詳細資訊: <a target="_blank" rel="noopener" href="https://course.hwchiu.com/">https://course.hwchiu.com/</a><br>另外,歡迎按讚加入我個人的粉絲專頁,裡面會定期分享各式各樣的文章,有的是翻譯文章,也有部分是原創文章,主要會聚焦於 CNCF 領域<br><a target="_blank" rel="noopener" href="https://www.facebook.com/technologynoteniu">https://www.facebook.com/technologynoteniu</a></p>
<p>如果有使用 Telegram 的也可以訂閱下列頻道來,裡面我會定期推播通知各類文章<br><a target="_blank" rel="noopener" href="https://t.me/technologynote">https://t.me/technologynote</a></p>
<p>你的捐款將給予我文章成長的動力</p>
<script type="text/javascript" src="https://cdnjs.buymeacoffee.com/1.0.0/button.prod.min.js" data-name="bmc-button" data-slug="hwchiu" data-color="#000000" data-emoji="" data-font="Cookie" data-text="Buy me a coffee" data-outline-color="#fff" data-font-color="#fff" data-coffee-color="#fd0" ></script>
</div>
<footer class="post-footer">
<div class="followme">
<span>Welcome to my other publishing channels</span>
<div class="social-list">
<div class="social-item">
<a target="_blank" class="social-link" href="https://twitter.com/hw_chiu">
<span class="icon">
<i class="fab fa-twitter"></i>
</span>
<span class="label">Twitter</span>
</a>
</div>
<div class="social-item">
<a target="_blank" class="social-link" href="https://t.me/technologynote">
<span class="icon">
<i class="fab fa-telegram"></i>
</span>
<span class="label">Telegram</span>
</a>
</div>
<div class="social-item">
<a target="_blank" class="social-link" href="/atom.xml">
<span class="icon">
<i class="fa fa-rss"></i>
</span>
<span class="label">RSS</span>
</a>
</div>
</div>
</div>
<div class="post-tags">
<a href="/tags/Docker/" rel="tag"># Docker</a>
<a href="/tags/ITHOME/" rel="tag"># ITHOME</a>
<a href="/tags/Container/" rel="tag"># Container</a>
</div>
<div class="post-nav">
<div class="post-nav-item">
<a href="/container-design-i.html" rel="prev" title="淺談 Container 實現原理, 以 Docker 為例(I)">
<i class="fa fa-chevron-left"></i> 淺談 Container 實現原理, 以 Docker 為例(I)
</a>
</div>
<div class="post-nav-item">
<a href="/container-design-iii.html" rel="next" title="淺談 Container 實現原理, 以 Docker 為例(III)">
淺談 Container 實現原理, 以 Docker 為例(III) <i class="fa fa-chevron-right"></i>
</a>
</div>
</div>
</footer>
</article>
</div>
<div class="comments utterances-container"></div>
</div>
</main>
<footer class="footer">
<div class="footer-inner">
<div class="copyright">
©
<span itemprop="copyrightYear">2023</span>
<span class="with-love">
<i class="fa fa-heart"></i>
</span>
<span class="author" itemprop="copyrightHolder">Hwchiu</span>
</div>
<div class="busuanzi-count">
<span class="post-meta-item" id="busuanzi_container_site_uv">
<span class="post-meta-item-icon">
<i class="fa fa-user"></i>
</span>
<span class="site-uv" title="Total Visitors">
<span id="busuanzi_value_site_uv"></span>
</span>
</span>
<span class="post-meta-item" id="busuanzi_container_site_pv">
<span class="post-meta-item-icon">
<i class="fa fa-eye"></i>
</span>
<span class="site-pv" title="Total Views">
<span id="busuanzi_value_site_pv"></span>
</span>
</span>
</div>
<div class="powered-by">Powered by <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/" rel="noopener" target="_blank">NexT.Gemini</a>
</div>
</div>
</footer>
<div class="back-to-top" role="button" aria-label="Back to top">
<i class="fa fa-arrow-up fa-lg"></i>
<span>0%</span>
</div>
<noscript>
<div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script>
<script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<script class="next-config" data-name="utterances" type="application/json">{"enable":true,"repo":"hwchiu/blog-comment","issue_term":"pathname","theme":"github-light"}</script>
<script src="/js/third-party/comments/utterances.js"></script>
</body>
</html>