美文网首页KubernetesDocker容器程序员
How to Use a Private Docker Regi

How to Use a Private Docker Regi

作者: iCaptain | 来源:发表于2017-07-23 20:00 被阅读124次

    Kubernetes中使用私有镜像仓库

    Kubernetes应用在生产环境中时,一般都会搭建一套私有的镜像仓库。在使用私有镜像仓库pull镜像时需要密钥,可以提前在节点上pull所需镜像,也可以使用ImagePullSecrets来解决这个问题。

    Note: 本文使用Harbor作为私有镜像仓库。

    1. Docker login(方案一)

    Docker pull 公有镜像仓库中的镜像时不需要认证信息,但pull私有仓库需要认证信息,所以需要用户提前登陆才可以pull该用户的镜像。

    登陆成功之后会生成一个文件 $HOME/.docker/config.json或$HOME/.dockercfg,$HOME/.docker/config.json内容如下所示:

    {
            "auths": {
                    "10.10.101.101": {
                            "auth": "YWRtaW46MTIz"
                    }
            }
    }
    

    $HOME/.dockercfg内容如下所示:

    {
        "10.100.100.77": {
              "username":"hc",
              "password":"Harbor123456",
              "email":" ",
              "auth":"aGM6SGFyYm9yMTIzNDU2"
            }
    }
    

    Note: auth为“用户名:密码”经base64加密后的字符串

    确保集群所有节点都有.docker/config.json,可以通过Kubernetes直接创建Pod,因为有了认证信息Docker可以直接从仓库里面pull镜像。

    2. 提前pull镜像(方案二)

    通常情况下,Kubelet组件会从指定的镜像仓库pull所有需要的镜像;

    如果imagePullPolicy设为IfNotPresentNever,将会使用本地镜像;

    如果使用提前pull所需镜像作为一种方案,必须确保及群中所有的节点都有所需的镜像;

    这种方案可以节约pull镜像所需时间,也可以作为私有镜像仓库身份认证的一种替代方法;

    3. ImgePullSecrets(方案三)

    3.1 用户名、密码加密(base64)

    # echo -n "hc" | base64
    aGM=
    # echo -n "Harbor12345" | base64
    SGFyYm9yMTIzNDU=
    

    3.2 解密

    # echo "SGFyYm9yMTIzNDU=" | base64 --decode
    Harbor12345
    

    3.3 Kubectl Create Secret
    在tom namespace中创建myregistrysecret,这种方式实际上创建了一个.dockercfg

    # kubectl create secret docker-registry myregistrysecret --docker-server=10.100.100.77 --docker-username=hc --docker-password=Harbor12345 --docker-email=" " -n tom
    secret "myregistrysecret" created
    

    如果需要访问多个私有仓库,可以给每个仓库创建一个secret,Kubelete在为Pod拉镜像时会把imagePullSecret合并到一个.docker/config.json文件中;需要注意的是,imagePullSecrets资源对象是属于namespace的。

    3.4 yaml文件创建Secret
    前面提到Docker登陆之后会生成两种类型的认证文件,Kubernetes同样支持创建这两种类型的ImagePullSecrets。

    .docker/config.json 类型的ImagePullSecrets

    # .docker/config.json 结构如下所示
    {"auths": {"10.100.100.77": {"auth": "Y2FwdGFpbjpDYXB0YWluODg4"}}}
    
    # 对.docker/config.json进行加密 
    # Note: 这里应特别注意使用\对分号“”进行转义,否则加密后的字符串会报错
    # echo -n "{\"auths\": {\"10.100.100.77\": {\"auth\": \"Y2FwdGFpbjpDYXB0YWluODg4\"}}}" | base64
    eyJhdXRocyI6IHsiMTAuMTAwLjEwMC43NyI6IHsiYXV0aCI6ICJZMkZ3ZEdGcGJqcERZWEIwWVdsdU9EZzQifX19
    
    #创建secret
    apiVersion: v1
    kind: Secret
    metadata:
      name: configjson
      namespace: tom
    data:
      .dockerconfigjson: eyJhdXRocyI6IHsiMTAuMTAwLjEwMC43NyI6IHsiYXV0aCI6ICJZMkZ3ZEdGcGJqcERZWEIwWVdsdU9EZzQifX19
    type: kubernetes.io/dockerconfigjson
    

    .dockercfg 类型的ImagePullSecrets

    # .dockercfg 结构如下所示: 
    {"10.100.100.77":{"username":"captain","password":"Captain888","email":" ","auth":"Y2FwdGFpbjpDYXB0YWluODg4"}}
    
    # 对.dockercfg文件进行加密
    # echo "{\"10.100.100.77\":{\"username\":\"captain\",\"password\":\"Captain888\",\"email\":\" \",\"auth\":\"Y2FwdGFpbjpDYXB0YWluODg4\"}}" | base64 
    eyIxMC4xMDAuMTAwLjc3Ijp7InVzZXJuYW1lIjoiY2FwdGFpbiIsInBhc3N3b3JkIjoiQ2FwdGFpbjg4OCIsImVtYWlsIjoiICIsImF1dGgiOiJZMkZ3ZEdGcGJqcERZWEIwWVdsdU9EZzQifX0K
    
    # 创建secret
    apiVersion: v1
    kind: Secret
    metadata:
      name: dockercfg
      namespace: tom
    data:
      .dockercfg: eyIxMC4xMDAuMTAwLjc3Ijp7InVzZXJuYW1lIjoiY2FwdGFpbiIsInBhc3N3b3JkIjoiQ2FwdGFpbjg4OCIsImVtYWlsIjoiICIsImF1dGgiOiJZMkZ3ZEdGcGJqcERZWEIwWVdsdU9EZzQifX0K
    type: kubernetes.io/dockercfg
    

    3.5 使用ImagePullSecrets
    使用ImagePullSecrets创建Pod,yaml文件如下;

    apiVersion: v1
    kind: Pod
    metadata:
      name: foo
      namespace: tom
    spec:
      containers:
        - name: foo
          image: 10.100.100.77/captain/nginx
      imagePullSecrets:
        - name: configjson          #这里使用上面创建的2个ImagePullSecrets进行验证
    

    4. 添加ImgePullSecrets到ServiceAccount(方案四)

    ServiceAccount也是授权认证的一种方式,用于Pod内的进程与kube-apiserver通信时进行权限验证,后面会对ServiceAccount进行详解;创建namespace时,会默认创建一个名为default的serviceAccount;

    按照3.4中的方法创建imagePullSecrets,并确保已经创建成功;

    编辑默认serviceAccount default,添加imagePullSecrets,如下:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: 2017-06-03T10:14:35Z
      name: default
      namespace: tom
      resourceVersion: "3286613"
      selfLink: /api/v1/namespaces/tom/serviceaccounts/default
      uid: 71f62f3b-4845-11e7-8a65-005056bc0f6b
    secrets:
    - name: default-token-bwh8x
    # -----------------------------添加以下内容-------------------------------
    imagePullSecrets:
    - name: configjsons
    # -----------------------------添加内容结束-------------------------------
    

    5. 小结

    本文概述了私有镜像仓库的四种方案,各有优劣;
    方案一,使用过程比较繁琐,在集群环境节点很多的情况下,每个节点登陆Docker无疑是一个非常繁琐的过程;
    方案二,提前pull镜像,解决了权限认证的问题,但需要每个节点上都提前pull需要的镜像,这无疑也是一个非常繁琐的过程;另外,如果在一个有100个节点的集群中创建一个副本为3的rc,这100个节点都要提前pull镜像,会造成不必要的资源浪费;如果集群扩容新加节点,而这些节点没有之前的镜像,那么之前的应用将无法调度到这些新加的节点;
    方案三,目前而言是相对较好的一个方案,适用于多租户环境下,可以细化到每个用户一个imagePullSecret; 创建Pod需要镜像的时候,通过imagePullSecrets的方式pull所需镜像,不会造成磁盘资源的浪费,也保证了镜像的安全性;
    方案四,有一定优势,但不太适用于在多租户的环境下;
    当然,使用哪种方式,还要根据实际情况而定,希望对你有所帮助!

    相关文章

      网友评论

        本文标题:How to Use a Private Docker Regi

        本文链接:https://www.haomeiwen.com/subject/lwkmfxtx.html