diff --git a/builtin/core/defaults/config/v1.23.yaml b/builtin/core/defaults/config/v1.23.yaml index b3fa171b..f50ea896 100644 --- a/builtin/core/defaults/config/v1.23.yaml +++ b/builtin/core/defaults/config/v1.23.yaml @@ -95,3 +95,4 @@ spec: - docker.io/openebs/linux-utils:3.3.0 - docker.io/openebs/provisioner-localpv:3.3.0 - quay.io/tigera/operator:v1.28.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.24.yaml b/builtin/core/defaults/config/v1.24.yaml index 210fb4be..fe6f931d 100644 --- a/builtin/core/defaults/config/v1.24.yaml +++ b/builtin/core/defaults/config/v1.24.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.29.3 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.25.yaml b/builtin/core/defaults/config/v1.25.yaml index f5341602..2cb795b5 100644 --- a/builtin/core/defaults/config/v1.25.yaml +++ b/builtin/core/defaults/config/v1.25.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.29.3 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.26.yaml b/builtin/core/defaults/config/v1.26.yaml index 115f530a..0de00c0a 100644 --- a/builtin/core/defaults/config/v1.26.yaml +++ b/builtin/core/defaults/config/v1.26.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.30.4 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.27.yaml b/builtin/core/defaults/config/v1.27.yaml index 373aa771..d6f3dc59 100644 --- a/builtin/core/defaults/config/v1.27.yaml +++ b/builtin/core/defaults/config/v1.27.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.30.4 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.28.yaml b/builtin/core/defaults/config/v1.28.yaml index 6b2b953c..daff4155 100644 --- a/builtin/core/defaults/config/v1.28.yaml +++ b/builtin/core/defaults/config/v1.28.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.29.yaml b/builtin/core/defaults/config/v1.29.yaml index 1b3a416d..0530e0d1 100644 --- a/builtin/core/defaults/config/v1.29.yaml +++ b/builtin/core/defaults/config/v1.29.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:3.5.0 - docker.io/openebs/provisioner-localpv:3.5.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.30.yaml b/builtin/core/defaults/config/v1.30.yaml index bb5e56a1..d40340ad 100644 --- a/builtin/core/defaults/config/v1.30.yaml +++ b/builtin/core/defaults/config/v1.30.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:4.0.0 - docker.io/openebs/provisioner-localpv:4.0.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.31.yaml b/builtin/core/defaults/config/v1.31.yaml index ef7e0746..ef70d86e 100644 --- a/builtin/core/defaults/config/v1.31.yaml +++ b/builtin/core/defaults/config/v1.31.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:4.1.0 - docker.io/openebs/provisioner-localpv:4.1.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.32.yaml b/builtin/core/defaults/config/v1.32.yaml index 596481ee..918bf7a1 100644 --- a/builtin/core/defaults/config/v1.32.yaml +++ b/builtin/core/defaults/config/v1.32.yaml @@ -96,3 +96,4 @@ spec: - docker.io/openebs/linux-utils:4.2.0 - docker.io/openebs/provisioner-localpv:4.2.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/defaults/config/v1.33.yaml b/builtin/core/defaults/config/v1.33.yaml index 4bad40bc..b19617d0 100644 --- a/builtin/core/defaults/config/v1.33.yaml +++ b/builtin/core/defaults/config/v1.33.yaml @@ -97,3 +97,4 @@ spec: - docker.io/openebs/linux-utils:4.2.0 - docker.io/openebs/provisioner-localpv:4.2.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine 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/defaults/main/01-cluster_require.yaml b/builtin/core/roles/defaults/defaults/main/01-cluster_require.yaml index 6e27c0c2..12ff29a0 100644 --- a/builtin/core/roles/defaults/defaults/main/01-cluster_require.yaml +++ b/builtin/core/roles/defaults/defaults/main/01-cluster_require.yaml @@ -10,6 +10,8 @@ cluster_require: - '"ubuntu"' - centos - '"centos"' + - kylin + - '"kylin"' # Required network plugins require_network_plugin: ['calico', 'flannel', 'cilium', 'hybridnet', 'kube-ovn'] # Minimum supported Kubernetes version diff --git a/builtin/core/roles/defaults/defaults/main/03-kubernetes.yaml b/builtin/core/roles/defaults/defaults/main/03-kubernetes.yaml index e23f8797..f650e1d5 100644 --- a/builtin/core/roles/defaults/defaults/main/03-kubernetes.yaml +++ b/builtin/core/roles/defaults/defaults/main/03-kubernetes.yaml @@ -82,7 +82,7 @@ kubernetes: mode: ARP image: registry: >- - {{ .dockerio_registry }} + {{ .image_registry.dockerio_registry }} repository: plndr/kube-vip tag: v0.7.2 haproxy: @@ -91,7 +91,7 @@ kubernetes: health_port: 8081 image: registry: >- - {{ .dockerio_registry }} + {{ .image_registry.dockerio_registry }} repository: library/haproxy tag: 2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/10-download.yaml b/builtin/core/roles/defaults/vars/10-download.yaml index ebf716b4..ef95c7b2 100644 --- a/builtin/core/roles/defaults/vars/10-download.yaml +++ b/builtin/core/roles/defaults/vars/10-download.yaml @@ -235,6 +235,10 @@ download: - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/debian-11-debs-arm64.iso" - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/kylin-v10SP3-rpms-amd64.iso" - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/kylin-v10SP3-rpms-arm64.iso" + - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/kylin-v10SP2-rpms-amd64.iso" + - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/kylin-v10SP2-rpms-arm64.iso" + - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/kylin-v10SP1-rpms-amd64.iso" + - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/kylin-v10SP1-rpms-arm64.iso" - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/ubuntu-18.04-debs-amd64.iso" - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/ubuntu-18.04-debs-arm64.iso" - "{{ .download.iso_url.base_path }}/kubesphere/kubekey/releases/download/iso-latest/ubuntu-20.04-debs-amd64.iso" diff --git a/builtin/core/roles/defaults/vars/v1.23.yaml b/builtin/core/roles/defaults/vars/v1.23.yaml index cfa4e77e..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: @@ -88,3 +90,4 @@ image_manifests: - docker.io/openebs/linux-utils:3.3.0 - docker.io/openebs/provisioner-localpv:3.3.0 - quay.io/tigera/operator:v1.28.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.24.yaml b/builtin/core/roles/defaults/vars/v1.24.yaml index fbd05bcb..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: @@ -91,3 +93,4 @@ image_manifests: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.29.3 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.25.yaml b/builtin/core/roles/defaults/vars/v1.25.yaml index 884c76a8..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 @@ -91,3 +93,4 @@ image_manifests: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.29.3 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.26.yaml b/builtin/core/roles/defaults/vars/v1.26.yaml index b5e8d339..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 @@ -91,3 +93,4 @@ image_manifests: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.30.4 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.27.yaml b/builtin/core/roles/defaults/vars/v1.27.yaml index 2b26370f..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: @@ -88,3 +90,4 @@ image_manifests: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.30.4 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.28.yaml b/builtin/core/roles/defaults/vars/v1.28.yaml index 94f7fdca..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: @@ -89,3 +91,4 @@ image_manifests: - docker.io/openebs/linux-utils:3.4.0 - docker.io/openebs/provisioner-localpv:3.4.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.29.yaml b/builtin/core/roles/defaults/vars/v1.29.yaml index 27b2bf03..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: @@ -89,3 +91,4 @@ image_manifests: - docker.io/openebs/linux-utils:3.5.0 - docker.io/openebs/provisioner-localpv:3.5.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.30.yaml b/builtin/core/roles/defaults/vars/v1.30.yaml index 6fc15754..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: @@ -89,3 +91,4 @@ image_manifests: - docker.io/openebs/linux-utils:4.0.0 - docker.io/openebs/provisioner-localpv:4.0.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.31.yaml b/builtin/core/roles/defaults/vars/v1.31.yaml index 711c8002..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: @@ -89,4 +91,5 @@ image_manifests: - docker.io/openebs/linux-utils:4.1.0 - docker.io/openebs/provisioner-localpv:4.1.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.32.yaml b/builtin/core/roles/defaults/vars/v1.32.yaml index 8ba89876..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 @@ -91,3 +93,4 @@ image_manifests: - docker.io/openebs/linux-utils:4.2.0 - docker.io/openebs/provisioner-localpv:4.2.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/defaults/vars/v1.33.yaml b/builtin/core/roles/defaults/vars/v1.33.yaml index c7022f05..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 @@ -91,3 +93,4 @@ image_manifests: - docker.io/openebs/linux-utils:4.2.0 - docker.io/openebs/provisioner-localpv:4.2.0 - quay.io/tigera/operator:v1.34.5 + - docker.io/library/haproxy:2.9.6-alpine diff --git a/builtin/core/roles/precheck/etcd/tasks/main.yaml b/builtin/core/roles/precheck/etcd/tasks/main.yaml index 99d890cc..72bac5bd 100644 --- a/builtin/core/roles/precheck/etcd/tasks/main.yaml +++ b/builtin/core/roles/precheck/etcd/tasks/main.yaml @@ -26,7 +26,7 @@ register_type: json - name: ETCD | Assert disk fsync latency meets requirements assert: - that: (index (.fio_result.stdout.jobs | first) "sync" "lat_ns" "percentile" "90.000000") | le .cluster_require.etcd_disk_wal_fysnc_duration_seconds + that: (index (.fio_result.stdout.jobs | first) "sync" "lat_ns" "percentile" "90.000000") | ge .cluster_require.etcd_disk_wal_fysnc_duration_seconds fail_msg: >- The 90th percentile fsync latency is {{ index (.fio_result.stdout.jobs | first) "sync" "lat_ns" "percentile" "90.000000" }}ns, which exceeds the maximum allowed: {{ .cluster_require.etcd_disk_wal_fysnc_duration_seconds }}ns. always: diff --git a/cmd/kk/app/options/builtin/artifact.go b/cmd/kk/app/options/builtin/artifact.go index b1b8e856..09d7f5c6 100644 --- a/cmd/kk/app/options/builtin/artifact.go +++ b/cmd/kk/app/options/builtin/artifact.go @@ -143,13 +143,16 @@ func (o *ArtifactImagesOptions) Complete(cmd *cobra.Command, args []string) (*kk } o.Playbook = args[0] - var tags = []string{"image_registry"} + var tags = make([]string, 0) if o.Push { tags = append(tags, "push") } if o.Pull { tags = append(tags, "pull") } + if !o.Pull && !o.Push { + tags = append(tags, "image_registry") + } playbook.Spec = kkcorev1.PlaybookSpec{ Playbook: o.Playbook, diff --git a/docs/zh/modules/image.md b/docs/zh/modules/image.md index 55a6aa55..8d8d9054 100644 --- a/docs/zh/modules/image.md +++ b/docs/zh/modules/image.md @@ -13,15 +13,39 @@ 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 | 否 | - | +| copy | 模版语法,将镜像在文件系统和镜像仓库内相互复制 | map | 否 | - | +| copy.from | 模版语法,源镜像信息 | map | 否 | - | +| copy.from.type | 镜像源类型 | 字符串 | 否 | - | +| copy.from.path | 镜像源地址。如果类型为file,则为文件地址,如果类型为hub,则为镜像仓库地址 | 字符串 | 否 | - | +| copy.from.skip_tls_verify | 仅在hub类型中生效;源镜像仓库是否跳过tls认证 | bool | 否 | - | +| copy.from.manifests | 源镜像列表 | 字符串数组 | 否 | - | +| copy.from.auths | 远程仓库的认证信息 | Object数组 | 否 | - | +| copy.from.auths.repo | 用于认证远程仓库的地址 | 字符串 | 否 | - | +| copy.from.auths.username | 用于认证远程仓库的用户名 | 字符串 | 否 | - | +| copy.from.auths.password | 用于认证远程仓库的密码 | 字符串 | 否 | - | +| copy.to | 模版语法,从本地目录镜像推送到的远程仓库镜像 | map | 否 | - | +| copy.to.type | 镜像目标类型 | 字符串 | 否 | - | +| copy.to.path | 镜像目标地址。如果类型为file,则为文件地址,如果类型为hub,则为仓库中的镜像地址 | 字符串 | 否 | - | +| copy.to.skip_tls_verify | 仅在hub类型中生效;目标镜像仓库是否跳过tls认证 | bool | 否 | - | +| copy.to.pattern | 正则表达式,过滤推送至目标的镜像 | 字符串 | 否 | - | +| copy.to.auths | 远程仓库的认证信息 | Object数组 | 否 | - | +| copy.to.auths.repo | 用于认证远程仓库的地址 | 字符串 | 否 | - | +| copy.to.auths.username | 用于认证远程仓库的用户名 | 字符串 | 否 | - | +| copy.to.auths.password | 用于认证远程仓库的密码 | 字符串 | 否 | - | + 每个本地目录存放的镜像对应一个dest镜像。 ```txt @@ -68,4 +92,72 @@ image模块允许用户下载镜像到本地目录或上传镜像到远程目录 即: docker.io/kubesphere/ks-apiserver:v4.1.3 => hub.kubekey/kubesphere/ks-apiserver:v4.1.3 docker.io/kubesphere/ks-controller-manager:v4.1.3 => hub.kubekey/kubesphere/ks-controller-manager:v4.1.3 -docker.io/kubesphere/ks-console:3.19 => hub.kubekey/kubesphere/ks-console:v4.1.3 \ No newline at end of file +docker.io/kubesphere/ks-console:3.19 => hub.kubekey/kubesphere/ks-console:v4.1.3 + +3. 将镜像从文件系统复制至其他文件系统 +```yaml +- name: file to file + image: + copy: + from: + type: file + path: "/tmp/images/" + manifests: + - docker.io/calico/apiserver:v3.28.2 + to: + type: file + path: "/tmp/others/images/" +``` + +4. 将镜像从文件系统推送至镜像仓库 +```yaml +- name: file to hub + image: + copy: + from: + type: file + path: "/tmp/images/" + manifests: + - docker.io/calico/apiserver:v3.28.2 + to: + type: hub + path: >- + hub.kubekey/{{ .module.image.src.reference.repository }}:{{ .module.image.src.reference.reference }} +``` + +5. 将镜像从仓库推送至文件系统 +```yaml +- name: hub to file + image: + copy: + from: + type: hub + auths: + - repo: docker.io + username: DockerAccount + password: DockerPassword + manifests: + - docker.io/calico/apiserver:v3.28.2 + to: + type: file + path: /tmp/images/ +``` + +6. 将镜像从仓库推送至其他仓库 +```yaml +- name: hub to hub + image: + copy: + from: + type: hub + auths: + - repo: docker.io + username: DockerAccount + password: DockerPassword + manifests: + - docker.io/calico/apiserver:v3.28.2 + to: + type: hub + path: >- + hub.kubekey/{{ .module.image.src.reference.repository }}:{{ .module.image.src.reference.reference }} +``` \ No newline at end of file diff --git a/pkg/modules/image.go b/pkg/modules/image.go index 4173349b..7104bf5e 100644 --- a/pkg/modules/image.go +++ b/pkg/modules/image.go @@ -59,18 +59,41 @@ 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 + copy: + from: + type: string # required: image source type, file or hub + path: string # optional: when image source type is file, then required, means image file path + manifests: []string # required: list of image manifests to pull + skipTLSVerify: bool # optional: 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 + to: + type: string # required: image target type, file or hub + path: string # required: image target path + skipTLSVerify: bool # optional: skip TLS verification + pattern: string # optional: source image pattern to push (regex supported). If not specified, all images in images_dir will be pushed + 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 Usage Examples in Playbook Tasks: 1. Pull images from registry: @@ -97,14 +120,33 @@ 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/{{ . }} register: push_result ``` +3. Copy image from file to file + ```yaml + - name: file to file + image: + copy: + from: + path: "/path/from/images" + manifests: + - nginx:latest + - prometheus:v2.45.0 + to: + path: /path/to/images + ``` + Return Values: - On success: Returns "Success" in stdout - On failure: Returns error message in stderr @@ -116,6 +158,7 @@ const defaultRegistry = "docker.io" type imageArgs struct { pull *imagePullArgs push *imagePushArgs + copy *imageCopyArgs } // imagePullArgs contains parameters for pulling images @@ -124,19 +167,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 +189,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 +220,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 +241,19 @@ 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 + } + return defaults + } + } + return defaults +} + // parse platform string to ocispec.Platform func parsePlatform(platformStr string) (imagev1.Platform, error) { parts := strings.Split(platformStr, "/") @@ -222,8 +280,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 +320,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 { @@ -282,6 +336,70 @@ func (i imagePushArgs) push(ctx context.Context, hostVars map[string]any) error return nil } +type imageCopyArgs struct { + From imageCopyTargetArgs `json:"from"` + To imageCopyTargetArgs `json:"to"` +} + +type imageCopyTargetArgs struct { + Path string `json:"path"` + manifests []string + Pattern *regexp.Regexp +} + +func (i *imageCopyArgs) parseFromVars(vars, cp map[string]any) error { + i.From.manifests, _ = variable.StringSliceVar(vars, cp, "from", "manifests") + fromPath, _ := variable.PrintVar(cp, "from", "path") + if fromStr, ok := fromPath.(string); !ok { + return errors.New("\"copy.to.path\" must be a string") + } else if fromStr == "" { + return errors.New("\"copy.to.path\" should not be empty") + } else { + i.From.Path = fromStr + } + toPath, _ := variable.PrintVar(cp, "to", "path") + if destStr, ok := toPath.(string); !ok { + return errors.New("\"copy.to.path\" must be a string") + } else if destStr == "" { + return errors.New("\"copy.to.path\" should not be empty") + } else { + i.To.Path = destStr + } + srcPattern, _ := variable.StringVar(vars, cp, "to", "src_pattern") + if srcPattern != "" { + pattern, err := regexp.Compile(srcPattern) + if err != nil { + return errors.Wrap(err, "\"to.pattern\" should be a valid regular expression. ") + } + i.To.Pattern = pattern + } + return nil +} + +func (i *imageCopyArgs) copy(ctx context.Context, _ map[string]any) error { + if sts, err := os.Stat(i.From.Path); err != nil || !sts.IsDir() { + return errors.New("\"copy.from.path\" must be a exist directory") + } + for _, img := range i.From.manifests { + if i.To.Pattern != nil && !i.To.Pattern.MatchString(img) { + // skip + continue + } + src, err := newLocalRepository(img, i.From.Path) + if err != nil { + return err + } + dst, err := newLocalRepository(filepath.Join(src.Reference.Registry, src.Reference.Repository)+":"+src.Reference.Reference, i.To.Path) + if err != nil { + return err + } + if _, err = oras.Copy(ctx, src, src.Reference.Reference, dst, dst.Reference.Reference, oras.DefaultCopyOptions); err != nil { + return errors.Wrapf(err, "failed to push image %q to remote", img) + } + } + return nil +} + // newImageArgs creates a new imageArgs instance from raw configuration func newImageArgs(_ context.Context, raw runtime.RawExtension, vars map[string]any) (*imageArgs, error) { ia := &imageArgs{} @@ -296,8 +414,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 +450,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") @@ -365,6 +490,22 @@ func newImageArgs(_ context.Context, raw runtime.RawExtension, vars map[string]a ia.push = ips } + if cpArgs, ok := args["copy"]; ok { + cp, ok := cpArgs.(map[string]any) + if !ok { + return nil, errors.New("\"copy\" should be map") + } + + cps := &imageCopyArgs{} + + err := cps.parseFromVars(vars, cp) + if err != nil { + return nil, err + } + + ia.copy = cps + } + return ia, nil } @@ -394,6 +535,12 @@ func ModuleImage(ctx context.Context, options ExecOptions) (string, string, erro } } + if ia.copy != nil { + if err := ia.copy.copy(ctx, ha); err != nil { + return StdoutFailed, "failed to push image", err + } + } + return StdoutSuccess, "", nil }