Giải thích và thiết Lập SSL Cho Dịch Vụ Public Trên Kubernetes Với Ingress

0 0 0

Người đăng: Trần Minh Hiếu

Theo Viblo Asia

Xin chào các bạn, ngày hôm nay chúng ta sẽ cùng nhau thảo luận về một chủ đề: Thiết lập SSL cho các dịch vụ Public trên K8s.

Bài toán đặt ra ở đây là khi expose IP ra ngoài cụm k8s rồi nhưng lại chỉ muốn add hosts hoặc đang test nhưng yêu cầu SSL.

Ok mình cùng bắt đầu thôi.

Giới thiệu

  1. Cluster Kubernetes : Cụm K8s cần hoạt động ổn định, có quyền truy cập quản trị
  2. Chứng chỉ SSL
    • Chứng chỉ từ nhà cung cấp uy tín hoặc tự ký (Self-signed certificate).
    • File .crt và .key
  3. Các tài nguyên
    • Namespace (ví dụ: ssl-test)
    • Deployment cần triển khai ssl
    • Ingress Controller
    • Ingress
    • Service
    • Load balancer

Tạo Secret chứa chứng chỉ SSL

Có 2 cách tạo secret chứa SSL là bằng file hoặc bằng CLI. Ví dụ ở đây sẽ tạo 1 secret tên my-ssl-secret có tham số là : tls.crttls.key

  1. Tạo bằng file secret.yaml
    •  apiVersion: v1 kind: Secret metadata: name: my-ssl-secret namespace: <Namespace> data: tls.crt: <base64encode> CERTIFICATE tls.key: <base64encode> PRIVATE KEY type: kubernetes.io/tls
      
    • Dùng lệnh kubelectl apply -f secret.yaml
  2. Tạo bằng CLI
    • kubectl create secret tls my-ssl-secret --cert=path/to/tls.crt --key=path/to/tls.key -n <Namespace>
    • my-ssl-secret : tên Secret
    • --cert và --key : đường dẫn đến file chứng chỉ và khóa riêng
    • -n <Namespace> : namespace chứa Secret

Luồng đi của các tài nguyên.

Đây sẽ là cách mà luồng traffic từ User về với Pod (Application), chỉ giới thiệu về cách tạo các tài nguyên cần thiết để làm việc này chứ không phải các tài nguyên khác.

Giả sử chúng ta đã có Deployment chứa application. App sẽ expose ra port 3000 (có thể là các port khác tùy theo nhu cầu và mong muốn). Ta có sơ đồ như sau :

  1. User

    • Người dùng gửi yêu cầu HTTP hoặc HTTPS từ trình duyệt hoặc ứng dụng.
    • Giao tiếp sử dụng cổng 443 cho HTTPS và 80 cho HTTP.
    • Yêu cầu sẽ được DNS phân giải tên miền thành địa chỉ IP public của Load Balancer.
  2. Load balancer

    • Đóng vai trò là endponit của K8s. Lắng nghe trên cổng 80 và 443.
    • Có vai trò chuyển lưu lượng đến các pod của Ingress Controller bên trong cluster trên cổng 80 và 443.
  3. Ingress Controller

    • Chịu trách nhiệm xử lý các yêu cầu HTTP/HTTPS đến cluster, lắng nghe trên cổng 80 và 443.
    • Đối với các yêu cầu HTTPS, Ingress Controller sử dụng Secret chứa chứng chỉ SSL để giải mã lưu lượng, đảm bảo kết nối bảo mật.
    • Sau khi xử lý, Ingress Controller sẽ định tuyến lưu lượng đến dịch vụ phù hợp dựa trên quy tắc trong Ingress Resource.
  4. Ingress Resource

    • Chứa các quy tắc định tuyến, cho phép Ingress Controller biết dịch vụ nào cần xử lý yêu cầu dựa trên tên miền và đường dẫn.
    • Sau khi xác định, Ingress Controller chuyển tiếp yêu cầu đến dịch vụ cụ thể. Lúc này, ta có thể sửa theo cổng theo yêu cầu (ở đây là 3000) để giao tiếp với Service (ClusterIp hoặc NodePort).
  5. Service (ClusterIp hoặc NodePort)

    • Dịch vụ Kubernetes lắng nghe trên cổng 3000 và chuyển tiếp lưu lượng đến ứng dụng chạy trong các pod.
    • Ứng dụng trong pod có thể chạy trên một cổng khác, trong trường hợp này là 3000.
  6. Pod (Application)

    • Pod nhận lưu lượng trên cổng 3000 và xử lý yêu cầu.
    • Ứng dụng trong pod xử lý dữ liệu và trả phản hồi về qua chuỗi dịch vụ.

