fluxCD позволяет реализовать GitOps на kustomize + sops, если вдруг нет vault webhook или что-то вроде.
Первым делом сделаем bootstrap в кластере. Нужно быть залогиненым в кластер или передать kubeconfig через
--kubeconfig.flux bootstrap git \
--url=ssh://git@<domain>/path/flux.git \
--branch=main \
--path=clusters/k8s-1 \
--private-key-file=<path/to/private_key>
Это установит нужные приложения в k8s.
Тоже самое можно сделать для кластера k8s-2 например. Итоговая структура с учетом нескольких приложений.
├── clusters
│ ├── apps
│ │ ├── keda
│ │ │ ├── helmrelease.yaml
│ │ │ ├── kustomization.yaml
│ │ │ ├── namespace.yaml
│ │ │ └── repository.yaml
│ │ └── teleport-agent
│ │ ├── clusterrolebinding.yaml
│ │ ├── helmrelease.yaml
│ │ ├── kustomization.yaml
│ │ ├── namespace.yaml
│ │ ├── repository.yaml
│ │ └── token.yaml
│ ├── k8s-1
│ │ ├── apps
│ │ │ └── kustomization.yaml
│ │ └── flux-system
│ │ ├── gotk-components.yaml
│ │ ├── gotk-sync.yaml
│ │ └── kustomization.yaml
│ └── k8s-2
│ ├── apps
│ │ ├── kustomization.yaml
│ │ └── teleport-agent
│ │ ├── kustomization.yaml
│ │ └── patch-values.yaml
│ └── flux-system
│ ├── gotk-components.yaml
│ ├── gotk-sync.yaml
│ └── kustomization.yaml
└── README.md
Собственно на верхний уровень вынесены общие для кластеров приложения. В этом примере keda и teleport-agent.
В телепорте нужно под кластер переопределять values + использовать секрет, который не нужно хранить в репе.
Собственно для секрета один из способов, это использование sops.
Я использую в качестве бэка sops - age.
Сформировать ключ можно так:
age-keygen -o ~/age.key
Далее завести в кластер:
kubectl create secret generic sops-age --namespace=flux-system --from-file=age.agekey=/path/to/age_private_key
В нашей структуре создаем secret вида:
apiVersion: v1
kind: Secret
metadata:
name: teleport-agent-token
namespace: teleport-agent
stringData:
values.yaml: |
authToken: "super-secret-token"
Странный ключ
values.yaml нужен для flux, иначе будет ошибка. А вот ключ authToken уже пойдет в переменную нужную чарту teleport.Можно добавить
.sops.yaml в корень репозитория:creation_rules:
- path_regex: clusters/apps/.*/.*\.yaml
encrypted_regex: '^(data|stringData)$'
age: '<age_public_key>'
И шифруем его sops-ом:
sops -e -i <path/to/secret>
В итоге в репозитории окажется зашифрованный файл. Flux из коробки умеет работать с sops, нужно только в
gotk-sync.yaml указать ему это например так:apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 10m0s
path: ./clusters/k8s-1
prune: true
sourceRef:
kind: GitRepository
name: flux-system
decryption:
provider: sops
secretRef:
name: sops-age
sops-age - секрет, который мы создали.
Касательно оверайда values. В кластерах нам нужно мочь переопределить значения в values под кластер для телепорт агента.
Создаем директорию
teleport-agent внутри clusters/<cluster>/apps.Там нужно два файла, собственно
kustomization.yamlapiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../../apps/teleport-agent
patchesStrategicMerge:
- patch-values.yaml
В нем подключаем общую директорию и указываем смержить с файлом
path-values.yaml.Собственно
patch-values.yaml:apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: teleport-agent
namespace: teleport-agent
spec:
values:
kubeClusterName: k8s-1
proxyAddr: <teleport_server_address>
labels:
team: <team>
env: <env>
name: <cluster_name>
Добавили spec.values. В общем файле его нет. Там мы подключаем переменную из секрета через valuesFrom.
При комите в целевую ветку, flux сам создаст релиз и подхватит деплой с kustomization + sops.
#flux