概述

  Harbor使用了基于角色的访问控制策略,当从nexus/docker-register中拉去镜像的时候,首先要进行身份认证,认证通过后才可以拉取镜像。在命令行模式下,需要先执行docker login,登陆成功后,才可以docker pull。通常情况下,在私有云环境中使用kubernetes时,我们要从docker registry拉取镜像的时候,都会给docker daemo配置 --insecure-registry 属性来告诉docker daemo我们所使用的docker registry是可信的,这样才能从私有的docker registry中拉取镜像,但是如果要使用nexus作为kubernetes的镜像仓库的话,这种方式就不适用了,下面让我们看看如何来使用nexus作为kubernetes的镜像仓库。

实现探索

  我们在命令行方式下,输入docker login登陆成功后,会在/root/.docker/目前下生成一个config.json文件。打开后可以看到如下的内容:

root@k8s-master:~/pods/kuber/jenkins # cat ~/.docker/config.json 
{
"auths": {
"10.30.30.127:4443": {
"auth": "YWRtaW46YWRtaW4xMjM="
},
"10.30.30.127:8082": {
"auth": "YWRtaW46YWRtaW4xMjM="
},

}#             

Secret

Kubernetes提供了Secret来处理敏感信息,目前Secret的类型有3种: 
Opaque(default): 任意字符串 
kubernetes.io/service-account-token: 作用于ServiceAccount
kubernetes.io/dockercfg: 作用于Docker registry(nexus),用户下载docker镜像认证使用。

Opaque Secret

Opaque Secret就是字符串

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

在使用的时候可以选择已volume方式或者是已环境变量的方式放到容器内使用。

{
 "apiVersion": "v1",
 "kind": "Pod",
  "metadata": {
    "name": "mypod",
    "namespace": "default"
  },
  "spec": {
    "containers": [{
      "name": "mypod",
      "image": "busybox",
      "command": ["sleep","3600"],
      "imagePullPolicy": "IfNotPresent",
      "volumeMounts": [{
        "name": "foo",
        "mountPath": "/etc/foo",
        "readOnly": true
      }]
    }],
    "volumes": [{
      "name": "foo",
      "secret": {
        "secretName": "mysecret"
      }
    }]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

这样就可以通过文件的方式挂载到容器内,在/etc/foo目录下回生成这个文件。

如果是环境变量当然也是ok的

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
    - name: mycontainer
      image: busybox
      imagePullPolicy: IfNotPresent
      command:
        - sleep
        - "3600"
      env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: SECRET_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

进入容器通过env命令,你将可以看到这两个环境变量被注入到容器内。

imagePullSecrets

当在需要安全验证的环境中拉取镜像的时候,需要通过用户名和密码。

apiVersion: v1
kind: Secret
metadata:
  name: myregistrykey
  namespace: awesomeapps
data:
  .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
type: kubernetes.io/dockerconfigjson
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

或者直接通过命令创建

kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
  • 1

接下来拉取镜像的时候,就可以使用了

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: myregistrykey
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

其实本质上还是kubelet把这个认证放到了docker的目录下面,如下:

cat ~/.docker/config.json 
{
    "auths": {
        "10.39.0.118": {
            "auth": "Y2hlbm1vOmNtMTM4MTE2NjY3ODY="
        },
        "10.39.0.12:5000": {
            "auth": "dXNlcjAxOjEyMzQ1YQ=="
        },
        "http://10.39.0.12:5000": {
            "auth": "dXNlcjAxOjEyMzQ1YQ=="
        }
    }
}
https://www.kubernetes.org.cn/1991.html

这里的内容就是docker daemon用来与docker registry进行认证的,其中,10.30.30.127:4443是docker registry server的地址,auth部分是加密后的认证信息,格式为:username:password,当输入命令docker pull的时候,docker daemon会获取该文件中的信息,并将auth部分的信息携带在请求的头部向docker registry server发送请求,docker registry server对请求认证通过后,就可以开始拉取镜像了,这部分的交互细节请参阅《从源码看Docker Registry v2中的Token认证实现机制》。那么如何使kubernetes通过docker registry的认证来获取镜像呢?通过翻阅kubernetes的相关文档,我们发现,kubernetes提供了2个对象:secret和serviceAccount,我们先来看下官方给出的定义:

  - secret:是一个保存少量诸如密码,token等敏感数据的对象,采用secret方式保存可以获取更好的控制力和减少敏感数据意外暴露的风险。secret对象的用途有:作为文件挂载到容器中或者是在kubelet拉取镜像时使用。

  - serviceAccount:为运行在pod中的进程提供身份信息。

看到了吗,kubernetes已经告诉了我们问题的答案。没错,使用secret和serviceAccount就可以实现kubernetes在创建pod的时候通过docker registry server的认证来拉取镜像。下面我们看下如何来使用这2个对象。

    1. 创建secret:

    有2种方式可以创建secret:

    a. 使用命令行:

kubectl create secret docker-registry SECRET_NAME --namespace=NAME_SPACE \      --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER \
      --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

   其中,
docker-server 为通过docker login登陆时输入的地址
docker-username 为登陆时的账号
docker-password 为登陆时的密码

docker-email 为注册的账号时的邮箱地址


图中data部分,dockercfg为data的类型,后面的一长串即为进过base64加密的内容,通过解密后,你就会发现,里面的内容基本上就是/root/.docker/config.json中的内容。

b. 定义yaml文件: 



   其中的type必须是:kubernetes.io/dockercfg

2. 创建serviceAccount 

serviceaccount.yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
name: build-robot

$ kubectl create -f serviceaccount.yaml
serviceaccounts/build-robot

$ kubectl get serviceaccounts/build-robot -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2015-08-14T09:59:39Z
name: build-robot
namespace: default
resourceVersion: "538168"
selfLink: /api/v1/namespaces/default/serviceaccounts/build-robot
uid: 2d55527f-426b-11e5-91cd-005056817c3e
secrets:
- name: build-robot-token-3uazg

可以看到ServiceAccount默认创建一个secret,也可以手动创建secret然后添加到ServiceAccount。

创建Pod使用ServiceAccount,
busybox-pod.yaml:

apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- image: busybox
command:
  - sleep
  - "3600"
imagePullPolicy: IfNotPresent
name: busybox
serviceAccountName: build-robot

 3.在pod中使用: 

04.png
参考:http://dockone.io/article/599                                       
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