拉取镜像时未指定账户和密码通常是因为需要访问的镜像仓库启用了认证,但 Kubernetes 默认配置中未提供访问凭据。要解决此问题,可以按照以下步骤配置镜像仓库的认证信息:
1. 创建 Kubernetes Secret
为镜像仓库配置访问凭据,使用 kubectl
创建一个类型为 docker-registry
的 Secret。
kubectl create secret -n kubesphere-devops-system docker-registry my-registry-secret \
--docker-server=registry.flow.cn \
--docker-username=<your-username> \
--docker-password=<your-password> \
--docker-email=<your-email>
-
参数说明:
-
--docker-server
:镜像仓库的地址,例如registry.flow.cn
。 -
--docker-username
:登录仓库的用户名。 -
--docker-password
:登录仓库的密码。 -
--docker-email
:邮箱地址(可以是任意值,不强制验证)。
-
2. Pod 单独配置
修改 CronJob
的 spec.template.spec
配置,添加 imagePullSecrets
字段,指定刚创建的 Secret 名称。
更新后的 CronJob 配置如下:
kind: CronJob
apiVersion: batch/v1
metadata:
name: devops
namespace: kubesphere-devops-system
labels:
app: devops-pipelinerun-gcjobs
app.kubernetes.io/managed-by: Helm
annotations:
meta.helm.sh/release-name: devops
meta.helm.sh/release-namespace: kubesphere-devops-system
spec:
schedule: "0/2 * * * *"
startingDeadlineSeconds: 4000
concurrencyPolicy: Forbid
suspend: false
jobTemplate:
spec:
template:
metadata:
labels:
app: devops
release: devops
spec:
containers:
- name: pipeline-run-gc
image: 'registry.flow.cn/kubesphereio/devops-tools:ks-v3.4.1'
command:
- ks
- pip
- gc
imagePullPolicy: Always
restartPolicy: Never
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
serviceAccountName: devops
serviceAccount: devops
imagePullSecrets: # 添加这一部分
- name: my-registry-secret
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
验证配置
-
检查 Secret:
kubectl get secret -n kubesphere-devops-system
确保
my-registry-secret
已成功创建。 -
检查 CronJob 运行状态:
kubectl get cronjob -n kubesphere-devops-system
-
查看 Pod 拉取镜像日志:
如果镜像拉取失败,检查 Pod 事件:kubectl describe pod <pod-name> -n kubesphere-devops-system xxxx
注意事项
-
镜像仓库地址:确保仓库地址(
docker-server
)与image
字段中配置的一致。 -
命名空间:Secret 和 CronJob 必须在同一命名空间下(如
kubesphere-devops-system
)。 - 权限问题:确保镜像仓库用户具备对目标镜像的拉取权限。
完成上述配置后,CronJob
应能够正确拉取镜像并运行。
3. ServiceAccount 配置: 如果多个 Pod 使用相同的 serviceAccount,可以为 ServiceAccount 配置 Secret
确认需要使用的 ServiceAccount
查看当前 Pod 使用的 ServiceAccount:
kubectl get pods <pod-name> -n <namespace> -o jsonpath='{.spec.serviceAccountName}'
我我们假设返回的是 openebs-maya-operator
如果 kubectl get pods
命令返回的 serviceAccountName
是空的,说明 Pod 没有显式绑定任何 ServiceAccount,它会默认使用 default ServiceAccount。在这种情况下,你可以为 default
ServiceAccount 配置 imagePullSecrets
,或者直接为该 Pod 显式指定一个 ServiceAccount。
解决方案
方案 1:为默认 ServiceAccount 配置 imagePullSecrets
默认情况下,每个命名空间都包含一个 default
ServiceAccount。如果 Pod 未显式指定 serviceAccountName
,它会使用这个默认账户。
-
为命名空间中的
default
ServiceAccount 添加imagePullSecrets
:kubectl patch serviceaccount default \ -n <namespace>\ -p '{"imagePullSecrets": [{"name": "my-registry-secret"}]}'
-
验证配置:
kubectl describe serviceaccount default -n <namespace>
确保输出中有以下内容:
Image pull secrets: my-registry-secret
方案 2:显式为 Pod 指定 ServiceAccount
为 Pod 指定一个具有正确配置的 ServiceAccount,比如 openebs-maya-operator
:
-
编辑 Pod 的 YAML 文件,将
serviceAccountName
字段显式指定:spec: serviceAccountName: openebs-maya-operator
-
如果没有现成的 ServiceAccount,可以创建一个新的并配置
imagePullSecrets
:
kubectl create serviceaccount openebs-maya-operator -n <namespace>
kubectl patch serviceaccount openebs-maya-operator \
-n <namespace>\
-p '{"imagePullSecrets": [{"name": "my-registry-secret"}]}'
- 删除并重新创建 Pod 以应用更改:
kubectl delete pod <pod-name> -n <namespace>
方案 3:临时修改 Pod 配置
如果你只想快速测试,可以直接在 Pod 配置中添加 imagePullSecrets
(不过这不是最佳实践)。
编辑 Pod 的 YAML 文件,添加以下内容:
spec:
imagePullSecrets:
- name: my-registry-secret
重新应用修改后的 Pod 配置:
kubectl replace -f pod.yaml
验证步骤
无论采用哪种方案,确保最终拉取镜像成功:
-
查看 Pod 状态:
kubectl get pods -n <namespace>
-
如果仍有错误,请检查具体日志:
kubectl describe pod <pod-name> -n <namespace>
-
确认镜像仓库的认证信息正确,并确保网络连接正常。