mmul.kubelab
Ta rola może być używana do wdrażania klastra Kubernetes z całkowicie zautomatyzowaną i idempotentną implementacją kilku komponentów.
Cechy
Tę rolę można skonfigurować, aby włączyć wszystkie te funkcje:
Implementacja klastra z pojedynczym lub wieloma węzłami sterującymi z HAProxy i Keepalived dla wysokiej dostępności.
Wielonetworkowe dodatki Flannel i Calico.
Panel kontrolny Kubernetes.
Zarządzanie użytkownikami z generowaniem certyfikatów i aktualizacją plików
kubeconfig
.Ceph-CSI StorageClass dla urządzeń blokowych.
MetalLB load balancer dla środowisk baremetalowych.
Ingress NGINX do ekspozycji usług.
Cert Manager do automatycznego zarządzania certyfikatami.
Instalacja klastra za pomocą Playbooka Ansible
Najlepszym sposobem na przygotowanie środowiska jest użycie wirtualnego środowiska Python, instalując ansible za pomocą pip3
:
user@lab ~ # python3 -m venv ansible
user@lab ~ # source ansible/bin/activate
(ansible) user@lab ~ # pip3 install ansible
Następnie potrzebujesz tej roli, a w tym przypadku użycie ansible-galaxy
jest dobrym wyborem, aby wszystko było automatyczne:
(ansible) user@lab ~ # ansible-galaxy install mmul.kubelab -p ansible/roles/
Gdy rola jest już na miejscu, możesz zrealizować wymagania, ponownie używając pip3
:
(ansible) user@lab ~ # pip3 install -r ansible/roles/mmul.kubelab/requirements.txt
Po zainstalowaniu wymagań, zazwyczaj używa się roli, uruchamiając playbook tests/kubelab.yml
, w ten sposób:
(ansible) user@lab ~ # ansible-playbook -i tests/inventory/kubelab tests/kubelab.yml
Uwaga: data i czas na zaangażowanych systemach są ważne! Różnica czasu między maszyną, na której wykonujesz playbooki Ansible, a maszynami docelowymi może spowodować, że weryfikacja certyfikatu się nie powiedzie.
Uwaga: możesz w każdej chwili zresetować wszystko, ustawiając k8s_reset
na true
. To zresetuje cały twój klaster, więc używaj tego ostrożnie:
(ansible) user@lab ~ # ansible-playbook -i tests/inventory/kubelab tests/kubelab.yml -e k8s_reset=true
Interakcja z klastrem po instalacji
Po zakończeniu wykonywania playbooka najlepszym sposobem interakcji z klastrem jest użycie polecenia kubectl
, które można zainstalować następująco:
user@lab ~ # curl -s -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
user@lab ~ # chmod +x kubectl
user@lab ~ # sudo mv kubectl /usr/local/bin
Rola Kubernetes tworzy lokalny katalog z głównym plikiem kubeconfig o nazwie admin.conf. Najłatwiejszym sposobem na jego użycie jest eksportowanie zmiennej KUBECONFIG, jak poniżej:
user@lab ~ # export KUBECONFIG=~/kubernetes/admin.conf
Od tej chwili, aż do końca sesji, za każdym razem, gdy użyjesz kubectl
, będzie się polegać na poświadczeniach zawartych w tym pliku:
user@lab ~ # kubectl cluster-info
Możesz również używać różnych użytkowników do logowania się do klastra, szczegóły znajdziesz w sekcji Użytkownicy.
Konfiguracja
Inwentaryzacja
Typowa inwentaryzacja zależy od tego, co chcesz wdrożyć, patrząc na przykład kubelab
, możesz zadeklarować w pliku hosts (zobacz tests/inventory/kubelab/hosts) wszystkie węzły:
# Węzły Kubernetes
[kubelab]
kubernetes-1 k8s_role=control-plane run_non_infra_pods=true
kubernetes-2 k8s_role=control-plane run_non_infra_pods=true
kubernetes-3 k8s_role=control-plane run_non_infra_pods=true
kubernetes-4 k8s_role=worker
Zdefiniujesz, które węzły będą działać jako węzły sterujące i czy będą uruchamiać podów niezwiązane z infrastrukturą (aby kontroler mógł również działać jako węzeł roboczy).
Następnie możesz zdefiniować, w pliku grupy (tj. inventory/kubelab/group_vars/kubelab.yml), wszystkie dodatkowe konfiguracje, w zależności od tego, co chcesz wdrożyć.
Domyślna nazwa grupy hostów dla hostów Kubernetes to kubelab
, ale można ją nadpisać, deklarując zmienną k8s_host_group
.
Klaster Kubernetes
Jeśli chcesz wdrożyć klaster o wysokiej dostępności z wieloma węzłami kontrolnymi, będziesz musiał określić te zmienne:
k8s_cluster_name: kubelab
k8s_control_plane_node: kubernetes-1
k8s_control_plane_port: 6443
k8s_control_plane_cert_key: "91bded725a628a081d74888df8745172ed842fe30c7a3898b3c63ca98c7226fd"
k8s_multi_control_plane: true
k8s_balancer_VIP: 192.168.122.199
k8s_balancer_interface: eth0
k8s_balancer_port: 8443
k8s_balancer_password: "d6e284576158b1"
k8s_wait_timeout: 1200
k8s_control_plane_ports:
- 2379-2380/tcp
- 6443/tcp
- 8443/tcp
- 10250/tcp
- 10257/tcp
- 10259/tcp
To uruchomi klaster, zaczynając od węzła kubernetes-1
, włączając wiele węzłów kontrolnych za pomocą k8s_multi_control_plane
oraz ustawiając adres VIP i interfejs.
Uwaga: będziesz chciał zmienić zarówno k8s_control_plane_cert_key
, jak i k8s_balancer_password
dla lepszej bezpieczeństwa.
Dodatek sieciowy
Rola Kubernetes obsługuje dodatki sieciowe Flannel i Calico. Konfiguracja zależy od wybranego dodatku.
Dla Flannel potrzebujesz czegoś takiego:
# Dodatek Flannel
k8s_network_addon: flannel
k8s_network_addon_ports:
- 8285/udp
- 8472/udp
Aby zobaczyć, jak wdrożyć Calico, sprawdź plik domyślny.
Panel kontrolny
Panel kontrolny Kubernetes można wdrożyć, dodając to do konfiguracji:
k8s_dashboard_enable: true
Po zakończeniu instalacji najłatwiejszym sposobem dostępu do panelu kontrolnego jest użycie kubectl proxy
, a następnie dostęp do odpowiedniego URL:
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/.
Pojawi się monit o zalogowanie, a ty możesz się zalogować, podając token. Domyślnie rola Kubernetes tworzy użytkownika o nazwie dashboard-user
(możesz to nadpisać).
Aby uzyskać token, musisz użyć kubectl
, w ten sposób:
user@lab ~ # kubectl -n kubernetes-dashboard create token dashboard-user
<TWÓJ TOKEN>
Skopiuj i wklej wynik powyższego polecenia w monicie, a zalogujesz się.
Użytkownicy
Możliwe jest dodanie użytkowników do klastra, deklarując coś takiego:
k8s_users:
- name: pod-viewer
namespace: default
role_name: pod-viewer-role
role_rules_apigroups: '""'
role_rules_resources: '"pods","pods/exec","pods/log"'
role_rules_verbs: '"*"'
rolebinding_name: pod-viewer-rolebinding
cert_expire_days: 3650
update_kube_config: true
To stworzy lokalny katalog zawierający te pliki:
user@lab ~ # ls -1 kubernetes/users/
pod-viewer.crt
pod-viewer.csr
pod-viewer.key
users.conf
users-rolebindings.yaml
users-roles.yaml
Plik users.conf
można następnie użyć do uzyskania dostępu do klastra z tym użytkownikiem, w ten sposób:
user@lab ~ # export KUBECONFIG=~/kubernetes/users/users.conf
rasca@catastrofe [~]> kubectl config get-contexts
Ceph CSI
Rola Kubernetes obsługuje wdrożenie klasy StorageClass Ceph CSI. Można to zdefiniować następująco:
k8s_ceph_csi_enable: true
k8s_ceph_csi_id: lab-ceph
k8s_ceph_csi_secret_userid: kubernetes
k8s_ceph_csi_secret_userkey: AQAWvU5jjBHSGhAAuAXtHFt0h05B5J/VHERGOA==
k8s_ceph_csi_clusterid: d046bbb0-4ee4-11ed-8f6f-525400f292ff
k8s_ceph_csi_pool: kubepool
k8s_ceph_csi_monitors:
- 192.168.122.11:6789
- 192.168.122.12:6789
- 192.168.122.13:6789
Następnie będzie można zadeklarować nowe PVC:
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
namespace: rasca
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc
I związany Pod:
---
apiVersion: v1
kind: Pod
metadata:
name: csi-rbd-demo-pod
namespace: rasca
spec:
containers:
- name: web-server
image: nginx
volumeMounts:
- name: mypvc
mountPath: /var/lib/www/html
volumes:
- name: mypvc
persistentVolumeClaim:
claimName: rbd-pvc
readOnly: false
Uwaga: w tej chwili obsługiwane jest tylko provisionowanie rbd
.
MetalLB
Aby włączyć MetalLB, implementację load-balacera dla klastra Kubernetes baremetalowego, korzystając ze standardowych protokołów routingu, wystarczy zadeklarować:
k8s_metallb_enable: true
k8s_metallb_pools:
- name: 'first-pool'
addresses: '192.168.122.100-192.168.122.130'
Następnie będzie można użyć tego LoadBalancer do tworzenia adresów IP w zadeklarowanym zakresie puli (zobacz następny przykład ingress-nginx
, aby zrozumieć jak).
Ingress NGINX
Aby włączyć Ingress NGINX, kontroler Ingressa dla Kubernetes używający NGINX jako odwrotnego proxy i load balancera, wystarczy zadeklarować:
k8s_ingress_nginx_enable: true
To zainstaluje kontroler Ingress NGINX, który można wykorzystać do różnych celów.
Ingress NGINX na węzłach kontrolnych
Na przykład można używać Ingress NGINX, wystawiając porty 80
i 443
na adresie IP zarządzanym przez HAProxy, deklarując to:
k8s_ingress_nginx_enable: true
k8s_ingress_nginx_haproxy_conf: true
k8s_ingress_nginx_services:
- name: ingress-nginx-externalip
spec:
externalIPs:
- 192.168.122.199
ports:
- name: port-1
port: 80
protocol: TCP
- name: port-2
port: 443
protocol: TCP
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
To wystawi oba porty na adres IP (w tym przypadku 192.168.122.199
) i sprawi, że usługa będzie odpowiadać na tym adresie.
Aby to przetestować, spróbuj:
$ kubectl create deployment demo --image=httpd --port=80
Lub aby przetestować TLS:
$ kubectl create deployment demo --image=httpd --port=80
$ openssl genrsa -out cert.key 2048
$ openssl req -new -key cert.key -out cert.csr -subj "/CN=demo.192.168.122.199.nip.io"
$ openssl x509 -req -days 366 -in cert.csr -signkey cert.key -out cert.crt
$ kubectl create secret tls tls-secret --cert=./cert.crt --key=./cert.key
Ingress NGINX z MetalLB
Inną możliwością jest użycie go w połączeniu z MetalLB, deklarując usługę LoadBalancer
, w następujący sposób:
k8s_ingress_nginx_enable: true
k8s_ingress_nginx_services:
- name: ingress-nginx-lb
spec:
type: LoadBalancer
loadBalancerIP: 192.168.122.100
ports:
- name: port-1
port: 80
protocol: TCP
- name: port-2
port: 443
protocol: TCP
To zainstaluje wszystko związane z kontrolerem i przypisze loadBalancerIP
, który jest częścią zakresu dostarczanego przez MetalLB, wystawiając oba porty 80
i 443
.
Cert Manager
Aby włączyć Cert Manager, kontroler do automatyzacji zarządzania certyfikatami w Kubernetes, wystarczy zadeklarować:
k8s_cert_manager_enable: true
k8s_cert_manager_issuers:
- name: letsencrypt
cluster: true
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
To zainstaluje wszystko związane z kontrolerem i utworzy wydawcę klastra, który będzie korzystał z letsencrypt
z rozwiązaniem wyzwania http01
, poprzez klasę ingress NGINX.
Gdy wszystko będzie zainstalowane i chcesz wystawić aplikację, możesz przetestować wszystko za pomocą czegoś takiego jak ten yaml:
apiVersion: v1
kind: Namespace
metadata:
name: rasca
---
apiVersion: v1
kind: ConfigMap
metadata:
name: index-html
namespace: rasca
data:
index.html: |
To jest mój fantastyczny serwer WWW!
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: rasca
labels:
app: nginx
spec:
containers:
- name: web-server
image: nginx
volumeMounts:
- name: docroot
mountPath: /usr/share/nginx/html
volumes:
- name: docroot
configMap:
name: index-html
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: rasca
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt
name: nginx-ingress
namespace: rasca
spec:
ingressClassName: nginx
rules:
- host: nginx.apps.kubelab.mmul.it
http:
paths:
- backend:
service:
name: nginx-service
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- nginx.apps.kubelab.mmul.it
secretName: nginx.apps.kubelab.mmul.it
W szczególności w ostatnim zasobie, Ingress
o nazwie nginx-ingress
, znajdziesz dwie ważne sekcje:
Pod
metadata
->annotations
adnotacjęcert-manager.io/cluster-issuer: letsencrypt
Pod
spec:
->tls
deklarację hosta.
Po tym czasie uzyskasz certyfikat dla wystawionej usługi.
Licencja
MIT
Informacje o autorze
Raoul Scarazzini (rascasoft)
This role automates the creation of a Kubernetes cluster complete of additional dashboard, users and operators.
ansible-galaxy install mmul.kubelab