containerd 客户端 + soci snapshotter:http:服务器向 HTTPS 客户端提供 HTTP 响应

问题描述 投票:0回答:1

我正在尝试设置和不安全的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
选项时,推拉过程可以正常工作。我有遗漏或做错了什么吗?

docker go containerd
1个回答
0
投票

我不知道您的 /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
配置的情况下也能工作吗?无论如何,这在您的用例中毫无意义?

© www.soinside.com 2019 - 2024. All rights reserved.