-
Kubernetes-käsitteet
Kubernetesin ja OKD:n käsitteet
Kubernetesin (ja OKD:n) voima perustuu suhteellisen yksinkertaisiin abstraktioihin, joita ne tarjoavat monimutkaisiin tehtäviin, kuten kuormantasaamiseen, hajautetun järjestelmän ohjelmistopäivityksiin tai automaattiseen skaalaukseen. Tässä annamme hyvin lyhyen yleiskatsauksen joihinkin tärkeimpiin abstraktioihin, mutta suosittelemme vahvasti, että luet myös Kubernetesin ja OKD:n käsitedokumentaation:
Nämä abstraktiot ovat objekteja, pysyviä entiteettejä Kubernetes-järjestelmässä. Näitä entiteettejä käytetään kuvaamaan projektin haluttua tilaa (jota Kubernetesissa kutsutaan myös nimiavaruudeksi). Suurin osa objekteista on yhteisiä sekä tavalliselle Kubernetesille että OKD:lle, mutta OKD tuo mukanaan myös joitakin omia lisäobjektejaan.
Kubernetesin käsitteet
Nimiavaruus
Useimmat Kubernetes-objektit luodaan nimiavaruuden sisään. Nimiavaruus on yksinkertaisesti hiekkalaatikko, jossa kaikki muut objektit sijaitsevat ja ovat eristettyinä muihin nimiavaruuksiin kuuluvista objekteista. OKD:ssä nimiavaruudesta käytetään nimitystä projekti. Molemmat termit (projekti ja nimiavaruus) ovat tietotekniikassa hyvin yleisiä sanoja, joten niihin viittaaminen voi joskus olla hämmentävää. Näissä dokumenteissa termejä nimiavaruus ja Rahti-projekti käytetään rinnakkain. Projektin luomisesta kerrotaan dokumentaatiossa Projektin luominen.
Podi
Podi sisältää yhden tai useamman kontin, joissa sovellukset suoritetaan. Se on Kubernetesin perusyksikkö: kun suoritat työkuorman Kubernetesissa, se suoritetaan aina podissa. Kubernetes huolehtii näiden podien ajastamisesta useille palvelimille. Podit voivat sisältää erityyppisiä taltioita datan käyttämistä varten. Jokaisella podilla on oma IP-osoitteensa, jonka kaikki podin kontit jakavat; tämä IP-osoite voi muuttua, jos podi lopetetaan ja luodaan uudelleen. Tyypillisimmässä tapauksessa podi sisältää yhden kontin ja ehkä yhden tai muutaman erilaisen taltioin.
Podit on tarkoitettu kertakäyttöisiksi, eli ne voidaan lopettaa milloin tahansa, ja "pilvinatiivin" sovelluksen on pystyttävä jatkamaan toimintaansa niin, ettei käyttäjä huomaa keskeytystä. Sen on palaututtava automaattisesti. Kaikki data, jonka täytyy säilyä podin lopettamisen jälkeen, tulee tallentaa podiin liitetylle pysyvälle taltiolle.

