在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):external-secrets/kubernetes-external-secrets开源软件地址(OpenSource Url):https://github.com/external-secrets/kubernetes-external-secrets开源编程语言(OpenSource Language):JavaScript 97.2%开源软件介绍(OpenSource Introduction):DeprecatedThis project has been deprecated. Please take a look at ESO (External Secrets Operator) instead https://github.com/external-secrets/external-secrets HistoryThis project was moved from the GoDaddy to the external-secrets GitHub organization in an effort to consolidate different projects with the same objective. More information here. Kubernetes External SecretsKubernetes External Secrets allows you to use external secret management systems, like AWS Secrets Manager or HashiCorp Vault, to securely add secrets in Kubernetes. Read more about the design and motivation for Kubernetes External Secrets on the GoDaddy Engineering Blog. The community and maintainers of this project and related Kubernetes
secret management projects use the
How it worksThe project extends the Kubernetes API by adding an An By default System architecture
How to use itInstall with HelmThe official helm chart can be used to create the $ helm repo add external-secrets https://external-secrets.github.io/kubernetes-external-secrets/
$ helm install [RELEASE_NAME] external-secrets/kubernetes-external-secrets For more details about configuration see the helm chart docs Install with kubectlIf you don't want to install helm on your cluster and just want to use $ helm template --include-crds --output-dir ./output_dir external-secrets/kubernetes-external-secrets The generated kubernetes manifests will be in Secrets Manager accessFor AWS based backendsAccess to AWS secrets backends (SSM & secrets manager) can be granted in various ways:
Optionally configure custom endpoints using environment variables
Using AWS access credentialsSet Additionally, you can specify a kind: Namespace
metadata:
name: iam-example
annotations:
# annotation key is configurable
iam.amazonaws.com/permitted: "arn:aws:iam::123456789012:role/.*" Add a secretAdd your secret data to your backend. For example, AWS Secrets Manager:
AWS Parameter Store:
and then create a apiVersion: "kubernetes-client.io/v1"
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: secretsManager
# optional: specify role to assume when retrieving the data
roleArn: arn:aws:iam::123456789012:role/test-role
data:
- key: hello-service/password
name: password
# optional: specify a template with any additional markup you would like added to the downstream Secret resource.
# This template will be deep merged without mutating any existing fields. For example: you cannot override metadata.name.
template:
metadata:
annotations:
cat: cheese
labels:
dog: farfel or apiVersion: "kubernetes-client.io/v1"
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: systemManager
data:
- key: /hello-service/password
name: password The following IAM policy allows a user or role to access parameters matching {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ssm:GetParameter",
"Resource": "arn:aws:ssm:us-west-2:123456789012:parameter/prod-*"
}
]
} The IAM policy for Secrets Manager is similar (see docs): {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:ListSecretVersionIds"
],
"Resource": [
"arn:aws:secretsmanager:us-west-2:111122223333:secret:aes128-1a2b3c",
"arn:aws:secretsmanager:us-west-2:111122223333:secret:aes192-4D5e6F",
"arn:aws:secretsmanager:us-west-2:111122223333:secret:aes256-7g8H9i"
]
}
]
} Save the file and run: kubectl apply -f hello-service-external-secret.yml Wait a few minutes and verify that the associated kubectl get secret hello-service -o=yaml The apiVersion: v1
kind: Secret
metadata:
name: hello-service
annotations:
cat: cheese
labels:
dog: farfel
type: Opaque
data:
password: MTIzNA== Create secrets of other types than opaqueYou can override apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: hello-docker
spec:
backendType: systemManager
template:
type: kubernetes.io/dockerconfigjson
data:
- key: /hello-service/hello-docker
name: .dockerconfigjson TemplatingKubernetes External Secrets supports templating in Template is applied to all Templating can be used for:
To demonstrate templating functionality let's assume the secure backend, e.g. Hashicorp Vault, contains the following data
Then, one could create the following apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: tmpl-ext-sec
spec:
backendType: vault
data:
- key: kv/data/extsec/secret1
name: s1
- key: kv/data/extsec/secret2
name: s2
kvVersion: 2
template:
data:
file.txt: |
<%= Buffer.from(JSON.stringify(JSON.parse(data.s1).objKey)).toString("base64") %>
metadata:
labels:
label1: <%= JSON.parse(data.s1).intKey %>
label2: <%= JSON.parse(data.s1).objKey.strKey.replace(" ", "-") %>
stringData:
file.yaml: |
<%= yaml.dump(JSON.parse(data.s1)) %>
<% let s2 = JSON.parse(data.s2) %><% s2.arrKey.forEach((e, i) => { %>arr_<%= i %>: <%= e %>
<% }) %>`
vaultMountPoint: kubernetes
vaultRole: demo After applying this apiVersion: v1
data:
file.txt: eyJzdHJLZXkiOiJoZWxsbyB3b3JsZCJ9
file.yaml: aW50S2V5OiAxMQpvYmpLZXk6CiAgc3RyS2V5OiBoZWxsbyB3b3JsZAoKYXJyXzA6IDEKYXJyXzE6IDIKYXJyXzI6IDMKYAo=
s1: eyJpbnRLZXkiOjExLCJvYmpLZXkiOnsic3RyS2V5IjoiaGVsbG8gd29ybGQifX0=
s2: eyJhcnJLZXkiOlsxLDIsM119
kind: Secret
metadata:
name: tmpl-ext-sec
labels:
label1: "11"
label2: hello-world
type: Opaque Resulting $ kubectl get secret/tmpl-ext-sec -ogo-template='{{ index .data "s1" | base64decode }}'
{"intKey":11,"objKey":{"strKey":"hello world"}}
$ kubectl get secret/tmpl-ext-sec -ogo-template='{{ index .data "s2" | base64decode }}'
{"arrKey":[1,2,3]}
$ kubectl get secret/tmpl-ext-sec -ogo-template='{{ index .data "file.txt" | base64decode }}'
{"strKey":"hello world"}
$ kubectl get secret/tmpl-ext-sec -ogo-template='{{ index .data "file.yaml" | base64decode }}'
intKey: 11
objKey:
strKey: hello world
arr_0: 1
arr_1: 2
arr_2: 3
$ kubectl get secret/tmpl-ext-sec -ogo-template='{{ .metadata.labels }}'
map[label1:11 label2:hello-world] Scoping accessUsing Namespace annotationEnforcing naming conventions for backend keys could be done by using namespace annotations.
By default an data:
- key: /dev/cluster1/core-namespace/hello-service/password
name: password An enforced naming convention helps to keep the structure tidy and limits the access according to your naming schema. Configure the schema as a regular expression in the namespace using an annotation.
This allows kind: Namespace
metadata:
name: core-namespace
annotations:
# annotation key is configurable
externalsecrets.kubernetes-client.io/permitted-key-name: "/dev/cluster1/core-namespace/.*" Using ExternalSecret controller configExternalSecret config allows scoping the access of kubernetes-external-secrets controller. This allows deployment of multiple kubernetes-external-secrets instances in the same cluster and each instance can access a set of predefined namespaces. To enable this option, set the env var in the controller side to a list of namespaces: env:
WATCHED_NAMESPACES: "default,qa,dev" Using ExternalSecret configExternalSecret manifest allows scoping the access of kubernetes-external-secrets controller. This allows deployment of multiple kubernetes-external-secrets instances at the same cluster and each instance can access a set of ExternalSecrets. To enable this option, set the env var in the controller side: env:
INSTANCE_ID: "dev-team-instance" And in ExternalSecret side: apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: foo
spec:
controllerId: 'dev-team-instance'
[...] Please note Scoping access by ExternalSecret config provides only a logical separation and it doesn't cover the security aspects. i.e it assumes that the security side is managed by another component like Kubernetes Network policies or Open Policy Agent. DeprecationsA few properties have changed name overtime, we still maintain backwards compatbility with these but they will eventually be removed, and they are not validated using the CRD validation.
Backendskubernetes-external-secrets supports AWS Secrets Manager, AWS System Manager, Akeyless, Hashicorp Vault, Azure Key Vault, Google Secret Manager and Alibaba Cloud KMS Secret Manager. AWS Secrets Managerkubernetes-external-secrets supports both JSON objects ("Secret key/value" in the AWS console) or strings ("Plaintext" in the AWS console). Using JSON objects is useful when you need to atomically update multiple values. For example, when rotating a client certificate and private key. When writing an ExternalSecret for a JSON object you must specify the properties to use. For example, if we add our hello-service credentials as a single JSON object:
We can declare which properties we want from apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: secretsManager
# optional: specify role to assume when retrieving the data
roleArn: arn:aws:iam::123456789012:role/test-role
# optional: specify region
region: us-east-1
data:
- key: hello-service/credentials
name: password
property: password
- key: hello-service/credentials
name: username
property: username
- key: hello-service/credentials
name: password_previous
# Version Stage in Secrets Manager
versionStage: AWSPREVIOUS
property: password
- key: hello-service/credentials
name: password_versioned
# Version ID in Secrets Manager
versionId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
property: password alternatively you can use apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: secretsManager
# optional: specify role to assume when retrieving the data
roleArn: arn:aws:iam::123456789012:role/test-role
# optional: specify region
region: us-east-1
dataFrom:
- hello-service/credentials
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: secretsManager
# optional: specify role to assume when retrieving the data
roleArn: arn:aws:iam::123456789012:role/test-role
# optional: specify region
region: us-east-1
dataFromWithOptions:
- key: hello-service/credentials
versionStage: AWSPREVIOUS
- key: hello-service/credentials
versionId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: secretsManager
# optional: specify role to assume when retrieving the data
roleArn: arn:aws:iam::123456789012:role/test-role
# optional: specify region
region: us-east-1
dataFrom:
- hello-service/credentials
dataFromWithOptions:
- key: hello-service/credentials
versionId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
data:
- key: hello-service/migration-credentials
name: password
property: password AWS SSM Parameter StoreYou can scrape values from SSM Parameter Store individually or by providing a path to fetch all keys inside. When fetching all keys by path, you can also recursively scrape all the sub paths (child paths) if you need to. The default is not to scrape child paths. apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: systemManager
# optional: specify role to assume when retrieving the data
roleArn: arn:aws:iam::123456789012:role/test-role
# optional: specify region
region: us-east-1
data:
- key: /foo/name
name: fooName
- path: /extra-people/
recursive: false
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
metadata:
name: hello-service
spec:
backendType: systemManager
# optional: specify role to assume when retrieving the data
roleArn: arn:aws:iam::123456789012:role/test-role
# optional: specify region
region: us-east-1
dataFrom:
- hello-service/credentials:3
data:
- key: /foo/name
name: fooName:5 |