Storskaliga distribuerade system av flera samarbetsvilliga tjänster blir allt viktigare. Dessa system körs på kluster av hundratals, tusentals eller fler servrar. Att utveckla, implementera och underhålla dessa system effektivt och ekonomiskt är en lång order.
Virtualisering och nyare containerisering möjliggör flexibel delning och hantering av resurser. Docker gjorde containerisering populär. Kolla in den här Envato Tuts + artikeln för en bra introduktion: The Hitchhiker's Guide to Docker and Modulus.
Google har kört sin enorma mjukvara och datacenter på containerisering i åratal och ackumulerat a massa av erfarenhet och knowhow. Kubernetes är ett open source-projekt av Google som ger all den kunskapen till massorna.
I denna artikel kommer jag att utforska Docker kort och dyka sedan djupt in i Kubernetes. Jag använder som ett körexempel en Python 3 quote REST API-tjänst. Låt oss hoppa in.
Citat tjänsten är ett REST API som låter dig lägga till citat och få en lista över alla citat. Det implementeras som en Python 3 webbtjänst med hjälp av det utmärkta krambiblioteket. Det avslöjar en enda slutpunkt kallad / citat. Du kan få alla citat eller skriva ett nytt citat. Låt oss lägga till några citat:
curl http: // localhost: 8000 / quotes -d "quote = TV är tuggummi för ögonen." Frank Lloyd Wright "curl http: // localhost: 8000 / quotes -d" quote = Det är bättre att dö på din ~ Emiliano Zapata "curl http: // localhost: 8000 / quotes -d" quote = Vi måste vara mycket försiktiga när vi ger råd till yngre människor: ibland följer de det! ~ Edsger W. Dijkstra "
Om du bläddrar till http: // localhost: 8000 / citat
du kommer få: ["TV är tuggummi för ögonen." Frank Lloyd Wright "," Det är bättre att dö på fötterna än att leva på knäna. "Emiliano Zapata", "Vi måste vara mycket försiktiga när vi ger råd till yngre människor: ibland följer de det! ~ Edsger W. Dijkstra "]
Om du bara vill se HUGs automatiskt genererade dokumentation, bläddra till: http: // localhost: 8000
"404": "API-samtalet du försökte göra var inte definierat. Här är en definition av API som hjälper dig att gå :)", "Dokumentation": "/ quotes": "GET": "exempel "" ["http: // localhost: 8000 / quotes"], "outputs": "content_type": "application / json", "format": "JSON (Javascript serialiserat objektnotation)", "POST" : "outputs": "content_type": "application / json", "format": "JSON (Javascript Serialized Object Notation)", "Inmatningar": "citat": "typ" strängvärde"
Jag kommer inte att förklara för mycket om Docker och bara tillämpa det på citat tjänsten.
Först behöver vi en Dockerfil. Det utför följande steg:
FRÅN Ubuntu: senaste HUVUDGIVARE Gigi Sayfan "[email protected]" Kör apt-get update -y Kör apt-get install -y python3 python3-pip python3-dev build-essential COPY. / quote-service WORKDIR / quote-service RUN pip3 installera -r requirements.txt EXPOSE 8000 ENTRYPOINT kram -f app.py
Nästa steg är att bygga en Docker-bild. Detta är så enkelt som:
dockningsbyggnad .
Jag gillar också att tagga bilder:
docker tag 715624b7e22a g1g1 / quote-service
G1G1
är mitt användarnamn på Docker Hub.
För att verifiera bilden byggdes framgångsrikt, skriv:
dockare ps --all
Du borde se den nya bilden:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTNAMMER 715624b7e22a g1g1 / quote-service "/ bin / sh-c" kram -f en "4 timmar sedan Upp 35 minuter 0.0.0.0:8000->8000/tcp agitated_northcutt
När du skapar en bild kan du också trycka den på Docker Hub, så den kan användas av andra personer (eller dig själv på en annan maskin).
docker push g1g1 / quote-service
Observera att du måste skapa ett konto på Docker Hub och logga in lokalt med:
docker login
Ok. Låt oss köra citatservicen och exponera port 8000 till värden.
docker kör -i -t -p 8000 g1g1 / quote-service
Du borde se: / ################################################# ########. "" ------- ... ".----. : / ::::: -: ---------: - ::::: // ... + :::: ---- ## / - / oo +: - ## - --- :::: // '// :: ------- / oosoo ------- ::: //. ############# .-: ------./++ o / o -.------ :: - '
## ## ## ## ## ----.-./ + O +: ... ----.
.: ///. ######## '----.- :::::: ------' .- :::: //. ##############: // ::--.
-:... ----- ... ": - :::::: -. ' ############: / ::::::::: -:-
". :::::-. ##############
.--::::::: ... :::.
"... :: ... :: EMBRACE FRAMTIDENS APIER :: -.: - - :: :: - VERSION 1.9.6
:: - - :: -::-
-:: --########################################### ############ Copyright (C) 2015 Timothy Edmund Crosley Under MIT-licensen
Serverar på port 8000 ... "Det här är ganska coolt. Innan du försöker få tillgång till din fantastiska citatservice på port 8000, kan du behöva utföra lite extra arbete beroende på din miljö.
Om du kör på Mac OS X med VirtualBox och dockningsmaskin kan du behöva publicera port 8000 på VirtualBox för att göra den tillgänglig på värddatorn.
Förutsatt att du försökte bläddra till http: // localhost: 8000 / citat
. Å nej. Internt serverfel! Vad hände?
Låt oss titta på koden:
redis_host = os.environ.get ('QUOTE_STORE_SERVICE_HOST', 'localhost') redis_server = redis.StrictRedis (värd = redis_host, port = 6379, db = 0)
Citattjänsten försöker ansluta till en redis-server. Värdadressen kan konfigureras som en miljövariabel, och om den inte är inställd kommer den att vara standard för localhost. Tyvärr är Redis inte installerat som standard och det går inte inuti behållaren. Låt oss fixa det tillfälligt. Om du vill få skalåtkomst i behållaren skriver du följande kommando:
docker exec -it 715624b7e22a / bin / bash
Då får du tillgång till behållare till behållaren, och du kan installera redis:
root @ 715624b7e22a: / quote-service # apt-get install redis-server
Slutligen kör redis: root @ 715624b7e22a: / quote-service # redis-server [25] 29 Nov 00: 14: 24.546 # Varning: Ingen konfigurationsfil specificerad, med standardkonfigurationen. För att ange en konfigurationsfil, använd redis-server / path /to/redis.conf _._ _.- "__" -._ _.- "." _. "-._ Redis 2.8.4 (00000000 / 0) 64 bitar .- ".-
."\ / .,"-._ (' , .- |
, ) Körning i fristående läge |-._
-... - __ ... -.
-._ |'
.-'| Hamn: 6379 | -._
. / .-'| PID: 25 -._
-. -./ _.- '_.-' |
-.-._
-..-'_.-'_.-' | | -._
-._ _.-'_.- '| http://redis.io -._
-._-.__.-'_.- '_.-' |
-._-._
-..-'_.-'.-'| | -._
-._ .-'.-'| -._
-.-.__.-'_.- '_.-'
-. -.__.- '_.-'
-._ _.- "-.__.- '
29 november 00: 14: 24.547 # Server startade, Redis version 2.8.4 [25] 29 Nov 00: 14: 24.547 # VARNING övercommit_memory är satt till 0! Bakgrundsbesparing kan misslyckas under lågt minne. För att åtgärda problemet lägger du till 'vm.overcommit_memory = 1' till /etc/sysctl.conf och starta om eller kör kommandot 'sysctl vm.overcommit_memory = 1' för att detta ska träda i kraft. 29 november 00: 14: 24.547 * DB laddad från disk: 0.000 sekunder [25] 29 Nov 00: 14: 24.547 * Servern är nu redo att acceptera anslutningar på port 6379 "Nu kan du börja lägga till citat och få citat genom http: // localhost: 8000 / citat
slutpunkt.
Placeringen av ansökan (citattjänst) och databasen (redis) fungerar i en nypa för en server. Men det förstår självklart inte. Ange Kubernetes.
Kubernetes, a.k.a. k8s, är en uppfattad ram för att hantera och orkestrera flera containrar. Den har sitt eget sätt att göra saker, vilket vanligtvis är mycket bra. Det är fortfarande under utveckling, så det finns fortfarande några grova kanter här och där. Kubernetes har många koncept och är väldigt flexibelt. Jag ska förklara och visa koncepten genom att tillämpa dem på citattjänsten.
Det finns många sätt att skapa ett Kubernetes-kluster. Kubernetes kan köras på obetydlig metall, på Google Container-motor, på AWS, på barometall (med Linux), och lokalt på alla operativsystem med virtuella maskiner. I den här artikeln skapade jag ett kluster av en mästare och två minioner med CoreOS OSX GUI k8s Cluster. På Mac OS X ger det en fin liten meny där du kan komma åt många klustringshanteringsverktyg.
Följ anvisningarna och du kommer att vara bra att gå på nolltid.
Om du inte använder Mac OSX eller bara bryr dig inte mycket om GUI kan du använda det här projektet för att skapa ett testkluster i en Vagrant VM.
Jag kommer att använda kommandoraden från och med nu.
kubectl är den schweiziska armékniven av Kubernetes. Du kan helt kontrollera och hantera ditt kluster från din konsols komfort med ingenting annat än kubectl.
Här är listan med kommandon: få Visa en eller flera resurser beskriva Visa detaljer för en specifik resurs skapa Skapa en resurs efter filnamn eller stdin-uppdatering Uppdatera en resurs efter filnamn eller stdin. radera Ta bort en resurs efter filnamn, stdin, resurs och ID, eller med resurser och etikettväljare. namespace SUPERCEDED: Ställ in och visa den aktuella Kubernetes namespace loggen Skriv ut loggarna för en behållare i en pod. rullande uppdatering Utför en rullande uppdatering av den givna ReplicationController. Ändra storlek Ange en ny storlek för en Replication Controller. exec Kör ett kommando i en behållare. port-forward Framåt en eller flera lokala hamnar till en pod. proxy Kör en proxy till Kubernetes API-serverns körcontainer Kör en viss bild på klustret. sluta Gracefully stänga av en resurs med id eller filnamn. exponera Ta en replikerad applikation och avslöja den som Kubernetes Service label Uppdatera etiketterna på en resurs config konfigurerar kubeconfig-filer cluster-info Visa cluster-info api-versioner Skriv ut tillgängliga API-versioner. version Skriv ut klient- och serverversionsinformationen. Hjälp hjälp om något kommando
Använd gärna kommandot hjälp eller dokumentationen för att undersöka vad varje gör. Många av dem används för att utföra manuell operationer som är bättre gjort med hjälp av konfigurationsfiler i ett storskaligt, skalbart, distribuerat system, men det är oumbärligt för snabb utforskning och felsökning. De vanligaste kommandon som jag använder mycket är: få, skapa, ta bort och starta.
En pod är den grundläggande enheten för utplacering och hantering i Kubernetes. En pod är en grupp av en eller flera behållare. Du kan ange en pod med en dedikerad YAML-fil eller som en del av en Kubernetes-tjänst (se nedan). En pod används alltid på en enda värd, och alla behållare i en pod kan komma åt varandra via localhost. Alla behållarens behållare startas alltid, stoppas och skalas ihop.
För att kolla alla pods i klustret skriver du:
kubectl få pods
Resultatet blir något som: NAMN KLAR STATUS RESTARTS ÅLDER citat-frontend-4 1/1 1/1 Running 0 1h quote-frontend-v4xk1 1/1 Running 0 1h quote-store-controller-y4ya1 1/1 Löpning 0 23h
### Volymer
Behållare är inte tänkt att upprätthålla kvarhållande tillstånd. När en behållare kraschar eller startar om, sätts det lokala filsystemet ut. Om du vill behålla kvarhållande tillstånd, bör du använda ihållande volymer. Eftersom allt i Kubernetes är baserat på pods, måste du också definiera volymer i en pod. Här är en poddefinitionsfil med en beständig volym: apiVersion: v1 typ: Podmetadata: namn: citat-butik etiketter: app: citat-api roll: persistent-storage spec: containrar: - namn: redis bild: redis volymMängder: - namn: citat-butik-volym mountPath: / data / redis volymer: - namn: citat-butik-volym emptyDir:
Observera att beständiga volymer är begränsade till noden och kommer att överleva behållaren kraschar och startar om, men inte nod / värdfel. Du behöver fortfarande göra jobbet för att kopiera och säkerhetskopiera viktiga data.
En av de viktigaste egenskaperna hos Kubernetes är dess förmåga att hantera och enkelt skala upp och ner antalet pods. Vanligtvis har du olika typer av pods i ditt system, och du vill kunna ange hur många podar av varje typ som ska vara igång.
Säg hej till replikeringsstyrenheter. En replikeringsregulator har en podmall som definierar en grupp containrar, en uppsättning etiketter för att identifiera dessa pods och antalet önskade pods. Replikeringsregulatorn ser till att antalet körspår som identifieras med dess etiketter alltid matchar önskat nummer. Om en pod avslutas, skapar replikeringsregulatorn omedelbart en ny.
Det finns flera intressanta användningsfall som stöds av replikeringsstyrenheter, som hög tillgänglighet, elastisk skalning och rullningsuppdateringar. Du kan till exempel lägga till och ta bort podar från dominionen hos en replikeringskontrollen genom att ändra etiketten.
Replikeringsregulatorer anges givetvis i en YAML-fil. Här är ett exempel: "apiVersion: v1 typ: ReplicationController
metadata: namn: citat-frontend spec: replicas: 2 # selector identifierar uppsättningen Pods att denna # replikeringscontroller ansvarar för hantering av väljare: app: citat-api-roll: frontend # podTemplate definierar "cookie cutter" som användes för att skapa # nya pods när nödvändig mall: metadata: etiketter: # Viktigt: dessa etiketter måste matcha väljaren ovan # Api-servern verkställer denna begränsning. app: citat-api roll: frontend spec: containrar: - namn: citat-service bild: g1g1 / quote-service env: - namn: GET_HOSTS_FROM # värde: dns värde: env portar: - containerPort: 8000 "Mallen är spec för Quote-Service Container använder g1g1 / Quote-Service-bilden Jag tryckte tidigare till Docker Hub. Notera env
avsnitt där informationsdelning över pods kan uppstå genom antingen DNS eller miljövariabler.
För att skapa en replikeringscontroller, skriv:
kubektl skapa -f
För att visa de aktuella replikeringsstyrenheterna i klustret skriver du:
kubectl få rc
Du borde se något som: CONTROLLER CONTAINER (S) BILD (S) SELECTOR REPLICAS ÅRSKRIFT quote-frontend quote-tjänst g1g1 / quote-service app = citat-api, roll = frontend 2 1h quote-store-controller master redis app = citat-api, roll = -storage 1 1d
### Tjänster
En tjänst utsätter sin pod för resten av klustret och eventuellt externt via antingen miljövariabler eller DNS. Citattjänsten är till exempel gjord av två typer av pods: en redis-butikspod och en front-end pod. Front-end-behållaren ska kunna hitta butiksbehållaren och klienter ska kunna slå en enda offentlig slutpunkt för att komma åt tjänsten.
Kubernetes-tjänsten implementeras i ännu en YAML-fil. Varje komponent i ditt system som behöver åtkomst av andra komponenter ska ha sin egen servicefil. Här är de två servicefilerna för citatservicekomponenterna:
apiVersion: v1 typ: Tjänstens metadata: namn: citat-frontend spec: typ: Nodeport portar: - port: 8000 # porten som den här tjänsten ska fungera på # behållaren på varje pod för att ansluta till, kan vara ett namn # 'www') eller ett nummer (t.ex. 80) targetPort: 80 protokoll: TCP # precis som väljaren i replikeringsregulatorn, # men den här gången identifierar den uppsättningen pods för att ladda saldo # trafik till. väljare: app: citat-api roll: frontend
#### srv-quote-store.yaml apiVersion: v1 typ: Service metadata: namn: citat-butik spec: portar: - port: 6379 # porten som denna tjänst ska tjäna på targetPort: 6379 # precis som väljaren i replikeringsregulatorn, # men den här gången identifierar den uppsättning pods för att ladda balans # trafik till. väljare: app: citat-api roll: beständig lagring
Värd och hamn för varje tjänst görs tillgänglig för varje behållare i klustret. Till exempel, om du kör ett interaktivt skal på en av frontendbehållarna:
kubectl-citat-frontend-4 ^ exec -i -t bash
Därefter kan du verifiera att miljön innehåller nödvändig värd- och portinformation för att ansluta till citataffären. root @ quote-frontend-4:: / quote-service # env | grep STORE QUOTE_STORE_PORT_6379_TCP_ADDR = 10.100.234.192 QUOTE_STORE_PORT_6379_TCP_PROTO = tcp QUOTE_STORE_SERVICE_PORT = 6379 QUOTE_STORE_PORT_6379_TCP_PORT = 6379 QUOTE_STORE_PORT = tcp: //10.100.234.192: 6379 QUOTE_STORE_PORT_6379_TCP = tcp: //10.100.234.192: 6379 QUOTE_STORE_SERVICE_HOST = 10.100.234.192
Bara för att uppdatera ditt minne är det precis vad frontend gör: redis_host = os.environ.get ('QUOTE_STORE_SERVICE_HOST', 'localhost') redis_server = redis.StrictRedis (värd = redis_host, port = 6379, db = 0)
## Slutsats
Docker och Kubernetes är spännande teknik. Denna artikel skrapade knappt ytan på vad som är möjligt. Fördelarna är enorma, men infrastrukturen, verktyg och bästa praxis utvecklas fortfarande. Om du ens är ansluten till stora distribuerade system, uppmuntrar jag dig åtminstone att hålla dig ovanpå den här teknologin och dämpa dina tårar och försöker verkligen använda dem. Det finns många sätt att experimentera och lära sig utan att engagera hela hela produktionsinfrastrukturen.
Så långt som Kubernetes går, finns det några andra alternativ för multi-containerhantering och orkestration, såsom den befintliga Mesos och Dockers egen komponent. Jag tror att Kubernetes är mer arkitektoniskt ljud, har mycket fart och är bättre än alternativen.