Published on

Quản lý secrets trên Kubernetes bằng Bitnami Sealed Secrets

Giới thiệu

Như chúng ta đã biết, để lưu trữ các thông tin cần bảo mật như mật khẩu, token,... trên Kubernetes chúng ta thường sử dụng đối tượng dạng Secrets để lưu trữ các giá trị đó, nhờ vậy các pod khi cần có thể lấy các giá trị đó sử dụng.

Để tạo các giá trị Secret sẽ có 2 cách:

  • Tạo bằng command line kubectl
  • Khai báo bằng file cấu hình (manifest):
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque
    data:
      username: YWRtaW4= # echo -n 'admin' | base64
      password: MWYyZDFlMmU2N2Rm # echo -n '1f2d1e2e67df' | base64
    
    Các giá trị của usernamepassword phải để ở dạng base64. Khi triển khai chúng ta chỉ cần đơn giản gõ lệnh kubectl apply -f file-secrets.yaml

Thông thường 1 dự án lớn, toàn bộ các file cấu hình sẽ được lưu trữ và quản lý trên git. Khái niệm này thường được gọi là GitOps, chi tiết các bạn có thể tìm hiểu thêm trên mạng.

Tuy nhiên, do cơ chế hoạt động của Kubernetes nên các giá trị Secrets chỉ mã hóa ở dạng base64 (chúng ta có thể dễ dàng decode và lấy được giá trị của nó). Nếu chúng ta đẩy file cấu hình của secret lên git sẽ dẫn đến rủi ro bảo mật thông tin.

Trên Kubernetes sẽ có nhiều giải pháp để khắc phục hạn chế đó, phổ biến nhất là lưu trữ secrets ở bên ngoài cluster bằng cách kết nối đến các dịch vụ của bên thứ 3 như: Azure KeyVault, HashiCorp Vault,... và cluster khi cần sẽ gọi đến đế lấy giá trị đó. Tuy nhiên chúng ta sẽ tốn thêm chi phí khi sử dụng các dịch vụ này.

Ngoài ra, chúng ta còn có một giải pháp khác giúp lưu trữ các giá trị Secrets an toàn trên git mà vẫn đảm báo tính bảo mật đó là thêm một lớp mã hóa nữa. Giá trị base64 sẽ được mã hóa một lần nữa, để giải mã giá trị thì cần phải có chìa khóa tương ứng, vì vậy mà chúng ta có thể để giá trị secret đã được mã hóa lên git mà không phải lo ngại vấn đề bảo mật. Dưới đây mình sẽ giới thiệu một công cụ như vậy đó là Sealed Secrets.

Bitnami Sealed Secrets

Bitnami Sealed Secrets là một công cụ mã nguồn mở cho Kubernetes giúp bảo vệ các thông tin nhạy cảm (secrets) khi lưu trữ chúng trong Git hoặc chia sẻ công khai.

Bitnami Sealed Secrets bao gồm một controller chạy trên cluster Kubernetes và một CLI tool để tạo ra các sealed secrets từ các secrets thông thường.

Các sealed secrets được mã hóa một chiều bằng cách sử dụng một cặp khóa công khai/riêng tư (private/public keys) được quản lý bởi controller.

Chỉ có controller mới có thể giải mã các sealed secrets và khôi phục lại các secrets ban đầu.

Bitnami Sealed Secrets giải quyết vấn đề lưu trữ và quản lý các secrets trong Kubernetes một cách an toàn và tiện lợi.

Cài đặt trên Kubernetes bằng Argo CD

Đầu tiên chúng ta cần cài đặt nó trên Kubernets, có nhiều cách nhưng mình giới thiệu phương pháp GitOps dùng Argo CD. Dưới đây là cấu hình tham khảo

argocd.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: sealed-secrets
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  syncPolicy:
    automated:
      selfHeal: true
      prune: true
      allowEmpty: false
    syncOptions:
      - Validate=false
      - CreateNamespace=true
      - PrunePropagationPolicy=foreground
      - PruneLast=true
      - RespectIgnoreDifferences=true
      - Replace=true
  project: default
  source:
    chart: sealed-secrets
    repoURL: https://bitnami-labs.github.io/sealed-secrets
    targetRevision: 2.*
    helm:
      releaseName: sealed-secrets
      passCredentials: false  
  destination:
    server: "https://kubernetes.default.svc"
    namespace: kube-system
  revisionHistoryLimit: 5

Để cài đặt chúng ta chỉ cần đơn giản chạy: kubectl apply -f argocd.yaml

Cách sử dụng

Đầu tiên bạn cần phải cài client command. Thông thường bạn sẽ cài trên máy nào đã có thể kết nối đến cluster và chạy được câu lệnh kubectl.

KUBESEAL_VERSION='' # Set this to, for example, KUBESEAL_VERSION='0.23.0'
wget "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?}/kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz"
tar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal

Bây giờ chúng ta sẽ mã hóa một secrets, giả sử bạn muốn tạo một secrets tên là github-token trên namespace test-ns với giá trị là: your token value thì chúng ta chạy đoạn command dưới đây:

echo -n 'your token value`' | kubeseal --controller-name sealed-secrets --raw --namespace test-ns --name github-token

Giả sử giá trị output là:

AgBhwZVwAe8l4Wv9TfJpMq3yENyb7Euc.....==

Bây giờ chúng ta chỉ việc khai báo 1 đối tượng SealedSecret như dưới đây:

sealed-secrets.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: github-token
  namespace: test-ns
spec:
  encryptedData:
    github-token: AgBhwZVwAe8l4Wv9TfJpMq3yENyb7Euc.....==    
  template:
    metadata:
      name: github-token
      namespace: test-ns

Sau đó chúng ta chạy lệnh kubectl apply -f sealed-secrets.yaml thì một secret tên là github-token trên namespace test-ns với giá trị là: your token value. Giá trị được mã hóa sẽ được giải mã trên cluster, chúng ta có thể lưu flle này trên git an toàn vì giá trị secret đã được mã hóa.

Hiển nhiên, nếu bất kì ai có được private thì sẽ giải mã được giá trị này.

Các cách sử dụng chi tiết và cụ thể hơn có thể xem thêm tại trang "Sealed Secrets" for Kubernetes

Chúc thành công,

ANH NGUYỄN