To już ostatnia część poradnika 'jak postawić własny klaster Kubernetes’. Zajmiemy się w niej wystawieniem naszej aplikacji na świat oraz zapewnimy automatyczne uzyskanie certyfikatu przy użyciu Let’s Encrypt dla naszej domeny.

Load balancer posłuży nam do obsługi ruchu przychodzącego. Ja użyję do tego MetalLB. Wiem, że firma Hetzner oferuje dedykowaną usługę load balancingu, ale na ten moment byłyby to niepotrzebne koszta. MetalLB działa wystarczająco dobrze dla niezbyt dużego ruchu. Jeżeli kiedyś przestanie mi wystarczać, zmienię go na dedykowaną usługę (i napiszę o tym kolejny wpis).

Aby zainstalować MetalLB, należy wykonać polecenie:

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml && \
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

Następnie dodajemy do konfiguracji nowo utworzonego load balancera nasz floating IP.

FLOATING_IP=$(hcloud floating-ip list -o noheader -o columns=ip)
cat <<EOF |kubectl apply -f-
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - $FLOATING_IP/32
EOF

MetalLB został poprawnie skonfigurowany. Oznacza to, że nadszedł czas na zainstalowanie FIP Controllera od Hetzner (wybieramy ten, ponieważ obsługuje on „pływające IP” w klastrze). Jako że floating IP jest przypisane do jednego z nodów, FIP Controller przepnie to IP na inny node, gdy ten właściwy będzie w stanie NotReady. Robimy to za pomocą polecenia:

kubectl create namespace fip-controller && \
kubectl apply -f https://raw.githubusercontent.com/cbeneke/hcloud-fip-controller/master/deploy/rbac.yaml && \
kubectl apply -f https://raw.githubusercontent.com/cbeneke/hcloud-fip-controller/master/deploy/deployment.yaml

W tym momencie FIP Controller jeszcze nie będzie działał. Potrzebna jest do tego dodatkowa konfiguracja i nasz token.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: fip-controller-config
  namespace: fip-controller
data:
  config.json: |
    {
      "hcloud_floating_ips": [ "$FLOATING_IP" ],
      "nodeAddressType": "external"
    }
---
apiVersion: v1
kind: Secret
metadata:
  name: fip-controller-secrets
  namespace: fip-controller
stringData:
  HCLOUD_API_TOKEN: "$HCLOUD_TOKEN"
EOF

Po tej operacji wszystkie pody w namespace fip-controller powinny mieć status „Running”. Ostatnia rzecz, która nam została, to zainstalowanie ingressa. Robi się to równie prosto, jak poprzednie rzeczy.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml
cat <<EOF | kubectl apply -f -
kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  annotations:
    metallb.universe.tf/allow-shared-ip: "$FLOATING_IP"
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https
EOF

Po poprawnym utworzeniu ingressa do kontrolera powinno zostać przypisane nasze zewnętrzne IP.

$ kubectl get svc -n ingress-nginx
NAME                                         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
service/ingress-nginx                        LoadBalancer   10.96.99.79    <pending>       80:32691/TCP,443:31774/TCP   37s
service/ingress-nginx-controller             LoadBalancer   10.96.86.31    49.12.118.254   80:32729/TCP,443:32511/TCP   44s
service/ingress-nginx-controller-admission   ClusterIP      10.96.235.46   <none>          443/TCP                      44s

Zanim ruszymy dalej, sprawdźmy, czy nasz zewnętrzny adres IP jest właściwie przypisany do ingressa. Skopiuj swój adres, a następnie wpisz go w przeglądarkę. Powinieneś otrzymać wiadomość z nignx, że nie odnaleziono strony i kod błędu 404. Co oznacza, że wszystko jest w porządku.

Następnie przypiszemy nasz IP do naszej domeny. Jeżeli nie masz jeszcze swojej domeny, możesz skorzystać ze strony freenom.com, gdzie za darmo można utworzyć domenę (z egzotycznym rozszerzeniem .tk, .ml lub .gq :-), ale na potrzeby testów wystarczy). Upewnij się, że Twoja domena jest już poprawnie mapowana na adres IP (wpisz w przeglądarkę domenę, znów powinieneś zobaczyć 404).

Okej. Sieci gotowe, ingress gotowy, domena przygotowana… Ostatni element, który warto zainstalować, to CertManager z Let’s Encrypt. Wygeneruje on automatycznie dla nas darmowy certyfikat TLS.

kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml

Mamy już CertManager, teraz należy doinstalować wydawcę certyfikatu (Issuer). U nas będzie to wspomniany wcześniej Let’s Encrypt.

cat <<EOF | kubectl apply -f-
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt
  namespace: cert-manager
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: <YOUR_EMAIL>
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt
    # Enable the HTTP-01 challenge provider
    solvers:
    - http01:
        ingress:
          class: nginx
EOF

Teraz już wszystko jest gotowe. Pora na testy.

Zaczniemy od uruchomienia serwera nginx i utworzenia serwisu dla niego (będzie on rozdzielał ruch pomiędzy wszystkie działające pody).

kubectl create deploy nginx --image=nginx --replicas=2 --port=80
kubectl expose deployment nginx --port=80 --target-port=80
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt" # nazwa wcześniej utworzonego Issuera
  name: nginx
spec:
  rules:
  - host: <YOUR_DOMAIN>
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: nginx
            port:
              number: 80
  tls:
  - hosts:
    - <YOUR_DOMAIN>
    secretName: <YOUR_DOMAIN>-tls
EOF

Teraz po wejściu na Twoją stronę powinieneś zostać automatycznie przekierowany na bezpieczne połączenie (https) i powinna wyświetlić się strona startowa nginx (jak na screenie poniżej).

Strona powitalna nginx

Jak widzisz, utworzenie całego klastra to tak naprawdę tylko dokładanie kolejnych elementów tak, by tworzyły razem wspólną całość. Jednak wierzę, że na początku może się to wydawać skomplikowane. Mam nadzieję, że po lekturze ostatnich czterech artykułów udało Ci się stworzyć działający klaster Kubernetes, czekający tylko na Twoje aplikacje. Daj znać w komentarzu, co zamierzasz uruchomić jako pierwsze na Twoim klastrze.

Powodzenia!


0 komentarzy

Dodaj komentarz

Avatar placeholder

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *