[DO-1690] Co-authored-by: denis.patrakeev <denis.patrakeev@avroid.tech> Reviewed-on: https://git.avroid.tech/K8s/k8s-configs/pulls/143 Reviewed-by: Rustam Tagaev <rustam.tagaev@avroid.team>
210 lines
10 KiB
Markdown
210 lines
10 KiB
Markdown
# Репозиторий с конфигурациями приложений, которые деплоятся на кластера K8s
|
||
|
||
## Структура каталогов в репозитории
|
||
|
||
```bash
|
||
├── clusters # каталог содержащий директории с кластерами
|
||
│ ├── k8s-avroid-office.prod.local # имя промышленного кластера
|
||
│ │ └── namespaces # каталог с директориями namespace, создаваемых в кластере k8s
|
||
│ │ ├── argocd # namespace для РУЧНОГО деплоя ArgoCD
|
||
│ │ │ ├── argo-cd # ArgoCD
|
||
│ │ │ ├── argocd-apps # мета-приложения ArgoCD Bootstrapping
|
||
│ │ │ ├── argocd-namespace.yaml # манифест namespace
|
||
│ │ │ └── README.md # порядок деплоя ArgoCD
|
||
│ │ │
|
||
│ │ ├── example # пример namespace
|
||
│ │ │ ├── <ПРИЛОЖЕНИЕ/СЕРВИС>
|
||
│ │ │ └── example.yaml # манифест namespace
|
||
│ │ │
|
||
│ │ ├── <NAMESPACE> # namespace для ручного или автоматического деплоя ArgoCD
|
||
│ │ │ ├── .rbac # манифесты различных политик или секретов
|
||
│ │ │ ├── app1 # приложение 1
|
||
│ │ │ ├── app2 # приложение 2
|
||
│ │ │ ├── ...
|
||
│ │ │ ├── appN # приложение N
|
||
│ │ │ └── <NAMESPACE>.yaml # манифест namespace
|
||
│ │ │
|
||
│ │ ├── kube-prometheus-stack # отдельный namespace cо стеком kube-prometheus-stack для мониторинга всего кластера
|
||
│ │ │
|
||
│ │ ├── jenkins-builds # отдельный namespace интеграции с промышленным Jenkins
|
||
│ │ │
|
||
│ │ ├── huawei-csi # отдельный namespace для Huawei CSI для интеграции с СХД
|
||
│ │ │
|
||
│ │ └── vault-infra # отдельный namespace для Bank Vault для интеграции HashiCorp Vault
|
||
│ │
|
||
│ ├── ... # имя промышленного кластера
|
||
│ │
|
||
│ └── <КЛАСТЕР_K8S_N> # имя промышленного кластера
|
||
│
|
||
└── README.md # этот файл
|
||
```
|
||
|
||
|
||
## ArgoCD. Автоматизация развёртывания сервисов
|
||
ArgoCD настроен таким образом, что он смотрит на `master`-ветку этого репозитория и, в зависимости от инстанса,
|
||
обрабатывает только файлы попадающие под вот такую маску:
|
||
|
||
```bash
|
||
Обрабатываемые файлы:
|
||
clusters/<КЛАСТЕР_K8S>/namespaces/*/argocd-apps-*.yaml
|
||
|
||
Исключение:
|
||
clusters/<КЛАСТЕР_K8S>/namespaces/{argocd/*,example/*,vault-infra/*}
|
||
```
|
||
|
||
|
||
## Настройка внешних секретов из HashiCorp Vault с помощью Bank Vaults
|
||
|
||
[Ссылка на офф. доку](https://bank-vaults.dev)
|
||
|
||
Для создания vault injector нужно установить helm
|
||
|
||
```bash
|
||
helm upgrade -n vault-infra --install --wait vault-secrets-webhook oci://ghcr.io/bank-vaults/helm-charts/vault-secrets-webhook
|
||
```
|
||
|
||
Далее создать роль секрет и рольбиндинг
|
||
|
||
```bash
|
||
kubectl apply -f clusters/k8s-avroid-office.prod.local/namespaces/vault-infra/vault-secrets-webhook/vault-service-account.yaml
|
||
kubectl apply -f clusters/k8s-avroid-office.prod.local/namespaces/vault-infra/vault-secrets-webhook/vault-cluster_role_binding.yaml
|
||
kubectl apply -f clusters/k8s-avroid-office.prod.local/namespaces/vault-infra/vault-secrets-webhook/vault-secret.yaml
|
||
```
|
||
|
||
Настройка со стороны vault
|
||
|
||
```bash
|
||
vault auth enable -path=avroid-office kubernetes
|
||
|
||
TOKEN=$(kubectl get secret vault -n vault-infra -o jsonpath="{.data.token}" | base64 --decode)
|
||
CA_CERT=$(kubectl get secret vault -n vault-infra -o jsonpath="{.data['ca\.crt']}" | base64 --decode)
|
||
ISSUER=$(kubectl get --raw /.well-known/openid-configuration | jq '.issuer')
|
||
K8S_CLUSTER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
|
||
|
||
vault write auth/avroid-office/config \
|
||
kubernetes_host="${K8S_CLUSTER}" \
|
||
token_reviewer_jwt="${TOKEN}" \
|
||
kubernetes_ca_cert="${CA_CERT}" \
|
||
issuer="${ISSUER}" \
|
||
disable_local_ca_jwt="true"
|
||
```
|
||
|
||
Далее создаем app роль - на каждый namespace нужно создавать свою роль с одноименным названием.
|
||
|
||
```bash
|
||
vault write auth/avroid-office/role/tavro-cloud-dev \
|
||
bound_service_account_names="*" \
|
||
bound_service_account_namespaces="tavro-cloud-dev" \
|
||
policies="prj-tavro-cloud-backend" \
|
||
ttl="24h"
|
||
```
|
||
|
||
policies - содержит список vault полиси, если нужно добавить новый, то просто добавляем и выполняем эту команду
|
||
|
||
ВНИМАНИЕ: для нормальной работы должен быть создан service-account в каждом namespace
|
||
|
||
для этого просто нужно выполнить
|
||
|
||
```bash
|
||
# не забудь поменять в файле namespace свой
|
||
cp clusters/k8s-avroid-office.prod.local/namespaces/vault-infra/vault-secrets-webhook/vault-service-account.yaml ./<your_namespace>
|
||
# далее меняем в файле имя на свой namespace и запускаем
|
||
kubectl apply -f vault-service-account.yaml
|
||
```
|
||
|
||
Простой пример для тестирования - в логах вы увидите свой секрет
|
||
|
||
```bash
|
||
kubectl apply -f - <<"EOF"
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: vault-test
|
||
namespace: sandbox
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app.kubernetes.io/name: vault-test
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app.kubernetes.io/name: vault-test
|
||
annotations:
|
||
vault.security.banzaicloud.io/vault-addr: "https://vault.avroid.tech" # внешний адрес vault
|
||
vault.security.banzaicloud.io/vault-role: "sandbox" # роль из под которой будем ходить в vault
|
||
vault.security.banzaicloud.io/vault-skip-verify: "false" # проверять сертификат или нет на стороне vault
|
||
# vault.security.banzaicloud.io/vault-tls-secret: "vault-tls" # сертификат для vault если он самоподписанный
|
||
# vault.security.banzaicloud.io/vault-agent: "false" # запускать агента который будет отслеживать изменения секрета
|
||
vault.security.banzaicloud.io/vault-ct-configmap: vault-test-config # конфиг который будет обрабатывать consul template
|
||
vault.security.banzaicloud.io/vault-path: "avroid-office" # название kubernetes аутентификации в vault
|
||
vault.security.banzaicloud.io/run-as-user: "100" # пользователь нужен что бы прочитать vault токен (100 - consul template)
|
||
spec:
|
||
serviceAccountName: vault # имя сервиса аккаунта - должен быть в каждом namespace
|
||
containers:
|
||
- name: alpine
|
||
image: alpine
|
||
command: ["sh", "-c", "echo ${FOO} && echo ${FOO_1} && echo going to sleep... && sleep 10000"]
|
||
resources:
|
||
requests:
|
||
cpu: 50m
|
||
memory: 32Mi
|
||
limits:
|
||
cpu: 50m
|
||
memory: 32Mi
|
||
env: # вариант когда секрет будет в переменную окружения
|
||
- name: FOO # переменная окружения куда попадет секрет
|
||
value: vault:sandbox/data/k8s/vault-test#FOO # путь до секрета
|
||
- name: FOO_1 # пример задания переменной окружения из секретв
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: vault-test-secret
|
||
key: FOO_1
|
||
---
|
||
# вариант когда секрет нужно поместить в файл конфигурации приложения
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
metadata:
|
||
name: vault-test-config # используется в аннотации vault.security.banzaicloud.io/vault-ct-configmap
|
||
namespace: sandbox
|
||
data:
|
||
config.hcl: |
|
||
vault {
|
||
vault_agent_token_file = "/vault/.vault-token"
|
||
retry {
|
||
backoff = "1s"
|
||
}
|
||
}
|
||
template {
|
||
contents = <<EOH
|
||
BAR: baz
|
||
{{- with secret "sandbox/data/k8s/vault-test" }}
|
||
FOO: {{ .Data.data.FOO }}
|
||
{{ end }}
|
||
EOH
|
||
destination = "/vault/secrets/config.yaml" # тут указан конечный файл конфигурации вашего приложения
|
||
}
|
||
---
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: vault-test-secret
|
||
namespace: sandbox
|
||
annotations:
|
||
vault.security.banzaicloud.io/vault-addr: "https://vault.avroid.tech"
|
||
vault.security.banzaicloud.io/vault-role: "sandbox"
|
||
vault.security.banzaicloud.io/vault-skip-verify: "false"
|
||
vault.security.banzaicloud.io/vault-path: "avroid-office"
|
||
type: Opaque
|
||
data:
|
||
FOO_1: dmF1bHQ6c2FuZGJveC9kYXRhL2s4cy92YXVsdC10ZXN0I0ZPTw==
|
||
EOF
|
||
```
|
||
|
||
В секрете строку с адресом секрета Bank Vault необходимо преобразовать в base64, это делается следующим образом:
|
||
```bash
|
||
# !!ВАЖНО!!
|
||
# ключ "-n" необходимо при преобразования для того чтобы в конце отсечь лишний символ перевода строки
|
||
echo -n "vault:sandbox/data/k8s/vault-test#FOO" | base64
|
||
```
|