四时宝库

程序员的知识宝库

Docker容器操作其他容器(docker容器调用其他容器命令)

需求:

后端服务可以随时备份mysql容器的数据库。以下以oa-mysql作为mysql容器名,数据库名称以oa举例示范。

正常直接备份数据库,使用mysqldump,如:

mysqldump -u  ${user} -p${dbpwd} --lock-all-tables --databases oa > oa.sql

宿主机部署服务,通过宿主机服务操作其他容器

该方式需要写一个assist助手服务,通过助手服务去备份数据库。

docker exec -i oa-mysql mysqldump -u  ${user} -p${dbpwd} --lock-all-tables --databases oa> oa.sql

容器通过调用宿主机命令,直接操作其他容器

该种方式可参考,《Docker容器内执行宿主机指令》文章。

nsenter -m -u -i -n -p -t 1 docker exec -i oa-mysql mysqldump -u  ${user} -p${dbpwd} --lock-all-tables --databases oa> oa.sql

通过docker api

该种方式直接使用docker官方提供的api。相信知道docker提供http api的同学并不多,docker官方宣传的也少。其实docker 提供很多api,宿主机上面能直接操作的docker命令,通过api基本都能操作。

官方文档:Develop with Docker Engine API

golang代码示例

// Path: pkg/docker
// FileName: api.go
// Author: GJing
// Date: 2023/6/9$ 18:24$

package docker

import (
    "context"
    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

var dockerClient *client.Client

func Init() {
    c, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
    if err != nil {

    }
    dockerClient = c
    return
}

// Exec
// @Description docker容器内执行命令
// @params
// @contact.name GJing
// @contact.email gjing1st@gmail.com
// @date 2023/6/9 18:35
func Exec(cId string, cmd []string) {
    ctx := context.Background()

    execResp, err := dockerClient.ContainerExecCreate(ctx, cId,
       types.ExecConfig{
          AttachStdin:  true,
          AttachStdout: true,
          //Cmd:          []string{"sh", "-c", "mysqldump -u root -p123456 test > /home/test.sql\n"},
          Cmd: cmd,
       },
    )
    if err != nil {

    }
    resp, err := dockerClient.ContainerExecAttach(ctx, execResp.ID,
       types.ExecStartCheck{
          Detach: false,
          Tty:    false,
       },
    )
    if err != nil {
       return
    }
    defer resp.Close()
}

// ContainerList
// @Description 容器列表
// @params
// @contact.name GJing
// @contact.email gjing1st@gmail.com
// @date 2023/6/16 11:15
func ContainerList() (list []types.Container, err error) {
    list, err = dockerClient.ContainerList(context.Background(), types.ContainerListOptions{})
    if err != nil {

    }
    //for _, v := range list {
    // fmt.Println(v.Image)
    //}
    return
}

// ContainExec
// @Description 在容器中执行命令
// @params containName容器名,在该容器中执行cmdStr命令
// @params cmdStr linux指令
// @contact.name GJing
// @contact.email gjing1st@gmail.com
// @date 2023/6/16 10:57
func ContainExec(containName string, cmdStr []string) (err error) {
    Init()
    list, err1 := ContainerList()
    if err1 != nil {
       return err1
    }
    containId := ""
    for _, v := range list {
       if len(v.Names) > 0 && v.Names[0] == "/"+containName {
          containId = v.ID
       }
    }
    Exec(containId, cmdStr)
    return
}

调用的地方:

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接