feat: kk 4.0 制品导出 支持skip_tls_verify 私仓镜像 #2854 (#2855)

* feat: kk 4.0 制品导出 支持skip_tls_verify 私仓镜像 #2854

* feat: update image skip tls verify func

Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com>

* feat: update image skip tls verify func

Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com>

* feat: update image skip tls verify func

Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com>

---------

Signed-off-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com>
Co-authored-by: xuesongzuo@yunify.com <xuesongzuo@yunify.com>
This commit is contained in:
LiYang 2025-11-27 12:45:23 +08:00 committed by GitHub
parent fc12d7b302
commit 4985395a4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 84 additions and 29 deletions

View File

@ -21,6 +21,7 @@
images_dir: >-
{{ .binary_dir }}/images/
manifests: "{{ .image_manifests | toJson }}"
skip_tls_verify: "{{ .cri.skip_tls_verify | default false }}"
when:
- .image_manifests | default list | empty | not
- .download.download_image

View File

@ -33,6 +33,8 @@ cri:
containerd_version: v1.6.8
# runc binary
runc_version: v1.1.4
# skip tls verify when pulling images
skip_tls_verify: false
cni:
multus:
image:

View File

@ -36,6 +36,8 @@ cri:
containerd_version: v1.6.16
# runc binary
runc_version: v1.1.4
# skip tls verify when pulling images
skip_tls_verify: false
cni:
multus:
image:

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.6.19
# runc binary
runc_version: v1.1.4
# skip tls verify when pulling images
skip_tls_verify: false
cni:
type: calico
ipv6_support: false

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.6.21
# runc binary
runc_version: v1.1.5
# skip tls verify when pulling images
skip_tls_verify: false
cni:
type: calico
ipv6_support: false

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.7.2
# runc binary
runc_version: v1.1.7
# skip tls verify when pulling images
skip_tls_verify: false
cni:
multus:
image:

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.7.3
# runc binary
runc_version: v1.1.7
# skip tls verify when pulling images
skip_tls_verify: false
cni:
multus:
image:

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.7.6
# runc binary
runc_version: v1.1.7
# skip tls verify when pulling images
skip_tls_verify: false
cni:
multus:
image:

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.7.6
# runc binary
runc_version: v1.1.7
# skip tls verify when pulling images
skip_tls_verify: false
cni:
multus:
image:

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.7.6
# runc binary
runc_version: v1.1.7
# skip tls verify when pulling images
skip_tls_verify: false
cni:
multus:
image:

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.7.6
# runc binary
runc_version: v1.1.7
# skip tls verify when pulling images
skip_tls_verify: false
cni:
type: calico
ipv6_support: false

View File

@ -34,6 +34,8 @@ cri:
containerd_version: v1.7.6
# runc binary
runc_version: v1.1.7
# skip tls verify when pulling images
skip_tls_verify: false
cni:
type: calico
ipv6_support: false

View File

