支持 Kubernetes VIM 身份验证的 OpenID¶
https://blueprints.launchpad.net/tacker/+spec/support-openid-k8s-vim
问题描述¶
Kubernetes VIM 中存在多种身份验证方式。目前,Tacker 已经支持使用服务帐户令牌作为 bearer token 进行身份验证。本规范建议 Tacker 支持 OpenID Connect Token [1] 作为 bearer token 进行身份验证。OpenID Connect 由 OpenID Connect Core 1.0 [2] 定义。
提议的变更¶
下图显示了使用 OpenID Connect 进行身份验证的图像
+----------------+ 1.setup OpenID Provider(IdP)
| +----------------------------------------------------------------+
| User | 2.setup Kubernetes |
| +----------------------------------------+ |
+-----+------+---+ | |
6.CNF LCM | | 3.register vim | |
(e.g. instantiate)| | | |
| | | |
+-----------------------------------------------------+ +---v---------+ +--------v--------+
| | | | | VIM | | |
| +-------v------v---+ 4.create vim +------------+ | | (Kubernetes | | OpenID Provider |
| | +-----------------> | | | API Server) | | (Keycloak etc.) |
| | Tacker-server | | NFVOPlugin | | | | | |
| | +-----+ | | | +---^---------+ +--------^--------+
| +-------+----------+ | +------+-----+ | | |
| | 8.create | 5.save | | | |
| | resource | VimAuth | | | |
| +------------------+ |7.get +------v-----+ | | |
| | +-----v--------+ | |VimAuth | | | |10.call Kubernetes API |
| | | | | +-----------> TackerDB | | | |
| | | InfraDriver | | | | | | |
| | | (Kubernetes) | | +------------+ | | |
| | | +------------------------------------------+ 9.get token |
| | | +------------------------------------------------------------------+
| | +--------------+ | |
| | Tacker-conductor | |
| +------------------+ Tacker |
+-----------------------------------------------------+
登录到 OpenID 提供程序(IdP),创建客户端,添加用户和组,等等。
配置 Kubernetes API 服务器以启用 OpenID Connect(OIDC) 插件。
使用命令或 API 注册 VIM。
此步骤仅适用于 V1 LCM 操作。在 V2 LCM 操作中,身份验证参数可以由每个 LCM 请求中的 VimConnectionInfo 传递,因此不再需要此步骤。
调用 NFVOPlugin 类的 create vim 方法。
将 client_id、client_secret、username、password、token_url、ssl_ca_cert 存储到 TackerDB。
执行 CNF LCM 操作(例如实例化)。
从 TackerDB 获取 client_id、client_secret、username、password、token_url、ssl_ca_cert。
调用 InfraDriver 的 Kubernetes 客户端方法以创建资源。
使用 client_id、client_secret、user_name、password、token_url、ssl_ca_cert 从 IdP 获取 id_token。
使用 id_token 调用 Kubernetes APIs。
注意
IdP 已经与 Keycloak [3] 进行了调查。使用其他 IdP 是否存在差异需要进一步调查。
支持 OIDC 身份验证需要以下更改
VIM APIs 中的更改
Kubernetes Infra Driver 中的更改
1) VIM APIs 中的更改¶
如上所述,Tacker 对 OIDC 身份验证的支持需要以下参数
client_id
client_secret
username
password
token_url
ssl_ca_cert
注意
client_id 是 IdP 中 Tacker (OIDC 客户端) 的标识符。
username 是 IdP 中用户的标识符。
username 将包含在 id_token (JSON Web Token) 中。
调用 Kubernetes APIs 时,id_token 中的 username 将被验证它对 Kubernetes 具有哪些权限。
Register VIM API [4] 的请求参数应设置为如下
username、password 和 ssl_ca_cert 设置在
auth_cred中。client_id 和 client_secret 应作为
auth_cred中的新字段添加。在使用服务帐户令牌进行身份验证时,
auth_url设置为 Kubernetes 的端点。在使用 OpenID Connect Token 进行身份验证时,auth_url仍然设置为 Kubernetes 的端点,并且应在auth_cred中添加一个新字段oidc_token_url用于设置 IdP 的端点。
因此,需要修改以下函数。
VIM 命令组(register/set/list/show)
VIM API 组(register/update/list/show)
VIM 配置¶
Kubernetes 的 VIM 配置示例文件
vim_config.yaml
auth_url: 'https://192.168.2.82:6443'
oidc_token_url: 'https://192.168.2.81:8443/auth/realms/kubernetes/protocol/openid-connect/token'
project_name: "default"
username: 'end-user'
password: 'end-user'
client_id: 'tacker'
client_secret: 'E3xaNpB8reiUuEyrD8y6wQ1obPJAtbbU'
ssl_ca_cert: |
-----BEGIN CERTIFICATE-----
MIICwjCCAaqgAwIBAgIBADANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwdrdWJl
LWNhMB4XDTIwMDgyNjA5MzIzMVoXDTMwMDgyNDA5MzIzMVowEjEQMA4GA1UEAxMH
a3ViZS1jYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALxkeE16lPAd
pfJj5GJMvZJFcX/CD6EB/LUoKwGmqVoOUQPd3b/NGy+qm+3bO9EU73epUPsVaWk2
Lr+Z1ua7u+iib/OMsfsSXMZ5OEPgd8ilrTGhXOH8jDkif9w1NtooJxYSRcHEwxVo
+aXdIJhqKdw16NVP/elS9KODFdRZDfQ6vU5oHSg3gO49kgv7CaxFdkF7QEHbchsJ
0S1nWMPAlUhA5b8IAx0+ecPlMYUGyGQIQgjgtHgeawJebH3PWy32UqfPhkLPzxsy
TSxk6akiXJTg6mYelscuxPLSe9UqNvHRIUoad3VnkF3+0CJ1z0qvfWIrzX3w92/p
YsDBZiP6vi8CAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgKkMA8GA1UdEwEB/wQFMAMB
Af8wDQYJKoZIhvcNAQELBQADggEBAIbv2ulEcQi019jKz4REy7ZyH8+ExIUBBuIz
InAkfxNNxV83GkdyA9amk+LDoF/IFLMltAMM4b033ZKO5RPrHoDKO+xCA0yegYqU
BViaUiEXIvi/CcDpT9uh2aNO8wX5T/B0WCLfWFyiK+rr9qcosFYxWSdU0kFeg+Ln
YAaeFY65ZWpCCyljGpr2Vv11MAq1Tws8rEs3rg601SdKhBmkgcTAcCzHWBXR1P8K
rfzd6h01HhIomWzM9xrP2/2KlYRvExDLpp9qwOdMSanrszPDuMs52okXgfWnEqlB
2ZrqgOcTmyFzFh9h2dj1DJWvCvExybRmzWK1e8JMzTb40MEApyY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDgTCCAmkCFBkaTpj6Fm1yuBJrOI7OF1ZxEKbOMA0GCSqGSIb3DQEBCwUAMH0x
CzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZTdXpob3Ux
DTALBgNVBAoMBGpmdHQxDDAKBgNVBAsMA2RldjEUMBIGA1UEAwwLdGFja2VyLmhv
c3QxGDAWBgkqhkiG9w0BCQEWCXRlc3RAamZ0dDAeFw0yMjAzMDgwMjQ2MDZaFw0y
MzAzMDgwMjQ2MDZaMH0xCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdKaWFuZ3N1MQ8w
DQYDVQQHDAZTdXpob3UxDTALBgNVBAoMBGpmdHQxDDAKBgNVBAsMA2RldjEUMBIG
A1UEAwwLdGFja2VyLmhvc3QxGDAWBgkqhkiG9w0BCQEWCXRlc3RAamZ0dDCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALIUIDZLvKs7NKBZo+172uH9dftL
pNM4dGgfc4jvmFjZswDex9Vqrlt7pcdrorlv2w3PWyODEzmx98EsDxVtrBNPP5lQ
aGk6zVtC7J7trIODqD/xhS8G2H4weX1znx0NVi50pqDxVxqeXO11rwtglJ7Wwkp6
R9dkMbr3ZHWWKEZauBWX4NX16XErniSemW8Co/Oa3coX7CtrSzRCDJJcD8MdMFBE
m02obSh88N+YJPRLBBIGl2JfZdD0IZldUe9RozhGA80gcJeLiVoNeVIpznc/LGTr
xHWOb2Wh0yP6gl3KX4JjJ0NubZPaskUHILFN34F5a3fVQE3t7dQk8jq7JlMCAwEA
ATANBgkqhkiG9w0BAQsFAAOCAQEAH0B2qgwKjWje0UfdQOb1go8EKsktHOvIDK5+
dXz2wNFJpKCekvSGK4/2KEp1McTTDj0w8nlWcGZgaOcvjuq8ufWrggjdADa2xJHr
4pfxNMQrQXCFZ5ikCoLDx9QKDyN81b12GWpr1yPYIanSghbhx4AW7BkVQwtELun8
d6nHGTixkqxljbEB9qM/wOrQMlm/9oJvyU4Po7weav8adPVyx8zFh9UCH2qXKUlo
3e5D8BKkBpo4DtoXGPaYBuNt/lI7emhfikcZ2ZbeytIGdC4InoooYMKJkfjMxyim
DSqhxuyffTmmMmEx1GK9PYLy7uPJkfn/mn9K9VL71p4QnJQt7g==
-----END CERTIFICATE-----
type: "kubernetes"
注意
参数 auth_cred.ssl_ca_cert 包含 2 个证书。一个用于 VIM,一个用于 IdP。
V1/V2 LCM API 的参数¶
如上所述,VIM 注册仅适用于 V1 LCM API。以下显示了使用 V1 实例化 API 的请求参数示例。
{
"flavourId": "simple",
"additionalParams": {
"lcm-kubernetes-def-files": [
"Files/kubernetes/stateful_set.yaml"
]
},
"vimConnectionInfo": [
{
"id": "8a3adb69-0784-43c7-833e-aab0b6ab4470",
"vimId": "8d8373fe-6977-49ff-83ac-7756572ed186"
"vimType": "kubernetes"
}
]
}
在 V2 LCM API 中,身份验证信息可以包含在每个 LCM 请求参数中的 VimConnectionInfo 中,因此 V2 实例化 VNF 的请求参数示例如下
{
"flavourId": "simple",
"additionalParams": {
"lcm-kubernetes-def-files": [
"Files/kubernetes/stateful_set.yaml"
]
},
"vimConnectionInfo": {
"vim1": {
"vimType": "kubernetes",
"accessInfo": {
"oidc_token_url": "https://keycloak.example.com:8443/realms/sample-realm/protocol/openid-connect/token",
"username": "user",
"password": "password",
"client_id": "sample-client-id",
"client_secret": "sample-secret"
},
"interfaceInfo": {
"endpoint": "https://k8s.example.com:6443",
"ssl_ca_cert": "sample-ssl-ca-cert"
}
}
}
}
1) Kubernetes Infra Driver 中的更改¶
调用 Kubernetes APIs 的流程如下所示(以 instantiate 为例)
客户端向 Tacker-server 发送请求以实例化 vnf。
Tacker-server 从 TackerDB 获取
vimAuth,并调用 Tacker-conductor 的 instantiate rpc-api。Tacker-conductor 调用 VnfLcmDriver 的 instantiate_vnf 方法。
VnfLcmDriver 调用 InfraDriver(Kubernetes) 的 instantiate_vnf。
InfraDriver(Kubernetes) 向 IdP 发送请求以获取 id_token。
InfraDriver(Kubernetes) 使用 id_token 向 Kubernetes 发送请求以创建资源。
注意
每个 LCM 操作(instantiate、terminate 等)将从 IdP 获取一个单独的 token,并且该 token 将在一次 LCM 处理中用于所有对 Kubernetes VIM 的 API 调用。
从 IdP 获取 token¶
从 IdP 获取 token 需要以下参数
token_url
client_id
client_secret
username
password
ssl_ca_cert
grant_type(值为固定为“password”)
scope(值为固定为“openid”)
通过 curl 获取 token 的示例
curl --cacert cacert.crt -d "grant_type=password" -d "scope=openid" \
-d "client_id=kubernetes" -d "client_secret=E3xaNpB8reiUuEyrD8y6wQ1obPJAtbbU" \
-d "username=tacker" -d "password=tacker" \
https://keycloakserver:8443/realms/kubenetes/protocol/openid-connect/token
备选方案¶
无
数据模型影响¶
如上所述,OIDC 身份验证需要 client_id、client_secret、username、password、token_url、ssl_ca_cert。
以下字段不会更改
username 位于
VimAuth.auth_cred.usernamepassword 位于
VimAuth.passwordssl_ca_cert 位于
VimAuth.ssl_ca_cert
需要在 VimAuth.auth_cred 中扩展以下字段
client_id 将位于
VimAuth.auth_cred.client_idclient_secret 将位于
VimAuth.auth_cred.client_secretoidc_token_url 将位于
VimAuth.auth_cred.oidc_token_url
由于 VimAuth.auth_cred 是一个 json,因此表实际上不需要任何更改。
注意
为了安全起见,client_secret 也可能需要使用 fernet 与 password 一起加密。
REST API 影响¶
VIM APIs 中的 auth_cred 将添加以下字段
client_id
client_secret
oidc_token_url
需要更改以下 APIs
Register VIM: POST /v1.0/vims (
auth_cred在 Request 和 Response 参数中)List VIMs: GET /v1.0/vims (
auth_cred在 Response 参数中)Show VIM: GET /v1.0/vims/{vim_id} (
auth_cred在 Response 参数中)Update VIM: PUT /v1.0/vims/{vim_id} (
auth_cred在 Request 和 Response 参数中)
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
无
开发人员影响¶
无
实现¶
负责人¶
- 主要负责人
Masaki Ueno<masaki.ueno.up@hco.ntt.co.jp>
- 其他贡献者
Qibin Yao <yaoqibin@fujitsu.com>
Ayumu Ueha<ueha.ayumu@fujitsu.com>
Yoshiyuki Katada <katada.yoshiyuk@fujitsu.com>
Yusuke Niimi<niimi.yusuke@fujitsu.com>
工作项¶
实现支持
扩展 VIM 命令组中的 client_id 和 client_secret 在
auth_cred中。扩展 VIM APIs 中的 client_id 和 client_secret 在
auth_cred中。添加使用 id_token 调用 Kubernetes 的逻辑。
修改 vim 配置生成工具 (gen_vim_config.sh) 以添加 client_id 和 client_secret。
添加新的单元和功能测试。
依赖项¶
无
测试¶
将添加单元和功能测试,以涵盖规范所需的用例。
文档影响¶
API 指南将在 VIM APIs 的
auth_cred中添加 client_id 和 client_secret。用户指南将添加有关如何使用 IdP 验证 Kubernetes 中用户的手册。