kubesphere/kubernetes 镜像拉取失败问题处理

1. 背景

最近 docker hub 下载镜像经常失败,同一台机器有可能这个镜像可以,那个镜像不行。另外,看到很多人安装 kubesphere/kubernetes 不知道如何处理镜像拉取失败问题。

2. 基本概念和基本操作

2.1 vim 基本操作

vim 基本操作,以下为按键流程说明,比如:

  • 前后左右用方向键即可,或者按 esc 状态下,h(左) j(下) k(上) l(右)
  • 查找 “image:”,ecs -> /image: -> 回车
  • 往后查找,前面查找按了回车后,按 n
  • 往前查找,前面查找按了回车后,按 N(shift + n)
  • 替换 aaa 成 bbb,esc -> 输入 :s@aaa@bbb@g (注意冒号)g 为全局替换,不加 g 则替换匹配到的第一个

基本能满足编辑需求了。

2.2 kubernetes 资源编辑

kubernetes 中最常见拉镜像的有:
deployment:kubectl 命令使用时简写:deploy
statefulset:kubectl 命令使用时简写:sts
daemonset:kubectl 命令使用时简写:ds

比如编辑一个 deployment abc,如果不是在 default 命名空间,则需要接上命令空间:
kubectl edit deploy abc [-n NAMESPACE]

命令执行后,就是 vim 操作了。

镜像拉取策略:

  • imagePullPolicy: "IfNotPresent":有相同地址和 tag 的镜像存在时则不拉取
  • imagePullPolicy: "Always":总是拉取镜像,即使存在相同地址和 tag 镜像时

3. kubesphere 安装设置私有仓库

3.1 私有仓库 harbor 说明

我的私有仓库是 harbor.ygqygq2.com,带宽小,勉强能用。其中 library 项目中保留的为 创建 issue 推送上去的镜像地址,对应关系是:

  • nginx:latest 对应 harbor.ygqygq2.com/library/nginx:latest
  • bitnami/nginx:latest 对应 harbor.ygqygq2.com/library/bitnami/nginx:latest

其中 proxy 项目为代理 docker hub,对应关系是:

  • nginx:latest 对应 harbor.ygqygq2.com/proxy/library/nginx:latest
  • bitnami/nginx:latest 对应 harbor.ygqygq2.com/proxy/bitnami/nginx:latest

私有仓库 harbor 推荐的做法就是 library 设置成公开,然后里面镜像保留原镜像目录结构,像我上面一样。

3.2 config-sample.yaml 先用默认的

kubekey 安装前设置环境变量
export KKZONE=cn

然后 config-sample.yaml 使用默认的:

  registry:
    privateRegistry: ""  # 私有仓库地址,如果镜像都在 library 中,则比如 harbor.ygqygq2.com/library
    namespaceOverride: ""
    registryMirrors: []
    insecureRegistries: []  # 如果私有仓库为 http 访问,得加到这里

kubekey 安装 kubernetes 集群,初始化时就可以使用命令查看容器运行情况了。

  • docker 环境推荐 docker 命令,比如 docker ps -a
  • containerd 环境推荐 nerdctl 命令,只是注意镜像拉取要指定命令空间 --namespace k8s.io,可以设置 alias nerdctl=nerdctl --namespace k8s.io,比如 nerdctl ps -a --namespace k8s.io

注意 sandbox_image 镜像地址:

  • docker 环境中查看 kubelet 配置 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf,可以看到 EnvironmentFile=-/etc/default/kubelet,所以可以配置 /etc/default/kubelet (Ubuntu)、/etc/sysconfig/kubelet(RHEL系),内容为:KUBELET_EXTRA_ARGS="--pod-infra-container-image="registry.cn-beijing.aliyuncs.com/kubesphereio/pause:3.9"
  • containerd 配置中可以配置为,sandbox_image = "registry.cn-beijing.aliyuncs.com/kubesphereio/pause:3.9"

安装完 kubernetes 后,kubectl get pod -A 可以查看 pod 运行情况,此时就可以根据 4 解决失败的 POD 镜像问题了。

3.3 kubesphere-installer.yaml

kubesphere-installer.yaml 中有个镜像地址,修成成你的仓库镜像地址,也可以使用我的仓库image: harbor.ygqygq2.com/proxy/kubesphere/ks-installer:v3.4.1,并注意修改策略 imagePullPolicy: "IfNotPresent"

installer 地址修改

kubectl apply -f kubesphere-installer.yaml
kubectl get pod -A  # 查看 pod 情况

有pod异常

kubectl describe pod ks-installer-67f67f9698-lglwb -n kubesphere-system

没有镜像

因为我们使用 yaml 安装的,直接修改 yaml,再 kubectl apply -f kubesphere-installer.yaml
直接修改 yaml

再次查看 pod,等待它运行正常。
再次查看

3.4 cluster-configuration.yaml

使用私有仓库地址

kubectl apply -f cluster-configuration.yaml 
kubectl get pod -A

kubectl logs -f <ks-installer pod名> -n kubesphere-system --tail=10

查看日志

