Pređi na glavni sadržaj

Kubernetes executor Enterprise

Sa Kubernetes executorom runner kreira jedan Pod po zadatku u namespace-u, prenosi njegov log u Semaphore i briše Pod kada se zadatak završi. Runner može da radi u klasteru (preporučeno) ili izvan njega, sa kubeconfig datotekom.

Kako se izvršava kontejnerski zadatak, šta se nalazi u kontejneru i šta nije podržano opisano je u Executori. Ova stranica pokriva podešavanje Kubernetes-a.

Pre nego što počnete​

  • Semaphore server sa Enterprise licencom.
  • Runner raspoređen u klasteru, pogledajte Instaliranje runnera na Kubernetes. Koraci u nastavku koriste njegov namespace semaphore i Deployment semaphore-runner. Za runner van klastera pogledajte Runner izvan klastera.
  • kubectl sa pravima da kreira servisne naloge i RBAC objekte u tom namespace-u.
  • Klaster može da preuzme semaphoreui/job i semaphoreui/helper (ili vaše image-e).

Šta runner kreira​

Za zadatak sa ID-jem 42 runner kreira, u svom namespace-u:

ObjekatImeSadržaj
Podsemaphore-job-42-<random>Init kontejner git-clone (helper image) i kontejner build (build image), restartPolicy: Never.
Secret<pod>-ssh-<key id>Jedan po SSH ključu, montiran u /secrets/ssh/<key id>/.
Secret<pod>-vaultAnsible vault lozinke.
Secret<pod>-extra-varsvalues.json sa dodatnim promenljivama.
Secret<pod>-envTajne iz Variable Group tipa Environment variable i SEMAPHORE_JWT, ubačene pomoću envFrom.
ConfigMap<pod>-inventoryStatički inventar.

Kreiraju se samo objekti koji su zadatku potrebni. Svi nose oznaku semaphoreui.com/runner=semaphore; Pod ima i semaphoreui.com/task-id=42. Runner ih sve briše kada se zadatak završi, i posle neuspeha ili Stop.

Podešavanje​

Korak 1. Kreirajte servisne naloge​

Runneru je potreban jedan servisni nalog za kreiranje Podova zadataka. Podovi zadataka dobijaju drugi, bez dozvola i bez API tokena, tako da playbook ne može da koristi prava runnera.

semaphore-serviceaccounts.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: semaphore-runner
namespace: semaphore
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: semaphore-job
namespace: semaphore
automountServiceAccountToken: false

Korak 2. Dodelite runneru dozvole​

Ovo je kompletna lista API poziva koje executor izvršava:

