我正在尝试设置和不安全的containerd客户端,以使用以下代码从不安全的私有注册表中提取图像:
package main
import (
"context"
"crypto/tls"
"fmt"
"os"
"github.com/awslabs/soci-snapshotter/fs/source"
"github.com/containerd/containerd"
"github.com/containerd/containerd/pkg/snapshotters"
"github.com/containerd/containerd/remotes/docker"
"github.com/containerd/containerd/remotes/docker/config"
)
func main() {
var address = "/run/containerd/containerd.sock"
var ref = "localhost:5000/python:3.9"
var sociIndexDigest = "sha256:7b09431ef0749bee7491ba28d1adbe6e6e9e008e9be65fe35eed0aca31a01c91"
client, err := containerd.New(address, containerd.WithDefaultNamespace("default"))
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
defer client.Close()
options := docker.ResolverOptions{
Hosts: config.ConfigureHosts(context.TODO(), config.HostOptions{
DefaultScheme: "http",
DefaultTLS: &tls.Config{
InsecureSkipVerify: true,
},
}),
}
_, err = client.Pull(context.TODO(), ref,
containerd.WithResolver(docker.NewResolver(options)),
containerd.WithPullSnapshotter("soci"),
containerd.WithPullUnpack,
containerd.WithImageHandlerWrapper(source.AppendDefaultLabelsHandlerWrapper(sociIndexDigest, snapshotters.AppendInfoHandlerWrapper(ref))))
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
fmt.Println("Success")
}
不幸的是,我总是收到一些错误(来自裁剪的日志):
{"error":"skipping mounting layer sha256:a99509a323905a80628005e4f3bc26ac15ebaf3ffdb08a9646a7f2d110ab38f9 as FUSE mount: no ztoc for layer","key":"default/33/extract-128831236-kfhG sha256:781d5934416a582cf712c35212a8f92940c0223da02c1360d9ebb834d0f2c873","level":"warning","msg":"failed to prepare remote snapshot","parent":"sha256:9bb22d850b6e163c76b5cee00494067210e96c4cf585e2cd9d68898e31f43f69","remote-snapshot-prepared":"false","time":"2024-06-13T14:49:30.132049905Z"}
...
...
{"error":"cannot unpack the layer: cannot fetch layer: unable to fetch descriptor (sha256:a99509a323905a80628005e4f3bc26ac15ebaf3ffdb08a9646a7f2d110ab38f9) from remote store: Get \"https://localhost:5000/v2/python/blobs/sha256:a99509a323905a80628005e4f3bc26ac15ebaf3ffdb08a9646a7f2d110ab38f9\": context canceled","key":"default/33/extract-128831236-kfhG sha256:781d5934416a582cf712c35212a8f92940c0223da02c1360d9ebb834d0f2c873","level":"warning","msg":"failed to prepare snapshot; deferring to container runtime","parent":"sha256:9bb22d850b6e163c76b5cee00494067210e96c4cf585e2cd9d68898e31f43f69","time":"2024-06-13T14:49:30.363771421Z"}
...
...
{"error":"cannot unpack the layer: cannot fetch layer: unable to fetch descriptor (sha256:a99509a323905a80628005e4f3bc26ac15ebaf3ffdb08a9646a7f2d110ab38f9) from remote store: Get \"https://localhost:5000/v2/python/blobs/sha256:a99509a323905a80628005e4f3bc26ac15ebaf3ffdb08a9646a7f2d110ab38f9\": unknown \"unknown\": giving up request after 9 attempt(s): Get \"https://localhost:5000/v2/python/blobs/sha256:a99509a323905a80628005e4f3bc26ac15ebaf3ffdb08a9646a7f2d110ab38f9\": http: server gave HTTP response to HTTPS client","key":"default/34/extract-776892714-Ki3b sha256:781d5934416a582cf712c35212a8f92940c0223da02c1360d9ebb834d0f2c873","level":"warning","msg":"failed to prepare snapshot; deferring to container runtime","parent":"sha256:9bb22d850b6e163c76b5cee00494067210e96c4cf585e2cd9d68898e31f43f69","time":"2024-06-13T14:49:44.089475833Z"}
/etc/containerd/config.toml
文件:
version = 2
[plugins."io.containerd.grpc.v1.cri".containerd]
disable_snapshot_annotations = false
[proxy_plugins]
[proxy_plugins.soci]
type = "snapshot"
address = "/run/soci-snapshotter-grpc/soci-snapshotter-grpc.sock"
我尝试删除
DefaultTLS
选项,但结果仍然相同。使用 nerdctl 中的 --insecure-registry
选项时,推拉过程可以正常工作。我有遗漏或做错了什么吗?
我不知道您的 /etc/containerd/config.toml
中的
“必要参数”是什么,但您将
ResolverOptions
配置为使用 TLS 配置,覆盖默认架构:
package main
import (
"context"
"crypto/tls"
"fmt"
"github.com/containerd/containerd/remotes/docker"
"github.com/containerd/containerd/remotes/docker/config"
)
func main() {
ctx := context.Background()
hosts := []struct {
name string
hosts docker.RegistryHosts
}{
{name: "ConfigureHosts with TLS", hosts: config.ConfigureHosts(ctx, config.HostOptions{
DefaultScheme: "http",
DefaultTLS: &tls.Config{
InsecureSkipVerify: true,
},
})},
{name: "ConfigureHosts without TLS", hosts: config.ConfigureHosts(ctx, config.HostOptions{
DefaultScheme: "http",
})},
{name: "ConfigureDefaultRegistries", hosts: docker.ConfigureDefaultRegistries(
docker.WithPlainHTTP(func(string) (bool, error) { return true, nil }),
)},
}
host := "localhost:5000"
for _, config := range hosts {
fmt.Printf("%s:\n", config.name)
if registryHosts, err := config.hosts(host); err == nil {
for _, registryHost := range registryHosts {
fmt.Printf("- %s//:%s\n", registryHost.Scheme, registryHost.Host)
}
}
}
}
ConfigureHosts with TLS:
- https//:localhost:5000
ConfigureHosts without TLS:
- http//:localhost:5000
ConfigureDefaultRegistries:
- http//:localhost:5000
配置 HTTP 和 TLS 时,containerd 的默认客户端会回退到 HTTP,但您使用的是自定义快照程序,这意味着它可能只能获取默认架构,而没有回退信息。它在没有
DefaultTLS
配置的情况下也能工作吗?无论如何,这在您的用例中毫无意义?