Cấu hình tệp YAML cho các tài nguyên

  1. Load balancer
apiVersion: v1
kind: Service
metadata: name: <Load balancer name> namespace: <Namespace> annotations: service.beta.kubernetes.io/aws-load-balancer-internal: "true" # Cấu hình riêng của từng cloud provider cho phép service expose IP
spec: type: LoadBalancer selector: app: <Ingress Controller Label> ports: - name: http port: 80 # port forward tiếp đến tài nguyên tiếp theo targetPort: 80 # port lắng nghe - name: https port: 443 # port forward tiếp đến tài nguyên tiếp theo targetPort: 443 # port lắng nghe
  1. Ingress Controller
apiVersion: apps/v1
kind: Deployment
metadata: name: <Ingress Controller Name> namespace: <Namespace>
spec: replicas: 1 selector: matchLabels: app: <Ingress Controller Label> template: metadata: labels: app: <Ingress Controller Label> spec: volumes: - name: webhook-cert secret: secretName: <Ingress Controller Secret> defaultMode: 420 containers: - name: <Ingress Container Name> image: >- registry.k8s.io/ingress-nginx/controller:v1.11.3@sha256:d56f135b6462cfc476447cfe564b83a45e8bb7da2774963b00d12161112270b7 args: - /nginx-ingress-controller - --publish-service=$(POD_NAMESPACE)/<Service Name> # Cập nhật tên service - '--controller-class=k8s.io/ingress-nginx' - '--ingress-class=nginx' - '--configmap=$(POD_NAMESPACE)/crm-ingress-ingress-nginx-controller' - '--validating-webhook=:8443' - '--validating-webhook-certificate=/usr/local/certificates/cert' - '--validating-webhook-key=/usr/local/certificates/key' - '--enable-metrics=false' ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: LD_PRELOAD value: /usr/local/lib/libmimalloc.so
  1. Ingress Recource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: name: <Ingress Resource Name> namespace: <Namespace> annotations: nginx.ingress.kubernetes.io/ssl-redirect: "true" # Buộc chuyển hướng tất cả các yêu cầu HTTP sang HTTPS.
spec: ingressClassName: nginx tls: - hosts: - <DOMAIN NAME> secretName: <SECRET chứa SSL> rules: - host: <DOMAIN NAME> http: paths: - path: / pathType: Prefix backend: service: name: <SERVICE NAME> port: number: 3000 # Port của Service đẩy sang
  1. Service
apiVersion: v1
kind: Service
metadata: name: <Service Name> namespace: <Namespace>
spec: selector: app: <Deployment App Name> ports: - protocol: TCP port: 3000 # Port của Service lắng nghe targetPort: 3000 # Port của container nhận traffic type: ClusterI

Một số lỗi phổ biến và cách xử lý

  1. x509: certificate signed by unknown authority

    • Nguyên nhân: Chứng chỉ được sử dụng trong Ingress Controller không được công nhận bởi hệ thống hoặc CA (Certificate Authority) không đáng tin cậy.
    • Cách giải quyết:
      • Kiểm tra và đảm bảo rằng chứng chỉ TLS và CA được thêm vào là hợp lệ.
      • Xác minh rằng Secret chứa chứng chỉ đã được tạo đúng cách (sử dụng kubectl get secret <secret-name> -n <namespace>).
      • Sử dụng chứng chỉ từ CA đáng tin cậy hoặc thêm CA vào các pod nếu cần.
  2. Failed calling webhook validate.nginx.ingress.kubernetes.io

    • Nguyên nhân: Webhook của Ingress Controller không hoạt động đúng do lỗi chứng chỉ hoặc không thể kết nối tới service của webhook.
    • Cách giải quyết:
      • Kiểm tra trạng thái của admission controller bằng lệnh kubectl get svc -n <namespace> để đảm bảo nó hoạt động.
      • Đảm bảo rằng chứng chỉ TLS của admission controller là hợp lệ và cập nhật lại nếu cần thiết.
  3. Không chuyển tiếp đúng lưu lượng đến pod (404 hoặc không phản hồi)

    • Nguyên nhân: Cấu hình Ingress hoặc Service không đúng, chẳng hạn như path, port, hoặc serviceName không khớp.
    • Cách giải quyết:
      • Kiểm tra tệp cấu hình Ingress để đảm bảo spec.rules và backend.service được đặt đúng.
      • Đảm bảo rằng Service đúng cổng và đang chuyển tiếp lưu lượng đến pod trên cổng 3000.
  4. No endpoints available for service

    • Nguyên nhân: Service không có endpoint nào khả dụng để chuyển tiếp lưu lượng đến pod.
    • Cách giải quyết:
      • Kiểm tra các pod bằng kubectl get pods -n <namespace> để đảm bảo chúng đang chạy và sẵn sàng.
      • Đảm bảo rằng selector của Service khớp với nhãn của pod.
  5. Default backend - 404 từ Ingress

    • Nguyên nhân: Ingress không thể tìm thấy backend phù hợp cho yêu cầu.
    • Cách giải quyết:
      • Kiểm tra rằng cấu hình host và path trong Ingress khớp với yêu cầu được gửi đến.
      • Đảm bảo rằng Service được tham chiếu tồn tại và hoạt động đúng.
  6. Liên quan đến cấu hình HTTPS không hoạt động

    • Nguyên nhân: Secret TLS hoặc cấu hình tls trong Ingress bị thiếu hoặc không chính xác.
    • Cách giải quyết:
      • Đảm bảo rằng Secret chứa chứng chỉ TLS hợp lệ (kiểm tra với kubectl describe secret <secret-name> -n <namespace>).
      • Đảm bảo cấu hình spec.tls trong Ingress tham chiếu đúng đến Secret chứa chứng chỉ TLS.
  7. Kết nối curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number

    • Nguyên nhân: Phiên bản SSL/TLS không khớp hoặc cấu hình Ingress không đúng.
    • Cách giải quyết:
      • Kiểm tra phiên bản TLS được hỗ trợ trong Ingress Controller và cấu hình client
      • Đảm bảo rằng không có sự cố về phiên bản TLS trong Secret và cấu hình Ingress.
  8. Lỗi load balancer tắc ở trạng thái pending và không có IP

    • Nguyên nhân: Có thể dải IP của cụm K8s không đủ để cũng cấp.
    • Cách giải quyết:
      • Kiểm tra lại cụm xem còn IP có thể expose ra không
      • Xóa những IP không sử dụng.
      • Extend thêm subnet cho cụm k8s.

Trên đây là bài viết đầu tay về tổng quan cách cấu hình SSL trên K8s của mình.

Cảm ơn các bạn đã dành thời gian.

Mình là Hiếu

Một Developer tập tành học DevOps.

Hẹn gặp các bạn trong bài viết sắp tới.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Phần 1: Giới thiệu về Kubernetes

Kubernetes là gì. Trang chủ: https://kubernetes.io/. Ai cần Kubernetes.

0 0 101

- vừa được xem lúc

Thực hành K8S trên Google Cloud

Kubernetes (K8S) trở nên quá phổ biến ở thời điểm hiện tại, ai cũng nói về nó. Trong bài hôm nay mình sẽ không đi quá nhiều vào các định nghĩa, mà đi thẳng vào thực tế để mọi người dễ hình dung.

0 0 35

- vừa được xem lúc

Kubernetes best practices - Liveness và Readiness Health checks

Mở đầu. Kubernetes cung cấp cho bạn một framework để chạy các hệ phân tán một cách mạnh mẽ.

0 0 50

- vừa được xem lúc

Kubernetes - deployment.yaml explained

Trong bài trước, mình có giới thiệu chạy các câu lệnh K8S bằng Command Line. Để tạo 1 deloyment đơn giản chỉ cần chạy lệnh.

0 0 91

- vừa được xem lúc

Tìm hiểu cơ bản về Kubernetes - K8s (Part 2): Minikube

Lời mở đầu. .

0 0 47

- vừa được xem lúc

ETCD - Bộ não của Kubernetes và cách cài đặt cụm ETCD Cluster (High Availability)

Hello anh em, sau vài ngày nghiên cứu đọc lại liệu cũng như cài cắm thủ công đủ thể loại, với vô số lỗi fail thì mình cũng cài đặt thành công cụm etcd cluster một cách thủ công. Trước giờ chuyên tạo c

0 0 44