這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
exec.Executor interface
定義(位於agent/exec/executor.go
):
// Executor provides controllers for tasks.type Executor interface { // Describe returns the underlying node description. Describe(ctx context.Context) (*api.NodeDescription, error) // Configure uses the node object state to propagate node // state to the underlying executor. Configure(ctx context.Context, node *api.Node) error // Controller provides a controller for the given task. Controller(t *api.Task) (Controller, error) // SetNetworkBootstrapKeys passes the symmetric keys from the // manager to the executor. SetNetworkBootstrapKeys([]*api.EncryptionKey) error}
container Package
實現了executor
結構體(位於agent/exec/container/executor.go
):
import engineapi "github.com/docker/engine-api/client"type executor struct { client engineapi.APIClient}
裡面只有一個成員:一個Docker APIClient
。executor
結構體實際只實現了下面兩個方法:
// Describe returns the underlying node description from the docker client.func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) { info, err := e.client.Info(ctx) if err != nil { return nil, err } plugins := map[api.PluginDescription]struct{}{} addPlugins := func(typ string, names []string) { for _, name := range names { plugins[api.PluginDescription{ Type: typ, Name: name, }] = struct{}{} } } addPlugins("Volume", info.Plugins.Volume) // Add builtin driver "overlay" (the only builtin multi-host driver) to // the plugin list by default. addPlugins("Network", append([]string{"overlay"}, info.Plugins.Network...)) addPlugins("Authorization", info.Plugins.Authorization) pluginFields := make([]api.PluginDescription, 0, len(plugins)) for k := range plugins { pluginFields = append(pluginFields, k) } sort.Sort(sortedPlugins(pluginFields)) // parse []string labels into a map[string]string labels := map[string]string{} for _, l := range info.Labels { stringSlice := strings.SplitN(l, "=", 2) // this will take the last value in the list for a given key // ideally, one shouldn't assign multiple values to the same key if len(stringSlice) > 1 { labels[stringSlice[0]] = stringSlice[1] } } description := &api.NodeDescription{ Hostname: info.Name, Platform: &api.Platform{ Architecture: info.Architecture, OS: info.OSType, }, Engine: &api.EngineDescription{ EngineVersion: info.ServerVersion, Labels: labels, Plugins: pluginFields, }, Resources: &api.Resources{ NanoCPUs: int64(info.NCPU) * 1e9, MemoryBytes: info.MemTotal, }, } return description, nil}// Controller returns a docker container controller.func (e *executor) Controller(t *api.Task) (exec.Controller, error) { ctlr, err := newController(e.client, t) if err != nil { return nil, err } return ctlr, nil}
Describe()
方法返回當前Docker engine
的資源配置資訊,而Controller()
則返回一個container.controller
結構體。
其中關於client
的初始化位於:
client, err := engineapi.NewClient(engineAddr, "", nil, nil) if err != nil { return err } executor := container.NewExecutor(client)
如果沒有對engineAddr
做特殊設定,就會使用其預設值:unix:///var/run/docker.sock
。client
值預設如下:
(dlv) p client*github.com/docker/swarmkit/vendor/github.com/docker/engine-api/client.Client { proto: "unix", addr: "/var/run/docker.sock", basePath: "", transport: (unreadable interface type "*transport.apiTransport" not found for 0xc8202ecbd8: no type entry found, use 'types' for a list of valid types), version: "", customHTTPHeaders: map[string]string [],}