在自动化部署的过程中,我们如果一直人为的输入docker命令效率不高而且不好管理。那么,我们可以使用docker提供的api来操作docker。
开启docker api
vim /usr/lib/systemd/system/docker.service
我们加入
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
[root@work atu]# systemctl daemon-reload
[root@work atu]# systemctl restart docker
[root@work atu]# ss -ntulp|grep 2375
tcp LISTEN 0 128 [::]:2375 [::]:* users:(("dockerd",pid=2857,fd=9))
docker对外的api就出来了
我们可以直接以web形式访问
但是很明显这样子是不安全的,因为没有权限认证机制,我们可以通过常用的web框架间接操作docker
举个例子
我们用goframe写一个操作docker api的web服务
路由
package router
import (
"app/app/api/controller"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func init() {
s := g.Server()
//首页模块
s.Group("/index", func(group *ghttp.RouterGroup) {
group.GET("/images", controller.Index.Images)
})
}
goframe 控制器
package controller
import (
"app/app/api/service"
"github.com/gogf/gf/net/ghttp"
)
var Index = IndexApi{}
type IndexApi struct {
BaseApi
}
//获取容器列表
func (i *IndexApi) Images(r *ghttp.Request) {
//获取镜像列表
result := service.IndexService.GetNewClient().GetImagesList()
//正常响应
i.Success(r, "获取镜像列表成功", result)
}
操作docker服务类
package service
import (
"fmt"
"github.com/docker/docker/api/types/swarm"
docker "github.com/fsouza/go-dockerclient"
)
var IndexService = IndexServiceStruct{}
type IndexServiceStruct struct{
BaseServiceStruct
docker *docker.Client
container map[string]*docker.Container
}
func (this *IndexServiceStruct)GetNewClient() *IndexServiceStruct{
var err error
endpoint := "unix:///var/run/docker.sock"
this.docker, err = docker.NewClient(endpoint)
if err != nil {
panic(err)
}
return this
}
//获取镜像列表
func (this *IndexServiceStruct) GetImagesList() []docker.APIImages{
opts := docker.ListImagesOptions{All: false}
images, err := this.docker.ListImages(opts)
if err != nil {
panic(err)
}
return images
}
//获取容器列表
func (this *IndexServiceStruct) GetContainerList() []swarm.Service {
//opts := docker.ListServicesOptions{Filters: map[string][]string {"name":{"<servicename>"}}}
opts := docker.ListServicesOptions{}
services, err := this.docker.ListServices(opts)
this.log(err)
return services
}
//创建容器
// 创建容器
func (this *IndexServiceStruct)CreateContainer() *docker.Container {
opts := docker.CreateContainerOptions{}
c , err := this.docker.CreateContainer(opts)
this.log(err)
return c
}
// 启动
func (this *IndexServiceStruct)StartContainer(containerId string) bool {
opts := this.container[containerId].HostConfig
err := this.docker.StartContainer(containerId,opts)
return this.log(err)
}
// 停止
func (this *IndexServiceStruct)StopContainer(containerID string) bool {
err := this.docker.StopContainer(containerID,6)
return this.log(err)
}
// 删除
func (this *IndexServiceStruct)RemoveContainer(containerID string) bool {
opts := docker.RemoveContainerOptions{ID: containerID}
err := this.docker.RemoveContainer(opts)
return this.log(err)
}
//统一错误处理
func (this *IndexServiceStruct)log(err error) bool {
if err != nil {
fmt.Printf("%v\n", err)
panic(err)
return false
}
return true
}
跑起这个服务
[root@work automatic-publishing-platform]# go run main.go
2022-01-21 17:36:28.244 [DEBU] SetServerRoot path: /mnt/hgfs/work/pro/go/automatic-publishing-platform/public
2022-01-21 17:36:28.245 [DEBU] SetServerRoot path: /mnt/hgfs/work/pro/go/automatic-publishing-platform/public
SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
----------|---------|---------|--------|---------------|----------------------------------------------|--------------------
default | default | :8080 | ALL | /* | app/app/middleware.AuthToken | GLOBAL MIDDLEWARE
----------|---------|---------|--------|---------------|----------------------------------------------|--------------------
default | default | :8080 | GET | /index/images | app/app/api/controller.(*IndexApi).Images-fm |
----------|---------|---------|--------|---------------|----------------------------------------------|--------------------
2022-01-21 17:36:28.247 4068: http server started listening on [:8080]
访问地址