如何将 kubernetes secret 创建为 json 对象,并在 kubernetes 环境中加载相同的 jso



我需要将 JWK 作为 kubernetes 环境变量传递给我的应用程序。

我创建了一个文件来存储我的密钥,如下所示:

cat deploy/keys/access-signature-public-jwk 
{
algorithm = "RS256"
jwk = {"kty":"RSA","e":"AQAB","n":"ghhDZxuUo6TaSvAlD23mLP6n_T9pQuJsFY4JWdBYTjtcp_8Q3QeR477jou4cScPGczWw2JMGnx-Ao_b7ewagSl7VHpECBFHgcnlAgs5j6jfnd3M9ADKD2Yc756iXlIMT9xKDblIcXQQYlXalqxGvnLRLv1KAgVVVpVWzQd6Iz8WdTnexVrh7L9N87QQbOWcAVWGHCWCLCBsVE7JbC-XDt9h9P1g1sMqMV-qp7HjSXUKWuF2NwOnL2VeFSED7gdefs2Za1UYqhfwxdGl7aaPDXhjib0cfg4NvbcXMzxDEVkeJqhdDfD82wHOs4qFvnFMVxq9n6VVExSxsJq8gBJ7Z2AmfoXpmZC1L1ZwULB2KKpFXDCzgBELPLrfyIf8mNnk2nuuLT-aaMsqy2uB-ea3du4lyWo9MLk6x-L5g-n1oADKFKBY9aP2QQwruCG92XSd7jA9yLtbgr9OGVCYezxIxFp4vW6KcmPwJQjozWtwkZjeo4hv-zhRac73WDox2hDkif7WPTuEvC21fRy3GvyPIUPKPJA8pJjb2TXT7DXknR97CTnOWicuh3HMoRlVIwUzM5SVLGSXex0VjHZKgLYwQYukg5O2rab_4NxpD6LqLHx1bbPssC7BedCIfWX1Vcae40tlfvJAM09MiwQPZjWRahW_fK_9X5F5_rtUhCznm32M"}
}

然后用于创建一个 kubernetes 密钥,如下所示:

kubectl create secret generic intimations-signature-public-secret --from-file=./deploy/keys/access-signature-public-jwk

然后在 kubernetes 环境变量中将其重新衍生为:

- name: ACCESS_SIGNATURE_PUBLIC_JWK
valueFrom:
secretKeyRef:
name: intimations-signature-public-secret
key: access-signature-public-jwk

并传递给应用程序的application.conf,如下所示:

pac4j.lagom.jwt.authenticator {
signatures = [
${ACCESS_SIGNATURE_PUBLIC_JWK}
]
}

pac4j 库期望将配置pac4j.lagom.jwt.authenticator作为 json 对象。但是当我运行此应用程序时会出现以下异常:

com.typesafe.config.ConfigException$WrongType: env variables: signatures has type list of STRING rather than list of OBJECT
at com.typesafe.config.impl.SimpleConfig.getHomogeneousWrappedList(SimpleConfig.java:452)
at com.typesafe.config.impl.SimpleConfig.getObjectList(SimpleConfig.java:460)
at com.typesafe.config.impl.SimpleConfig.getConfigList(SimpleConfig.java:465)
at org.pac4j.lagom.jwt.JwtAuthenticatorHelper.parse(JwtAuthenticatorHelper.java:84)
at com.codingkapoor.holiday.impl.core.HolidayApplication.jwtClient$lzycompute(HolidayApplication.scala

容器描述

Name:         holiday-deployment-55b86f955d-9klk2
Namespace:    default
Priority:     0
Node:         minikube/192.168.99.103
Start Time:   Thu, 28 May 2020 12:42:50 +0530
Labels:       app=holiday
pod-template-hash=55b86f955d
Annotations:  <none>
Status:       Running
IP:           172.17.0.5
IPs:
IP:           172.17.0.5
Controlled By:  ReplicaSet/holiday-deployment-55b86f955d
Containers:
holiday:
Container ID:   docker://18443cfedc7fd39440f5fa6f038f36c58cec1660a2974e6432500e8c7d51f5e6
Image:          codingkapoor/holiday-impl:latest
Image ID:       docker://sha256:6e0ddcf41e0257755b7e865424671970091d555c4bad88b5d896708ded139eb7
Port:           8558/TCP
Host Port:      0/TCP
State:          Terminated
Reason:       Error
Exit Code:    255
Started:      Thu, 28 May 2020 22:49:24 +0530
Finished:     Thu, 28 May 2020 22:49:29 +0530
Last State:     Terminated
Reason:       Error
Exit Code:    255
Started:      Thu, 28 May 2020 22:44:15 +0530
Finished:     Thu, 28 May 2020 22:44:21 +0530
Ready:          False
Restart Count:  55
Liveness:       http-get http://:management/alive delay=20s timeout=1s period=10s #success=1 #failure=10
Readiness:      http-get http://:management/ready delay=20s timeout=1s period=10s #success=1 #failure=10
Environment:
JAVA_OPTS:                     -Xms256m -Xmx256m -Dconfig.resource=prod-application.conf
APPLICATION_SECRET:            <set to the key 'secret' in secret 'intimations-application-secret'>  Optional: false
MYSQL_URL:                     jdbc:mysql://mysql/intimations_holiday_schema
MYSQL_USERNAME:                <set to the key 'username' in secret 'intimations-mysql-secret'>                                 Optional: false
MYSQL_PASSWORD:                <set to the key 'password' in secret 'intimations-mysql-secret'>                                 Optional: false
ACCESS_SIGNATURE_PUBLIC_JWK:   <set to the key 'access-signature-public-jwk' in secret 'intimations-signature-public-secret'>   Optional: false
REFRESH_SIGNATURE_PUBLIC_JWK:  <set to the key 'refresh-signature-public-jwk' in secret 'intimations-signature-public-secret'>  Optional: false
REQUIRED_CONTACT_POINT_NR:     1
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-kqmmv (ro)
Conditions:
Type              Status
Initialized       True 
Ready             False 
ContainersReady   False 
PodScheduled      True 
Volumes:
default-token-kqmmv:
Type:        Secret (a volume populated by a Secret)
SecretName:  default-token-kqmmv
Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type     Reason   Age                    From               Message
----     ------   ----                   ----               -------
Normal   Pulled   5m21s (x23 over 100m)  kubelet, minikube  Container image "codingkapoor/holiday-impl:latest" already present on machine
Warning  BackOff  27s (x466 over 100m)   kubelet, minikube  Back-off restarting failed container

我想知道是否有任何方法可以将环境变量作为 json 对象而不是字符串传递。请指教。蒂亚。

首先,文件access-signature-public-jwk不是有效的 JSON 文件。您应该将其更新为有效版本。

{
"algorithm" : "RS256",
"jwk" : {"kty":"RSA","e":"AQAB","n":"ghhDZxuUo6TaSvAlD23mLP6n_T9pQuJsFY4JWdBYTjtcp_8Q3QeR477jou4cScPGczWw2JMGnx-Ao_b7ewagSl7VHpECBFHgcnlAgs5j6jfnd3M9ADKD2Yc756iXlIMT9xKDblIcXQQYlXalqxGvnLRLv1KAgVVVpVWzQd6Iz8WdTnexVrh7L9N87QQbOWcAVWGHCWCLCBsVE7JbC-XDt9h9P1g1sMqMV-qp7HjSXUKWuF2NwOnL2VeFSED7gdefs2Za1UYqhfwxdGl7aaPDXhjib0cfg4NvbcXMzxDEVkeJqhdDfD82wHOs4qFvnFMVxq9n6VVExSxsJq8gBJ7Z2AmfoXpmZC1L1ZwULB2KKpFXDCzgBELPLrfyIf8mNnk2nuuLT-aaMsqy2uB-ea3du4lyWo9MLk6x-L5g-n1oADKFKBY9aP2QQwruCG92XSd7jA9yLtbgr9OGVCYezxIxFp4vW6KcmPwJQjozWtwkZjeo4hv-zhRac73WDox2hDkif7WPTuEvC21fRy3GvyPIUPKPJA8pJjb2TXT7DXknR97CTnOWicuh3HMoRlVIwUzM5SVLGSXex0VjHZKgLYwQYukg5O2rab_4NxpD6LqLHx1bbPssC7BedCIfWX1Vcae40tlfvJAM09MiwQPZjWRahW_fK_9X5F5_rtUhCznm32M"}
}

我遵循的步骤进行验证。

kubectl create secret generic token1 --from-file=jwk.json

将密钥装载到容器中。

env:
- name: JWK
valueFrom:
secretKeyRef:
name: token
key: jwk.json

execpod 并检查变量envJWK

$ echo $JWK
{ "algorithm" : "RS256", "jwk" : {"kty":"RSA","e":"AQAB","n":"ghhDZxuUo6TaSvAlD23mLP6n_T9pQuJsFY4JWdBYTjtcp_8Q3QeR477jou4cScPGczWw2JMGnx-Ao_b7ewagSl7VHpECBFHgcnlAgs5j6jfnd3M9ADKD2Yc756iXlIMT9xKDblIcXQQYlXalqxGvnLRLv1KAgVVVpVWzQd6Iz8WdTnexVrh7L9N87QQbOWcAVWGHCWCLCBsVE7JbC-XDt9h9P1g1sMqMV-qp7HjSXUKWuF2NwOnL2VeFSED7gdefs2Za1UYqhfwxdGl7aaPDXhjib0cfg4NvbcXMzxDEVkeJqhdDfD82wHOs4qFvnFMVxq9n6VVExSxsJq8gBJ7Z2AmfoXpmZC1L1ZwULB2KKpFXDCzgBELPLrfyIf8mNnk2nuuLT-aaMsqy2uB-ea3du4lyWo9MLk6x-L5g-n1oADKFKBY9aP2QQwruCG92XSd7jA9yLtbgr9OGVCYezxIxFp4vW6KcmPwJQjozWtwkZjeo4hv-zhRac73WDox2hDkif7WPTuEvC21fRy3GvyPIUPKPJA8pJjb2TXT7DXknR97CTnOWicuh3HMoRlVIwUzM5SVLGSXex0VjHZKgLYwQYukg5O2rab_4NxpD6LqLHx1bbPssC7BedCIfWX1Vcae40tlfvJAM09MiwQPZjWRahW_fK_9X5F5_rtUhCznm32M"} }

将内容复制到文件

echo $JWK > jwk.json

验证文件

$ jsonlint-php jwk.json 
Valid JSON (jwk.json)

如果我使用您提供的文件并按照相同的步骤进行操作。它给出了一个 json 验证错误。此外,env 变量始终是字符串。您必须将它们转换为代码中的所需类型。

$ echo $JWK
{ algorithm = "RS256" jwk = {"kty":"RSA","e":"AQAB","n":"ghhDZxuUo6TaSvAlD23mLP6n_T9pQuJsFY4JWdBYTjtcp_8Q3QeR477jou4cScPGczWw2JMGnx-Ao_b7ewagSl7VHpECBFHgcnlAgs5j6jfnd3M9ADKD2Yc756iXlIMT9xKDblIcXQQYlXalqxGvnLRLv1KAgVVVpVWzQd6Iz8WdTnexVrh7L9N87QQbOWcAVWGHCWCLCBsVE7JbC-XDt9h9P1g1sMqMV-qp7HjSXUKWuF2NwOnL2VeFSED7gdefs2Za1UYqhfwxdGl7aaPDXhjib0cfg4NvbcXMzxDEVkeJqhdDfD82wHOs4qFvnFMVxq9n6VVExSxsJq8gBJ7Z2AmfoXpmZC1L1ZwULB2KKpFXDCzgBELPLrfyIf8mNnk2nuuLT-aaMsqy2uB-ea3du4lyWo9MLk6x-L5g-n1oADKFKBY9aP2QQwruCG92XSd7jA9yLtbgr9OGVCYezxIxFp4vW6KcmPwJQjozWtwkZjeo4hv-zhRac73WDox2hDkif7WPTuEvC21fRy3GvyPIUPKPJA8pJjb2TXT7DXknR97CTnOWicuh3HMoRlVIwUzM5SVLGSXex0VjHZKgLYwQYukg5O2rab_4NxpD6LqLHx1bbPssC7BedCIfWX1Vcae40tlfvJAM09MiwQPZjWRahW_fK_9X5F5_rtUhCznm32M"} }
$ echo $JWK > jwk.json
$ jsonlint-php jwk.json 
jwk.json: Parse error on line 1:
{ algorithm = "RS256" 
-^
Expected one of: 'STRING', '}'

虽然不是直接答案,而是解决此问题的替代方法。

正如@hariK指出的那样,环境变量始终是字符串,为了将它们用作 json,我们需要将读取为字符串的 env var 转换为 json。

但是,就我而言,这不是一个可行的解决方案,因为我使用的是期望 Config 对象而不是直接使用 json 对象的库,这意味着很多工作。转换string->json->Config。此外,这种方法与开发场景中Config对象的构建方式不一致,即json->Config。看这里。

我用来构建此应用程序的框架基于 Play 框架,它允许在单独的文件中模块化应用程序配置,然后将所需的部分组合到所需的配置文件中,如下所示。您可以在此处更详细地阅读。

应用程序.conf

include "/opt/conf/app1.conf"
include "/opt/conf/app2.conf"

这允许我利用使用机密作为 Pod 中的文件。 来自 Kubernetes 的功能。

  1. 基本上,我创建了一个小配置文件,其中包含主应用程序配置文件的一部分,如下所示:
cat deploy/keys/signature-public-jwk 
pac4j.lagom.jwt.authenticator {
signatures = [
{
algorithm = "RS256"
jwk = {"kty":"RSA","e":"AQAB","n":"ghhDZxuUo6TaSvAlD23mLP6n_T9pQuJsFY4JWdBYTjtcp_8Q3QeR477jou4cScPGczWw2JMGnx-Ao_b7ewagSl7VHpECBFHgcnlAgs5j6jfnd3M9ADKD2Yc756iXlIMT9xKDblIcXQQYlXalqxGvnLRLv1KAgVVVpVWzQd6Iz8WdTnexVrh7L9N87QQbOWcAVWGHCWCLCBsVE7JbC-XDt9h9P1g1sMqMV-qp7HjSXUKWuF2NwOnL2VeFSED7gdefs2Za1UYqhfwxdGl7aaPDXhjib0cfg4NvbcXMzxDEVkeJqhdDfD82wHOs4qFvnFMVxq9n6VVExSxsJq8gBJ7Z2AmfoXpmZC1L1ZwULB2KKpFXDCzgBELPLrfyIf8mNnk2nuuLT-aaMsqy2uB-ea3du4lyWo9MLk6x-L5g-n1oADKFKBY9aP2QQwruCG92XSd7jA9yLtbgr9OGVCYezxIxFp4vW6KcmPwJQjozWtwkZjeo4hv-zhRac73WDox2hDkif7WPTuEvC21fRy3GvyPIUPKPJA8pJjb2TXT7DXknR97CTnOWicuh3HMoRlVIwUzM5SVLGSXex0VjHZKgLYwQYukg5O2rab_4NxpD6LqLHx1bbPssC7BedCIfWX1Vcae40tlfvJAM09MiwQPZjWRahW_fK_9X5F5_rtUhCznm32M"}
}
]
}
  1. 然后创建了一个 kubernetes 密钥并在部署中挂载了卷,以作为文件显示在 Pod 中
kubectl create secret generic signature-public-secret --from-file=./deploy/secrets/signature-public-jwks.conf
// deployment yaml
spec:
containers:
- name: employee
image: "codingkapoor/employee-impl:latest"
volumeMounts:
- name: signature-public-secret-conf
mountPath: /opt/conf/signature-public-jwks.conf
subPath: signature-public-jwks.conf
readOnly: true
volumes:
- name: signature-public-secret-conf
secret:
secretName: signature-public-secret
  1. application.conf中使用此挂载的文件位置以包含相同的
include file("/opt/conf/signature-public-jwks.conf")

请注意,mountPathapplication.conf中的文件位置是相同的。

这种方法的优点:

  1. 该解决方案与开发和测试、生产环境一致,因为如上所述,我们可以将 json 而不是字符串返回到库中

  2. 无论如何,机密不应作为环境变量传递!您可以在此处阅读有关它的更多信息。

相关内容

最新更新