dimarts, 9 de febrer del 2021

Exemple de creació d’un clúster Kubernetes en el núvol

Què és Kubernetes?

 Es sol dir que és un «orquestrador» de contenidors d’aplicacions, més tècnicament, un middleware que permet integrar serveis provinents de diverses fonts, i proveir informació de forma síncrona o asíncrona. Està escrit en Go, creat per Google i cedit com programari lliure a la Cloud Native Computing Foundation (CNCF, https://www.cncf.io/ ).

S’estructura en Pods, la unitat mínima de computació, que permet executar un conjunt de contenidors sota una única IP, i el ReplicaSets, que controla les rèpliques de cada Pod. Aporta tolerància a errades, alta disponibilitat i escalabilitat en calent. A més a més permet fer instal·lacions i actualitzacions automàtiques, i mitjançant el proxy invers Ingress permet fer balanç de càrrega entre servidors (nodes). Els pods s'executen en nodes, que són màquines virtuals funcionant de forma sincronitzada formant un clúster.

Crear des de zero, usant màquines virtuals, un clúster Kubernetes no és tasca fàcil, i a més a més per fer-ho bé calen un mínim de tres màquines.  El més habitual en la pràctica és contractar un servei de virtualització en el núvol que facilita molt la tasca. En aquesta entrada de bloc veurem un exemple de creació de clúster en el núvol, en el que iniciarem un servei web simple, també habilitarem una interfície web de control del clúster.

Pas 1: creació del «pool» de nodes

Usarem el proveïdor OVH → Public Cloud Services → Crear un cluster Kubernetes; inicia un assistent:

 

Tres nodes és el mínim «sensat»: un node actua de màster i els altres dos s’anomenen «minions»: El màster no executa contenidors, són els encarregats de decidir en quin node (minion) s'executa cada contenidor, de mantenir l'estat eficient del clúster, d'assegurar que en tot moment hi ha el nombre desitjat de contenidors en execució i d'actualitzar les aplicacions de forma coordinada quan es despleguen noves versions. Node minion és aquell que executa els contenidors desplegats al clúster. De sèrie, Kubernetes pot executar contenidors Docker i RKT, sent possible integrar-lo amb altres motors existents a través de CRI (Container Runtime Interface).

 

Cada node és una màquina virtuals, però amb aquesta opció activada cada MV estarà en una màquina física diferent, per millorar la disponibilitat, si estan totes les MV en una màquina física si cau aquesta cau tot el clúster!

 

Ja el tenim creat.

Ens proporcionen les dades d’accés al clúster al núvol:

 


Ara mateix no hi han encara contenidors en execució:

 


 

Preparar accés al clúster des de màquina local

Per administrar el clúster remotament ens cal instal·lar el comandament kubectl en la nostra màquina local (la de casa, per entendre'ns). Primer el descarreguem:

 

jordi@jordi-sve1513c5e:~$ sudo curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/rel
ease/stable.txt)/bin/linux/amd64/kubectl"
[sudo] password for jordi:  
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
100   161  100   161    0     0    851      0 --:--:-- --:--:-- --:--:--   851
100 38.3M  100 38.3M    0     0  5580k      0  0:00:07  0:00:07 --:--:-- 5970k
jordi@jordi-sve1513c5e:~$

 

Validar la descàrrega amb el hash:


jordi@jordi-sve1513c5e:~$ curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.t
xt)/bin/linux/amd64/kubectl.sha256"
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                Dload  Upload   Total   Spent    Left  Speed
100   161  100   161    0     0    914      0 --:--:-- --:--:-- --:--:--   914
100    64  100    64    0     0    117      0 --:--:-- --:--:-- --:--:--   117
jordi@jordi-sve1513c5e:~$ echo "$(<kubectl.sha256) kubectl" | sha256sum --check
kubectl:
OK
jordi@jordi-sve1513c5e:~$


Instal·lar el comandament:


jordi@jordi-sve1513c5e:~$ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
jordi@jordi-sve1513c5e:~$


