Sealed Secrets 設定

# 概要
 - k8sテスト環境構築<br>
<b>Sealed Secrets 設定</b>

# 構築目次
 - [全体目次] (https://qiita.com/prodigy413/items/89fcb8cfb71e80f541d8)

# 環境
 - Rancher: v2.6.3
 - kubernetes(Client): v1.22.4
 - kubernetes(Server): v1.22.4
 - Sealed Secrets: v0.17.1

# Sealed Secrets インストール
 - 作業場所: ClientPC
 - kubeseal release page<br>
https://github.com/bitnami-labs/sealed-secrets/releases
 - kubesealコマンドをダウンロード  

~~~
$ wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.17.1/kubeseal-0.17.1-linux-amd64.tar.gz
$ tar xvf kubeseal-0.17.1-linux-amd64.tar.gz
$ sudo mv kubeseal /usr/local/bin/
$ kubeseal --version
kubeseal version: 0.17.1
~~~

### Sealed Secret CRDとコントローラーのインストール  
 - <b>インストール方法#1</b>: 設定変更が不要な場合はリンクから直接インストール  
※default namespaceは`kube-system`

~~~
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.17.1/controller.yaml
~~~

 - <b>インストール方法#2</b>: 設定をカスタマイズしたい場合  

~~~:controller.yamlをダウンロード
$ wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.17.1/controller.yaml
~~~
controller.yamlを編集  

~~~yaml:※編集例
......
apiVersion: apps/v1
kind: Deployment
metadata:
......
spec:
  minReadySeconds: 30
  replicas: 2  # コントローラーのインストール数変更
......
    metadata:
      annotations: {}
      labels:
        name: sealed-secrets-controller
    spec:
      containers:
      - args: [--key-renew-period=0]  # キーの自動リニューアルを無効にするフラグの追加
        command:
        - controller
        env: []
        image: quay.io/bitnami/sealed-secrets-controller:v0.17.1
......
~~~

インストール

~~~
## インストール ##
$ kubectl apply -f controller.yaml

## 確認 ##
$ kubectl get all -n kube-system
NAME                                                   READY   STATUS      RESTARTS      AGE
..........
pod/sealed-secrets-controller-f64f6484c-k9qzd          1/1     Running     0             56s
..........

NAME                                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE
..........
service/sealed-secrets-controller                       ClusterIP   10.43.235.106   <none>        8080/TCP                       56s
..........

NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
..........
deployment.apps/sealed-secrets-controller         1/1     1            1           57s
..........

NAME                                                         DESIRED   CURRENT   READY   AGE
..........
replicaset.apps/sealed-secrets-controller-f64f6484c          1         1         1       57s
..........
~~~
# Sealed Secrets 作成
 - secretマニフェスト作成

~~~:作成例
## passwordが「password」のsecretマニフェスト作成
$ kubectl create secret generic test-secret --dry-run=client --from-literal=password=password -o yaml > test-secret.yaml
~~~
 - sealed secrets マニフェスト作成

~~~
$ kubeseal <test-secret.yaml -o yaml >sealed-test-secret.yaml
~~~
 - 適用と確認

~~~ 
$ kubectl apply -f sealed-test-secret.yaml
$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
......
test-secret           Opaque                                1      6s
......
~~~
# ※Sealed SecretsのScope
### 設定可能なscope
 - **strict**: sealed secretsの名前とnamespaceの変更不可(**default**)
 - **namespace-wide**: sealed secretsの名前のみ変更可能
 - **cluster-wide**: sealed secretsの名前とnamespaceの変更可能  

### Scope: strict
デフォルト設定のため、マニフェスト編集は不要

 - sealed secrets マニフェスト作成

~~~
$ kubeseal <test-secret.yaml -o yaml >sealed-test-secret.yaml
~~~

 - sealed secretsマニフェストの名前変更

~~~yaml:sealed-test-secret.yaml
piVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: test-secret-change  # 名前変更
  namespace: default
spec:
  encryptedData:
    password: 
......
~~~
 -  適用と確認  
scopeが`strict`のため、名前を変更すると適用に失敗

~~~
$ kubectl apply -f sealed-test-secret.yaml
$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
......
~~~
### Scope: namespace-wide
 - sealed secrets マニフェスト作成

~~~
$ kubeseal --scope namespace-wide <test-secret.yaml -o yaml >sealed-test-secret.yaml
~~~

 - sealed secretsマニフェストの名前変更

~~~yaml:sealed-test-secret.yaml
piVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: test-secret-change  # 名前変更
  namespace: default
spec:
  encryptedData:
    password: 
......
~~~

 -  適用と確認  
名前を変更しても適用成功

~~~
$ kubectl apply -f sealed-test-secret.yaml
$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
......
test-secret-change    Opaque                                1      4s
......
~~~
### Scope: cluster-wide
 - sealed secrets マニフェスト作成

~~~
$ kubeseal --scope cluster-wide <test-secret.yaml -o yaml >sealed-test-secret.yaml
~~~

 - sealed secretsマニフェストの名前変更

~~~yaml:sealed-test-secret.yaml
piVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: test-secret-change  # 名前変更
  namespace: test-sealedsecrets  # namespace変更
spec:
  encryptedData:
    password: 
......
~~~

 -  適用と確認  
名前とnamespaceを変更しても適用成功

~~~
$ kubectl apply -f sealed-test-secret.yaml
$ kubectl get secret -n test-sealedsecrets
NAME                  TYPE                                  DATA   AGE
......
test-secret-change    Opaque                                1      4s
......
~~~

# Master Key管理
### Master Key バックアップ
namespaceはコントローラーをインストールしたnamespaceに変更

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

### ※障害時
障害によりsealed secrets環境を再構築した場合、既存キーがないため、sealed secretsの適用に失敗

~~~
$ kubectl apply -f sealed-test-secret.yaml
$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
......
~~~
### Master Key リストア

~~~
## 既存キーをリストア
$ kubectl apply -f master.key

## キーを適用するため、コントローラーを再起動
$ kubectl delete pod -n kube-system -l name=sealed-secrets-controller

## 既存sealed secretsを適用
$ kubectl apply -f sealed-test-secret.yaml

## 適用に成功
$ kubectl get secret
NAME                  TYPE                                  DATA   AGE
......
test-secret           Opaque                                1      4s
......
~~~