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

BJ266-Group5: Add blog & translation for PouchContainer #22 #66,and fix typo #75

Closed
wants to merge 11 commits into from
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# 介绍
PouchContainer 是高效的、轻量级企业级容器引擎技术,拥有隔离性强、可移植性高、资源占用少等特性。它目前仅支持Linux操作系统,故需要使用虚拟机进行本地运行和测试。本篇指南将指导读者在Mac或Windows上搭建基于VirtualBox + Ubuntu16.04的PouchContainer环境。

# VirtualBox的安装
__1、可以从以下方式中选择其一进行安装:__
* 阿里郎-管家-办公软件管理中搜索VirtualBox,下载并安装。
* 从[https://download.virtualbox.org/virtualbox/5.2.16/VirtualBox-5.2.16-123759-OSX.dmg](https://download.virtualbox.org/virtualbox/5.2.16/VirtualBox-5.2.16-123759-OSX.dmg) 下载安装包,下载并安装

__2、下载完成后,双击VirtualBox.pkg,然后点击“继续”进入安装__

![image.png | left | 506x337](https://cdn.nlark.com/lark/0/2018/png/135654/1532951526444-e74b8693-7e36-40f9-b1da-84d4658d0389.png "")

__3、自定义安装__

![image.png | left | 502x334](https://cdn.nlark.com/lark/0/2018/png/135654/1532951637319-dd1a8547-4c4c-4db1-91cd-4fb9ec386d93.png "")

# VirtualBox的配置
1、__打开VirtualBox,选择"新建",新建虚拟机__

![image.png | left | 236x61](https://cdn.nlark.com/lark/0/2018/png/124199/1532951984471-9dc5e69b-04d6-4ca3-acfe-cb33341445c4.png "")

__2、设置新建虚拟电脑的名称和系统类型__
* 名称-自定义
* 类型-Linux
* 版本-Ubuntu(64-bit)

![image.png | left | 498x449](https://cdn.nlark.com/lark/0/2018/png/124199/1532952147747-22a62b89-a974-4e25-a835-1327ba455f78.png "")

__3、设置内存大小,可以选择默认大小(1024MB),点击“继续”__

![image.png | left | 497x438](https://cdn.nlark.com/lark/0/2018/png/124199/1532952488126-781dcfd5-521e-46cb-88b0-fe55ddc6c2de.png "")

__4、虚拟硬盘选择:__
* 选择“使用已有的虚拟硬盘文件”,点击选择文件(选择ubuntuPouch.vdi,此Ubuntu已安装PouchContainer),点击“创建”。
* 如果没有这样的文件。点击“现在创建虚拟硬盘”,自行配置系统并手动[安装PouchContainer](https://github.com/alibaba/pouch/blob/master/INSTALLATION.md)。

![image.png | left | 493x430](https://cdn.nlark.com/lark/0/2018/png/124199/1532965407472-70a22b38-dfbb-4598-97ce-f2188ad7bd5d.png "")

# 启动虚拟机并登录pouch
__1、点击“启动”,输入初始的用户名和密码__
```
用户名:pouch
密 码:123456
```

__2、切换到root权限__
```
sudo -i
```

__3、检查网络__
```
ping www.alibaba-inc.com
```

__4、启动pouch服务(默认开机启动)__
```
systemctl start pouch # 如果有问题,请确认网络连接正确
```

__5、启动一个已经存在的busybox基础容器__
```
pouch run -t -d busybox sh
```

__6、如果您没有busybox,可以pull__
```
pouch pull busybox
```

__7、登录到启动的容器中,其中{ID}是启动命令输出的完整ID中的前六位__
```
pouch exec -it {ID} sh
```
操作成功后如图所示:

![image.png | left | 747x113](https://camo.githubusercontent.com/91f9a4433d2cdbf34b4f3469d4e80c2bd21cfa0a/68747470733a2f2f63646e2e6e6c61726b2e636f6d2f6c61726b2f302f323031382f706e672f3132313937312f313533323335323136373137312d33313637633962362d396234392d343639382d623035362d6532363037336536343331322e706e67 "")

# Mac终端连接到virtualbox虚拟机
使用virtualbox创建虚拟机进行工作,可以有效减少本机环境与工作环境之间的相互影响。但由于Server虚拟机的界面不友好,因而使用SSH连接到虚拟机,使用本地终端编辑是一个非常好的选择。

__1、端口转发__

点击“设置”-“网络”-“高级”-“端口转发”

![image.png | left | 558x389](https://cdn.nlark.com/lark/0/2018/png/135654/1532955458851-bc1c46ed-1ad9-4714-8d4c-1a2deb83f5ec.png "")

点击红框中的icon,设置主机端口**9022**,子系统端口**22**,保存。

![image.png | left | 550x397](https://cdn.nlark.com/lark/0/2018/png/135654/1532955772003-e4dba259-6dae-46bf-96a8-bc9c38f10115.png "")

__2、本机终端连接__

在终端输入
```
$ ssh -p 9022 [email protected]
```
或者
```
$ ssh -p 9022 username@localhost
```
连接成功效果如图所示:

![image.png | left | 747x352](https://cdn.nlark.com/lark/0/2018/png/135654/1532956235912-f6789f20-c0e8-4758-8f5e-a76fea5b61b7.png "")

至此,您已完成环境搭建,并且可以用终端操作,尽情享受PouchContainer吧!

75 changes: 75 additions & 0 deletions blog-cn/带prometheus的pouch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Prometheus加持的PouchContainer

`PouchContainer`通过`Prometheus`支持多种监测指标。我们现在已经有了基本的`golang`的运行环境和一些api延时指标。我们将在以下两个主要领域中增加更多的评测指标:
* 重要的`pouchd`评测指标
* 重要的api延时评测指标列表

## 如何增加新评测指标

我们倾向于在`PouchContainer`使用`prometheus`的[评测指标和标签命名约定](https://prometheus.io/docs/practices/naming/)。因此,当你要添加新的评测指标时,请遵循`prometheus`的评测指标和标签命名约定。

我们使用`promethus` 的[go-sdk](https://github.com/prometheus/client_golang) 去监测`pouchd`。它支持计数器、计量和概要等度量指标。请参考 [指标类型](https://prometheus.io/docs/concepts/metric_types/) 以获得更多信息。

## 如何使用

用户可通过`pouchd -l tcp://0.0.0.0:4243`指令启动`pouchd`来监听`0.0.0.0:4243`,然后发出`GET http://127.0.0.1:4243/metrics`请求以获取`prometheus`格式的评测指标的完整列表,具体如下:

```
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0.000111176
go_gc_duration_seconds{quantile="0.25"} 0.000198062
go_gc_duration_seconds{quantile="0.5"} 0.000269599
go_gc_duration_seconds{quantile="0.75"} 0.000474291
go_gc_duration_seconds{quantile="1"} 0.002013351
go_gc_duration_seconds_sum 0.021835193
go_gc_duration_seconds_count 52
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 22
# HELP go_info Information about the Go environment.
# TYPE go_info gauge
go_info{version="go1.9"} 1
...
# HELP http_request_size_bytes The HTTP request sizes in bytes.
# TYPE http_request_size_bytes summary
http_request_size_bytes{handler="prometheus",quantile="0.5"} NaN
http_request_size_bytes{handler="prometheus",quantile="0.9"} NaN
http_request_size_bytes{handler="prometheus",quantile="0.99"} NaN
http_request_size_bytes_sum{handler="prometheus"} 0
http_request_size_bytes_count{handler="prometheus"} 0
# HELP http_response_size_bytes The HTTP response sizes in bytes.
# TYPE http_response_size_bytes summary
http_response_size_bytes{handler="prometheus",quantile="0.5"} NaN
http_response_size_bytes{handler="prometheus",quantile="0.9"} NaN
http_response_size_bytes{handler="prometheus",quantile="0.99"} NaN
http_response_size_bytes_sum{handler="prometheus"} 0
http_response_size_bytes_count{handler="prometheus"} 0
# HELP pouch_image_pull_latency_microseconds Latency in microseconds to pull a image.
# TYPE pouch_image_pull_latency_microseconds summary
pouch_image_pull_latency_microseconds{image="docker.io/library/ubuntu:latest",quantile="0.5"} 3.7803132e+07
pouch_image_pull_latency_microseconds{image="docker.io/library/ubuntu:latest",quantile="0.9"} 3.7803132e+07
pouch_image_pull_latency_microseconds{image="docker.io/library/ubuntu:latest",quantile="0.99"} 3.7803132e+07
pouch_image_pull_latency_microseconds_sum{image="docker.io/library/ubuntu:latest"} 3.7803132e+07
pouch_image_pull_latency_microseconds_count{image="docker.io/library/ubuntu:latest"} 1
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 4.78
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1024
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 9
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 3.4521088e+07
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.51064406778e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 4.91610112e+08
```

这样,我们可以在`prometheus`中设置新目标以获得评价指标在每轮迭代中的取值。
147 changes: 147 additions & 0 deletions blog-cn/带插件的pouch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# 带插件的PouchContainer

为了让用户运行自定义代码,`golang 1.8`支持引入插件框架。在插件框架中,我们支持用户在以下阶段添加自定义代码:

- 预启动守护阶段
- 预停止守护阶段
- 预创建容器阶段
- 预启动容器阶段
- 预创建端点容器阶段

以上5个阶段点由`DaemonPlugin`和`ContainerPlugin`组织,两个插件定义如下:

```
// DaemonPlugin defines in which place does pouchd support plugin
type DaemonPlugin interface {
// PreStartHook is invoked by pouchd before real start, in this hook user could start dfget proxy or other
// standalone process plugins
PreStartHook() error

// PreStopHook is invoked by pouchd before daemon process exit, not a promise if daemon is killed, in this
// hook user could stop the process or plugin started by PreStartHook
PreStopHook() error
}

// ContainerPlugin defines places where a plugin will be triggered in container lifecycle
type ContainerPlugin interface {
// PreCreate defines plugin point where receives an container create request, in this plugin point user
// could change the container create body passed-in by http request body
PreCreate(io.ReadCloser) (io.ReadCloser, error)

// PreStart returns an array of priority and args which will pass to runc, the every priority
// used to sort the pre start array that pass to runc, network plugin hook always has priority value 0.
PreStart(interface{}) ([]int, [][]string, error)

//NetworkGenericParams accepts the container id and env of this container and returns the priority of this endpoint
// and if this endpoint should enable resolver and a map which will be used as generic params to create endpoints of
// this container
PreCreateEndpoint(string, []string) (priority int, disableResolver bool, genericParam map[string]interface{})
}
```

这两个插件符号将通过名称`DaemonPlugin`和`ContainerPlugin`从共享对象文件中获取,如下所示:

```
p, _ := plugin.Open("path_to_shared_object_file")
daemonPlugin, _ := p.Lookup("DaemonPlugin")
containerPlugin, _ := p.Lookup("ContainerPlugin")
```

## 范例

定义两个在对应阶段打印日志的插件符号:

```
package main

import (
"fmt"
"io"
)

var ContainerPlugin ContPlugin

type ContPlugin int

var DaemonPlugin DPlugin

type DPlugin int

func (d DPlugin) PreStartHook() error {
fmt.Println("pre-start hook in daemon is called")
return nil
}

func (d DPlugin) PreStopHook() error {
fmt.Println("pre-stop hook in daemon is called")
return nil
}

func (c ContPlugin) PreCreate(in io.ReadCloser) (io.ReadCloser, error) {
fmt.Println("pre create method called")
return in, nil
}

func (c ContPlugin) PreStart(interface{}) ([]int, [][]string, error) {
fmt.Println("pre start method called")
// make this pre-start hook run after network in container setup
return []int{-4}, [][]string{{"/usr/bin/touch", "touch", "/tmp/pre_start_hook"}}, nil
}

func (c ContPlugin) PreCreateEndpoint(string, []string) (priority int, disableResolver bool, genericParam map[string]interface{}) {
fmt.Println("pre create endpoint")
return
}

func main() {
fmt.Println(ContainerPlugin, DaemonPlugin)
}
```

用如下命令行生成:

```
go build -buildmode=plugin -ldflags "-pluginpath=plugins_$(date +%s)" -o hook_plugin.so
```

要使用生成的共享对象文件,启动`--plugin = path_to_hook_plugin.so` flag 的 pouchd,然后当你启动停止守护进程并创建容器时,在日志中会有如下日志:

```
pre-start hook in daemon is called
pre create method called
pre-stop hook in daemon is called
```

当你启动一个容器时,config.json文件(其地址为$ home_dir / containerd / state / io.containerd.runtime.v1.linux / default / $ container_id / config.json)将包含以上代码中定义的预启动挂钩,例如:

```
"hooks": {
"prestart": [
{
"args": [
"libnetwork-setkey",
"f67df14e96fa4b94a6e386d0795bdd2703ca7b01713d48c9567203a37b05ae3d",
"8e3d8db7f72a66edee99d4db6ab911f8d618af057485731e9acf24b3668e25b6"
],
"path": "/usr/local/bin/pouchd"
},
{
"args": [
"touch",
"/tmp/pre_start_hook"
],
"path": "/usr/bin/touch"
}
]
}
```

如果你使用如上代码,每当你启动容器,路径`/tmp/pre_start_hook`下的文件将被调用。

## 使用

- 在预启动守护程序阶段,您可以启动协助过程,如网络插件和dfget代理,其需要pouchd,并且其生命周期与pouchd相同。
- 在预停止守护程序阶段,你可以优雅地停止辅助进程,但这并不是实时有效,因为可能会被SIGKILL杀死。
- 在容器的预创建阶段,你可以根据一些规则改变输入流,在一些公司里面他们会有过时的编排系统,其用环境变量来传递一些限制条件,这些环境变量是pouchContainer中的属性。你可以在预创建阶段将环境变量的值转换成PouchContainer create Api中用到的ContainerConfig或者HostConfig的属性。
- 在容器的预开始阶段,你可以设置更多针对oci规格的钩子,你可以在入口启动开始前做一些特殊的事情,也可以针对钩子运行的顺序设置优先级。libnetwork的优先级是0,所以如果你期望它在容器启动阶段时先于network运行,你就该给它设一个大于0的优先级,反之亦然。
- 在容器的端点预创建阶段,你可以返回端点的优先级和该端点是否需要激活分解器以及该端点的通用参数。
Loading