Secret encrypted storage in Kubernetes

Preface

When using Kubernetes, we often configure some environment variables through native resources such as configmap and secret so that they can be used for git version management together with the code. It's okay if it is used to store general information, but sometimes we may need to use these resources to configure some account passwords and other sensitive information. Although secrets have encryption properties, because their own encryption method is based on base64, it is not suitable for a little bit. For people with some relevant knowledge, it is equivalent to plain text.

In the management of R&D departments of many companies, many account passwords in the production environment are not allowed to be known by personnel other than administrators (such as database passwords). If the relevant information is not encrypted and stored, version management can be performed directly in git. For those involved, it is tantamount to running naked. So here we introduce an open source resource type of K8Ssealed-secrets

What are sealed-secrets?

官方地址:bitnami-labs/sealed-secrets: A Kubernetes controller and tool for one-way encrypted Secrets (github.com)

Problem: “I can manage all my K8s config in git, except Secrets.”

Solution: Encrypt your Secret into a SealedSecret, which is safe to store - even inside a public repository. The SealedSecret can be decrypted only by the controller running in the target cluster and nobody else (not even the original author) is able to obtain the original Secret from the SealedSecret.

This question and answer in the official document clearly expresses the role of sealed-secrets. It is to allow us to safely share, store and use secrets and avoid the encryption of information from being cracked.

Installation and deployment

Sealed Secrets consists of two parts:

  • Server-side controller
  • Client tool: kubeseal

kubeseal uses asymmetric encryption to encrypt data. Only the server-side controller can decrypt the data. The encrypted data is encoded in SealedSecret resources.

Install kubeseal

1. Log in to Releases · bitnami-labs/sealed-secrets (github.com) , find the latest version, select the version suitable for your system to download
Insert image description here
2. Unzip the compressed package and put the tool in the /usr/local/bin/ directory

tar -zxvf kubeseal-0.19.3-linux-amd64.tar.gz
install -m 755 kubeseal /usr/local/bin/kubeseal
##验证一下
[root@master sealed-secrets]# kubeseal --version
kubeseal version: 0.19.3

Install the controller

1.Download

Log in to github and download the corresponding resource file Releases · bitnami-labs/sealed-secrets (github.com)
Insert image description here
2. Deployment

kubectl apply -f controller.yaml

3. View pod