NOTA: en entorn real caldrà sempre establir un tunel VPN i usar el comandament kubectl dins de la VPN! És altament insegur fer administració remota usant una connexió pública! Com hi ha una certa confusió entre connexió encriptada (com ara ssh) i xarxa privada virtual (VPN), convé un breu repàs.

  • Les connexions tipus SSH (com ara la de kubectl) connecten una màquina amb una altre màquina, a través de una xarxa local o d'una xarxa pública, encriptant la transmissió. 
  • Les connexions VPN en canvi connecten una màquina a una xarxa local sencera, també encriptant, de forma que la màquina es com si estigues dintre de la xarxa local remota, per això se li diu "xarxa privada (o local, no pública) virtual": l'equip remot es converteix en part de la xarxa a la que es connecta, i té accés complert a tota la xarxa. El tràfic de informació provinent dels  usuaris de la xarxa remota es vist com provinent d'una única adreça IP pública; això dificulta el seguiment d'un usuari de la xarxa remota doncs queda ocult en una única IP.
  • Per últim tenim les connexions ssh amb túnel, que són diferents a la VPN: ssh per defecte obre una sessió de shell (és a dir, el vostre terminal local està connectat a un shell que s’executa al sistema remot), però hi ha diferents tipus de dades que es poden transportar, un d’aquests tipus és una connexió de socket, per exemple, una connexió TCP: això s'anomena un túnel SSH; el client SSH escolta en un port TCP i transporta totes les connexions realitzades a aquest port a través del canal segur i surt de la connexió des del sistema remot. Per defecte, quan configureu un túnel, encara obtindreu un intèrpret d’ordres, SSH transporta dos tipus de dades per la mateixa connexió: el túnel i l’intèrpret d’ordres. A més a més les connexions SSH via túnel poden dirigir-se a través de ports TCP arbitraris

 

Configuració de la connexió remota amb el cluster

Descarreguem el fitxer de configuració del clúster proporcionat pel proveïdor del servei fins la màquina local, i el guardem en el directori ocult $HOME/.kube amb el nom config

 


El fitxer descarregat és quelcom semblant a: 

apiVersion: v1

clusters:

- cluster:

certificate-authority-data: LS0tLS1CRUdJTiBD(...)==

server: https://9tvsxd.c1.gra7.k8s.ovh.net

name: ASIXcs

contexts:

- context:

cluster: ASIXcs

user: kubernetes-admin-ASIXcs

name: kubernetes-admin@ASIXcs

current-context: kubernetes-admin@ASIXcs

kind: Config

preferences: {}

users:

- name: kubernetes-admin-ASIXcs

user:

client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ (etc ...)



Creem a continuació el servei "demo" proporcionat per el proveïdor hello-world, activant el balanç de càrrega entre nodes; el servei es  defineix pel fitxer de configuració en llenguatge yaml següent:


apiVersion: v1

kind: Service

metadata:

name: hello-world

labels:

app: hello-world

spec:

type: LoadBalancer

ports:

- port: 80

targetPort: 80

protocol: TCP

name: http

selector:

app: hello-world

---

apiVersion: apps/v1

kind: Deployment

metadata:

name: hello-world-deployment

labels:

app: hello-world

spec:

replicas: 1

selector:

matchLabels:

app: hello-world

template:

metadata:

labels:

app: hello-world

spec:

containers:

- name: hello-world

image: ovhplatform/hello

ports:

- containerPort: 80



Iniciem el servei amb el comandament kubectl:


jordi@jordi-sve1513c5e:~$ kubectl apply -f hello.yml
service/hello-world created
deployment.apps/hello-world-deployment created
jordi@jordi-sve1513c5e:~$

Llistem els contenidors (pods) i serveis (deploys) disponibles per veure que està actiu:

jordi@jordi-sve1513c5e:~$ kubectl -n=default get pods
NAME                                      READY   STATUS    RESTARTS   AGE
hello-world-deployment-559d658ffb-pdh8l   1/1     Running   0          2m56s
jordi@jordi-sve1513c5e:~$

