Chaos Testing
testing platform
SYSTÉMOVÉ SECRETY a jejich správa
1. SYSTÉMOVÉ SECRETY
Systémové certifikáty jsou uloženy v SYS ARGO repozitáři daného clusteru v adresáři secrets.
Ne všechny tyto certifikáty jsou zpracovávány GitOpsově. Řešíme často problém “slepice/vejce” takže některé secrets jsou aplikovány ručně po založení clusteru.
tree secrets/
├── api-certificate.yml # Openshift api TLS certifikát
├── argocd-app # argocd app secrets
│ ├── argocd-secret.yml
│ ├── token-git-github-csas-ops.yml
│ ├── token-helm-artifactory-1.yml
│ └── token-helm-artifactory-2.yml
├── argocd-sys # argocd sys secrets
│ ├── argocd-cluster.yml
│ ├── token-git-bitbucket-ocp4.yml
│ ├── token-git-github-csas-ops.yml
│ ├── token-helm-artifactory-1.yml
│ └── token-helm-artifactory-2.yml
├── azure-auth.yml # OIDC setting for Azure Auth
├── azure-group-sync.yml # Group sync operátor secret pro AAD group sync
├── backend-tprgnasbe02.yml # Trident NFS
├── kafka-credentials.yaml # kafka credentials pro logy
├── router-be-certificate.yml # BE router TLS
├── router-default-certificate.yml # default router TLS
├── router-dmz-certificate.yml # dmz router TLS
├── router-fe-certificate.yml # FE router TLS
└── sealed-secrets.yml # Sealed secrets private KEY/CERT
Tyto secrets jsou ve standartní struktuře kind:Secrets a jsou zašifrovány pomocí ‘Ansible vault’.
2. GITOPS zpracování
Pro GITOPS zpracování secretů, Ansible vault secrety dešifrujeme, updatujeme a následně zašifrujeme certifikátem pro Kubeseal do adresáře confidential-secrets. Standartním procesem pak provedeme Gitops sync.
# secrety řízené GITOPS
tree secrets/
├── api-certificate.yml # Openshift api TLS certifikát
├── azure-auth.yml # OIDC setting for Azure Auth
├── azure-group-sync.yml # Group sync operátor secret pro AAD group sync
├── kafka-credentials.yaml # kafka credentials pro logy
├── router-be-certificate.yml # BE router TLS
├── router-default-certificate.yml # default router TLS
├── router-dmz-certificate.yml # dmz router TLS
└── router-fe-certificate.yml # Sealed secrets private KEY/CERT
Provedení výměny secretů
#decrypt
ansible-vault decrypt $secret
# update obsahu secretu novými hodnotami
#encrypt
ansible-vault encrypt $secret
#pipe it through sealed-secrets
read ansible_vault_pass </dev/tty
#pokud chceme pouzit kubeseal certifikat lokalne
ansible-vault view $secret --vault-password-file <(cat <<<"$ansible_vault_pass")|kubeseal --cert cert.pem --scope namespace-wide >confidential-secrets/$secret
#pokud chceme pouzit kubeseal certifikat ze serveru
ansible-vault view api-certificate.yml --vault-password-file <(cat <<<"$ansible_vault_pass")|kubeseal --cert https://certificate-sealed-secrets.apps.<CLUSTER_NAME>.<BASE_DOMAIN>/v1/cert.pem --scope namespace-wide >confidential-secrets/$secret
# následuje standartní render a GIT commit/push
3. Spracování neřízených GITOPS
Některé secrety jsou potřeba pro konfiguraci samotného clusteru a jeho komponent. Musí tedy být přítomny v clusteru ještě před jeho konfigurací a je tedy nutné je aplikovat ručně.
# secrety neřízené GITOPS
tree secrets/
├── argocd-app
│ ├── argocd-secret.yml
│ ├── token-git-github-csas-ops.yml
│ ├── token-helm-artifactory-1.yml
│ └── token-helm-artifactory-2.yml
├── argocd-sys
│ ├── argocd-cluster.yml
│ ├── token-git-bitbucket-ocp4.yml
│ ├── token-git-github-csas-ops.yml
│ ├── token-helm-artifactory-1.yml
│ └── token-helm-artifactory-2.yml
├── backend-tprgnasbe02.yml # Trident NFS
└── sealed-secrets.yml # Sealed secrets private KEY/CERT
## provadime update hodnot
#decrypt
ansible-vault decrypt $secret
# update obsahu secretu novými hodnotami
#encrypt
ansible-vault encrypt $secret
## aplikujeme nove nebo stavajici hodnoty
read ansible_vault_pass </dev/tty
ansible-vault view $secret --vault-password-file <(cat <<<"$ansible_vault_pass")|oc apply -f -
141. Testovací scénáře
1. Výpadek master nodu v SRM poolu a jeho stěhování do druhé lokality
Očekávaný stav:
Nebude mít žádný dopad na funkčnost clusteru. Control plane bude stále v quoru.
Opravné kroky:
Provedeme failover SRM poolu na druhou lokalitu. Zjistíme stav memberů v ETCD, tedy zda jsou skutečně 3 členové.
Akceptační kritéria:
Počet master nodů=3, počet memberů v ETCD=3
Pracnost:
S
Výsledek: Výpadek master nodu neměl žádný dopad na funkčnost clusteru. SRM failover nebyl testován
2. Výpadek jedné lokality
Jelikož master nody jsou mezi lokalitami rozděleny disproporčně, provedeme výpadek na straně majority master nodu.
Očekávný stav:
Control plane přijde o quorum, API server se přepne do readonly nastavení. Jelikož je API server bez zápisu, nebude možné provést
automatický rescheduling workloadu v postižené lokalitě na druhou lokalitu.
Opravné kroky:
Provedeme failover SRM poolu na druhou lokalitu a/nebo vytvoříme v druhé lokalitě nový master nod a přidáme ho do poolu. Zjistíme stav memberů v ETCD, tedy zda jsou skutečně 3 členové.
Worload by se měl začít schedulovat na workernody v druhé lokalitě dle svých priorityclass.
Akceptační kritéria:
Počet master nodů=3, počet memberů v ETCD=3, běžící workload do limitu zdrojů (nějaký workload může zůstat ve stavu “pending”)
Pracnost:
S
Výsledek:
Openshift API není funkční, ETCD není funkční jelikož má na sobě “proby” kontrolující majoritu (tedy nejede v jedné instanci). Samotné aplikace jedou DC1/DC2, pokud je v jejich logice volání OCP API budou failovat.
Po nastartování master nodů došlo ke spojení ETCD a získání majority a nastartuje API.
3. Výpadek nodu s přidělenými více EgressIP
Očekávný stav:
Workload namespacu s definovaným Egress se nedostane po dobu failoveru na outbound, EgressIP bude automaticky přestěhována na dostupný nod.
Opravné kroky:
Vše by se mělo provést automaticky, jde jen o zjištění doby trvání failoveru pro EgressIP a vyhodnocení dopadu.
Akceptační kritéria:
Zjištění doby failoveru vícero egressIP adres na jiný nód.
Poznámka:
Otestovat myšlenku více egressIP pro jeden namespace, případně sdílení egressIP mezi vícero namespace(Openshift 4.12).
Pracnost:
S
Výsledek:
Jakmile je nod labelován jako k8s.ovn.org/egress-assignable, EgressIP operator prezentován jako ovnkube-master pod bude periodicky kontrolovat zda je nod použitelný.
EgressIP adresy přidělené nodu který není dosažitelný jsou přesunuty na jiný dosažitelný nod.
Periodická kontrola dostupnosti egres nodu je definovana v kubernetes OVN na periodu 5 sekund.
Aplikace používající egressIP z poolu vypnutého nodu budou mit packet lost pro outbound po dobu failoveru na jiný nód to je cca 10s.
Nepovedlo se dokázat že větší množství egressIP pro které je potřeba provést failover mají vazbu na délku failoveru samotného a tedy dopad na dostupnost aplikačního outboundu.
4. Znefunkčnění celého clusteru a jeho GITOPS obnova
Očekávný stav:
Nefunkční cluster
Opravné kroky:
Vytvoření nového clusteru, připojení systémového a aplikačního ArgoCD a jeho všech zdrojů. Validace průběhu vytvoření všech původních objektů.
Akceptační kritéria:
Množství řádků limitně se blížící nule.
oc get pods --field-selector status.phase!=Running,status.phase!=Succeeded --all-namespaces
Pracnost:
S
Výsledek:
Test proveden s dostatečným množstvím dummy aplikací na testovacím clusteru. Chybějící kroky dopsány do GITOPS sys flow, ArgoCD SYS bootstrap.
5. Výpadek “network” nodu ve vazbě na ingressControler
Očekávný stav:
Nefunkční network nod, pod pro ingressControler ve stavu pending
Opravné kroky:
Funkční network nod
Akceptační kritéria:
Trafic směřující z venku přez ingress kontroler nebyl omezen.
Pracnost:
XS
Výsledek:
Ingress kontroler běží v RS=4, rozprostřeny přez všechny “network node” pro daný cluster. Ingresscontroller běží jako hostNetwork tedy na definovaném portu každého “network nodu”. V případě pádu ingress nodu jde o to po jaké době F5 jako loadbalancer přestane na neodpovídající nod posílat requesty. Proby na F5 jsou pro tcp nastany na 5s a po 3 neúspěšných pokusech je member vyřazen, celková doba vyřazení memberu z LB je tedy 16s.
6.Distribuce requestů mezi vícero ingress kontrolerů
Očekávný stav:
Requesty jsou dle nastavení F5 loadbalancer posílány na jednotlivé membery.
Akceptační kritéria:
Prověření normálního rozložení requestů mezi jednotlivé ingresscontrolery.
Pracnost:
XS
Výsledek:
Ingress kontroler běží v RS=4, rozprostřeny přez všechny “network node” pro daný cluster. Ingresscontroller běží jako hostNetwork tedy na definovaném portu každého “network nodu”. F5 na základě interních mechanismů odesílá střídavě requesty na jednotlivé membery. Pro tcp je použit roundrobin.
7.Test alertingu pro kritické prvky infrastruktu
Očekávný stav:
Alerty jsou doručeny dle konfigurace alertManager
Akceptační kritéria:
Alerty byli doručeny dle konfigurace alertManager
Pracnost:
S
Výsledek:
8.Jak se cluster zachová, když mu přetížíme jeden, dva X node. Jak rychle přestěhuje, jestli vůbec. Tady bych rád věděl, jak se cluster zachová, když v něm jeden nebo dva node (abych byl exaktní - cca 20% kapacity clusteru) vyžere výkon
Očekávný stav:
Nestane se nic, nový workload bude schedulován na nezatížené nódy.
Akceptační kritéria:
Nestalo se nic, nový worload byl schedulován na nezatížené nódy.
Pracnost:
S
Výsledek:
Workload na nodu se sám stěhovat nebude. Další workload bude plánován na nezatížené nody dle hodnotících kritérií a samozřejmě nastevení deploymentu samotného, ale pokud nedojde k pádu aplikace nebude přestěhována z původních zatížených nodů.
Scheduling na nod je v době deploymentu definován pouze na úrovni následujících váhových ohodnocení
{"name" : "LeastRequestedPriority", "weight" : 1},
{"name" : "BalancedResourceAllocation", "weight" : 1},
{"name" : "ServiceSpreadingPriority", "weight" : 1},
{"name" : "NodePreferAvoidPodsPriority", "weight" : 1},
{"name" : "NodeAffinityPriority", "weight" : 1},
{"name" : "TaintTolerationPriority", "weight" : 1},
{"name" : "ImageLocalityPriority", "weight" : 1},
{"name" : "SelectorSpreadPriority", "weight" : 1},
{"name" : "InterPodAffinityPriority", "weight" : 1},
{"name" : "EqualPriority", "weight" : 1}
LeastRequestedPriority: The node is prioritized based on the fraction of the node that would be free if the new Pod were scheduled onto the node. (In other words, (capacity - sum of requests of all Pods already on the node - request of Pod that is being scheduled) / capacity). CPU and memory are equally weighted. The node with the highest free fraction is the most preferred. Note that this priority function has the effect of spreading Pods across the nodes with respect to resource consumption.
CalculateNodeLabelPriority: Prefer nodes that have the specified label.
BalancedResourceAllocation: This priority function tries to put the Pod on a node such that the CPU and Memory utilization rate is balanced after the Pod is deployed.
CalculateSpreadPriority: Spread Pods by minimizing the number of Pods belonging to the same service on the same node. If zone information is present on the nodes, the priority will be adjusted so that pods are spread across zones and nodes.
CalculateAntiAffinityPriority: Spread Pods by minimizing the number of Pods belonging to the same service on nodes with the same value for a particular label.
9.Zjištění limitů ingress nodu
Budeme testovat přetěžování ingress nodu v izolovaném prostředí kde bude jako ingresscontroler sloužit pouze jeden pod a distribuovat zátěž na několik aplikačních cílových podů.
Očekávný stav:
Postupné zpomalování odpovědí, možné HTTP error.
Akceptační kritéria:
Definice limitů pro ingress.
Pracnost:
M
Výsledek:
Testované maximum bylo 4000 kind:Ingress per jeden IngressClass. Při tomto maximu nebyly pozorovány problémy s routerem pro danou IngressClass. Doporučená hodnota RH je 2000 kind:Ingress na jeden ingress controller.
Vyhodnocovací nástroje
Pro vyhodnocení dopadu jednotlivých testovacich scénářů využijeme Cerberus (celkový pohled na cluster) a pak standartní monitorovací nástroje Prometheus/Grafana.
27. Definice postupu pro DR
Obnova cestou GITOPS
Openshift cluster se nebudeme snažit obnovovat ze zálohy, kompletní obnova spolu s obnovou ETCD by vyžadovala mít i stejnou hardware konvenci a i tak by byla obnova celé ETCD problematická.\ Z tohoto pohledu se jeví jako jednodušší,a hlavně proveditelné, obnovit cluster tak že postavíme nový základ tedy controllplane a přidáme potřebný pool worker nodů. Samotný systémový a aplikační workload obnovíme z příslušných GIT repozitářů.
Je tedy nutné aby aplikace běžící na Openshiftu tento princip dodržovali a všechny jejich definice byly v GITU obsažené.
Workflow v závislosti na Project/Application CRD
Openshift cluster používá applicationOperátor a projectOperátor pro automatické vytváření objektů pro jenotlivé aplikace. Všechny projekty pro cluster jsou uloženy v “projektovém repozitáři” a jsou synchronizovány přez Systémové argoCD do clusteru.
Worflow na základě zjednodušených manifestů:
—> z projektového repozitáře, sync přez ArgoCD sys
apiVersion: ops.csas.cz/v1
kind: Project
metadata:
name: bokeh
spec:
environments:
- name: lab
type: lab
—> automaticky vytvořené přez projectOperator na základě project.ops.csas.cz
apiVersion: ops.csas.cz/v1
kind: ProjectEnvironment
metadata:
labels:
ops.csas.cz/environment-name: lab
ops.csas.cz/project: bokeh
name: bokeh-lab
spec:
applicationSource:
path: .
repoURL: https://github.com/csas-ops/bokeh-ocp4s-apps.git
targetRevision: env/lab
—> automaticky vytvořené přez projectOperator na základě projectenvironment.ops.csas.cz
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
labels:
ops.csas.cz/environment-name: lab
ops.csas.cz/environment-type: lab
ops.csas.cz/project: bokeh
name: bokeh-lab
namespace: csas-argocd-app
spec:
destinations:
- namespace: bokeh-lab
server: https://kubernetes.default.svc
—> automaticky vytvořené přez projectOperator na základě projectenvironment.ops.csas.cz
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
labels:
ops.csas.cz/environment-name: lab
ops.csas.cz/project: bokeh
name: bokeh-lab-apps
namespace: csas-argocd-app
spec:
destination:
namespace: bokeh-lab
server: https://kubernetes.default.svc
project: bokeh-lab
source:
path: .
repoURL: https://github.com/csas-ops/bokeh-ocp4s-apps.git
targetRevision: env/lab
—> definováno v Aplikačním repozitáři na který ukazuje předchozí application.argoproj.io
apiVersion: ops.csas.cz/v1
kind: Application
metadata:
labels:
argocd.argoproj.io/instance-app: bokeh-lab-apps
name: deva-helloworld-be
namespace: bokeh-lab
spec:
source:
chart: helloworld
helm:
values: |
key: value1
repoURL: https://artifactory.csin.cz/artifactory/api/helm/bokeh-helm-virtual
targetRevision: 0.17.0
—> vytvořeno applicationOperatorem na základě application.ops.csas.cz
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
labels:
application.ops.csas.cz/owner-name: deva-helloworld-be
application.ops.csas.cz/owner-namespace: bokeh-lab
name: bokeh-lab-deva-helloworld-be
namespace: csas-argocd-app
spec:
destination:
namespace: bokeh-lab
server: https://kubernetes.default.svc
project: bokeh-lab
source:
chart: helloworld
helm:
values: |
key: value1
repoURL: https://artifactory.csin.cz/artifactory/api/helm/bokeh-helm-virtual
targetRevision: 0.1.0