Kubernetesin/OKD:n abstraktiot kuvataan YAML- tai JSON-muodossa. YAML ja JSON ovat niin sanottuja datasarjallistuskieliä: ne tarjoavat tavan kuvata avain-arvo-pareja ja tietorakenteita, kuten listoja, muodossa, jota sekä ihmiset että tietokoneet voivat lukea helposti. Alla on esimerkki siitä, miltä podin esitys näyttää YAML-muodossa:
apiVersion: v1
kind: Pod
metadata:
name: example
labels:
app: foo
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: httpd
image: 'image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest'
ports:
- containerPort: 8080
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
Yllä oleva YAML-esitys kuvaa selainkäyttöliittymäpalvelimen podia, jossa on yksi kontti ja joka avaa portin 8080. Voisit tallentaa tämän tekstikatkelman tiedostoon ja luoda podin, joka suorittaa Apache HTTP -palvelinta, syöttämällä tiedoston Rahti-API:lle.
InitContainer
initContainer on podissa oleva kontti, joka on tarkoitettu suoritettavaksi loppuun ennen kuin pääkontit käynnistetään. Dataa init-containereista voidaan siirtää pääkonttiin käyttämällä esimerkiksi tyhjiä taltioiden liitoksia.
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
initContainers:
- name: init-permissions
image: busybox
command: ["sh", "-c", "mkdir -p /workdir/data && chmod 755 /workdir/data"]
volumeMounts:
- name: workdir
mountPath: /workdir
containers:
- name: main-app
image: nginx:latest
volumeMounts:
- name: workdir
mountPath: /usr/share/nginx/html
volumes:
- name: workdir
emptyDir: {}
Yllä oleva Pod-määrittely sisältää yhden init-kontin ja yhden pääkontin. init-permissions-niminen init-kontti suoritetaan ennen kuin pääkontti käynnistyy. Tässä esimerkissä init-kontti luo hakemiston ja asettaa käyttöoikeudet jaetussa taltiossa, joka on liitetty polkuun /workdir. Vasta kun init-kontti päättyy onnistuneesti, Kubernetes käynnistää pääkontin, joka tässä tapauksessa suorittaa Nginxiä. Pääkontti liittää saman jaetun taltioin polkuun /usr/share/nginx/html, joten se voi käyttää init-kontin luomaa hakemistoa.
Palvelu
Podien IP-osoitteet eivät ole ennustettavia. Jos podi korvataan osana normaaleja toimintoja, kuten päivitystä, uuden podin IP-osoite on erilainen. Palvelut (lyhennettynä myös svc) tarjoavat vakaan yksityisen IP-osoitteen yhdelle tai useammalle Podille. Tämä IP toimii kuormantasaimena ja jakaa liikennekuorman sen takana olevien Podien kesken. Tätä varten palvelu huolehtii siitä, että sillä on ajan tasalla oleva lista IP-osoitteista, jotta pyynnöt lähetetään vain kelvollisiin osoitteisiin.
Palvelut on rakennettu julkaisemaan yksi tai useampi portti, ja ne tarjoavat myös sisäisen DNS-nimen. Mikä tahansa näistä nimistä on kelvollinen ja ratkeaa samaan palvelun IP-osoitteeseen:
<service_name>, esimerkiksiexample-svc<service_name>.<namespace>, esimerkiksiexample-svc.my-project- ja
<service_name>.<namespace>.svc.cluster.local, esimerkiksiexample-svc.my-project.svc.cluster.local
Samalla tavoin kuin Podit, myös Rahdissa olevat palvelut ovat saavutettavissa vain sen nimiavaruuden sisältä, jossa ne toimivat; toisesta nimiavaruudesta tuleva pyyntö pystyy ratkaisemaan DNS-nimen IP-osoitteeksi, mutta ei koskaan muodosta yhteyttä oletusarvoisten NetworkPolicies -sääntöjen vuoksi. Toinen palveluiden ominaisuus on, että ne voivat välittää pyyntöjä yhdestä portista toiseen kohdeporttiin (esim. 80:stä 8080:aan). Tämä on hyödyllistä Rahdissa, koska Podit eivät voi kuunnella etuoikeutettuja portteja (alle 1024).
Palveluita voidaan käyttää sisäisiin yhteyksiin. Oletetaan esimerkiksi, että meillä on yksi tai useampi MongoDB-tietokannan replika käynnissä my-project-nimiavaruudessa, kukin eri podissa, ja kaikki julkaisevat portin 27017. Voimme luoda mongo-nimisen palvelun, joka liitetään näihin podeihin tällä nimellä. Tämän jälkeen voimme käynnistää Podit, joissa suoritetaan Python-sovellusta ja jotka käyttävät URL-osoitetta mongo:27017 yhteyden muodostamiseen tietokantaan. Kun yhteyttä palveluun yritetään muodostaa, yksi mongo-podeista valitaan palvelemaan datapyyntöä.