[root@master sealed-secrets]# kubectl get pods -n kube-system -l name=sealed-secrets-controller
NAME                                         READY   STATUS    RESTARTS   AGE
sealed-secrets-controller-8645675c65-jtrc2   1/1     Running   0          10d
[root@master sealed-secrets]# kubectl logs sealed-secrets-controller-8645675c65-jtrc2 -n kube-system 
controller version: 0.19.3
2022/12/23 09:15:22 Starting sealed-secrets controller version: 0.19.3
2022/12/23 09:15:22 Searching for existing private keys
2022/12/23 09:15:24 New key written to kube-system/sealed-secrets-keymrkx6
2022/12/23 09:15:24 Certificate is 
-----BEGIN CERTIFICATE-----
MIIEzTCCArWgAwIBAgIRAONV9p03jyrJuRrGUwyJJ2AwDQYJKoZIhvcNAQELBQAw
ADAeFw0yMjEyMjMwOTE1MjRaFw0zMjEyMjAwOTE1MjRaMAAwggIiMA0GCSqGSIb3
DQEBAQUAA4ICDwAwggIKAoICAQDMkPndKm9g0XpgdNMuHvZ2qWsSGlET3pGyiSSs
APWDPT8FJEOcO1d4SrevrBCfWLxsd+CMyl4SE6Os1zqGXNMPAWJuag0JJBqcONgi
k3yWpma3h3g0fY21T7MUoAO16a+uMBJEPZAfzjfb3Oz8q26mWi8Ct96DKsvZkdZs
Xt1PL6nCKvj8DuAqH9+VzDiW/z66TeOCd8RsvJkMjGpyBZR+puIiDdDZ0dY/bS5l
0p3Ri72cTKnTBToLr3tM91einiJ0vhaMMVEdCED84rautJtbyBk/Km15g+D9ojW+
LcL5z8qKtDn13Hxo/2RRuUt4gsucuqrBWYUwKj8qoQZ/+iHAs6Ym+Y3A94qNFxNQ
udAbu/7HVIEOIU5G64HY5dqiQN5LJRqM7zlUjip65Rrr/Ysk/t0kNULKDX1060/k
EaVC8pPYa5hQLcWmyRBWstQTSNYGHO2ANevBIOT+O4wjrmEyC9dMuVRomdkqSkBi
NJsIYc3JATiGWcDax6H1G2V+QYmjg0PlH008e/n2wbJmAfHIxxBgMHGL0FPUFthX
rNhMHAirDrB7I1yW/OaoIm/YRJM+PMmJOk4IkJ66a6pVHDuRfY8lwDiH8vJaYk6y
oDS6T9qJ1bKTFDZtPg4rna+C36/px57BW/bTADHNckefuPFtAGbflEabeGr0TcoC
sU/ATQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAAEwDwYDVR0TAQH/BAUwAwEB/zAd
BgNVHQ4EFgQULw16NueVc/9IABCb1k6GGESJVJkwDQYJKoZIhvcNAQELBQADggIB
ACXaJ318/8KLv8MOzqtA0dhzQsqZkdrC+jm+Sf+nAmGFP1K/MsSQa8Ggyw/o8t/E
c+q2UYBF8CeP5hDRWlTavvkJISjQTyGJlhuhwA9EefFgcX4hIJhXrLqOGL7tJplr
oVyCoqDbeWuR4M3Nr2z44AQqbo0L9QFkEW4fHHOtIjjt9535yGgB5ApuryM/Crad
7Y3dC1Uohn7oW/4xO0EIjn1blOh9XFc4a862frTiQP54gZ3yU9/JhieSLlNFkReT
ZHcIIGKvNp52mw1hVJATClWKF3JljK4YLG+lHd1NGiuBLDvI6s/9x/3Fih8S37Tv
V3AFz1F0yb5xbFALmhzhgi744vK2lXt2/Gp6SzLq4cIQFi10wYNrW7I2dlpJczs3
p0PmCEJa1r2WEBLvlS+85FkJy7CXrCc9te4vHGIqY2kBG5u2VUUm/gl21HHrTYDt
P5HalOefSq+ve02Tiyyye8STz1sr0bN0db47DOhylnkzJPgHWMCuOq0KNZBry2N9
euPDbGlhga3USPWOyKV6eingIFFT7ug9Fc5vLBh+mD8FQjDOAJ4Cl0MbkIDuQy+x
wYf9W21fxfKQnBgjYvjcNb5no7wKp2KsWshXWDkoih/05icJMfTSkwQ/Qzu4dbDw
6IifuAQn4SzIUd6y+0sVNjZK9XQ3ve+NYYBvM01OhfUA
-----END CERTIFICATE-----

4. View public/private key information

kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml

test

1. Create a secret file

kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456 --dry-run -o yaml > mysecret.yaml

# 查看生成的文件
[root@master sealed-secrets]# cat mysecret.yaml 
apiVersion: v1
data:
  password: MTIzNDU2
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: null
  name: mysecret

2. Use kubeseal to encrypt and convert mysercret.yaml

kubeseal --format=yaml < mysecret.yaml > mysecret-sealed.yaml
### kubeseal输出的默认格式是json,此处使用--format将格式转为yaml,这一步是kubeseal从Kubernetes集群获取公钥并使用该公钥加密数据

##查看转换后的SealedSecret
[root@master sealed-secrets]# cat mysecret-sealed.yaml 
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: mysecret
  namespace: default
