{"action":"created","comment":{"url":"https://api.github.com/repos/LCTT/TranslateProject/pulls/comments/76518137","id":76518137,"diff_hunk":"@@ -0,0 +1,59 @@\n+Linux 容器和镜像签名简介\n+====================\n+\n+![](https://opensource.com/sites/default/files/styles/image-full-size/public/images/business/containers_2015-1-osdc-lead.png?itok=E1imOYe4)\n+\n+从根本上说，几乎所有的主要软件，即使开源软件，都是在基于镜像的容器技术出现之前设计的。这意味着把软件放到容器中相当于是一次平台移植。这也意味着一些程序可以很容易就迁移，[而一些就更困难][1]。\n+\n+我大约在 3 年半前开展基于镜像的容器相关工作。到目前为止，我已经容器化了大量应用。我了解到什么是真实的，什么是迷信。今天，我想简要介绍一下 Linux 容器是如何设计的，以及谈谈镜像签名。\n+\n+### Linux 容器是如何设计的\n+\n+对于基于镜像的 Linux 容器，让大多数人感到困惑的是，它把操作系统分割成两个部分：[内核空间与用户空间][2]。在传统操作系统中，内核运行在硬件上，你无法直接与其交互。用户空间才是你真正能交互的，这包括所有你可以通过文件浏览器或者运行`ls`命令能看到的文件、类库、程序。当你使用`ifconfig`命令调整 IP 地址时，你实际上正在借助用户空间的程序来使内核根据 TCP 协议栈改变。这点经常让没有研究过 [Linux/Unix 基础][3]的人大吃一惊。\n+\n+过去，用户空间中的类库曾经支持过与内核交互的程序比如 (ifconfig, sysctl, tuned-adm) 以及如网络服务器和数据库之类的面向用户的程序。但这些都在单文件系统层次体系中取消了。用户可以通过检查 /sbin 或者 /lib 文件夹，查看所有面向用户的程序和类库（查阅[文件系统层次结构标准][4]）。这个模型的问题在于操作系统程序和业务支持程序没有绝对的隔离。/usr/bin 中的程序可能依赖 /lib 中的类库。如果一个应用所有者需要改变一些东西，就很有可能破坏操作系统。相反地，如果负责安全更新的团队需要改变一个类库，就可能（常有的事）破坏面向业务的应用。这真是一团糟。\n+\n+借助基于镜像的容器，比如 Docker, LXD, RKT, 应用程序所有者可以打包和调整所有 /sbin, /lib, /usr/bin, 和 /usr/lib 中的依赖，而不用担心破坏底层操作系统。本质上讲，容器技术再次干净地将操作系统隔离为两部分，内核空间与用户空间。现在开发人员和运维人员可以分别独立地更新各自的东西。\n+\n+然而还是有些令人困扰的地方。通常，每个应用所有者（或开发者）并不想负责更新这些应用依赖：像 openssl、glibc，或很底层的基础组件，比如，XML 解析器、JVM，再或者处理与性能相关的设置。过去，这些问题都委托给运维团队来处理。由于我们在容器中打包了很多依赖，对于很多组织来讲，对容器内的所有东西负责仍是个严峻的问题。\n+\n+### 迁移现有应用到 Linux 容器\n+\n+把应用放到容器中算得上是平台移植，我准备突出介绍究竟是什么让移植某些应用到容器当中这么困难。\n+\n+开发者现在对 /sbin /lib /usr/bin /usr/lib 中的内容有完全的控制权。但是，他们面临的挑战是，他们仍需要将数据和配置放到 /etc 或者 /var/lib 文件夹中。对于基于镜像的容器来说，这是一个糟糕的想法。我们真正需要的是代码、配置以及数据的隔离。我们希望开发者把代码放在容器当中，而数据和配置通过环境来获得，比如，开发、测试或生产环境。\n+\n+这意味着我们在实例化容器时，需要挂载 /etc 或 /var/lib 中的一些文件或文件夹。这会允许我们到处移动容器并仍能从环境中获得数据和配置。听起来很酷吧？这里有个问题，我们需要能够干净地隔离配置和数据。很多现代开源软件比如 Apache，MySQL，MongoDB, Nginx 默认就这么做了。[但很多自产的，遗留的，或专有程序并未默认这么设计][5]。对于很多组织来讲，这是主要的痛点。对于开发者来讲的最佳实践是，开始架构新的应用，移植遗留代码，以完成配置和数据的完全隔离。\n+\n+### 镜像签名简介\n+\n+信任机制是容器的重要议题。容器镜像签名允许用户添加数字指纹到镜像中。这个指纹随后可被加密测试验证。这使得容器镜像的用户可以验证其来源并信任。\n+\n+容器社区经常使用“容器镜像”这个词组，但这个命名方法会让人相当困惑。Docker，LXD，和 RKT 推行这样的概念，获取远程文件来当作容器运行。这些技术各自通过不同的方式处理容器镜像。LXD 用单独的一层来获取单独一个容器，而 Docker 和 RKT 使用基于开放容器镜像(OCI)格式，可由多层组成。糟糕的是，会存在不同团队和组织对容器镜像中的不同层负责。容器镜像概念下隐含的是容器镜像格式的概念。拥有统一的镜像格式比如 OCI 会让容器生态系统围绕着镜像扫描，签名，和在不同云服务提供商间转移而繁荣发展。\n+\n+现在谈到签名了。\n+\n+容器存在一个问题，我们把一堆代码，二进制文件，和类库放放入其中。一旦我们打包了代码，我们就要把它和必要的文件服务器（注册服务器）共享。代码只要被共享，它基本上就是不具名的，缺少某种密文签名。更糟糕的是，容器镜像经常由不同人或团队控制的各个镜像层组成。每个团队都需要能够检查上一个团队的工作，增加他们自己的工作，并在上面添加批准的印记。他们需要继续把工作交给下个团队。\n+\n+（由很多镜像组成的）容器镜像的最终用户需要检查监管链。他们需要验证每个往其中添加文件的团队的可信度。对于最终用户而言，对容器镜像中的每一层都有信心是极其重要的。\n+\n+作者 Scott McCarty 于 8 月 24 日在 ContainerCon 会议上作了题为 [Containers for Grownups: Migrating Traditional & Existing Applications][6] 的报告，更多内容请参阅报告[幻灯片][7]。","path":"translated/tech/20160810 A brief introduction to Linux containers and image signing.md","position":36,"original_position":40,"commit_id":"5a0add40be12d56d9ec6c154cae9871962850fdb","original_commit_id":"5a0add40be12d56d9ec6c154cae9871962850fdb","user":{"login":"Tanete","id":5023202,"avatar_url":"https://avatars.githubusercontent.com/u/5023202?v=3","gravatar_id":"","url":"https://api.github.com/users/Tanete","html_url":"https://github.com/Tanete","followers_url":"https://api.github.com/users/Tanete/followers","following_url":"https://api.github.com/users/Tanete/following{/other_user}","gists_url":"https://api.github.com/users/Tanete/gists{/gist_id}","starred_url":"https://api.github.com/users/Tanete/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tanete/subscriptions","organizations_url":"https://api.github.com/users/Tanete/orgs","repos_url":"https://api.github.com/users/Tanete/repos","events_url":"https://api.github.com/users/Tanete/events{/privacy}","received_events_url":"https://api.github.com/users/Tanete/received_events","type":"User","site_admin":false},"body":"本文内容略觉空洞，添加了报告PPT链接，内容更多。","created_at":"2016-08-27T15:32:18Z","updated_at":"2016-08-27T15:32:18Z","html_url":"https://github.com/LCTT/TranslateProject/pull/4337#discussion_r76518137","pull_request_url":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337","_links":{"self":{"href":"https://api.github.com/repos/LCTT/TranslateProject/pulls/comments/76518137"},"html":{"href":"https://github.com/LCTT/TranslateProject/pull/4337#discussion_r76518137"},"pull_request":{"href":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337"}}},"pull_request":{"url":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337","id":82990760,"html_url":"https://github.com/LCTT/TranslateProject/pull/4337","diff_url":"https://github.com/LCTT/TranslateProject/pull/4337.diff","patch_url":"https://github.com/LCTT/TranslateProject/pull/4337.patch","issue_url":"https://api.github.com/repos/LCTT/TranslateProject/issues/4337","number":4337,"state":"open","locked":false,"title":"翻译完成","user":{"login":"Tanete","id":5023202,"avatar_url":"https://avatars.githubusercontent.com/u/5023202?v=3","gravatar_id":"","url":"https://api.github.com/users/Tanete","html_url":"https://github.com/Tanete","followers_url":"https://api.github.com/users/Tanete/followers","following_url":"https://api.github.com/users/Tanete/following{/other_user}","gists_url":"https://api.github.com/users/Tanete/gists{/gist_id}","starred_url":"https://api.github.com/users/Tanete/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tanete/subscriptions","organizations_url":"https://api.github.com/users/Tanete/orgs","repos_url":"https://api.github.com/users/Tanete/repos","events_url":"https://api.github.com/users/Tanete/events{/privacy}","received_events_url":"https://api.github.com/users/Tanete/received_events","type":"User","site_admin":false},"body":"[Translated] 20160810 A brief introduction to Linux containers and image signing\r\n\r\nPS: 更改了文末过期内容","created_at":"2016-08-27T15:30:13Z","updated_at":"2016-08-27T15:32:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2351f8a56366cc6020dbd9a6c658b64974ff7195","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337/commits","review_comments_url":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337/comments","review_comment_url":"https://api.github.com/repos/LCTT/TranslateProject/pulls/comments{/number}","comments_url":"https://api.github.com/repos/LCTT/TranslateProject/issues/4337/comments","statuses_url":"https://api.github.com/repos/LCTT/TranslateProject/statuses/5a0add40be12d56d9ec6c154cae9871962850fdb","head":{"label":"Tanete:master","ref":"master","sha":"5a0add40be12d56d9ec6c154cae9871962850fdb","user":{"login":"Tanete","id":5023202,"avatar_url":"https://avatars.githubusercontent.com/u/5023202?v=3","gravatar_id":"","url":"https://api.github.com/users/Tanete","html_url":"https://github.com/Tanete","followers_url":"https://api.github.com/users/Tanete/followers","following_url":"https://api.github.com/users/Tanete/following{/other_user}","gists_url":"https://api.github.com/users/Tanete/gists{/gist_id}","starred_url":"https://api.github.com/users/Tanete/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tanete/subscriptions","organizations_url":"https://api.github.com/users/Tanete/orgs","repos_url":"https://api.github.com/users/Tanete/repos","events_url":"https://api.github.com/users/Tanete/events{/privacy}","received_events_url":"https://api.github.com/users/Tanete/received_events","type":"User","site_admin":false},"repo":{"id":65561009,"name":"TranslateProject","full_name":"Tanete/TranslateProject","owner":{"login":"Tanete","id":5023202,"avatar_url":"https://avatars.githubusercontent.com/u/5023202?v=3","gravatar_id":"","url":"https://api.github.com/users/Tanete","html_url":"https://github.com/Tanete","followers_url":"https://api.github.com/users/Tanete/followers","following_url":"https://api.github.com/users/Tanete/following{/other_user}","gists_url":"https://api.github.com/users/Tanete/gists{/gist_id}","starred_url":"https://api.github.com/users/Tanete/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Tanete/subscriptions","organizations_url":"https://api.github.com/users/Tanete/orgs","repos_url":"https://api.github.com/users/Tanete/repos","events_url":"https://api.github.com/users/Tanete/events{/privacy}","received_events_url":"https://api.github.com/users/Tanete/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Tanete/TranslateProject","description":"Linux中国翻译项目","fork":true,"url":"https://api.github.com/repos/Tanete/TranslateProject","forks_url":"https://api.github.com/repos/Tanete/TranslateProject/forks","keys_url":"https://api.github.com/repos/Tanete/TranslateProject/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Tanete/TranslateProject/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Tanete/TranslateProject/teams","hooks_url":"https://api.github.com/repos/Tanete/TranslateProject/hooks","issue_events_url":"https://api.github.com/repos/Tanete/TranslateProject/issues/events{/number}","events_url":"https://api.github.com/repos/Tanete/TranslateProject/events","assignees_url":"https://api.github.com/repos/Tanete/TranslateProject/assignees{/user}","branches_url":"https://api.github.com/repos/Tanete/TranslateProject/branches{/branch}","tags_url":"https://api.github.com/repos/Tanete/TranslateProject/tags","blobs_url":"https://api.github.com/repos/Tanete/TranslateProject/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Tanete/TranslateProject/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Tanete/TranslateProject/git/refs{/sha}","trees_url":"https://api.github.com/repos/Tanete/TranslateProject/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Tanete/TranslateProject/statuses/{sha}","languages_url":"https://api.github.com/repos/Tanete/TranslateProject/languages","stargazers_url":"https://api.github.com/repos/Tanete/TranslateProject/stargazers","contributors_url":"https://api.github.com/repos/Tanete/TranslateProject/contributors","subscribers_url":"https://api.github.com/repos/Tanete/TranslateProject/subscribers","subscription_url":"https://api.github.com/repos/Tanete/TranslateProject/subscription","commits_url":"https://api.github.com/repos/Tanete/TranslateProject/commits{/sha}","git_commits_url":"https://api.github.com/repos/Tanete/TranslateProject/git/commits{/sha}","comments_url":"https://api.github.com/repos/Tanete/TranslateProject/comments{/number}","issue_comment_url":"https://api.github.com/repos/Tanete/TranslateProject/issues/comments{/number}","contents_url":"https://api.github.com/repos/Tanete/TranslateProject/contents/{+path}","compare_url":"https://api.github.com/repos/Tanete/TranslateProject/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Tanete/TranslateProject/merges","archive_url":"https://api.github.com/repos/Tanete/TranslateProject/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Tanete/TranslateProject/downloads","issues_url":"https://api.github.com/repos/Tanete/TranslateProject/issues{/number}","pulls_url":"https://api.github.com/repos/Tanete/TranslateProject/pulls{/number}","milestones_url":"https://api.github.com/repos/Tanete/TranslateProject/milestones{/number}","notifications_url":"https://api.github.com/repos/Tanete/TranslateProject/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Tanete/TranslateProject/labels{/name}","releases_url":"https://api.github.com/repos/Tanete/TranslateProject/releases{/id}","deployments_url":"https://api.github.com/repos/Tanete/TranslateProject/deployments","created_at":"2016-08-12T14:52:20Z","updated_at":"2016-08-12T14:52:28Z","pushed_at":"2016-08-27T15:28:20Z","git_url":"git://github.com/Tanete/TranslateProject.git","ssh_url":"git@github.com:Tanete/TranslateProject.git","clone_url":"https://github.com/Tanete/TranslateProject.git","svn_url":"https://github.com/Tanete/TranslateProject","homepage":"http://lctt.github.io/","size":24605,"stargazers_count":0,"watchers_count":0,"language":"GCC Machine Description","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"LCTT:master","ref":"master","sha":"9151a28ee0c896ba7242380f06af2f9b3159c2cf","user":{"login":"LCTT","id":5432002,"avatar_url":"https://avatars.githubusercontent.com/u/5432002?v=3","gravatar_id":"","url":"https://api.github.com/users/LCTT","html_url":"https://github.com/LCTT","followers_url":"https://api.github.com/users/LCTT/followers","following_url":"https://api.github.com/users/LCTT/following{/other_user}","gists_url":"https://api.github.com/users/LCTT/gists{/gist_id}","starred_url":"https://api.github.com/users/LCTT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LCTT/subscriptions","organizations_url":"https://api.github.com/users/LCTT/orgs","repos_url":"https://api.github.com/users/LCTT/repos","events_url":"https://api.github.com/users/LCTT/events{/privacy}","received_events_url":"https://api.github.com/users/LCTT/received_events","type":"Organization","site_admin":false},"repo":{"id":12745174,"name":"TranslateProject","full_name":"LCTT/TranslateProject","owner":{"login":"LCTT","id":5432002,"avatar_url":"https://avatars.githubusercontent.com/u/5432002?v=3","gravatar_id":"","url":"https://api.github.com/users/LCTT","html_url":"https://github.com/LCTT","followers_url":"https://api.github.com/users/LCTT/followers","following_url":"https://api.github.com/users/LCTT/following{/other_user}","gists_url":"https://api.github.com/users/LCTT/gists{/gist_id}","starred_url":"https://api.github.com/users/LCTT/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LCTT/subscriptions","organizations_url":"https://api.github.com/users/LCTT/orgs","repos_url":"https://api.github.com/users/LCTT/repos","events_url":"https://api.github.com/users/LCTT/events{/privacy}","received_events_url":"https://api.github.com/users/LCTT/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/LCTT/TranslateProject","description":"Linux中国翻译项目","fork":false,"url":"https://api.github.com/repos/LCTT/TranslateProject","forks_url":"https://api.github.com/repos/LCTT/TranslateProject/forks","keys_url":"https://api.github.com/repos/LCTT/TranslateProject/keys{/key_id}","collaborators_url":"https://api.github.com/repos/LCTT/TranslateProject/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/LCTT/TranslateProject/teams","hooks_url":"https://api.github.com/repos/LCTT/TranslateProject/hooks","issue_events_url":"https://api.github.com/repos/LCTT/TranslateProject/issues/events{/number}","events_url":"https://api.github.com/repos/LCTT/TranslateProject/events","assignees_url":"https://api.github.com/repos/LCTT/TranslateProject/assignees{/user}","branches_url":"https://api.github.com/repos/LCTT/TranslateProject/branches{/branch}","tags_url":"https://api.github.com/repos/LCTT/TranslateProject/tags","blobs_url":"https://api.github.com/repos/LCTT/TranslateProject/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/LCTT/TranslateProject/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/LCTT/TranslateProject/git/refs{/sha}","trees_url":"https://api.github.com/repos/LCTT/TranslateProject/git/trees{/sha}","statuses_url":"https://api.github.com/repos/LCTT/TranslateProject/statuses/{sha}","languages_url":"https://api.github.com/repos/LCTT/TranslateProject/languages","stargazers_url":"https://api.github.com/repos/LCTT/TranslateProject/stargazers","contributors_url":"https://api.github.com/repos/LCTT/TranslateProject/contributors","subscribers_url":"https://api.github.com/repos/LCTT/TranslateProject/subscribers","subscription_url":"https://api.github.com/repos/LCTT/TranslateProject/subscription","commits_url":"https://api.github.com/repos/LCTT/TranslateProject/commits{/sha}","git_commits_url":"https://api.github.com/repos/LCTT/TranslateProject/git/commits{/sha}","comments_url":"https://api.github.com/repos/LCTT/TranslateProject/comments{/number}","issue_comment_url":"https://api.github.com/repos/LCTT/TranslateProject/issues/comments{/number}","contents_url":"https://api.github.com/repos/LCTT/TranslateProject/contents/{+path}","compare_url":"https://api.github.com/repos/LCTT/TranslateProject/compare/{base}...{head}","merges_url":"https://api.github.com/repos/LCTT/TranslateProject/merges","archive_url":"https://api.github.com/repos/LCTT/TranslateProject/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/LCTT/TranslateProject/downloads","issues_url":"https://api.github.com/repos/LCTT/TranslateProject/issues{/number}","pulls_url":"https://api.github.com/repos/LCTT/TranslateProject/pulls{/number}","milestones_url":"https://api.github.com/repos/LCTT/TranslateProject/milestones{/number}","notifications_url":"https://api.github.com/repos/LCTT/TranslateProject/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/LCTT/TranslateProject/labels{/name}","releases_url":"https://api.github.com/repos/LCTT/TranslateProject/releases{/id}","deployments_url":"https://api.github.com/repos/LCTT/TranslateProject/deployments","created_at":"2013-09-11T01:54:15Z","updated_at":"2016-08-27T03:21:50Z","pushed_at":"2016-08-27T15:30:14Z","git_url":"git://github.com/LCTT/TranslateProject.git","ssh_url":"git@github.com:LCTT/TranslateProject.git","clone_url":"https://github.com/LCTT/TranslateProject.git","svn_url":"https://github.com/LCTT/TranslateProject","homepage":"http://lctt.github.io/","size":28308,"stargazers_count":472,"watchers_count":472,"language":"GCC Machine Description","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":376,"mirror_url":null,"open_issues_count":1,"forks":376,"open_issues":1,"watchers":472,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337"},"html":{"href":"https://github.com/LCTT/TranslateProject/pull/4337"},"issue":{"href":"https://api.github.com/repos/LCTT/TranslateProject/issues/4337"},"comments":{"href":"https://api.github.com/repos/LCTT/TranslateProject/issues/4337/comments"},"review_comments":{"href":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337/comments"},"review_comment":{"href":"https://api.github.com/repos/LCTT/TranslateProject/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/LCTT/TranslateProject/pulls/4337/commits"},"statuses":{"href":"https://api.github.com/repos/LCTT/TranslateProject/statuses/5a0add40be12d56d9ec6c154cae9871962850fdb"}}}}
{"actor":{"display_login":"Tanete"}}