apiVersion: v1
kind: Service
metadata:
name: example-svc
spec:
ports:
- port: 8081
protocol: TCP
targetPort: 8080
name: web-server
selector:
app: foo
sessionAffinity: None
type: ClusterIP
Portit
-
Kubernetes-palvelun
ports-kenttä määrittää verkkoporit, jotka palvelu julkaisee asiakkaille, ja miten ne yhdistetään podien vastaaviin portteihin. -
Se koostuu tyypillisesti useista osista:
- Name: Portin tunniste, joka voi helpottaa sen tunnistamista.
- Port: Porttinumero, jota asiakkaat käyttävät palvelun käyttämiseen.
- Protocol: Käytettävä viestintäprotokolla (yleensä TCP).
- TargetPort: Podissa oleva portti (nimi tai numero), johon palvelu ohjaa liikenteen.
Valitsin
-
Kubernetes-palvelun
selector-kenttä on keskeinen sen määrittämisessä, mihin podeihin palvelun tulee ohjata liikenne. -
Se koostuu avain-arvo-pareista, jotka vastaavat podeille annettuja tunnisteita. Palvelu käyttää näitä tunnisteita tunnistaakseen ja yhdistääkseen oikeisiin podeihin dynaamisesti.
-
Jos käytetään useita label-valitsimia, ne yhdistetään JA-operaatiolla.
-
Avain-arvo-pari (
app: foo): Tämä tarkoittaa, että palvelu ohjaa liikenteen kaikkiin podeihin, joilla on tunniste app: foo. -
Toiminnallisuus: Tämä mahdollistaa sen, että palvelu yhdistyy automaattisesti kaikkiin olennaisiin podeihin. Jos tällä tunnisteella varustettuja podeja lisätään tai poistetaan, palvelu mukauttaa reititystään vastaavasti ja varmistaa, että liikenne ohjautuu aina oikeisiin podeihin.
ReplicaSet
ReplicaSet varmistaa, että podista on käynnissä n kopiota. Jos yksi podeista kuolee, ReplicaSet luo uuden sen tilalle. ReplicaSetejä ei yleensä käytetä suoraan, vaan osana Deploymentia, joka selitetään seuraavaksi.

Deployment
Deploymentit hallitsevat sovelluksen päivityksiä. Ne sisältävät tyypillisesti ReplicaSetin ja useita podeja. Jos teet muutoksen, joka vaatii päivityksen, kuten vaihdat podin konttien imaget uudempaan versioon, deployment varmistaa strategiansa mukaisesti, että muutos otetaan käyttöön ilman palvelukatkosta. Tyypillinen strategia tekee liukuvan päivityksen, jossa kaikki podit lopetetaan yksi kerrallaan ja korvataan uudemmilla, samalla varmistaen, että loppukäyttäjien liikenne ohjautuu koko ajan toimiviin podeihin.

