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-05: add translation doc #66 #105

Closed
wants to merge 1 commit into from
Closed
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
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的优先级,反之亦然。
- 在容器的端点预创建阶段,你可以返回端点的优先级和该端点是否需要激活分解器以及该端点的通用参数。