Skip to content

Commit

Permalink
Merge pull request #8 from deckhouse/small-docs-fix
Browse files Browse the repository at this point in the history
Minor documentation updates
  • Loading branch information
trublast authored Aug 14, 2024
2 parents fd288e2 + 60d21b1 commit 4e2f3fe
Show file tree
Hide file tree
Showing 6 changed files with 369 additions and 208 deletions.
75 changes: 38 additions & 37 deletions docs/FAQ.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
---
title: "The secrets-store-integration module: FAQ"
description: Hashicorp vault example configuration. Example of secret autorotation implementation.
description: Hashicorp Vault configuration examples. Example of secret autorotation implementation.
---

## How to set up the Hashicorp vault as a secret store for use with the secrets-store-integration module:
## How to set up the Hashicorp Vault as a secret store to use with the secrets-store-integration module:

First of all, we need a root or similiar token and the vault address.
Root token can be obtained during new secrets store initialization.
First of all, you'll need a root or similiar token and the vault address.
You can get such a root token while initializing a new secrets store.


```bash
export VAULT_TOKEN=xxxxxxxxxxx
export VAULT_ADDR=https://secretstoreexample.com
```

In this guide we provide two ways to obtain needed result:
- usage of the console version of the Hashicorp Vault (Installation guide: https://developer.hashicorp.com/vault/docs/install)
- usage of the cURL equivalent command to make a direct requests to the secrets store API
This guide will cover two ways to do this:
- using the console version of HashiCorp Vault (see the installation guide: https://developer.hashicorp.com/vault/docs/install);
- using curl to make direct requests to the secrets store API.

Enable and create Key-Value storage:
Enable and create the Key-Value store:

```bash
vault secrets enable -path=secret -version=2 kv
```

or curl equivalent:
The same command as a curl HTTP request:

```bash
curl \
Expand All @@ -34,13 +34,13 @@ curl \
${VAULT_ADDR}/v1/sys/mounts/secret
```

Set a secret with a database password:
Set the database password as the secret value:

```bash
vault kv put secret/database-for-python-app password="db-secret-password"
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -50,13 +50,13 @@ curl \
${VAULT_ADDR}/v1/secret/data/database-for-python-app
```

Double-check that it is written:
Double-check that the password has been saved successfully:

```bash
vault kv get secret/database-for-python-app
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -70,7 +70,7 @@ Allow authentication and authorization in the vault with Kubernetes API by defin
vault auth enable -path=main-kube kubernetes
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -80,13 +80,13 @@ curl \
${VAULT_ADDR}/v1/sys/auth/main-kube
```

If we have more than one cluster, we need to allow authentication and authorization in the vault with Kubernetes API for the second cluster, defining the second authentication path:
If you have more than one cluster, set the authentication path (authPath) and enable authentication and authorization in Vault using the Kubernetes API of the second cluster:

```bash
vault auth enable -path=secondary-kube kubernetes
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -96,14 +96,14 @@ curl \
${VAULT_ADDR}/v1/sys/auth/secondary-kube
```

Set up Kubernetes API address for each auth point (in that case, it is k8s API server service):
Set the Kubernetes API address for each cluster (in this case, it is the K8s's API server service):

```bash
vault write auth/main-kube/config \
kubernetes_host="https://api.kube.my-deckhouse.com"
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -118,7 +118,7 @@ vault write auth/secondary-kube/config \
kubernetes_host="https://10.11.12.10:443"
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -128,7 +128,7 @@ curl \
${VAULT_ADDR}/v1/auth/secondary-kube/config
```

Create an internal-app policy in the vault:
Create a policy in Vault named `backend` that allows reading secrets:

```bash
vault policy write backend - <<EOF
Expand All @@ -138,7 +138,7 @@ path "secret/data/database-for-python-app" {
EOF
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -148,7 +148,7 @@ curl \
${VAULT_ADDR}/v1/sys/policies/acl/backend
```

Create database role and link it with backend-sa ServiceAccount in "my-namespace1" namespace and "backend" policy:
Create a database role and bind it to the `backend-sa` ServiceAccount in the `my-namespace1` namespace and the `backend` policy:

```bash
vault write auth/main-kube/role/my-namespace1_backend \
Expand All @@ -158,7 +158,7 @@ vault write auth/main-kube/role/my-namespace1_backend \
ttl=10m
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -168,7 +168,7 @@ curl \
${VAULT_ADDR}/v1/auth/main-kube/role/my-namespace1_backend
```

Almost the same for the second k8s cluster:
Do the same for the second K8s cluster:

```bash
vault write auth/secondary-kube/role/my-namespace1_backend \
Expand All @@ -178,7 +178,7 @@ vault write auth/secondary-kube/role/my-namespace1_backend \
ttl=10m
```

or curl equivalent:
The curl equivalent of the above command:

```bash
curl \
Expand All @@ -188,15 +188,15 @@ curl \
${VAULT_ADDR}/v1/auth/secondary-kube/role/my-namespace1_backend
```

**The recommended value for TTL of the Kubernetes token is 10m.**
**The recommended TTL value of the Kubernetes token is 10m.**

Those settings allow any pod within the "my-namespace1" namespace from both k8s clusters and with the "backend-sa" ServiceAccount to authenticate, authorize, and read secrets inside Vault covered by the backend policy.
These settings allow any pod within the `my-namespace1` namespace in both K8s clusters that uses the `backend-sa` ServiceAccount to authenticate, authorize, and read secrets in the Vault according to the `backend` policy.

## How to use autorotation with the file-mounted secret inside a container without restarting:
## How to autorotate secrets mounted as files in containers without restarting them?

The autorotation feature of the secret-store-integration module is enabled by default. Every two minutes, module polls and resyncs mounted secret values if someone changed the secret's value inside the secret store.
The autorotation feature of the secret-store-integration module is enabled by default. Every two minutes, the module polls Vault and synchronizes the secrets in the mounted file if it has been changed.

Create ServiceAccount ```backend-sa```
Create the ```backend-sa``` ServiceAccount

```yaml
apiVersion: v1
Expand All @@ -206,7 +206,7 @@ metadata:
namespace: my-namespace1
```
Here we have the example SecretStoreImport definition:
Below is an example of the SecretStoreImport definition:
```yaml
apiVersion: deckhouse.io/v1alpha1
Expand All @@ -224,7 +224,7 @@ spec:
key: "password"
```
And the example “backend” Deployment definition, which has the SecretStoreImport as a volume to deliver the database password to the application:
In the `backend` example below, the SecretStoreImport (defined above) is mounted as a volume to push the database password to the application:

```yaml
apiVersion: apps/v1
Expand Down Expand Up @@ -258,10 +258,11 @@ spec:
secretsStoreImport: "python-backend"
```

Upon applying this deployment the pod “backend” will be started, inside which we have “secrets” Volume, mounted to /mnt/secrets/ with file “db-password”, containing a password from the Vault.
We have two options to detect changes in a secret file mounted to the pod. The first is to monitor the mtime of the mounted file to detect when it changes. The second option is to monitor filesystem changes with inotify API, which provides a mechanism for monitoring filesystem events. Inotify is a part of the Linux kernel. Many options exist for reacting to detected changes, depending on the architecture and language used. The simplest example is to force the k8s to restart the pod by failing the liveness probe.
Once these resources have been applied, a `backend` pod will be started. In it, there will be a `/mnt/secrets` directory with the `secrets` volume mounted. The directory will contain a `db-password` file with the password for the Vault database.

To determine if the password has changed inside the Python application using inotify and Python inotify package:
There are two ways to keep track of changes to the secret file in the pod. The first is to keep track of when the mounted file changes (mtime), reacting to changes in the file. The second is to use the inotify API, which provides a mechanism for subscribing to file system events. Inotify is part of the Linux kernel. Once a change is detected, there are a large number of options for responding to the change event, depending on the application architecture and programming language used. The most simple one is to force K8s to restart the pod by failing the liveness probe.

Here is how you can use inotify in a Python application leveraging the `inotify` Python package:

```python
#!/usr/bin/python3
Expand All @@ -282,7 +283,7 @@ if __name__ == '__main__':
_main()
```

The example code to determine if the password has changed inside the Go application using inotify and Go inotify package:
Sample code to detect whether a password has been changed within a Go application using inotify and the `inotify` Go package:

```python
watcher, err := inotify.NewWatcher()
Expand All @@ -306,7 +307,7 @@ for {

## Secret rotation limitations

A container using `subPath` volume mount will not receive secret updates when it is rotated.
A container that uses the `subPath` volume mount will not get secret updates when the latter is rotated.

```yaml
volumeMounts:
Expand Down
22 changes: 11 additions & 11 deletions docs/FAQ_RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ title: "Модуль secrets-store-integration: FAQ"
description: Как настроить HashiCorp Vault в качестве secret store. Пример реализации авторотации секретов.
---

## Как настроить HashiCorp vault в качестве secret store для использования с модулем secrets-store-integration?
## Как настроить HashiCorp Vault в качестве secret store для использования с модулем secrets-store-integration?

Прежде всего нам необходим адрес и токен с правами root от Vault:
Прежде всего нам необходим адрес и токен с правами root от Vault.
Такой токен с правами root можно получить во время инициализации нового secrets store.

```bash
Expand All @@ -14,8 +14,8 @@ export VAULT_ADDR=https://secretstoreexample.com
```

В этом руководстве мы приводим два вида примерных команд:
- команда с использованием консольной версии HashiCorp Vault (Руководство по установке: https://developer.hashicorp.com/vault/docs/install)
- команда с использованием cURL для выполнения прямых запросов в API secrets store
- команда с использованием консольной версии HashiCorp Vault (руководство по установке: https://developer.hashicorp.com/vault/docs/install);
- команда с использованием curl для выполнения прямых запросов в API secrets store.

Включим и создадим Key-Value хранилище:

Expand Down Expand Up @@ -129,7 +129,7 @@ curl \
${VAULT_ADDR}/v1/auth/secondary-kube/config
```

Создаём в Vault политику с названием "backend", разрешающую чтение секретов:
Создаём в Vault политику с названием «backend», разрешающую чтение секретов:

```bash
vault policy write backend - <<EOF
Expand All @@ -149,7 +149,7 @@ curl \
${VAULT_ADDR}/v1/sys/policies/acl/backend
```

Создаём роль, состоящую из названия неймспейса и приложения. Связываем её с ServiceAccount "backend-sa" из нашего неймспейса "my-namespace1" и политикой "backend":
Создаём роль, состоящую из названия пространства имён и приложения. Связываем её с ServiceAccount «backend-sa» из пространства имён «my-namespace1» и политикой «backend»:

```bash
vault write auth/main-kube/role/my-namespace1_backend \
Expand All @@ -169,7 +169,7 @@ curl \
${VAULT_ADDR}/v1/auth/main-kube/role/my-namespace1_backend
```

Повторяем тоже самое для второго кластера, указав другой путь аутентификации:
Повторяем то же самое для второго кластера, указав другой путь аутентификации:

```bash
vault write auth/secondary-kube/role/my-namespace1_backend \
Expand All @@ -191,7 +191,7 @@ curl \

**Рекомендованное значение TTL для токена Kubernetes составляет 10m.**

Эти настройки позволяют любому поду из неймспейса "my-namespace1" из обоих k8s кластеров, который использует ServiceAccount "backend-sa", аутентифицироваться и авторизоваться в Vault для чтения секретов согласно политике "backend".
Эти настройки позволяют любому поду из пространства имён «my-namespace1» из обоих K8s-кластеров, который использует ServiceAccount «backend-sa», аутентифицироваться и авторизоваться в Vault для чтения секретов согласно политике «backend».

## Как использовать авторотацию секретов, примонтированных как файл в контейнер без его перезапуска?

Expand Down Expand Up @@ -258,10 +258,10 @@ spec:
volumeAttributes:
secretsStoreImport: "python-backend"
```
`
После применения этих ресурсов будет запущен под с названием `backend`, внутри которого будет папка `/mnt/secrets` с примонтированным внутрь томом secrets. Внутри папки будет лежать файл `db-password` с паролем от базы данных из Vault.

Есть два варианта следить за изменениями файла с секретом в поде. Первый - следить за временем изменения примонтированного файла, реагируя на его изменение. Второй - использовать inotify API, который предоставляет механизм для подписки на события файловой системы. Inotify является частью ядра Linux. После обнаружения изменений есть большое количество вариантов как реагировать на событие изменения в зависимости от используемой архитектуры приложения и используемого языка программирования. Самый простой - заставить K8s перезапустить pod, перестав отвечать на liveness пробу.
После применения этих ресурсов будет запущен под с названием `backend`, внутри которого будет каталог `/mnt/secrets` с примонтированным внутрь томом `secrets`. Внутри каталога будет лежать файл `db-password` с паролем от базы данных из Vault.

Есть два варианта следить за изменениями файла с секретом в поде. Первый - следить за временем изменения примонтированного файла, реагируя на его изменение. Второй - использовать inotify API, который предоставляет механизм для подписки на события файловой системы. Inotify является частью ядра Linux. После обнаружения изменений есть большое количество вариантов реагирования на событие изменения в зависимости от используемой архитектуры приложения и используемого языка программирования. Самый простой — заставить K8s перезапустить под, перестав отвечать на liveness-пробу.

Пример использования inotify в приложении на Python с использованием пакета inotify:

Expand Down
Loading

0 comments on commit 4e2f3fe

Please sign in to comment.