Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

266期7组翻译 #79

Merged
merged 2 commits into from
Aug 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions blog-cn/富容器技术.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# 富容器技术

当容器化应用程序时,富容器是一种非常有用的容器模式。此模式可帮助技术人员几乎毫不费力地打包粗壮应用程序。它提供了有效的方法来装备更多基本软件或系统服务除了目标应用程序在单个容器中。然后,容器中的应用程序可以像通常在虚拟机或物理机中一样平滑运行。这是一种更通用的以应用程序为中心的模式,该模式对开发人员和运营商都没有任何侵略性。特别是对于运营商而言,他们可以像往常一样使用他们可能需要的所有必要工具或服务流程来维护容器中的应用程序。

PouchContainer 提供的富容器模式不是默认模式。拓展用户的容器体验是 PouchContainer 带来的一种额外模式。用户仍然可以通过关闭富容器标志来管理普通容器。

总之,富容器可以帮助企业实现以下两个目标:

* 与传统操作系统兼容;
* 仍然利用镜像概念的优势来加快应用程序交互。

## 脚本

容器技术和编排平台现在变得非常流行。它们都为应用程序提供了更好的环境。尽管如此,我们不得不说容器化是企业采用容器相关技术的第一步,例如容器,编排,服务网等。将传统应用程序转移到容器中是一个非常实际的问题。虽然一些简单的应用程序总是对容器显示友好,但更传统和复杂的企业应用程序可能不那么幸运。这些传统应用程序通常与底层基础架构相耦合,例如机器架构,旧内核,甚至某些软件也不需要维护。当然,强耦合不是每个人的菜。它是企业数字化转型之路的发起者。因此,所有行业都在寻求一种可行的方法来解决这个问题。 docker提供的方式是一种,但不是最好的。在过去的7年里,阿里巴巴也遇到了同样的问题。幸运的是,富容器模式是一种更好的处理方式。

开发人员有自己的编程风格。他们的工作是创建有用的应用程序,而不是设计绝对解耦的应用程序,因此他们通常利用工具或系统服务来实现它。当容器化这些应用程序时,如果仅在容器中设置一个应用程序一个进程,则相当薄弱。富容器模式找出了使用户在容器中配置进程的内部启动顺序的方法,包括应用程序和系统服务。

运营商富有保护应用程序正常运行的神圣职责。为了使业务在应用程序中运行,技术必须充分尊重运营商的传统。在线调试和解决问题时,环境变化不是一个好消息。富容器模式可以确保富容器中的环境与传统VM或物理机中的环境完全相同。如果操作员需要一些系统工具,它们仍然定位于那里。如果某些前后挂钩应该生效,只需在启动富容器时设置它们即可。 如果内部发生了一些问题,富容器启动的系统服务可以像自我修复一样修复它们。

## 架构

富容器模式与运营团队的传统操作方式兼容。 以下架构图显示了如何实现:

![pouch_with_rich_container](https://github.com/alibaba/pouch/blob/master/docs/static_files/pouch_with_rich_container.png)

更详细的说,富容器承诺与oci适配镜像兼容。在运行富容器时,pouchd 会将镜像文件系统作为富容器本身的根文件系统。在内部容器的运行时,除了内部应用程序和系统服务之外,还有一些hook如prestart hook 和 poststop hook。前者重点在于如何在 systmed 和相关进程运行之前准备或初始化环境。后者主要是当容器停止时进行清理工作。

## 启动

用户可以很容易地在 PouchContainer 中启动富容器模式。 如果我们需要通过 PouchContainer 在富容器模式下运行普通镜像,我们可以添加两个标志:`--rich`,`--rich-mode`和 `--initscript`。 以下是关于这两个标志的更多描述:

* `--rich`:标识是否打开富容器模式。此标志的类型为`boolean`,默认值为`false`。

* `--rich-mode`:选择初始化容器的方式,当前支持 systemd,/ sbin / init 和 dumb-init 的方式。默认情况下是 dumb-init。

* `--initscript`:标识在容器中执行的初始脚本。该脚本将在入口点或命令之前执行。有时,它被称为 prestart hook。在 prestart hook 中可以做很多工作,例如环境检查,环境准备,网络路由准备,各种代理设置,安全设置等。如果 pouchd 无法在由从镜像和实际位于容器外部的潜在挂载卷提供的容器文件系统中找到此 initscript 标志,则该脚本可能会失败并且用户会收到相关的错误消息。如果 initscript 正常工作,容器进程的控制将由进程 pid 1接管,主要是`/ sbin / init`或`dumbinit`。



事实上,PouchContainer 团队计划添加另一个标志`--initcmd`以使用户输入 prestart hook。实际上它是`--initscript`的简化版。同时它比`--initscript`更便捷。 `--initcmd`可以根据用户的意愿设置任何命令,并且不需要事先将其放置在镜像中。可以说实现了命令与镜像解耦。但是对于`--initscript`,脚本文件必须首先位于镜像中,这是某种耦合。

如果用户指定`--rich`标志并且未提供`--initscript`标志,则仍将启用富容器模式,但不会执行initscript。 如果`--rich`标志在命令行中丢失,而`--initscript`存在,PouchContainer CLI 或Pouchd 将返回错误以显示`--initscipt`只能与`--rich`标志一起使用。

如果容器正在运行`--rich`标志,那么每次启动或重启此容器都会触发相应的 initscipt。

### 使用 dumb-init

以下是富容器模式的使用 dumb-init 来初始化容器的简单示例:

1.按如下步骤安装 dumb-init:

```shell
# wget -O /usr/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v1.2.1/dumb-init_1.2.1_amd64
# chmod +x /usr/bin/dumb-init
```

2.运行富模式的容器:

```shell
#pouch run -d --rich --rich-mode dumb-init registry.hub.docker.com/library/busybox:latest sleep 10000
f76ac1e49e9407caf5ad33c8988b44ff3690c12aa98f7faf690545b16f2a5cbd

#pouch exec f76ac1e49e9407caf5ad33c8988b44ff3690c12aa98f7faf690545b16f2a5cbd ps -ef
PID USER TIME COMMAND
1 root 0:00 /usr/bin/dumb-init -- sleep 10000
7 root 0:00 sleep 10000
8 root 0:00 ps -ef
```

### 使用 systemd 或 sbin-init

为了使用systemd或/ sbin / init初始化容器,请确保将它们安装在镜像文件上。

如下图所示,centos镜像两者都有。

此外,在这种情况下需要`--privileged` 。 systemd 和 sbin-init的示例如下:

```
#cat /tmp/1.sh
#! /bin/sh
echo $(cat) >/tmp/xxx

#pouch run -d -v /tmp:/tmp --privileged --rich --rich-mode systemd --initscript /tmp/1.sh registry.hub.docker.com/library/centos:latest /usr/bin/sleep 10000
3054125e44443fd5ee9190ee49bbca0a842724f5305cb05df49f84fd7c901d63

#pouch exec 3054125e44443fd5ee9190ee49bbca0a842724f5305cb05df49f84fd7c901d63 ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 7.4 0.0 42968 3264 ? Ss 05:29 0:00 /usr/lib/systemd/systemd
root 17 0.0 0.0 10752 756 ? Ss 05:29 0:00 /usr/lib/systemd/systemd-readahead collect
root 18 3.2 0.0 32740 2908 ? Ss 05:29 0:00 /usr/lib/systemd/systemd-journald
root 34 0.0 0.0 22084 1456 ? Ss 05:29 0:00 /usr/lib/systemd/systemd-logind
root 36 0.0 0.0 7724 608 ? Ss 05:29 0:00 /usr/bin/sleep 10000
dbus 37 0.0 0.0 24288 1604 ? Ss 05:29 0:00 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root 45 0.0 0.0 47452 1676 ? Rs 05:29 0:00 ps aux

#cat /tmp/xxx
{"ociVersion":"1.0.0","id":"3054125e44443fd5ee9190ee49bbca0a842724f5305cb05df49f84fd7c901d63","status":"","pid":125745,"bundle":"/var/lib/pouch/containerd/state/io.containerd.runtime.v1.linux/default/3054125e44443fd5ee9190ee49bbca0a842724f5305cb05df49f84fd7c901d63"}

#pouch run -d -v /tmp:/tmp --privileged --rich --rich-mode sbin-init --initscript /tmp/1.sh registry.hub.docker.com/library/centos:latest /usr/bin/sleep 10000
c5b5eef81749ce00fb68a59ee623777bfecc8e07c617c0601cc56e4ae8b1e69f

#pouch exec c5b5eef81749ce00fb68a59ee623777bfecc8e07c617c0601cc56e4ae8b1e69f ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 7.4 0.0 42968 3260 ? Ss 05:30 0:00 /sbin/init
root 17 0.0 0.0 10752 752 ? Ss 05:30 0:00 /usr/lib/systemd/systemd-readahead collect
root 20 3.2 0.0 32740 2952 ? Ss 05:30 0:00 /usr/lib/systemd/systemd-journald
root 34 0.0 0.0 22084 1452 ? Ss 05:30 0:00 /usr/lib/systemd/systemd-logind
root 35 0.0 0.0 7724 612 ? Ss 05:30 0:00 /usr/bin/sleep 10000
dbus 36 0.0 0.0 24288 1608 ? Ss 05:30 0:00 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root 45 0.0 0.0 47452 1676 ? Rs 05:30 0:00 ps aux

#cat /tmp/xxx
{"ociVersion":"1.0.0","id":"c5b5eef81749ce00fb68a59ee623777bfecc8e07c617c0601cc56e4ae8b1e69f","status":"","pid":127183,"bundle":"/var/lib/pouch/containerd/state/io.containerd.runtime.v1.linux/default/c5b5eef81749ce00fb68a59ee623777bfecc8e07c617c0601cc56e4ae8b1e69f"}
```

## 底层实现

在学习底层实现之前,我们将简要回顾一下`systemd`,`entrypoint`和`cmd`。 另外,prestart hook 由runC 执行。

### systemd,entrypoint 和 cmd

待补充。

### initscript 和 runC

`initscript`将被添加。

`runc`是一个CLI工具,用于根据OCI规范生成和运行容器。



Loading