Docker容器的生命周期管理

通过docker的API或者docker event命令,我们都可以获取到容器生命周期内发生了那些事情。首先把结论放出来,然后在看实现过程。
这里写图片描述
这个是实验的结论,那我怎么获取到这些状态和事件的呢?很简单,就是通过上面的api watch。
通过docker go client很容易实现

func (w *watcher) watch() {
    filters := filters.NewArgs()
    filters.Add("type", "container")

    options := types.EventsOptions{
        Since:   fmt.Sprintf("%d", w.lastValidTimestamp),
        Filters: filters,
    }

    for {
        events, errors := w.client.Events(w.ctx, options)

    WATCH:
        for {
            select {
            case event := <-events:
            fmt.Printf("get event %v action %v \n",event.Actor.Attributes["name"],event.Action)
                logp.Debug("docker", "Got a new docker event: %v", event)
                w.lastValidTimestamp = event.Time

                // Add / update
                if event.Action == "create" || event.Action == "update" {
                    name := event.Actor.Attributes["name"]
                    image := event.Actor.Attributes["image"]
                    delete(event.Actor.Attributes, "name")
                    delete(event.Actor.Attributes, "image")
                    container := &Container{
                        ID:     event.Actor.ID,
                        Name:   name,
                        Image:  image,
                        Labels: event.Actor.Attributes,
                        Env:    make(map[string]string),
                    }
                    info, err := w.client.ContainerInspect(w.ctx, event.Actor.ID)
                    if err == nil {
                        for _, env := range info.Config.Env {
                            kv := strings.SplitN(env, "=", 2)
                            if len(kv) >= 2 {
                                container.Env[kv[0]] = kv[1]
                            }
                        }
                    }
                    w.containers[container.ID] = container
                    w.containers[container.Name] = container
                }

                // Delete
                if event.Action == "die" || event.Action == "kill" {
                    delete(w.containers, event.Actor.ID)
                    delete(w.containers, event.Actor.Attributes["name"])
                }

            case err := <-errors:
                // Restart watch call
                logp.Err("Error watching for docker events: %v", err)
                time.Sleep(1 * time.Second)
                break WATCH

            case <-w.ctx.Done():
                logp.Debug("docker", "Watcher stopped")
                return
            }
        }
    }
}

这样当我们操作docker上的时候就能顺利的获取到它的状态,譬如一次docker run操作,

get event big_meninsky action create 
get event big_meninsky action start

相应的一次stop操作就可以获取到

get event big_meninsky action kill 
get event big_meninsky action kill 
get event big_meninsky action die 
get event big_meninsky action stop 

这里有个很有意思的事,就是怎么会有两次kill操作呢!那是因为,docker stop命令的玩法

docker stop: Stop a running container (send SIGTERM, and then SIGKILL after grace period)

就是先发现TERM信号(为了让容器优雅关闭),再发送KILL信号。所以收到两次kill event命令。这个和kill最大的区别,它是直接发送KILL信号,所以不会有两次kill event。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳清风09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值