@ -13,13 +13,17 @@ image模块允许用户下载镜像到本地目录或上传镜像到远程目录
| pull.auths.repo | 用于认证远程仓库的地址 | 字符串 | 否 | - |
| pull.auths.username | 用于认证远程仓库的用户名 | 字符串 | 否 | - |
| pull.auths.password | 用于认证远程仓库的密码 | 字符串 | 否 | - |
| pull.auths.insecure | 是否跳过当前远程仓库的tls认证 | bool | 否 | - |
| pull.platform | 镜像的架构信息 | 字符串 | 否 | - |
| pull.skip_tls_verify | 是否跳过远程仓库的tls认证 | bool | 否 | - |
| pull.skip_tls_verify | 默认的是否跳过远程仓库的tls认证 | bool | 否 | - |
| push | 从本地目录中推送镜像到远程仓库 | map | 否 | - |
| push.images_dir | 镜像存放的本地目录 | 字符串 | 否 | - |
| push.username | 用于认证远程仓库的用户 | 字符串 | 否 | - |
| push.password | 用于认证远程仓库的密码 | 字符串 | 否 | - |
| push.skip_tls_verify | 是否跳过远程仓库的tls认证 | bool | 否 | - |
| push.auths | 远程仓库的认证信息 | Object数组 | 否 | - |
| push.auths.repo | 用于认证远程仓库的地址 | 字符串 | 否 | - |
| push.auths.username | 用于认证远程仓库的用户名 | 字符串 | 否 | - |
| push.auths.password | 用于认证远程仓库的密码 | 字符串 | 否 | - |
| push.auths.insecure | 是否跳过当前远程仓库的tls认证 | bool | 否 | - |
| push.skip_tls_verify | 默认的是否跳过远程仓库的tls认证 | bool | 否 | - |
| push.src_pattern | 正则表达式,过滤本地目录中存放的镜像 | map | 否 | - |
| push.dest | 模版语法,从本地目录镜像推送到的远程仓库镜像 | map | 否 | - |

View File

