容器镜像构建完成后,一般推送到容器镜像仓库,发布应用到Kubernetes集群后,由容器运行时(Docker,Containerd等)从容器镜像仓库中拉取镜像,本文介绍容器运行时进行登录认证的具体过程。
1、协商API版本
容器运行时首先调用容器镜像仓库 `/v2/` 接口
以Harbor为例,会返回
```
curl -v http://198.168.0.1:8021
* About to connect() to 198.168.0.1 port 8201 (#0)
* Trying 198.168.0.1...
* Connected to 198.168.0.1 (198.168.0.1) port 8201 (#0)
> GET /v2/ HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 198.168.0.1:8201
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Server: nginx
< Date: Fri, 28 Jul 2023 07:39:32 GMT
< Content-Type: application/json; charset=utf-8
< Content-Length: 76
< Connection: keep-alive
< Docker-Distribution-Api-Version: registry/2.0
< Set-Cookie: sid=e17055f453b5b9263cb16ff4b5d6ee3e; Path=/; HttpOnly
< Www-Authenticate: Bearer realm="http://198.168.0.1:8201/service/token",service="harbor-registry"
< X-Request-Id: f0520981-f61c-4b24-bc14-74614e4d8317
<
{"errors":[{"code":"UNAUTHORIZED","message":"unauthorized: unauthorized"}]}
```
容器镜像仓库一定返回401,在Header中包括
- `Docker-Distribution-Api-Version: registry/2.0`:确定api版本
- `Www-Authenticate: Bearer realm="http://198.168.0.1:8201/service/token",service="harbor-registry"`: 获取token的地址
2、使用用户名和密码登录
容器运行时调用 1 中反馈的获取token的地址 `http://198.168.0.1:8201/service/token`
用户名密码放在Header中,`Authorization: Basic ${basicToken}`,
其中 basicToken 使用 `echo ${username}:${password}|base64` 生成
```
curl -v -H "Authorization: Basic dXNlbmFtZTpwYXNzd29yZAo=" -H "service: harbor-registry" http://198.168.0.1:8201/service/token?service=harbor-registry
{
"token": "xxxxx.yyyyy.zzzzz",
"expires_in": 14400,
"issued_at": "2023-07-28T09:01:32Z"
}
```
其中 `xxxxx.yyyyy.zzzzz`是Harbor返回的jwt
后续操作包括推送、拉取镜像都要带上这个token
对于未登录的用户拉取镜像时,也是先经过1、2,获取到一个匿名用户的token