需求:
后端服务可以随时备份mysql容器的数据库。以下以oa-mysql作为mysql容器名,数据库名称以oa举例示范。
正常直接备份数据库,使用mysqldump,如:
代码语言:javascript复制mysqldump -u ${user} -p${dbpwd} --lock-all-tables --databases oa > oa.sql
- 宿主机部署服务,通过宿主机服务操作其他容器
该方式需要写一个assist助手服务,通过助手服务去备份数据库。
代码语言:javascript复制docker exec -i oa-mysql mysqldump -u ${user} -p${dbpwd} --lock-all-tables --databases oa> oa.sql
代码语言:javascript复制
- 容器通过调用宿主机命令,直接操作其他容器
该种方式可参考,《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复制
- 通过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复制
调用的地方: