Vault - Kulichanin/speedtest GitHub Wiki
Проблема! Есть много данных, которые необходимо передать в вертуальное окружение для работы сервиса должным образом. Секреты хроняться сейчас в Secret k8s.
Все секреты должны быть переданы зарнее и если их большой список их надо автоматизировать в helm. Также не нравится что они храняться в base64 в деплое
Лучше изменить ширование и передавать их из единой точки хранения. Подробнее
Решение! Для решения подходит vault или Helm Secrets
install of programs74
install of dmosk
You must have a valid Vault binary.
CentOS/RHEL
But this content is not currently available in your region!
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install vault
wget https://releases.hashicorp.com/vault/1.18.3/vault_1.18.3_linux_amd64.zip
install of Manually install a Vault binary
export VAULT_DATA=/opt/vault/data
export VAULT_CONFIG=/etc/vault.d
sudo mv PATH/TO/VAULT/BINARY /usr/bin/
sudo setcap cap_ipc_lock=+ep $(readlink -f $(which vault))
sudo mkdir -p ${VAULT_DATA}
sudo mkdir -p ${VAULT_CONFIG}
sudo useradd --system --home ${VAULT_DATA} --shell /sbin/nologin vault
sudo chown vault:vault ${VAULT_DATA}
sudo chmod -R 750 ${VAULT_DATA}
sudo tee ${VAULT_CONFIG}/vault.hcl <<EOF
ui = true
cluster_addr = "http://127.0.0.1:8201"
api_addr = "https://127.0.0.1:8200"
disable_mlock = true
storage "raft" {
path = "${VAULT_DATA}"
node_id = "127.0.0.1"
}
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_disable = 1
}
EOF
Change ownership and permissions on the Vault configuration file.
sudo chown vault:vault "${VAULT_CONFIG}/vault.hcl" && \
sudo chmod 640 "${VAULT_CONFIG}/vault.hcl"
Adding an option to skip certificate verification is a more acceptable option because The connection remains encrypted, but the certificate is not verified.
echo "VAULT_API_ADDR=https://127.0.0.1:8200" > /etc/vault.d/vault.env
echo "VAULT_API_SKIP_VERIFY=true" >> /etc/vault.d/vault.env
sudo chown vault:vault "${VAULT_CONFIG}/vault.env" && \
sudo chmod 640 "${VAULT_CONFIG}/vault.env"
Confirm the path to your Vault binary: VAULT_BINARY=$(which vault)
sudo tee /lib/systemd/system/vault.service <<EOF
[Unit]
Description="HashiCorp Vault"
Documentation="https://developer.hashicorp.com/vault/docs"
ConditionFileNotEmpty="${VAULT_CONFIG}/vault.hcl"
[Service]
User=vault
Group=vault
SecureBits=keep-caps
AmbientCapabilities=CAP_IPC_LOCK
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
NoNewPrivileges=yes
ExecStart=${VAULT_BINARY} server -config=${VAULT_CONFIG}/vault.hcl
ExecReload=/bin/kill --signal HUP
KillMode=process
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
EOF
Change permision
sudo chmod 644 /lib/systemd/system/vault.service
CentOS/RHEL install selinux policies
sudo sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
sudo setenforce 0
sudo systemctl daemon-reload
sudo systemctl start vault.service
sudo systemctl status vault.service
Ubuntu/Debian
sudo iptables -I INPUT -p tcp --dport 8200 -j ACCEPT
CentOS/RHEL
sudo firewall-cmd --permanent --add-port=8200/tcp
sudo firewall-cmd --reload
После установки, сервер Vault находится в запечатанном (sealed) состоянии. То есть, он не знает, как ему расшифровывать секреты, которые будут храниться в базе.
При попытке выполнить любую операцию с хранилищем секретов мы получим ошибку: Vault is sealed
Теперь нам нужно инициировать Vault и создать мастер-ключ и секретное хранилище, для этого используется команда
vault operator init
ВАЖНО! Не вводите ключ в качестве аргумента команды vault operator unseal, т.к. он сохраниться в истории bash и это может очень негативно сказаться на безопасности!
НЕ ДЕЛАЙТЕ ТАК!
vault operator unseal 4v8A0s4aHJ9cyywmeKTJnTeS2liP3OYY/MQGPz0KGSv1
Перед началом работы настройки интеграции Kubernetes с Vault необходимо создать файлы с секретом и политики работы с ним.
Создадим секрет V2 для работы с ним.
export VAULT_ADDR=http://x.x.x.x:8200/
vault login
vault secrets enable -path=kvv2 kv-v2
Vault при успехе команды вернет положительный ответ
Success! Enabled the kv-v2 secrets engine at: kvv2/
Теперь в простар секрета kvv2 можно записать секреты
Например:
vault kv put kvv2/app/config username="static-user" password="static-password"
Vault при успехе команды вернет положительный ответ
==== Secret Path ====
kvv2/data/app/config
======= Metadata =======
Key Value
--- -----
created_time 2025-02-10T12:58:02.143452289Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
Определим политику взаимодействия с этим секретом
В данном случае для файла config в каталоге app создадим правило для чтения и просмотра списка. Больше про политики тут
tee app.json <<EOF
path "kvv2/data/app/config" {
capabilities = ["read", "list"]
}
EOF
vault policy write app app.json
Существует 3 способа интегрировать Vault в Kubernetes
Для того чтобы создать интеграцию любым из этих методов необходимо создать аккаунт в Kubernetes для взаимодействия с Vault
Создайте serviceaccount vault с привязкой secret и cluster role binding в пространстве имен default.
apiVersion: v1
kind: ServiceAccount
metadata:
name: vault
namespace: default
---
apiVersion: v1
kind: Secret
metadata:
name: vault
namespace: default
annotations:
kubernetes.io/service-account.name: vault
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: role-tokenreview-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: vault
namespace: default
Включите метод аутентификации Kubernetes.
vault auth enable kubernetes
Получите веб-токен JSON (JWT) из секрета.
TOKEN_REVIEW_JWT=$(kubectl get secret vault --output='go-template={{ .data.token }}' | base64 --decode)
Получите сертификат CA Kubernetes.
KUBE_CA_CERT=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.certificate-authority-data}' | base64 --decode)
Получите URL-адрес хоста Kubernetes.
KUBE_HOST=$(kubectl config view --raw --minify --flatten --output='jsonpath={.clusters[].cluster.server}')
Создайте в vault аунтефикацию и именем vault с типом kubernetes
vault auth enable -path=vault kubernetes
Настройте метод аутентификации Kubernetes для использования токена учетной записи службы, местоположения узла Kubernetes, его сертификата и имени эмитента учетной записи службы.
vault write auth/vault/config \
token_reviewer_jwt="$TOKEN_REVIEW_JWT" \
kubernetes_host="$KUBE_HOST" \
kubernetes_ca_cert="$KUBE_CA_CERT" \
disable_issuer_verification=true
Привяжем политику app, которая будет опредена для секретов, с помощью serviceaccount vault kubernetes в пространстве kubernetes default
vault write auth/vault/role/role1 \
bound_service_account_names=vault \
bound_service_account_namespaces=default \
policies=app \
audience=vault \
ttl=24h
Подробная информация настройки тут
Как пользоваться тут
Clone repo with vault helm
git clone https://github.com/hashicorp/vault-helm.git && cd vault-helm
Install the Vault Helm chart
helm install vault ./vault-helm --set "global.externalVaultAddr=http://external-vault:8200"
Add metadata annotations
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
annotations:
vault.hashicorp.com/agent-inject: 'true'
vault.hashicorp.com/role: 'app'
vault.hashicorp.com/agent-inject-secret-config.env: 'kvv2/data/app/config'
vault.hashicorp.com/agent-inject-template-config.env: |
{{- with secret "kvv2/data/app/config" }}
{{- range $k, $v := .Data -}}
{{ $k | nindent 0}}={{ $v }}
{{- end }}
{{- end }}
spec:
serviceAccountName: vault
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
Метод рабочий, но не умет работать с k8s Secret, а значит выдать данные в env пода не возможно! Работает только определение в файл. Надо иметь ввиду это при разработке.
Также не работают динамические секреты!
Подробная доку тут
Как настраивать:
- Использование HashiCorp Vault для хранения секретов
- Секреты в kubernetes используя Hashicorp Vault + External Secrets Operator
- Manage your Kubernetes secrets with Hashicorp Vault
- Configure Hashicorp's Vault for Kubernetes Auth
Он является решение, которое работает с External Secrets Operator
Подробный гайд
Скопируем резиторий VSO
git clone https://github.com/hashicorp/vault-secrets-operator.git
Изменим vault-secrets-operator/chart/values.yaml
/:567
defaultVaultConnection:
enabled: true
address: "http://external-vault::8200"
skipTLSVerify: false
Установка
helm install vault-secrets-operator vault-secrets-operator/chart -n vault-secrets-operator-system --create-namespace -f vault-secrets-operator/chart/values.yaml
Создадим ресурсы для авторизации и взаимодействия с vault vault-auth-static.yaml
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: static-auth
namespace: default
spec:
method: kubernetes
mount: vault
kubernetes:
role: role1
serviceAccount: vault
audiences:
- vault
Применем политику
kubectl apply -f vault-auth-static.yaml
В случае успеха вывод команды вернет положительный ответ
kubectl get vaultauth static-auth -o json | jq .status
{
"specHash": "xxxx",
"valid": true
}
Создайте VaultStaticSecret с именем, который создаст secretkv в пространстве имен по default.
static-secret.yaml
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: vault-kv-vso
namespace: default
spec:
type: kv-v2
# mount path
mount: kvv2
# path of the secret
path: app/config
# dest k8s secret
destination:
name: secretkv
create: true
# static secret refresh interval
refreshAfter: 30s
# Name of the CRD to authenticate to Vault
vaultAuthRef: static-auth
Применем static-secret.yaml
kubectl apply -f static-secret.yaml
Просмотрим секрет
kubectl describe secret secretkv
Name: secretkv
Namespace: default
Labels: app.kubernetes.io/component=secret-sync
app.kubernetes.io/managed-by=hashicorp-vso
app.kubernetes.io/name=vault-secrets-operator
secrets.hashicorp.com/vso-ownerRefUID=21e82006-c4cc-4b78-b486-4fb781217708
Annotations: <none>
Type: Opaque
Data
====
_raw: 197 bytes
password: 15 bytes
username: 11 bytes