0

我需要将 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 对象而不是字符串传递。请建议。TIA。

4

2 回答 2

2

首先,该文件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

将秘密挂载到 pod 中。

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

exec到 pod 并检查env变量JWK

$ 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 验证错误。此外,环境变量始终是字符串。您必须将它们转换为代码中所需的类型。

$ 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', '}'
于 2020-05-28T19:24:37.820 回答
1

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

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

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

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

应用程序.conf

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

这让我可以使用来自 kubernetes的 Pod 功能的 Using Secrets 作为文件 。

  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")

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

这种方法的优点:

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

  2. 无论如何,秘密不应该作为环境变量传递!你可以在这里阅读更多关于它的信息。

于 2020-05-29T19:05:45.297 回答