英文:
query a docker registry (hub.docker.com) using go docker client without docker daemon dependency
问题
我正在尝试使用Go访问Docker注册表(公共或私有)。我需要一个简单的程序,可以访问任何注册表并验证镜像是否存在。
我查看了Go中可用的Docker客户端https://pkg.go.dev/github.com/docker/docker@v20.10.11+incompatible/client
但问题是,这个客户端需要运行Docker守护程序才能工作。是否有任何方法可以在不依赖底层Docker引擎的情况下查询Docker注册表(例如:hub.docker.com)?
我的想法是在Docker容器上运行此程序,并且容器内部不会运行任何Docker引擎。我不想在Docker内部运行Docker或任何其他类型的黑客。我只想连接到注册表并查询镜像。请不要引用Stack Overflow中的其他问题。没有人回答过这个问题。
这是我目前的进展:
package main
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/docker/docker/api/types/filters"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
cli, err := client.NewClientWithOpts(client.WithHost("https://hub.docker.com"), client.WithAPIVersionNegotiation())
if err != nil {
fmt.Println(err.Error())
return
}
err = imagemanifest(cli)
if err != nil {
fmt.Println(err)
}
err = imageSearch(cli)
}
func imagemanifest(dockerClient *client.Client) error {
var authConfig = types.AuthConfig{
Username: "amokkara",
Password: "M@vr1ck2009",
ServerAddress: "https://index.docker.io/v2/",
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*1200)
defer cancel()
authConfigBytes, _ := json.Marshal(authConfig)
authConfigEncoded := base64.URLEncoding.EncodeToString(authConfigBytes)
ctx, cancel = context.WithTimeout(context.Background(), time.Second*1200)
defer cancel()
searchres, err := dockerClient.DistributionInspect(ctx, "amokkara/amokkara:3", authConfigEncoded)
if err != nil {
return err
}
fmt.Println(searchres.Descriptor.Digest.String())
return nil
}
如果我像这样初始化客户端:
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
这样可以工作,因为它使用底层的Docker守护程序(在我的情况下是Docker桌面)来查询注册表。但是,如果使用以下方式创建客户端:
client.NewClientWithOpts(client.WithHost("https://hub.docker.com"), client.WithAPIVersionNegotiation())
它会失败并返回404错误。这个客户端是否需要Docker守护程序才能工作?如果是这样,是否有其他方法可以查询注册表?请帮助我解决这个问题。
英文:
I'm trying to access a docker registry (public or private) using Go. A simple program which can access any registry and verify if an image is present.
I looked at docker client available in Go https://pkg.go.dev/github.com/docker/docker@v20.10.11+incompatible/client
But the problem is, this client needs a docker daemon running in order to work. Is there any way to query a docker registry (ex: hub.docker.com) without any dependency on underlying docker engine?
My idea is to run this program on a docker container and there wont be any docker engine running inside a container. And I don't want to run docker inside docker or any sort of hack. I just want to connect to a registry and query an image. And please don't quote other questions in stack overflow. No one has answered this.
This is what I have done so far
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/docker/docker/api/types/filters"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
func main() {
cli, err := client.NewClientWithOpts(client.WithHost("https://hub.docker.com"), client.WithAPIVersionNegotiation())
if err != nil {
fmt.Println(err.Error())
return
}
err = imagemanifest(cli)
if err != nil {
fmt.Println(err)
}
err = imageSearch(cli)
}
func imagemanifest(dockerClient *client.Client) error {
var authConfig = types.AuthConfig{
Username: "amokkara",
Password: "M@vr1ck2009",
ServerAddress: "https://index.docker.io/v2/",
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*1200)
defer cancel()
authConfigBytes, _ := json.Marshal(authConfig)
authConfigEncoded := base64.URLEncoding.EncodeToString(authConfigBytes)
ctx, cancel = context.WithTimeout(context.Background(), time.Second*1200)
defer cancel()
searchres , err := dockerClient.DistributionInspect(ctx,"amokkara/amokkara:3",authConfigEncoded)
if err != nil {
return err
}
fmt.Println(searchres.Descriptor.Digest.String())
return nil
}
If I initialize client like this
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
This works because its using underlying docker daemon (in my case docker desktop) to query the registry. But if create client using
client.NewClientWithOpts(client.WithHost("https://hub.docker.com"), client.WithAPIVersionNegotiation())
it fails giving 404 error. Does this client require a docker daemon to work. If so, is there any other way i can query a registry? Please help me with this.
答案1
得分: 0
Skopeo是处理无守护程序的注册表的领先软件。
它也是用Go语言编写的。
你可以参考inspect.go。
请注意,你不需要使用github.com/docker/docker/*
模块,而是使用github.com/containers/*
,具体来说是https://github.com/containers/image。
英文:
Skopeo is the leader software on dealing with registries without daemon.
It's also written with Go.
You can inspire from inspect.go
Note that, you don't need to use github.com/docker/docker/*
modules, but it will be github.com/containers/*
, and namely https://github.com/containers/image
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论