kubekey 安装ks 会有默认 storageclass,但是使用 ks-installer 安装,因为没有默认 storageclass 可能日志提示 "msg": "Default StorageClass was not found !",创建一个:

cat > local-sc.yaml<<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  annotations:
    cas.openebs.io/config: |
      - name: StorageType
        value: "hostpath"
      - name: BasePath
        value: "/var/openebs/local"
    openebs.io/cas-type: local
    storageclass.beta.kubernetes.io/is-default-class: "true"
    storageclass.kubesphere.io/supported-access-modes: '["ReadWriteOnce"]'
  name: local
provisioner: openebs.io/local
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: openebs-localpv-provisioner
    openebs.io/component-name: openebs-localpv-provisioner
    openebs.io/version: 3.3.0
  name: openebs-localpv-provisioner
  namespace: kube-system
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      name: openebs-localpv-provisioner
      openebs.io/component-name: openebs-localpv-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        name: openebs-localpv-provisioner
        openebs.io/component-name: openebs-localpv-provisioner
        openebs.io/version: 3.3.0
    spec:
      containers:
      - env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName
        - name: OPENEBS_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: OPENEBS_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.serviceAccountName
        - name: OPENEBS_IO_ENABLE_ANALYTICS
          value: "true"
        - name: OPENEBS_IO_INSTALLER_TYPE
          value: openebs-operator-lite
        - name: OPENEBS_IO_HELPER_IMAGE
          value: openebs/linux-utils:3.3.0
        # image: harbor.ygqygq2.com/proxy/openebs/provisioner-localpv:3.3.0
        image: openebs/provisioner-localpv:3.3.0
        imagePullPolicy: IfNotPresent
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - test 0 = 1
          failureThreshold: 3
          initialDelaySeconds: 30
          periodSeconds: 60
          successThreshold: 1
          timeoutSeconds: 1
        name: openebs-provisioner-hostpath
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: openebs-maya-operator
      serviceAccountName: openebs-maya-operator
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: openebs-maya-operator
  namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: openebs-maya-operator
rules:
- apiGroups: ["*"]
  resources: ["nodes", "nodes/proxy"]
  verbs: ["*"]
- apiGroups: ["*"]
  resources: ["namespaces", "services", "pods", "pods/exec", "deployments", "deployments/finalizers", "replicationcontrollers", "replicasets", "events", "endpoints", "configmaps", "secrets", "jobs", "cronjobs"]
  verbs: ["*"]
- apiGroups: ["*"]
  resources: ["statefulsets", "daemonsets"]
  verbs: ["*"]
- apiGroups: ["*"]
  resources: ["resourcequotas", "limitranges"]
  verbs: ["list", "watch"]
- apiGroups: ["*"]
  resources: ["ingresses", "horizontalpodautoscalers", "verticalpodautoscalers", "poddisruptionbudgets", "certificatesigningrequests"]
  verbs: ["list", "watch"]
- apiGroups: ["*"]
  resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"]
  verbs: ["*"]
- apiGroups: ["apiextensions.k8s.io"]
  resources: ["customresourcedefinitions"]
  verbs: [ "get", "list", "create", "update", "delete", "patch"]