spec:
  encryptedData:
    password: AgBPYXyfWoN6YH/Dls8+L8uIQbHEfVmd6T4bOe3Y0W7d4wL9YPCLDS4fNpjJMPGx7nnR2nJkL2nWcr8xqepkLuIgn5cIZxQ5+EV624nzDIrm/PWE/3GNgb6oCQmpbcW2fIYVbicG6xpz3KHsPKHgxXQCGUJD9wB6bb1wWw5UZOGmihjHanzqbWZhdicDyfKdkyGHPiVi83xgdRmCaScgz9f1EQOfNsD5IkjD3gyLp3ZoMJUBprx0vvKDfZcoIL7vBJLHke9SrvDFtPdfmIneL2yJ7Gew4DJazlUct/U9FnMczl7Wr1Y6YAOFNNV9ysCRVC+C1bmrwr5r21G17KeES+GWLyXIy/epKoCpmtWcHJ22YNhSEtR0RGHWHCwSPeXbr2SdQegZ0Pk64X9QAYrEBO7IhF2gA1JA045DwFMXJjrKzDW+4ogslDXT2a5cIcVKVdrCGk8ajSsXQeOFq5GIcWLPeXs/LRu5SYyj7nr+xjyrPUtV7vxbNUmBCoFJ5TvWnO5yKE6wGQuTUxCOiIRf44KZqy03XZD2nsxe5UW/tyLJHXp1VL8hYHcoSfVSMHsTVPCNpDDUxCnZRnncfRHAXUyPnI2Cpx7uKsg8zu7M6TKklm8g1Ow+P8XBjzTY5vAr441oTad86REHQ6FVdBw8IKtZHYy2kxaTrThnWB3L+3ckk7ZhM3kbIDUdbXkFTkEx82A76ucXSLc=
    username: AgCwYrUhSKTgBZ5rf8DTToyB6yztH1+4P5tCv3mSCXt0dJ4L5sCso38JwBQJW6IRgw9nHqXdNwdZKpZW7Yjjr/LpsKUrs/9XkO+rgyf68uXi5tqNSHpsCza3e9Jx9qUI7k3WjHFHtRt5IsaO4OH7tUEmVlnCeuegXZ51HJfnmsZIgzGqDhnHWt6Z9FUOMvyd8jpro58p8tjjZIEBgrIRlMJdGSuUuSP0o3x30/4oPO7+yqbeV9B7OOp7i+sk4LBNfclmjLgySbCww6bc6wHr45NIt/bhIYkiKwk/IWh5e5LBqmZh+klkWA+GcltDTXi7+wv2UMAJXBmPhg4x41/unZUDhsljMvkPC92xWjivp4SMcMrRnjzKYI5UiTi5czS3uqRjH23q6U5/QM0o9IqVRojbSsnF9RmAAsfvZSoToHMgxOyS5ApF+4K/p9LI5t+vz3h7SQ+QhwYyyCcA3JRoK8a0ZFa3fz6bSMFMR+ANC7JtNez7Kiem9WjFhP+FB99UJCGdPmVHWL44uThtRZf/B3hO2hb/oXNHfZiUdjvXdB6Ee56yCUZrurkfjGd0ElnTy7a2CpEHjk2KIETv47qXnL4R6hRbd7nwdprjEg/0hawa0xhwat2PA4Vt+ZG2VbWYIgqc8TgDHJObb6IPn0HEoPvaZCGK1GzXspsbslNMdWrHu5bmbimVDrl7VUAKMWQe7uOy1PHy9A==
  template:
    metadata:
      creationTimestamp: null
      name: mysecret
      namespace: default

3. Deploy mysecret-sealed.yaml

kubectl apply -f mysecret-sealed.yaml
##查看部署后的文件
[root@master sealed-secrets]# kubectl get secrets mysecret -o yaml
apiVersion: v1
data:
  password: MTIzNDU2
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: "2022-12-23T09:24:38Z"
  name: mysecret
  namespace: default
  ownerReferences:
  - apiVersion: bitnami.com/v1alpha1
    controller: true
    kind: SealedSecret
    name: mysecret
    uid: af66d9ea-3ce3-4894-a1b5-0c3396ffb8d3
  resourceVersion: "2935007"
  uid: ed797abd-4390-4fc3-bda0-56c36c531d37
