/etc/systemd/system/docker.service
文件注释原来的ExecStart,添加一行新的如下:
#ExecStart=/usr/bin/dockerd
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
说明:
- 第一个
-H tcp://0.0.0.0:2375
是远程调用- 第二个
-H unix:///var/run/docker.sock
是本地调用(如果不写本地将不能调用)
[root@liubei-test ~]# systemctl daemon-reload
[root@liubei-test ~]# systemctl restart docker.service
[root@liubei-test ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
……
tcp6 0 0 :::2375 :::* LISTEN 5632/dockerd
……
>2379这个端口是docker的api端口
- docker API需要对应的安全策略
- tls策略,如果控制大量虚拟机,没有内部DNS的情况似乎并不好用
因此建议此时使用防火墙策略:
iptables -P INPUT ACCEPT
iptables -I INPUT -p tcp --dport 2375 -j DROP
iptables -I INPUT -p tcp --dport 2375 -s 10.10.87.18 -j ACCEPT
func NewClientWithOpts(ops ...Opt) (*Client, error)
cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375"))
client.WithAPIVersionNegotiation()
如是——协商API版本,如果不添加,可能会报错,比如:2023/03/14 13:55:53 Error response from daemon: client version 1.42 is too new. Maximum supported API version is 1.40
client.WithAPIVersionNegotiation()
client.WithTimeout(10*time.Second)
如果后边查看实时日志用这个会自动断开
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"log"
)
func main() {
cli, err := ConnectDocker()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("docker API 链接成功")
}
}
func ConnectDocker() (cli *client.Client, err error) {
cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375"))
if err != nil {
fmt.Println(err)
return nil, err
}
return cli, nil
}
func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]ImageSummary, error)
ctx := context.Background()
images, err := cli.ImageList(ctx, types.ImageListOptions{All: true})
import (
"bufio"
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"io"
"log"
"os"
)
func main() {
cli, err := ConnectDocker()
defer cli.Close()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("docker 链接成功")
}
err = GetImageList(cli)
if err != nil {
fmt.Println(err)
}
}
// ConnectDocker
// 链接docker
func ConnectDocker() (cli *client.Client, err error) {
cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375"))
if err != nil {
fmt.Println(err)
return nil, err
}
return cli, nil
}
// GetImageList
// 获取镜像列表
func GetImageList(cli *client.Client) error {
ctx := context.Background()
images, err := cli.ImageList(ctx, types.ImageListOptions{All: true})
if err != nil {
return err
}
//打印结果
for _, image := range images {
fmt.Printf("================\n%q %q\n", image.RepoTags, image.ID)
}
return nil
}
docker 链接成功
================
["harbocto.xxx.com.cn/crow/crow-qin:latest"] "sha256:04f135a90290c42b8cf9b52395c04753b4d9ed48ddae7c714a0eccdf8acd9682"
================
[] "sha256:b8f6736f7d1cee3e993bf0ba2a308fb747ed25dbd98fa2a2aba23b726cd8311b"
================
……
func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (ImageInspect, []byte, error)
imageInfo,imageInfoByte, err = cli.ImageInspectWithRaw(ctx, imageID)
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
cli, err := ConnectDocker()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("docker 链接成功")
}
imageId := "04f135a90290"
imageInfo, err := GetImage(cli, imageId)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("查询到镜像 %q", imageInfo.RepoTags)
}
func GetImage(cli *client.Client, imageID string) (imageInfo types.ImageInspect, err error) {
ctx := context.Background()
imageInfo, _, err = cli.ImageInspectWithRaw(ctx, imageID)
if err != nil {
return imageInfo, err
}
return imageInfo, nil
}
docker 链接成功
查询到镜像 ["harbocto.xxx.com.cn/crow-test/crow-qin:latest" "harbocto.xxx.com.cn/crow/crow-qin:latest"]
结果可见,改id的镜像有两个RepoTag
func (cli *Client) ImagePull(ctx context.Context, refStr string, options ImagePullOptions) (io.ReadCloser, error)
ctx := context.Background()
reader, err := Cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"io"
"os"
)
var Cli *client.Client
func main() {
cli, err := ConnectDocker()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("docker 链接成功")
}
//GetContainers()
err = PullImage(cli, "harbocto.xxx.com.cn/public/redis:6.2.6")
if err != nil {
fmt.Println(err)
}
}
// ConnectDocker
// 链接docker
func ConnectDocker() (cli *client.Client, err error) {
cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("tcp://10.10.239.32:2375"))
if err != nil {
fmt.Println(err)
return nil, err
}
return cli, nil
}
// PullImage
// 拉取指定镜像
func PullImage(cli *client.Client, imageName string) error {
ctx := context.Background()
reader, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
if err != nil {
fmt.Println(err)
}
_, err = io.Copy(os.Stdout, reader)
if err != nil {
return err
}
return nil
}
输出
docker 链接成功
{"status":"Pulling from public/redis","id":"6.2.6"}
{"status":"Pulling fs layer","progressDetail":{},"id":"a2abf6c4d29d"}
{"status":"Pulling fs layer","progressDetail":{},"id":"c7a4e4382001"}
……
{"status":"Extracting","progressDetail":{"current":409,"total":409},"progress":"[==================================================\u003e] 409B/409B","id":"1abfd3011519"}
{"status":"Pull complete","progressDetail":{},"id":"1abfd3011519"}
{"status":"Digest: sha256:563888f63149e3959860264a1202ef9a644f44ed6c24d5c7392f9e2262bd3553"}
{"status":"Status: Downloaded newer image for harbocto.boe.com.cn/public/redis:6.2.6"}
镜像拉取成功
RegistryAuth
参数out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{RegistryAuth: authStr})
package main
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"io"
"os"
)
func main() {
cli, err := ConnectDocker()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("docker 链接成功")
}
err = PullPrivateImage(cli, "harbocto.boe.com.cn/crow-test/crow-qin")
if err != nil {
fmt.Println(err)
}
//, "48bcf68112"
}
// PullPrivateImage
// 拉取私有仓库的镜像
func PullPrivateImage(cli *client.Client, imageName string) error {
ctx := context.Background()
authConf := types.AuthConfig{
Username: "10264953",
Password: "30gmcyt8Kllyhy",
}
encodeJson, _ := json.Marshal(authConf)
authStr := base64.StdEncoding.EncodeToString(encodeJson)
out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{RegistryAuth: authStr})
if err != nil {
fmt.Println(err)
return err
}
defer out.Close()
_, err = io.Copy(os.Stdout, out)
if err != nil {
return err
}
return nil
}
func (cli *Client) ImageTag(ctx context.Context, source string, target string) error
ctx := context.Background()
err := cli.ImageTag(ctx, "harbocto.boe.com.cn/crow/crow-qin", "harbocto.boe.com.cn/public/crow-qin:0323")
package main
import (
"context"
"fmt"
"github.com/docker/docker/client"
)
func main() {
cli, err := ConnectDocker()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("docker 链接成功")
}
err = AddNewTag(cli, "harbocto.boe.com.cn/crow/crow-qin", "harbocto.boe.com.cn/public/crow-qin:0323")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("REPOSITORY:TAG 添加成功")
}
func AddNewTag(cli *client.Client, sourceImageName string, newImageName string) error {
ctx := context.Background()
err := cli.ImageTag(ctx, sourceImageName, newImageName)
if err != nil {
return err
}
return nil
}
docker 链接成功
REPOSITORY:TAG 添加成功
func (cli *Client) ImageRemove(ctx context.Context, imageID string, options ImageRemoveOptions) ([]ImageDeleteResponseItem, error)
ctx := context.Background()
imageDeleteResponseItems, err = cli.ImageRemove(ctx, imageId, types.ImageRemoveOptions{Force: true})
package main
import (
"context"
"fmt"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
cli, err := ConnectDocker()
if err != nil {
fmt.Println(err)
} else {
fmt.Println("docker 链接成功")
}
imageDeleteResponseItems, err := DeleteImage(cli, "04f135a90290")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("==== 被删除的 REPOSITORY:TAG ====\n", imageDeleteResponseItems)
}
func DeleteImage(cli *client.Client, imageId string) (imageDeleteResponseItems []types.ImageDeleteResponseItem, err error) {
ctx := context.Background()
imageDeleteResponseItems, err = cli.ImageRemove(ctx, imageId, types.ImageRemoveOptions{Force: true})
if err != nil {
fmt.Println(err)
return imageDeleteResponseItems, err
}
return imageDeleteResponseItems, nil
}
输出
docker 链接成功
==== 被删除的 REPOSITORY:TAG ====
[{ harbocto.boe.com.cn/crow-test/crow-qin:latest} { harbocto.boe.com.cn/crow-test/crow-qin@sha256:5891ae5e691914196af46e869a6cba45c6e53266b4110b85c5c37385cc3b6b84} { harbocto.boe.com.cn/crow/crow-qin:latest} { harbocto.boe
.com.cn/crow/crow-qin@sha256:5891ae5e691914196af46e869a6cba45c6e53266b4110b85c5c37385cc3b6b84} { harbocto.boe.com.cn/public/crow-qin:0323} { harbocto.boe.com.cn/public/crow-qin:latest} {sha256:04f135a90290c42b8cf9b52395c047
53b4d9ed48ddae7c714a0eccdf8acd9682 } {sha256:b823e639a7311f26a530dad46f8ac237412fb28455213bd10f1167920e3afcd4 } {sha256:28b4ee770c69121697cce33f6c52990920c3023b4cc2cf14711e2e489ea5259f } {sha256:42197fd514211b6e3d9f10f9afcd
4ad95620371f22f16656fd671e446c3e3a1e } {sha256:89ae5c4ee501a09c879f5b58474003539ab3bb978a553af2a4a6a7de248b5740 }]