From 4985395a4d7e06e81c6e253e54b7b80a8a796eb2 Mon Sep 17 00:00:00 2001 From: LiYang <771232186@qq.com> Date: Thu, 27 Nov 2025 12:45:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20kk=204.0=20=E5=88=B6=E5=93=81=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=20=E6=94=AF=E6=8C=81skip=5Ftls=5Fverify=20=E7=A7=81?= =?UTF-8?q?=E4=BB=93=E9=95=9C=E5=83=8F=20#2854=20(#2855)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: kk 4.0 制品导出 支持skip_tls_verify 私仓镜像 #2854 * feat: update image skip tls verify func Signed-off-by: xuesongzuo@yunify.com * feat: update image skip tls verify func Signed-off-by: xuesongzuo@yunify.com * feat: update image skip tls verify func Signed-off-by: xuesongzuo@yunify.com --------- Signed-off-by: xuesongzuo@yunify.com Co-authored-by: xuesongzuo@yunify.com --- builtin/core/playbooks/artifact_images.yaml | 1 + builtin/core/roles/defaults/vars/v1.23.yaml | 2 + builtin/core/roles/defaults/vars/v1.24.yaml | 2 + builtin/core/roles/defaults/vars/v1.25.yaml | 2 + builtin/core/roles/defaults/vars/v1.26.yaml | 2 + builtin/core/roles/defaults/vars/v1.27.yaml | 2 + builtin/core/roles/defaults/vars/v1.28.yaml | 2 + builtin/core/roles/defaults/vars/v1.29.yaml | 2 + builtin/core/roles/defaults/vars/v1.30.yaml | 2 + builtin/core/roles/defaults/vars/v1.31.yaml | 2 + builtin/core/roles/defaults/vars/v1.32.yaml | 2 + builtin/core/roles/defaults/vars/v1.33.yaml | 2 + docs/zh/modules/image.md | 12 ++-- pkg/modules/image.go | 78 ++++++++++++++------- 14 files changed, 84 insertions(+), 29 deletions(-) diff --git a/builtin/core/playbooks/artifact_images.yaml b/builtin/core/playbooks/artifact_images.yaml index 8163da27..2f9b9040 100644 --- a/builtin/core/playbooks/artifact_images.yaml +++ b/builtin/core/playbooks/artifact_images.yaml @@ -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 diff --git a/builtin/core/roles/defaults/vars/v1.23.yaml b/builtin/core/roles/defaults/vars/v1.23.yaml index 9716a245..7736fc3e 100644 --- a/builtin/core/roles/defaults/vars/v1.23.yaml +++ b/builtin/core/roles/defaults/vars/v1.23.yaml @@ -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: diff --git a/builtin/core/roles/defaults/vars/v1.24.yaml b/builtin/core/roles/defaults/vars/v1.24.yaml index 20a60de0..e0af7d7b 100644 --- a/builtin/core/roles/defaults/vars/v1.24.yaml +++ b/builtin/core/roles/defaults/vars/v1.24.yaml @@ -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: diff --git a/builtin/core/roles/defaults/vars/v1.25.yaml b/builtin/core/roles/defaults/vars/v1.25.yaml index a4d2c651..24c62a30 100644 --- a/builtin/core/roles/defaults/vars/v1.25.yaml +++ b/builtin/core/roles/defaults/vars/v1.25.yaml @@ -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 diff --git a/builtin/core/roles/defaults/vars/v1.26.yaml b/builtin/core/roles/defaults/vars/v1.26.yaml index ce8ff0d1..6e604f1a 100644 --- a/builtin/core/roles/defaults/vars/v1.26.yaml +++ b/builtin/core/roles/defaults/vars/v1.26.yaml @@ -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 diff --git a/builtin/core/roles/defaults/vars/v1.27.yaml b/builtin/core/roles/defaults/vars/v1.27.yaml index 8cfc5e28..9ca7578d 100644 --- a/builtin/core/roles/defaults/vars/v1.27.yaml +++ b/builtin/core/roles/defaults/vars/v1.27.yaml @@ -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: diff --git a/builtin/core/roles/defaults/vars/v1.28.yaml b/builtin/core/roles/defaults/vars/v1.28.yaml index b80fba9a..f868db4b 100644 --- a/builtin/core/roles/defaults/vars/v1.28.yaml +++ b/builtin/core/roles/defaults/vars/v1.28.yaml @@ -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: diff --git a/builtin/core/roles/defaults/vars/v1.29.yaml b/builtin/core/roles/defaults/vars/v1.29.yaml index 5a42367a..f7889620 100644 --- a/builtin/core/roles/defaults/vars/v1.29.yaml +++ b/builtin/core/roles/defaults/vars/v1.29.yaml @@ -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: diff --git a/builtin/core/roles/defaults/vars/v1.30.yaml b/builtin/core/roles/defaults/vars/v1.30.yaml index 6af128dd..fd9ca170 100644 --- a/builtin/core/roles/defaults/vars/v1.30.yaml +++ b/builtin/core/roles/defaults/vars/v1.30.yaml @@ -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: diff --git a/builtin/core/roles/defaults/vars/v1.31.yaml b/builtin/core/roles/defaults/vars/v1.31.yaml index 036b5315..58d6860d 100644 --- a/builtin/core/roles/defaults/vars/v1.31.yaml +++ b/builtin/core/roles/defaults/vars/v1.31.yaml @@ -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: diff --git a/builtin/core/roles/defaults/vars/v1.32.yaml b/builtin/core/roles/defaults/vars/v1.32.yaml index 9fbfb3a9..67f19002 100644 --- a/builtin/core/roles/defaults/vars/v1.32.yaml +++ b/builtin/core/roles/defaults/vars/v1.32.yaml @@ -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 diff --git a/builtin/core/roles/defaults/vars/v1.33.yaml b/builtin/core/roles/defaults/vars/v1.33.yaml index 9c7875fa..58c46c6b 100644 --- a/builtin/core/roles/defaults/vars/v1.33.yaml +++ b/builtin/core/roles/defaults/vars/v1.33.yaml @@ -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 diff --git a/docs/zh/modules/image.md b/docs/zh/modules/image.md index 55a6aa55..cbef274c 100644 --- a/docs/zh/modules/image.md +++ b/docs/zh/modules/image.md @@ -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 | 否 | - | diff --git a/pkg/modules/image.go b/pkg/modules/image.go index 4173349b..ab9a3895 100644 --- a/pkg/modules/image.go +++ b/pkg/modules/image.go @@ -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")