type: Opaque

As you can see, mysecret-sealed.yaml is restored to secret and deployed

We can see the conversion process through the log: the controller intercepts the request, decrypts the encrypted data from the SealedSecret, and then creates the Secret object

kubectl logs sealed-secrets-controller-8645675c65-jtrc2 -n kube-system
....
2022/12/23 09:24:38 WARNING: Empty API version & kind, filling it...
2022/12/23 09:24:38 Updating default/mysecret
2022/12/23 09:24:38 Event(v1.ObjectReference{Kind:"SealedSecret", Namespace:"default", Name:"mysecret", UID:"af66d9ea-3ce3-4894-a1b5-0c3396ffb8d3", APIVersion:"bitnami.com/v1alpha1", ResourceVersion:"2935006", FieldPath:""}): type: 'Normal' reason: 'Unsealed' SealedSecret unsealed successfully
....

Install web-ui

In many cases (such as full-process devops), cluster administrators and business operations and maintenance do not have the same permissions, so this command line operation method cannot be applied to all situations. In this case, a WEB-UI interface is needed to complete this For the encryption process, luckily Github has open sourced the web interface corresponding to secret-sealed.

web-ui official website address

bakito/sealed-secrets-web: A web interface for Sealed Secrets by Bitnami. (github.com)

Install directly using helm
helm repo add bakito https://charts.bakito.net
helm repo update

helm upgrade --install sealed-secrets-web bakito/sealed-secrets-web

Of course, we may need some custom configuration

helm upgrade --install sealed-secrets-web bakito/sealed-secrets-web \
  --set sealedSecrets.namespace=sealed-secrets-web \
  --set sealedSecrets.serviceName=sealed-secrets

For other usage methods, please refer to the official documentation.

View deployment

[root@master sealed-secrets]# kubectl get all -n sealed-secrets-web 
NAME                                      READY   STATUS    RESTARTS   AGE
pod/sealed-secrets-web-6874bbdfb5-9p5wq   1/1     Running   0          8d

NAME                         TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
service/sealed-secrets-web   ClusterIP   10.1.3.215   <none>        80:/TCP   8d

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/sealed-secrets-web   1/1     1            1           8d

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/sealed-secrets-web-6874bbdfb5   1         1         1       8d

We expose the service/sealed-secrets-web port in nodeport mode (of course you can also use ingressgateway):

kubectl edit svc sealed-secrets-web -n sealed-secrets-web ##编辑svc
...
  spec:
    clusterIP: 10.1.3.215
    clusterIPs:
    - 10.1.3.215
    externalTrafficPolicy: Cluster
    internalTrafficPolicy: Cluster
    ipFamilies:
    - IPv4
    ipFamilyPolicy: SingleStack
    ports:
    - name: http
      nodePort: 30088  #------------------新增
      port: 80
      protocol: TCP
      targetPort: http
    selector:
      app.kubernetes.io/instance: sealed-secrets-web
      app.kubernetes.io/name: sealed-secrets-web
    sessionAffinity: None
    type: NodePort   #--------------将ClusterIP修改为NodePort
  status:
    loadBalancer: {
    
    }

...
[root@master sealed-secrets]# kubectl get svc -n sealed-secrets-web 
NAME                 TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
sealed-secrets-web   NodePort   10.1.3.215   <none>        80:30088/TCP   8d

web access
Insert image description here

  • Encode : Base64 secretly encodes each key in the stringData field.

  • Decode : Base64 secretly decodes each key in the data field.

  • Secrets : Returns a list of all Sealed Secrets in all namespaces. Click Sealed Secret to load the decrypted Kubernetes secret.

  • Seal : Encrypt Kubernetes secrets and create Sealed Secrets.

shortcoming

The web does not have a login authentication system, so you need to find a way to solve the permission problem by yourself, such as integrating it into other web permission management. The official API provides a reference for transformation.

Guess you like

Origin blog.csdn.net/Mrheiiow/article/details/128530761