semaphore-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: semaphore-runner
namespace: semaphore
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "delete"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
- apiGroups: [""]
resources: ["secrets", "configmaps"]
verbs: ["create", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: semaphore-runner
namespace: semaphore
subjects:
- kind: ServiceAccount
name: semaphore-runner
namespace: semaphore
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: semaphore-runner

Role, a ne ClusterRole: runner može da dira samo svoj namespace.

Korak 3. Prebacite runner na Kubernetes executor​

Podovi zadataka ne postavljaju securityContext, pa ih namespace koji nameće Pod Security nivo restricted odbija. Dozvolite baseline:

kubectl label namespace semaphore pod-security.kubernetes.io/enforce=baseline --overwrite

Dodelite Podu runnera njegov servisni nalog i podešavanja executora. U Deployment-u runnera dodajte u spec.template.spec:

semaphore-runner.yaml (fragment)
    spec:
serviceAccountName: semaphore-runner
containers:
- name: runner
env:
# ...SEMAPHORE_WEB_ROOT and SEMAPHORE_RUNNER_TOKEN as before
- name: SEMAPHORE_RUNNER_EXECUTOR_TYPE
value: k8s
- name: SEMAPHORE_RUNNER_K8S_NAMESPACE
value: semaphore
- name: SEMAPHORE_RUNNER_K8S_SERVICE_ACCOUNT
value: semaphore-job
- name: SEMAPHORE_RUNNER_K8S_IMAGE
value: semaphoreui/job:latest
kubectl apply -f semaphore-serviceaccounts.yaml -f semaphore-rbac.yaml -f semaphore-runner.yaml
kubectl -n semaphore rollout status deploy/semaphore-runner

Bez podešenog kubeconfig-a runner koristi kredencijale naloga semaphore-runner unutar klastera. Zadaci se više ne izvršavaju u Podu runnera, pa možete smanjiti njegove resources (na primer 100m CPU-a i 256Mi memorije).

Korak 4. Pokrenite zadatak​

Usmerite šablon na runner i pokrenite zadatak. Pratite kako se njegov Pod pojavljuje i nestaje:

kubectl -n semaphore get pods -l semaphoreui.com/runner=semaphore -w

Log zadatka prikazuje:

k8s: created pod semaphore/semaphore-job-42-a1b2c3 (1 ssh keys installed)
=== git-clone (init) ===
Cloning into '/workspace/repo'...
=== build (build) ===
semaphore: container executor: task 42, template 7
...
k8s: deleted pod semaphore/semaphore-job-42-a1b2c3

Primeri​

Runner izvan klastera​

Runner radi na VM-u ili u Docker-u i pristupa API serveru pomoću kubeconfig-a. Dajte kubeconfig-u Role iz Koraka 2 i ništa više:

{
"web_host": "https://semaphore.example.com",
"runner": {
"token_file": "/var/lib/semaphore/runner_token.txt",
"executor": {
"type": "k8s",
"k8s": {
"kubeconfig": "/etc/semaphore/kubeconfig",
"namespace": "semaphore",
"service_account": "semaphore-job"
}
}
}
}

Koristi se trenutni kontekst kubeconfig-a.

Image-i iz privatnog registra​

Kreirajte pull secret u namespace-u i navedite ga u pull_secrets; više imena se razdvaja zarezima:

kubectl -n semaphore create secret docker-registry registry-example \
--docker-server=registry.example.com \
--docker-username=<user> --docker-password=<password>
            - name: SEMAPHORE_RUNNER_K8S_IMAGE
value: registry.example.com/semaphore/job-aws:1.0
- name: SEMAPHORE_RUNNER_K8S_PULL_SECRETS
value: registry-example

Secrets se dodaju svakom Podu zadatka, podjednako za build image, helper image i Executor image šablona.

CPU i memorija Podova zadataka​

Executor ne postavlja requests ni limits na Podove zadataka. Podesite podrazumevane vrednosti za namespace pomoću LimitRange; on važi za kontejnere git-clone i build:

semaphore-limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: semaphore-task-defaults
namespace: semaphore
spec:
limits:
- type: Container
defaultRequest:
cpu: 250m
memory: 256Mi
default:
cpu: "2"
memory: 2Gi

Dodajte ResourceQuota da ograničite koliko svi paralelni zadaci namespace-a mogu da koriste.

Ograničavanje mreže Podova zadataka​

Podovi zadataka nose oznaku semaphoreui.com/runner=semaphore, pa ih NetworkPolicy može izabrati. Ova dozvoljava samo DNS, Git server i SSH ka upravljanim hostovima:

semaphore-netpol.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: semaphore-tasks
namespace: semaphore
spec:
podSelector:
matchLabels:
semaphoreui.com/runner: semaphore
policyTypes: ["Ingress", "Egress"]
egress:
- ports:
- { protocol: UDP, port: 53 }
- { protocol: TCP, port: 53 }
- to:
- ipBlock: { cidr: 10.20.0.0/16 } # Git server and managed hosts
ports:
- { protocol: TCP, port: 22 }
- { protocol: TCP, port: 443 }

Referenca konfiguracije​

Sve opcije se nalaze pod runner.executor.k8s u konfiguraciji runnera.

OpcijaPromenljiva okruženjaPodrazumevanoOpis
kubeconfigSEMAPHORE_RUNNER_K8S_KUBECONFIGunutar klasteraPutanja do kubeconfig datoteke. Prazno: servisni nalog Poda runnera.
namespaceSEMAPHORE_RUNNER_K8S_NAMESPACEsemaphoreNamespace Podova zadataka, Secrets i ConfigMaps. Mora da postoji.
imageSEMAPHORE_RUNNER_K8S_IMAGEsemaphoreui/job:latestImage kontejnera build. Executor image šablona ga zamenjuje.
helper_imageSEMAPHORE_RUNNER_K8S_HELPER_IMAGEsemaphoreui/helper:latestImage init kontejnera git-clone.
service_accountSEMAPHORE_RUNNER_K8S_SERVICE_ACCOUNTdefaultServisni nalog Podova zadataka. Koristite nalog bez dozvola, pogledajte Korak 1.
pull_secretsSEMAPHORE_RUNNER_K8S_PULL_SECRETS—imagePullSecrets za Podove zadataka, razdvojeni zarezima.
poll_interval_secondsSEMAPHORE_RUNNER_K8S_POLL_INTERVAL_SECONDS3Koliko često runner čita status Poda. Niže vrednosti ranije pokreću prenos loga i troše više API poziva.
cleanup_grace_secondsSEMAPHORE_RUNNER_K8S_CLEANUP_GRACE_SECONDS30Grace period brisanja Poda posle završetka ili zaustavljanja zadatka.

Pull politika image-a prati podrazumevano ponašanje Kubernetes-a: Always za :latest, inače IfNotPresent.

Bezbednost​

  • Najmanja prava za runner. Role je ograničen na namespace i navodi samo ono što executor poziva. Ne vezujte cluster-admin.
  • Bez API pristupa za zadatke. Sa podrazumevanim service_account: default Pod zadatka dobija token podrazumevanog naloga namespace-a. Koristite namenski nalog sa automountServiceAccountToken: false.
  • Namespace samo za Semaphore. Runner ne može ništa da čita, ali tamo može da kreira i briše Podove i Secrets; ne delite namespace sa drugim workload-ima.
  • Tajne su zasebni Kubernetes Secrets po zadatku, montirani samo za čitanje (tajne okruženja preko envFrom, pa njihove vrednosti nisu u specifikaciji Poda) i brišu se sa Podom. Ko može da čita Secrets u namespace-u, može da ih pročita dok zadatak radi; uključite šifrovanje u mirovanju za Secrets.
  • Mreža. Ograničite šta zadaci dosežu pomoću NetworkPolicy.

Zaustavljanje i čišćenje​

Stop u korisničkom interfejsu prekida prenos loga i briše Pod sa cleanup_grace_seconds, a zatim njegove Secrets i ConfigMaps.

Ako se runner ubije tokom zadatka, objekti zadatka ostaju u namespace-u; runner ih ne prikuplja pri sledećem pokretanju. Uklonite ih kada nijedan zadatak ne radi:

kubectl -n semaphore get pods,secrets,configmaps -l semaphoreui.com/runner=semaphore
kubectl -n semaphore delete pods,secrets,configmaps -l semaphoreui.com/runner=semaphore

Rešavanje problema​

SimptomUzrok i rešenje
Log runnera: k8s executor is only available in the proprietary buildRunner je Community verzija. Koristite semaphoreui/runner ili zvanični binarni fajl.
Log runnera: failed to initialise executor provider sa unable to load in-cluster configurationRunner je izvan klastera i kubeconfig je prazan, ili je putanja do kubeconfig-a pogrešna.
Zadatak: create pod ...: pods is forbidden: User "system:serviceaccount:..." cannot create resourceRBAC nedostaje ili je vezan u drugom namespace-u. Proverite kubectl auth can-i create pods -n semaphore --as=system:serviceaccount:semaphore:semaphore-runner.
Zadatak: create pod ...: namespaces "semaphore" not foundKreirajte namespace; runner to ne radi.
Zadatak: create pod ...: violates PodSecurity "restricted"Označite namespace sa pod-security.kubernetes.io/enforce: baseline.
Zadatak ostaje u statusu Running bez izlazaPod je zaglavljen u Pending: nijedan čvor ne odgovara, image ne može da se preuzme (ImagePullBackOff) ili ga blokira kvota. Runner čeka dok se Pod ne završi. Proverite kubectl -n semaphore describe pod -l semaphoreui.com/task-id=<task id> i zaustavite zadatak.
Zadatak: pod ... finished with status FailedKloniranje ili aplikacija nisu uspeli. Log iznad prikazuje izlaz git-clone i build.
interpreter python3 not found in imageBuild image-u nedostaje binarni fajl aplikacije; podesite drugi image ili Executor image šablona.
No user exists for uid ... (OpenShift)U /etc/passwd image-a grupa ne može da piše. Pogledajte Izgradnja prilagođenog image-a.