基于k8s集群免密拉取需认证的仓库镜像

一、环境背景

1、k8s集群,1.17+,目前k8s最新版本已更新至V1.31版本;

2、镜像仓库,如harbor、registry、portus、nexus等;

3、配置镜像仓库用户登录认证,参考资料如下:

harbor参考:https://www.geekby.cn/posts/harbor-https/

registry参考:https://www.cnblogs.com/chen2ha/p/14787695.html

二、优雅拉取镜像

k8s集群内部与docker通信机制如下:

kubelet——>docker shim——>docker-daemon(grpc接口)-containerd-socket--containerd-{containerd-shim-runcontainer————(单个进程与一个容器相对应)}

当需要下载镜像时,docker根据daemon.json文件中的insecure-registries配置参数,拉取镜像。

       如果私有镜像仓库设置了用户认证,kubelet无法直接拉取镜像,在创建容器中会报错:“Failed to pull image”,查看日志定位为:访问镜像仓库失败;通过以下方法可以正常拉取私有镜像仓库镜像。

2.1基于secret方式实现

       k8s集群内置的密钥(secret)机制,可以完成此需求。

#secret分类

$ kubectl  create secret -h

Create a secret using specified subcommand.



Available Commands:

  docker-registry   创建一个给 Docker registry 使用的 secret

  generic         从本地 file, directory 或者 literal value 创建一个 secret

  tls             创建一个 TLS secret

2.1.1 创建docker-registry 类型的secret

#基于k8s集群的名字空间隔离机制,需指定名字空间(注意:创建的secret只在此名字空间下生效)

kubectl  create secret  docker-registry  -n NAMESPACE  registry  \

              --docker-server=*****.cn \         #填写镜像仓库的ip或域名

              --docker-username=test  \         #填写登录名

              --docker-password=12345678      #填写用户名对应的登录密码

建完成后,查看secret内容:

$ kubectl  get  secret  -n  NAMESPACE

NAME                  TYPE                                  DATA   AGE
registry              kubernetes.io/dockerconfigjson        1      


$ kubectl  get  secret  registry  -t  NAMESPACE  -o yaml
kind: Secret
apiVersion: v1
metadata:
  name: registry
  namespace: NAMESAPCE
data:
  .dockerconfigjson: >-
    eyJHHSDIAHSIDHAhaishdasphdoasjdaoisjdoaisjdoiasjdoaisjdoi  #生成的dockerconfigjson配置,解码后可以得到镜像仓库的用户名及密码
type: kubernetes.io/dockerconfigjson

.1.2 使用secret完成优雅拉取镜像

secret调用需使用imagePullSecrets参数,有两种调用方法,一种是直接写入服务的yaml文件中,另一种是写入服务运行所使用的serviceaccount中,具体如下:

①写入服务yaml中

#deploy类型服务的yaml文件
kind: Deployment
apiVersion: apps/v1
metadata:
  name: text
  namespace: NAMESPACE
  labels:
    app: cc
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cc
spec:
  imagePullSecrets:
  - name: registry(创建的密钥名称)
  containers:
    - name: container-neji8o
       image: alpine:latest
       command:
         - sleep
       args:
         - '11111'
  restartPolicy: Always

写入服务使用servceaccount的yaml中:使用此serviceaccount所运行服务均可以正常拉取镜像

#serviceaccountk8s集群对于pod的认证凭证

kubectl edit sa default -n NAMESPACE

---

添加如下内容:

imagePullSecrets:

- name: registry(创建的密钥名称)

---

#完整版如下:

apiVersion: v1

imagePullSecrets:

- name: registry(创建的密钥名称)

kind: ServiceAccount

metadata:

  name: default

  namespace: NAMESPACE

secrets:

- name: default-token-dfsfas

#不要忘记进行拉取镜像验证,过程没问题即可完成镜像拉取;

2.2基于config.json方式实现

       在2.1章节中,基于k8s集群层面,通过传参的方式使docker获得登录用户及密码,而官网中定义了一种更简单的方法,通过在kubelet的工作目录下添加config.json配置,亦可达到相同效果(官方文档中默认配置文件名称为:config.json,如有改名需求,参考官方文档进行改正,此篇文档不赘述)。

2.2.1 创建config.json文件

#通过加密用户名及密码生成auth

$ echo -n ‘USER:PASSWORD’ | base64 -d

#跳转到kubelet工作目录下,默认是/var/lib/kubelet,具体生产环境可能会产生变更;

$cd  kubelet

$vim config.json

{

        "auths": {

                "******.cn(仓库域名或ip)": {

                        "auth": "************base64生成的auth值)"

                }

        }

}

#保存退出后需重启kubelet

#不要忘记进行拉取镜像验证,过程没问题即可完成镜像拉取

三、参考文档

k8s官网:https://kubernetes.io/docs/concepts/containers/images/#configuring-nodes-to-authenticate-to-a-private-registry

你可能感兴趣的:(kubernetes,docker,linux,http)