@ -59,16 +59,20 @@ image:
pull: # optional: pull configuration
manifests: []string # required: list of image manifests to pull
images_dir: string # required: directory to store pulled images
skipTLSVerify: bool # optional: skip TLS verification
skipTLSVerify: bool # optional: default skip TLS verification
autus: # optional: target image repo access information, slice type
- repo: string # optional: target image repo
username: string # optional: target image repo access username
password: string # optional: target image repo access password
insecure: bool # optional: skip TLS verification for current repo
push: # optional: push configuration
username: string # optional: registry username
password: string # optional: registry password
autus: # optional: target image repo access information, slice type
- repo: string # optional: target image repo
username: string # optional: target image repo access username
password: string # optional: target image repo access password
insecure: bool # optional: skip TLS verification for current repo
images_dir: string # required: directory containing images to push
skipTLSVerify: bool # optional: skip TLS verification
skipTLSVerify: bool # optional: default skip TLS verification
src_pattern: string # optional: source image pattern to push (regex supported). If not specified, all images in images_dir will be pushed
dest: string # required: destination registry and image name. Supports template syntax for dynamic values
@ -97,8 +101,13 @@ Usage Examples in Playbook Tasks:
- name: Push images to private registry
image:
push:
username: admin
password: secret
auths:
- repo: docker.io
username: MyDockerAccount
password: my_password
- repo: registry.example.com
username: admin
password: secret
namespace_override: custom-ns
images_dir: /path/to/images
dest: registry.example.com/{{ . }}
@ -124,19 +133,21 @@ type imagePullArgs struct {
manifests []string
skipTLSVerify *bool
platform string
auths []imagePullAuth
auths []imageAuth
}
type imagePullAuth struct {
type imageAuth struct {
Repo string `json:"repo"`
Username string `json:"username"`
Password string `json:"password"`
Insecure *bool `json:"insecure"`
}
// pull retrieves images from a remote registry and stores them locally
func (i imagePullArgs) pull(ctx context.Context, platform string) error {
for _, img := range i.manifests {
src, err := remote.NewRepository(normalizeImageNameSimple(img))
img = normalizeImageNameSimple(img)
src, err := remote.NewRepository(img)
if err != nil {
return errors.Wrapf(err, "failed to get remote image %s", img)
}
@ -144,12 +155,12 @@ func (i imagePullArgs) pull(ctx context.Context, platform string) error {
Client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: *i.skipTLSVerify,
InsecureSkipVerify: skipTlsVerifyFunc(img, i.auths, *i.skipTLSVerify),
},
},
},
Cache: auth.NewCache(),
Credential: i.pullAuthFunc(),
Credential: authFunc(i.auths),
}
dst, err := newLocalRepository(filepath.Join(src.Reference.Registry, src.Reference.Repository)+":"+src.Reference.Reference, i.imagesDir)
@ -175,9 +186,9 @@ func (i imagePullArgs) pull(ctx context.Context, platform string) error {
return nil
}
func (i imagePullArgs) pullAuthFunc() func(ctx context.Context, hostport string) (auth.Credential, error) {
func authFunc(auths []imageAuth) func(ctx context.Context, hostport string) (auth.Credential, error) {
var creds = make(map[string]auth.Credential)
for _, inputAuth := range i.auths {
for _, inputAuth := range auths {
var rp = inputAuth.Repo
if rp == "docker.io" || rp == "" {
rp = "registry-1.docker.io"
@ -196,6 +207,20 @@ func (i imagePullArgs) pullAuthFunc() func(ctx context.Context, hostport string)
}
}
func skipTlsVerifyFunc(img string, auths []imageAuth, defaults bool) bool {
imgHost := strings.Split(img, "/")[0]
for _, a := range auths {
if imgHost == a.Repo {
if a.Insecure != nil {
return *a.Insecure
} else {
return defaults
}
}
}
return defaults
}
// parse platform string to ocispec.Platform
func parsePlatform(platformStr string) (imagev1.Platform, error) {
parts := strings.Split(platformStr, "/")
@ -222,8 +247,7 @@ type imagePushArgs struct {
skipTLSVerify *bool
srcPattern *regexp.Regexp
destTmpl string
username string
password string
auths []imageAuth
}
// push uploads local images to a remote registry
@ -263,15 +287,12 @@ func (i imagePushArgs) push(ctx context.Context, hostVars map[string]any) error
Client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: *i.skipTLSVerify,
InsecureSkipVerify: skipTlsVerifyFunc(dest, i.auths, *i.skipTLSVerify),
},
},
},
Cache: auth.NewCache(),
Credential: auth.StaticCredential(dst.Reference.Registry, auth.Credential{
Username: i.username,
Password: i.password,
}),
Cache: auth.NewCache(),
Credential: authFunc(i.auths),
}
if _, err = oras.Copy(ctx, src, src.Reference.Reference, dst, dst.Reference.Reference, oras.DefaultCopyOptions); err != nil {
@ -296,8 +317,8 @@ func newImageArgs(_ context.Context, raw runtime.RawExtension, vars map[string]a
}
ipl := &imagePullArgs{}
ipl.manifests, _ = variable.StringSliceVar(vars, pull, "manifests")
ipl.auths = make([]imagePullAuth, 0)
pullAuths := make([]imagePullAuth, 0)
ipl.auths = make([]imageAuth, 0)
pullAuths := make([]imageAuth, 0)
_ = variable.AnyVar(vars, pull, &pullAuths, "auths")
for _, a := range pullAuths {
a.Repo, _ = tmpl.ParseFunc(vars, a.Repo, func(b []byte) string { return string(b) })
@ -332,8 +353,15 @@ func newImageArgs(_ context.Context, raw runtime.RawExtension, vars map[string]a
}
ips := &imagePushArgs{}
ips.username, _ = variable.StringVar(vars, push, "username")
ips.password, _ = variable.StringVar(vars, push, "password")
ips.auths = make([]imageAuth, 0)
pullAuths := make([]imageAuth, 0)
_ = variable.AnyVar(vars, push, &pullAuths, "auths")
for _, a := range pullAuths {
a.Repo, _ = tmpl.ParseFunc(vars, a.Repo, func(b []byte) string { return string(b) })
a.Username, _ = tmpl.ParseFunc(vars, a.Username, func(b []byte) string { return string(b) })
a.Password, _ = tmpl.ParseFunc(vars, a.Password, func(b []byte) string { return string(b) })
ips.auths = append(ips.auths, a)
}
ips.imagesDir, _ = variable.StringVar(vars, push, "images_dir")
srcPattern, _ := variable.StringVar(vars, push, "src_pattern")
destTmpl, _ := variable.PrintVar(push, "dest")