Docker容器操作其他容器

2024-08-30 11:27:12 浏览数 (1)

需求:

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

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

代码语言:javascript复制
mysqldump -u  ${user} -p${dbpwd} --lock-all-tables --databases oa > oa.sql
  1. 宿主机部署服务,通过宿主机服务操作其他容器

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

代码语言:javascript复制
docker exec -i oa-mysql mysqldump -u  ${user} -p${dbpwd} --lock-all-tables --databases oa> oa.sql
代码语言:javascript复制
  1. 容器通过调用宿主机命令,直接操作其他容器

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

代码语言:javascript复制
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
代码语言:javascript复制
  1. 通过docker api

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

官方文档:Develop with Docker Engine API

golang代码示例

代码语言:javascript复制
// Path: pkg/docker
// FileName: api.go
// Created by dkedTeam
// 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.sqln"},
      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
}
代码语言:javascript复制

调用的地方:

0 人点赞