gitops diagram
Popis procesu obnovy
Celá obnova je postavena na principech GITOPS, pro systémovou část může dojít k aplikaci některých objektů v rámci BootStrap fáze. Bootstrap fáze je kompletně skriptovaná.
- Odstranění původního clusteru. Dostačující je smazání dat disků pro jednotlivé VM například utilitou dd.
- Instalace nového clusteru
- použití Ansible playbook instalace
- Ověření stavu nově nainstalovaného clusteru (běžné ověření funkčnosti)
- BOOTSTRAPING
- rekonfigurace(reflektovat změny pro nový cluster, pokud bude znovupoužita stejná konfigurace infrastruktry nemusí se měnit nic) + spuštění shell scriptu běžící proti API, dojde k vytvoření a konfiguraci ARGOCD SYS, které následně vytvoří applikace definované v GITHUB repository
- příprava a aplikace systémových “secrets” z bezpečného místa
- ARGOCD SYS: vytvořeno během bootstrapu, aplikuje všechen infrastrukturní workload spolu s komponenty pro ArgoCDAPP
- ARGOCD APP: sledování procesu množícího se deploymentu v ArgoCD APP \
- kontrola běhu aplikací
Dostačující je zevrubná kontrola běhu, založená na statusu aplikací oproti OC API.Bližší kontrola by měla být viditelná z metrik s vazbou na jednotlivé aplikace.
oc get pods --field-selector status.phase!=Running,status.phase!=Succeeded --all-namespaces
Časová náročnost
Celková náročnost se dá odhadnout na 2-3 hodiny
28. Postup pro UPGRADE
vizualizace možných update cest
Obecně se postup pro upgrade clusteru skládá ze dvou částí
- Cluster Version Operator (CVO) upgrade
Postupný upgrade všech podů které definují jednotlivé CVO pro systémovou část Openshiftu. Nad touto částí není možné mít žádnou deklarativní kontrolu a jakmile se spustí dojde k upgrade. Případné problémy se řeší na úrovni jednotlivých operátorů CVO.
Proto je vhodné upgrade nejdříve otestovat na nižších prostředích a zůstávat u stable upgrade kanálu.
V této fázi nedochází k restartu žádných nodů. - Machine Config Operator (MCO) node updates
- Cordon and drain all the nodes
- Update the operating system (OS)
- Reboot the nodes
- Uncordon all nodes and schedule workloads on the node
Default hodnota pro maxUnaviable je jedna takže v jeden okamžik bude updatován pouze jeden nod.
Update channel
Jako update channel bude použit pro všechna prostředí kanál stable
Prerekvizity
Vyřešené konflikty s životním cyklem API zdrojů dle dokumentace RedHat.
Časová náročnost upgrade
**Počítáme s množstvím worker nodů >10. Nastavení MCP pro “.spec.maxUnavailable” bude dle následující tabulky:
MCP role | maxUnavailable |
---|---|
master | 1 |
worker | 10% |
infra | 1 |
Nód může být součástí maximálně jednoho poolu a nody z každého poolu se upgradují nezávisle, takže podle našeho nastavení se bude najednou updatovat 1 nod z master MCP, 10% z worker MCP a 1 nod z infra MCP.
Celkový čas pak bude odpovídat součtu času pro CVO(cca 60 minut) a maxima času ze všech poolu. V testovacím clusteru který má 34 nodů (24 worker, 3 master,7 infra) bude tedy celkový čas:
CELKOVY_CAS = (60 + max((10*10),(3*10),(7*10)) ) + bufferzaokrouhlení ~ 200 minut
Zajištění HA pro aplikace
Aplikace které musí mít zajištěno HA během restartu, musí mít nastaven podDistruptionBudget například na minAvailable=1 a musí běžet v replicaSetu > 1.
Pro aplikace běžící v RS=1 nejsme schopni zajistit HA v průběhu upgrade procesu.
Canary Update
Pro upgrade kritických worker nodů lze použít canary update.
Kritický worker nod je nakonfigurován a vlastní prostředky tak jak to ostatní nody nemají, není tedy jednoduše zastupitelný obecným nodem.
Zatím nejsou definovány kritické worker nody ale můžeme definovat kritický workload definujicí vlastně tento nód, jako deployment které mají RS=1 nebo prostě nemohou v jeden okamžik běžet ve více replikách. Případně to může být nód na kterém běží workload který vyžaduje velké množství resourců a nebylo by možné tento workload přeshedulovat na jiný nod.
Tento workload nebude stěhován na jiný nód automaticky(nod nebude automaticky update a tedy ani nebude potřeba auto drainu) ale proces přesunu vybraného workloadu bude řízen.
Zároveň pokud nejsme schopni se vejít do servisního okna je vhodné rozdělit pooly na vícero částí a provést upgrade na částech spojitě.
Je ale potřeba brát v potaz že upgrade není dokončen dokud nejsou upradovány všechny nody.
Nody které nechceme updatnout dáme do samostatného “canary MCP”, tento MCO zapauzujeme
oc label node workernode node-role.kubernetes.io/workerpool-canary=
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfigPool
metadata:
name: workerpool-canary
spec:
machineConfigSelector:
matchExpressions:
- {
key: machineconfiguration.openshift.io/role,
operator: In,
values: [worker,workerpool-canary]
}
nodeSelector:
matchLabels:
node-role.kubernetes.io/workerpool-canary: ""
V této chvíli MCP zapauzujeme a nody v něm obsažené nebudou updatovány
oc patch mcp/workerpool-canary --patch '{"spec":{"paused":true}}' --type=merge
Pustíme update a počkáme až se provede na všech nodech kromě zapauzovaných.
Následně odpauzujeme MCP a update se začne provádět na nodech v tomto poolu
oc patch mcp/workerpool-canary --patch '{"spec":{"paused":false}}' --type=merge
Provedeme test aplikací které sjou vázány na tento kontrétní machineConfig (machineConfigPool).
V případě chyb, provedeme drain a cordon nodů v poolu a donutíme tak aplikaci přesídlit se na jiný nód ve vazbě “taint/tolleration”
Nod pak můžeme vrátit do původního MCP
oc label node workernode node-role.kubernetes.io/workerpool-canary-
EgressIP worker upgrade
Upgrade může být citlivý u nodů držících EgressIP. Nody držicí egressIP jsou v MCP infra. Při použití OVN Kubernetes CNI pluginu však dochází k automatickému failoveru IP adress na jiný nód labelovaný jako k8s.ovn.org/egress-assignable="" v případě nedostupnosti nodů, tzn třeba jeho restart.
Dosažitelnost EgressIP nodu
Jakmile je nod labelován jako k8s.ovn.org/egress-assignable, EgressIP operator prezentován jako ovnkube-master pod bude periodicky kontrolovat zda je nod použitelný.
EgressIP adresy přidělené nodu který není dosažitelný jsou přesunuty na jiný dosažitelný nod.
Periodická kontrola dostupnosti egres nodu je “hard coded” na periodu 5 sekund.
DR scénář
V případě že se Openshift dostane do stavu nepoužitenosti v rámci upgrade, bude použit DR scénář stejný jako běžný DR scénář popsaný výše v bodě 27.
Tento stav by v rámci upgrade procesu neměl nastat, resp rozhodně to není běžný stav pokud budeme používat stabilní stable upgrade channel
30. Minimální počet worker nodu pro zajištění HA aplikací během upgrade
Minimální počet worker nodu se dá definovat jako 3 , rozprostřeny přez mezi dvěma lokalitami.
Při tomto malém počtu nodů je potřeba při HA upgrade počítat s minimálním množstvím volných resourců jako 1/počet_nodu z celkové kapacity worker poolu (jak CPU tak RAM). Zároveň je potřeba počítat s možností že nějaký workload může vyžadovat velké množství zdrojů které sice v celkovém součtu jsou ale nejsme schopni tento workload naschedulovat na jeden konkrétní nód. Podobný scénář bude vyžadovat servisní zásah a přesun některého workloadu tak aby byl požadované množství zdrojů na jednom nodu uvolněno.
počet worker nodu | maxUnavailable | volná kapacita |
---|---|---|
3 - 9 | 1 | 1/počet_worker_nodu z celkové kapacity worker poolu |
>10 | 10% | 1/10 celkové kapacity worker poolu |
Dá se však říci že pro clutery vyšších prostředí bude vždy množství worker nodů >10 a dále s tím tak budeme počítat.
Upgrade probíhá s nastavením “maxUnavailable=10%” tzn v jeden okamžik bude nedostupný maximálně 10% worker nodů. Zároveň v průběhu upgrade je proveden cordon a drain, tedy je zastaveno schedulování na postižený nody a aplikace jsou bezpečně terminovány a přesunuty na nod jiný.
HA pro aplikace jsme schopni udržet pouze pokud mají nastaven podDistruptionBudget například na minAvailable=1 a musí běžet v replicaSetu > 1.
Pro aplikace běžící v RS=1 nejsme schopni zajistit HA v průběhu upgrade procesu.
Z pohledu upgrade je vhodné držet minimální množství volných zdrojů tak aby byla možnost provést reschedule workloadu na ostatní běžící worker nody v průběhu upgrade. Tzn volná kapacita při stejné velikosti worker nodu by měla být > 10% (vhodnější je spíše 20%) jak pro CPU tak pro paměť.
Pro samotné applikace bude použit defaultně PodTopologySpread scheduler plugin.
defaultConstraints:
- maxSkew: 3
topologyKey: "kubernetes.io/hostname"
whenUnsatisfiable: ScheduleAnyway
- maxSkew: 5
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: ScheduleAnyway
Aplikace si mohou zároveň definovat vlastní spreadTopologyConstraints na úrovni podAPI, tak aby repliky byly “rovnoměrně” rozprostřeny mezi lokalitami. Pokud má aplikace tento spec nastaven bude mít prioritu před defaultním nastavením scheduleru.
Je třeba říci že je vhodnější pokud by si aplikace nastavovali tento parametr sami jelikož chování scheduler pluginu je značně benevoletní.
kind: Pod
apiVersion: v1
metadata:
name: mypod
labels:
app: part1
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: part1
46. Definice komponenty LOKI
94. Integrace na centralni trustStore
Potřebné CA certifikáty ve formátu PEM, JKS a jejich provisioning směrem k workloadu.
1. custom CA trust (X509)
certifikáty pro CA trust vloženy do CM
apiVersion: v1
data:
ca-bundle.crt: |
# CAIR3 CSAS
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
#CAIMS2
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
#CAIMST2
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
#CAIRT3
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
kind: ConfigMap
metadata:
name: user-ca-bundle
namespace: openshift-config
Injekce certifikátu do ConfigMapy:
apiVersion: v1
kind: ConfigMap
metadata:
name: trusted-ca
namespace: appnamespace
labels:
config.openshift.io/inject-trusted-cabundle: "true"
Takto labelovaná configmapa bude obsahovat jak náš custom trust tak i obecný RH CA trust
Reference v aplikaci:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-example-custom-ca-deployment
namespace: my-example-custom-ca-ns
spec:
...
spec:
containers:
- name: my-container-that-needs-custom-ca
volumeMounts:
- name: trusted-ca
mountPath: /etc/pki/ca-trust/extracted/pem
readOnly: true
volumes:
- name: trusted-ca
configMap:
name: trusted-ca
items:
- key: ca-bundle.crt
path: tls-ca-bundle.pem
2. JKS trust
Pro vytvoření JKS trustu z CA trust bundlu využijeme funkcionalitu cert-utils-operatoru který přez interní keystore vytvoří JKS trust z CA trust bundlu a injektne zpátky do configmapy.
apiVersion: v1
kind: ConfigMap
metadata:
name: trusted-ca
namespace: appnamespace
labels:
config.openshift.io/inject-trusted-cabundle: "true"
annotations:
cert-utils-operator.redhat-cop.io/generate-java-truststore: "true"
Configmapa pak vypadá:
apiVersion: v1
kind: ConfigMap
metadata:
name: trusted-ca
namespace: appnamespace
labels:
config.openshift.io/inject-trusted-cabundle: "true"
annotations:
cert-utils-operator.redhat-cop.io/generate-java-truststore: "true"
binaryData:
truststore.jks: ...
data:
ca-bundle.crt: ...
Reference v aplikaci pak může vypadat jako:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-example-custom-ca-deployment
namespace: my-example-custom-ca-ns
spec:
...
spec:
containers:
- name: my-container-that-needs-custom-ca
volumeMounts:
- name: trusted-ca
mountPath: /etc/pki/ca-trust/extracted/pem
readOnly: true
- mountPath: /etc/pki/ca-trust/extracted/java
name: jks-trust
readOnly: true
volumes:
- name: trusted-ca
configMap:
name: trusted-ca
items:
- key: ca-bundle.crt
path: tls-ca-bundle.pem
- name: jks-trust
configMap:
name: trusted-ca
items:
- key: truststore.jks
path: cacerts
Defaultní heslo pro keystore je changeit. Dá se změnit přez anotaci konfigmapy
annotation:
cert-utils-operator.redhat-cop.io/java-keystore-password: heslo
Alias pro certifikáty v keystoru je alias.