- apiGroups: ["openebs.io"]
  resources: [ "*"]
  verbs: ["*"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: openebs-maya-operator
subjects:
- kind: ServiceAccount
  name: openebs-maya-operator
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: openebs-maya-operator
  apiGroup: rbac.authorization.k8s.io
EOF

kubectl apply -f local-sc.yaml

安装 openelb localpath storageclass,就会有镜像拉取问题了。所以你现在就可以尝试解决了。

openelb init

查看问题,可以看出来 init-pvc 的 pod 并不属于 deploy 啥的,它只是一个 pod,
查看问题

所以直接编辑 pod,因为也没有 deploy/sts/ds 给你编辑 init-pvc,
编辑pod

可以看到运行成功
正常完成

其它 2 个 pod 同理处理。如果想 pod 快速重启,直接删除 pod 即可,它自动会重启。

重启 pod

还在卡住

kubectl describe pod -n kubesphere-system openldap-0 看是什么状态,发现是 pvc 还没准备好。
查原因

查 localpv provisioner pod 日志
kubectl logs -f -n kube-system openebs-localpv-provisioner-7bbb56b778-mwrp5
日志
看来是 init pod存在

尝试删除 init-pvc pod
删除 pod

再次看日志
看到成功日志
pvc成功创建

看ks-installer pod 日志
看ks-installer pod 日志

如果 ks-installer POD 没有动作,你又想它执行任务,可以删除 ks-installer POD,kubectl delete pod <ks-installer pod名> -n kubesphere-system,它重启后,就会执行任务了。
重启ks-installer pod

看安装情况
查看pod

发现问题,重试几次都卡在这
重试几次都在这

把 minio 关了,删除它的 pvc
设置 pod为0
删除pvc

尝试恢复 pod,但是还是一样
恢复pod

helm list -n kubesphere-system 查看是否安装成功 minio,看到没安装成功
没有安装

进 ks-installer 手动安装,安装失败,发现其实只是没显示出来,安装名字可以看看正常集群是什么。uninstall 后,重启 ks-installer安装。
进ks-installer手动安装

查看日志,minio 安装成功,已经跳过了。
minio已经安装成功

继续看 pod 和日志
继续看pod

又有镜像拉取问题
发现又有镜像拉取问题

发现是 busybox 镜像,这个我提过 issue
busybox镜像

kubectl edit sts -n kubesphere-logging-system opensearch-cluster-master
改它

        image: harbor.ygqygq2.com/proxy/busybox:latest
        imagePullPolicy: IfNotPresent

后面镜像问题处理基本前面已经出现过,都能处理了。
ks 可能还有 CRD 处理镜像的,因为直接编辑无法修改,CRD 会还原,所以修改自定义的 CRD 资源来改镜像,比如 kubectl edit notificationManager notification-manager

4. 总结镜像失败处理

4.1 直接编辑资源 deploy、sts、ds 等

  • kubectl get pod -A 找一下有什么失败的 POD
  • kubectl describe pod <POD 名> [-n namespace] 查看 pod 状态
  • 修改资源 deploy/sts/ds 的镜像地址和拉取策略

4.2 无法修改资源修改镜像地址和拉取策略时

这种一般是程序(比如 ks)封装了,你虽然修改资源可以拉取镜像,但是它还是可能被恢复,那只能使用 tag 镜像方式,比如前面遇到的的 initContainers 使用 busybox:latestimagePullPolicy: "Always",如果镜像拉取策略无法被修改,这更麻烦。推荐命令有前面的 docker/nerdctl

在 pod 所在节点

nerdctl pull harbor.ygqygq2.com/proxy/library/busybox:latest --namespace k8s.io
nerdctl tag harbor.ygqygq2.com/proxy/library/busybox:latest busybox:latest --namespace k8s.io

然后就等 pod 自动重启。

4.3 helm chart 修改镜像仓库地址

推荐使用 bitnami/charts,写的很规范,因为它们都可以通过 values.yaml 中的 global.imageRegistry 设置镜像仓库地址,比如我的镜像都在 library 中,而且保持原镜像目录构建,则可以设置 global.imageRegistryharbor.ygqygq2.com/library

全局仓库地址

如果遇到不规范的 charts,而且它引用其它的 charts,可以从主 values.yaml 设置子 charts 的镜像地址设置,也可以直接修改子 charts 目录下的 values.yaml 来设置。

在使用 helm charts 安装应用时,推荐使用 helm pull 到本地安装,比如:

helm repo add kubesphere https://charts.kubesphere.io/stable
helm repo update
mkdir -p /data/helm # 专门建个目录管理安装的 helm charts
cd /data/helm
helm pull --untar kubesphere/openelb # 拉到本地
cd openelb
mkdir kube-system # 将要安装在这个命名空间下
rsync -avz ../values.yaml . # 不修改原 values.yaml,因为可能还要作参考
helm install openelb -f values.yaml ../ -n kube-system
### 获 `kubesphere/ks-installer:v3.3.1` 镜像文件 为了获并使用 `kubesphere/ks-installer:v3.3.1` 镜像文件,通常有几种方法可以实现这一目标。 #### 方法一:通过 Docker Hub 下载镜像 如果网络条件允许连接到互联网,则可以直接从 Docker Hub 上该版本的 KubeSphere 安装器镜像: ```bash docker pull kubesphere/ks-installer:v3.3.1 ``` 此命令会下载指定标签为 `v3.3.1` 的官方 KubeSphere 安装程序容器镜像[^1]。 #### 方法二:离线环境中准备镜像 对于无法直接访问外网的情况,在其他能够上网的机器上先完成上述操作之后,保存成 tar 文件再传输至目标主机加载入本地仓库: ```bash # 在联网设备执行如下指令打包镜像 docker save -o ks-installer_v3.3.1.tar kubesphere/ks-installer:v3.3.1 # 将生成好的 .tar 文件拷贝给待部署服务器后运行下面语句恢复数据 docker load < ks-installer_v3.3.1.tar ``` 这种方法适用于构建完全独立于公共网络资源供应链之外的企业级生产环境中的 Kubernetes 及其附加组件如 KubeSphere 平台本身及其依赖服务实例化所需的一切前置准备工作之一部分[^2]。 #### 方法三:利用私有 Harbor 或者其他 Registry 存储库同步镜像 企业内部往往已经搭建好了自己的镜像管理平台比如 VMware Tanzu、Harbor 等等。此时可以把所需的镜像推送到这些自定义地址下以便后续更方便快捷地调用它们而无需每次都重复以上过程;同时也便于实施安全策略控制谁有权推送新版本以及哪些团队成员被授权消息等内容[^3]。 ```bash # 登录到私有的 registry docker login your.private.registry.com # 打标签 docker tag kubesphere/ks-installer:v3.3.1 your.private.registry.com/path/to/kubesphere/ks-installer:v3.3.1 # 推送镜像 docker push your.private.registry.com/path/to/kubesphere/ks-installer:v3.3.1 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ygqygq2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值