jordi@jordi-sve1513c5e:~$ kubectl -n=default get deploy
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
hello-world-deployment   1/1     1            1           3m42s
jordi@jordi-sve1513c5e:~$

Llistem també els serveis disponibles, el que hem iniciat dona servei TCP/IP pel port 80 i és de l tipus servidor web:

jordi@jordi-sve1513c5e:~$ kubectl -n=default get services 
NAME          TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
hello-world   LoadBalancer   10.3.125.127   51.210.210.34   80:32452/TCP   4m37s

kubernetes    ClusterIP      10.3.0.1       <none>          443/TCP        39m
jordi@jordi-sve1513c5e:~$
Aquest servei de demostració és un servidor web que només retorna una pàgina; ara que està actiu, amb el navegador, anem a la IP externa per provar el servei: 

 

Aquest servei web s'està executant simultàniament en dos nodes (màquines virtuals) situades en diferents màquines físiques, dintre de contenidors Docker; un tercer node, el màster, s'encarrega de l'orquestració (balanç de càrrega i alta disponibilitat).

 

Instal·lació del tauler de control de Kubernetes


És una interfície web d’aministració per Kubernetes. La baixem i instal·lem mitjançant el comandament kubectl i un fitxer de configuració:


jordi@jordi-sve1513c5e:~$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.
0.0-rc7/aio/deploy/recommended.yaml


namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
jordi@jordi-sve1513c5e:~$

Ara creem un compte d’administració remota, usant un fitxer yaml


apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard

i el comandament kubectl:



jordi@jordi-sve1513c5e:~$ kubectl apply -f dashboard-service-account.yml                             
serviceaccount/admin-user created
jordi@jordi-sve1513c5e:~$

a continuació, apliqueu el fitxer per afegir el compte de servei al clúster:


jordi@jordi-sve1513c5e:~$ kubectl apply -f dashboard-cluster-role-binding.yml
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in
v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
jordi@jordi-sve1513c5e:~$

després, utilitzant la funció d'administrador de clústers per al vostre clúster, crearem un RoleBinding, que el vincularà al vostre compte de serveis, amb el següent yaml:


apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

executem:


jordi@jordi-sve1513c5e:~$ kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-das
hboard get secret | grep admin-user-token | awk '{print $1}')
Name:         admin-user-token-ggd8b
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
             kubernetes.io/service-account.uid: e2d4cfa2-1bd3-4c09-a2bb-e671736642f3

Type:  kubernetes.io/service-account-token

Data
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6Ii1pMEpPRkdaRGNZaC1UajZXMi05S0hkRzdoMVN2QWlUbGZmS3BDUlpBeWMif
.......
bMQTWwtzkLz4O_Rb7_FETXBJKtgMkTJBnRzeyYZ7VUnNixpsAjLftn-6KQ-KfFFTM_c4xFvodjW8ZQCMIRzbVS8
ca.crt:     1801 bytes
namespace:  20 bytes
jordi@jordi-sve1513c5e:~$


Iniciem l’aplicació:


jordi@jordi-sve1513c5e:~$ kubectl proxy
Starting to serve on 127.0.0.1:8001

Accedim a la interfície web d’administració, ens demana la cadena «token» encriptada com a contrasenya, i entrem a la pantalla principal:


La interfície web  pot desplegar aplicacions en contenidors d'un clúster de Kubernetes, solucionar problemes de l'aplicació, gestionar els recursos del clúster, donar una visió general de les aplicacions que s’executen al clúster, crear o modificar recursos de Kubernetes individuals (com ara deploys).  Per exemple, podeu escalar un deploy (escalar vol dir donar o treure-li recursos) iniciar una actualització, reiniciar un pod o desplegar noves aplicacions mitjançant un assistent de desplegament.

Tutorial interactiu de Kubernetes: https://kubernetes.io/docs/tutorials/kubernetes-basics/







 

 

 

 

 

 




 






Cap comentari:

Publica un comentari a l'entrada

Gestió d'usuaris i grups en Linux

Usuaris i grups Linux  Els comptes de Linux són com els comptes de Windows o MacOS; però els detalls no, així que cal explicar alguns detall...