StatefulSet
Useimmat Kubernetes-objektit ovat tilattomia. Tämä tarkoittaa, että ne voidaan poistaa ja luoda uudelleen, ja sovelluksen pitäisi pystyä käsittelemään tämä ilman näkyvää vaikutusta. Esimerkiksi Deployment voi määrittää Podin, jossa on 5 replikaa ja liukuvan päivityksen strategia. Kun uusi image otetaan käyttöön, Kubernetes korvaa vanhat Podit vähitellen uusilla, luoden ne uudelleen eri nimillä ja mahdollisesti eri noodeille, samalla pitäen riittävästi replikoita käytettävissä liikenteen palvelemiseksi koko käyttöönoton ajan (strategian maxUnavailable- ja maxSurge-asetusten rajoissa). Joillekin sovelluksille tämä ei ole hyväksyttävää, ja tätä käyttötapausta varten luotiin StatefulSetit.
Kuten Deployment, StatefulSet määrittää Podinsa yhteisestä Pod-mallista. Mutta toisin kuin Deployment, jonka Podit ovat keskenään vaihdettavissa, StatefulSet antaa jokaiselle Podille vakaan, yksilöllisen identiteetin, joka säilyy uudelleensijoitusten, uudelleenkäynnistysten ja päivitysten yli. StatefulSet tarjoaa:
- Vakaat, yksilölliset verkkotunnisteet.
- Vakaan, pysyvän tallennuksen.
- Järjestetyn, hallitun käyttöönoton ja skaalauksen.
- Järjestetyt, automatisoidut liukuvat päivitykset.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # If omitted, by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: openshift/hello-openshift
ports:
- containerPort: 8888
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard-csi"
resources:
requests:
storage: 1Gi
Jobi
Jobi käyttää podeja tietyn tehtävän suorittamiseen yhden tai useamman kerran, ja se yrittää jatkaa podien suorittamista uudelleen, kunnes määritetty määrä niistä päättyy onnistuneesti tai backoff-raja saavutetaan. Kun podit valmistuvat onnistuneesti, Jobi seuraa onnistuneita valmistumisia. Kun määritetty määrä onnistuneita valmistumisia saavutetaan, tehtävä (eli Jobi) on valmis. Jobin poistaminen siivoaa sen luomat Podit. Jobin keskeyttäminen poistaa sen aktiiviset Podit, kunnes Jobia jatketaan uudelleen.
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
volumes:
- name: smalldisk-vol
emptyDir: {}
containers:
- name: pi
image: perl
command:
- sh
- -c
- >
echo helloing so much here! Lets hello from /mountdata/hello.txt too: &&
echo hello to share volume too >> /mountdata/hello-main.txt &&
cat /mountdata/hello.txt
volumeMounts:
- mountPath: /mountdata
name: smalldisk-vol
restartPolicy: Never
initContainers:
- name: init-pi
image: perl
command:
- sh
- -c
- >
echo this hello is from the initcontainer >> /mountdata/hello.txt
volumeMounts:
- mountPath: /mountdata
name: smalldisk-vol
backoffLimit: 4
Tämä jobi nimeää podin automaattisesti, ja podia voidaan kysellä job-name-tunnisteella:
Jobin vakiotuloste:
$ oc logs pi-gj7xg
helloing so much here! Lets hello from /mountdata/hello.txt too:
this hello is from the initcontainer
Projektin nimiavaruudessa voi olla vain yksi objekti tietyllä nimellä; siksi jobia ei voi suorittaa kahdesti, ellei sen առաջին instanssia poisteta. Podia ei kuitenkaan tarvitse siivota; se poistetaan automaattisesti ketjussa Jobin poistamisen jälkeen.
CronJob
CronJob perustuu Jobin käsitteeseen suorittamalla Jobeja toistuvalla aikataululla. Sen sijaan, että se suoritettaisiin kerran, CronJob luo uuden Jobin määrittäminäsi ajankohtina cron-lausekkeen perusteella (esimerkiksi joka yö tai kerran tunnissa), mikä on kätevää toistuviin tehtäviin, kuten varmuuskopioihin, raporttien luontiin tai säännölliseen siivoukseen. Jokainen ajastettu suoritus tuottaa alla esitetyn kaltaisen Jobin, joka puolestaan luo tehtävän suorittavat Podit.
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "30 14 * * *" # At 14:30 everyday.
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Rahti!
restartPolicy: OnFailure
Yllä oleva esimerkin CronJob luo podin joka päivä klo 14.30 ja suorittaa sen loppuun asti.
ConfigMap
ConfigMapit ovat hyödyllisiä kokoonpanotyyppisen datan kokoamisessa Kubernetes-objekteihin. Niiden sisältö välitetään konteille ympäristömuuttujien tai volumeMounts-liitosten avulla.
kind: ConfigMap
apiVersion: v1
metadata:
name: my-config-map
data:
data.prop.a: hello
data.prop.b: bar
data.prop.long: |-
fo=bar
baz=notbar
Luo ConfigMap
ConfigMapeja voidaan luoda eri tavoilla. Jos meillä on yllä configmap.yaml-tiedostossa esitetyn kaltainen ConfigMap-objektin määrittely, siitä voidaan luoda instanssi komennolla oc create -f configmap.yaml. Voit myös käyttää tarkempaa komentoa oc create configmap <configmap_name> [options] luodaksesi ConfigMap-instanssin hakemistoista, tietyistä tiedostoista tai literaaliarvoista. Oletetaan esimerkiksi, että sinulla on hakemisto, jonka tiedostot sisältävät ConfigMapin täyttämiseen tarvittavan datan, seuraavasti:
Voit sitten luoda configmap.yaml-tiedostossa määritellyn kaltaisen ConfigMapin näin:
Tämä komento toimii myös tiedostojen kanssa hakemistojen sijaan.
Käytä ConfigMapia
Seuraava podi tuo arvon data.prop.a ympäristömuuttujaan DATA_PROP_A ja luo tiedostot data.prop.a, data.prop.b ja data.prop.long hakemistoon /etc/my-config:
kind: Pod
apiVersion: v1
metadata:
name: my-config-map-pod
spec:
restartPolicy: Never
volumes:
- name: configmap-vol
configMap:
name: my-config-map
containers:
- name: confmap-cont
image: perl
command:
- /bin/sh
- -c
- |-
cat /etc/my-config/data.prop.long &&
echo "" &&
echo DATA_PROP_A=$DATA_PROP_A
env:
- name: DATA_PROP_A
valueFrom:
configMapKeyRef:
name: my-config-map
key: data.prop.a
optional: true # Run this pod even
volumeMounts: # if data.prop.a is not defined in configmap
- name: configmap-vol
mountPath: /etc/my-config
Ota podi käyttöön komennolla oc create -f configmap-pod.yaml. Tämän kontin tulosteloki, joka saadaan komennolla oc logs my-config-map-pod, pitäisi olla:
Secret
Secretit toimivat pitkälti samalla tavalla kuin ConfigMapit, sillä erotuksella, että luomisen jälkeen ne tallennetaan base64-koodatussa muodossa, eikä niiden sisältöä näytetä oletusarvoisesti komentorivillä tai selainkäyttöliittymässä. Kun Secret liitetään taltiona, sen sisältö säilytetään muistissa (tmpfs-tiedostojärjestelmässä) sen sijaan, että se kirjoitettaisiin isäntäkoneen paikalliselle levylle.
apiVersion: v1
kind: Secret
data:
WebHookSecretKey: dGhpc19pc19hX2JhZF90b2tlbgo=
metadata:
name: webhooksecret
Luo secret
Kuten mikä tahansa muukin Kubernetes-/OKD-objekti, myös Secretit voidaan luoda Secret-objektin määrittelystä. Yllä secret.yaml-tiedostona esitetystä määrittelystä voidaan luoda Secret-instanssi komennolla oc create -f secret.yaml. Voit myös käyttää tarkempaa komentoa oc create secret [flags] <secret_name> [options] luodaksesi Secret-instanssin hakemistoista, tietyistä tiedostoista tai literaaliarvoista. Jos sinulla on esimerkiksi tiedosto nimeltä WebHookSecretKey, joka sisältää salaisen avaimen, voit käyttää sitä luodaksesi yllä secret.yaml-tiedostossa määritellyn kaltaisen Secretin seuraavasti:
Muokkaa secretiä
Secretin muokkausprosessi ei ole aivan suoraviivainen. Ajatuksena on hakea Secretin JSON-määrittely, purkaa se, muokata sitä ja sitten koodata se uudelleen ja korvata alkuperäinen.
- Ensin sinun täytyy hakea Secretin sisällä olevat eri tiedostot/salaisuudet (esimerkeissä käytetään
jq:ta JSON-tiedostojen käsittelyyn, mutta tämän voi tehdä myös ilman sitä):
- Valitse sitten jokin vaihtoehdoista ja hae itse tiedosto/salaisuus:
oc get secrets <SECRET_NAME> -o json >secret.json
jq '.data.<KEY_NAME>' -r secret.json | base64 -d > <KEY_NAME>.file
-
Muokkaa tiedostoa haluamallasi editorilla.
-
Koodaa uusi tiedosto ja korvaa aiempi arvo JSON-tiedostossa:
B64=$(base64 <KEY_NAME>.file -w0)
jq " .data.<KEY_NAME> = \"$B64\" " secret.json
oc replace -f secret.json
Kuten huomaat, prosessi voi olla hieman työläs.
OKD:n laajennukset
OKD sisältää kaikki Kubernetes-objektit sekä joitakin laajennuksia:
Info
OKD on Red Hat OpenShiftin avoimen lähdekoodin jakelu. Se tarjoaa samat Kubernetesin laajennus-API:t kuin OpenShift, mukaan lukien *.openshift.io API -ryhmät.
- ImageStream-objektit abstrahoivat imaget ja rikastavat ne virroiksi, jotka lähettävät signaaleja, kun niihin ladataan uusi image, esimerkiksi BuildConfigin toimesta.
- BuildConfig-objektit rakentavat kontti-imaget lähdetiedostojen perusteella.
- Route-objektit yhdistävät Service-objektin internetiin käyttäen HTTP:tä.
ImageStream
ImageStream -resurssit tallentavat kontti-imageja. Ne yksinkertaistavat kontti-imagejen hallintaa, ja ne voidaan luoda BuildConfigilla tai käyttäjän toimesta, kun uusia imageja ladataan rekisteriin.
Yksinkertainen ImageStream-objekti:
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
labels:
app: serveapp
name: serveimagestream
spec:
lookupPolicy:
local: false
BuildConfig
BuildConfig -resurssit luovat kontti-imageja tiettyjen sääntöjen mukaisesti. Seuraavassa esimerkissä käytetään Docker-strategiaa rakentamaan triviaalinen laajennus OKD:n mukana toimitetusta httpd-imagesta.
kind: "BuildConfig"
apiVersion: "build.openshift.io/v1"
metadata:
name: "serveimg-generate"
labels:
app: "serveapp"
spec:
runPolicy: "Serial"
output:
to:
kind: ImageStreamTag
name: serveimagestream:latest
source:
dockerfile: |
FROM image-registry.openshift-image-registry.svc:5000/openshift/httpd
strategy:
type: Docker
Kun build-objekti on luotu (tässä nimellä serveimg-generate), voimme pyytää OKD-klusteria rakentamaan imagen:
Muita lähdestrategioita ovat Custom ja Source.
Route
Route -resurssit ovat OKD:n vastine tavallisen Kubernetesin Ingressille; ne julkaisevat yhden portin yhdestä Service-objektista nimiavaruuden ulkopuolelta ja internetistä tulevalle liikenteelle, vain HTTP/HTTPS:n kautta. Tyypillinen Route-määrittely voisi olla:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: example-route
spec:
to:
name: example-svc
weight: 100
kind: Service
host: ''
path: ''
tls:
insecureEdgeTerminationPolicy: Redirect
termination: edge
port:
targetPort: web-server
Kaikilla isäntänimillä, jotka vastaavat mallia *.2.rahtiapp.fi ja *.rahtiapp.fi, on automaattisesti DNS-tietue ja kelvollinen TLS-varmenne. Route on mahdollista määrittää millä tahansa annetulla isäntänimellä, mutta tällöin on määritettävä CNAME, joka osoittaa osoitteeseen router-default.apps.2.rahti.csc.fi, ja lisäksi on toimitettava TLS-varmenne. Katso lisätietoja artikkelista Mukautetut verkkotunnukset ja suojattu tiedonsiirto.
Oletusisäntänimi
Oletusarvoisesti Routen isäntänimi on metadata.name + - + projektin nimi + .2.rahtiapp.fi, ellei spec.host-kentässä määritetä muuta, kuten my-app.rahtiapp.fi.
Yksityiskohtaiset tiedot Routeista
Katso lisätietoja Routeista tästä dokumentista.