Làm sao để config SSL/TLS cho Ingress trong cụm Kubernetes?
Trong bài viết này ta sẽ cùng tìm hiểu về cách cấu hình TLS certificate cho các Kubernetes Ingress.
Cách lấy Kubernetes Ingress SSL/TLS Certificate
Yêu cầu cơ bản của Ingress TLS là một TLS/SSL certificate. Bạn có thể lấy các certificate đó bằng các cách sau:
Self-Signed Certificates: TLS certificate được tạo và kí bởi Certificate Authority của riêng bạn. Đây là một cách tạo certificate tốt nếu như bạn có thể chia sẻ rootCA cùng với team và browser có thể tin tưởng certificate đó. Tham khảo bài viết dưới đây để tạo các certificate của riêng bạn.
Mua một SSL Certificate: Bạn cần mua một SSL certificate từ môt certificate authority.
Sử dụng Let's encrypt certificate: Let's encrypt là một certificate authority phi lơi nhuận cung cấp các TLS certificate miễn phí.
Mọi SSL certificate đều có thời gian hết hạn (expiry date). Ta cần phải gia hạn cho các certificate trước khi nó hết hạn. Ví dụ Let's encrypt certificate sẽ hết hạn sau mỗi 3 tháng. Ta sẽ nói về gia hạn tự động các certificate trong phần cuối của bài viết này.
Nếu bạn làm việc trên một ứng dụng nội bộ, hầu hết các công ty đều có hạ tầng PKI của riêng công ty để cung cấp SSL cho các ứng dụng nội bộ. Bạn có thể request team network hoặc security để cung cấp các certificate.
Ingress TLS/SSL hoạt động thế nào?
Để thêm TLS vào Ingress ta chỉ cần:
Tạo môt Kubernetes secret với
server.crt
certificate và file private keyserver.key
Thêm TLS block vào Ingress resource với hostname được sử dụng để tạo cert tương ứng với TLS certificate.
SSL được xử lý bởi Ingress controller chứ không phải Ingress resource. Khi bạn thêm TLS certificate vào Ingress resource như một Kubernetes secret thì Ingress controller sẽ truy cập nó và đưa các certificate đó vào cấu hình của nó.
Ví dụ trong Nginx controller, SSL certificate được xử lý trong nginx.conf
bởi block sau:
ssl_certificate_by_lua_block {
certificate.call()
}
Biểu đồ sau biểu diễn workflow của Ingress TLS:
Cấu hình Ingress TLS/SSL Certificates
Deploy một ứng dụng Test
Hãy bắt đầu với việc triển khai một ứng dụng sample. Ta sẽ sử dụng ứng dụng này để test Ingress TLS.
Create a dev namespace. Tạo một namespace dev
kubectl create -n dev
Lưu manifest sau thành hello-app.yaml
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-app
namespace: dev
spec:
selector:
matchLabels:
app: hello
replicas: 2
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-app:2.0"
---
apiVersion: v1
kind: Service
metadata:
name: hello-service
namespace: dev
labels:
app: hello
spec:
type: ClusterIP
selector:
app: hello
ports:
- port: 80
targetPort: 8080
protocol: TCP
Triển khai manifest:
kubectl apply -f hello-app.yaml
Tạo một Kubernetes TLS Secret
server.crt
và server.key
SSL từ một Certificate authority.SSL certificate nên đực thêm vào như một Kubernetes Secret sau đó nó sẽ được chuyển vào Ingress resource TLS block.
Hãy tạo một Kubernetes secret loại TLS với server.crt
và server.key
. Ta sẽ tạo secret trong dev
namespace nơi ta đã triển khai hello-app.
Thực thi kubectl command sau từ thư mục nơi ta lưu server.crt
và server.key
hoặc cung cấp absolute path của các file đó. hello-app-tls
là tên ta đặt cho secret.
kubectl create secret tls hello-app-tls \
--namespace dev \
--key server.key \
--cert server.crt
Nếu muốn sử dụng YAML để tạo secret ta cũng có thể sử dụng như sau:
apiVersion: v1
kind: Secret
metadata:
name: hello-app-tls
namespace: dev
type: kubernetes.io/tls
data:
server.crt: |
<crt contents here>
server.key: |
<private key contents here>
Thêm TLS block vào Ingress Object
Ingress resource với TLS đã được tạo trong cùng namespace ta đã triển khai ứng dụng. Ta sẽ tạo Ingress resource bằng ingress.yaml
sau:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-app-ingress
namespace: dev
spec:
ingressClassName: nginx
tls:
- hosts:
- demo.mlopshub.com
secretName: hello-app-tls
rules:
- host: "demo.mlopshub.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-service
port:
number: 80
Bạn có thể thấy ta đã thêm TLS block cùng hostname và TLS secret ta đã tạo trong bước trước.
Host trong TLS block và rule block cần phải giống nhau.
Kiểm tra Ingress TLS
Ta có thể kiểm tra hoạt động của Ingress TLS sử dụng curl
hoặc browser.
curl https://demo.mlopshub.com -kv
Trong output trong phần server certificate ta có thể kiểm tra thông tin về certificate:
If you don’t have a valid certificate or if the ingress TLS configuration is wrong, you will see “Your connection is not private” security warning and if you check the certificate details, you will see the certificate name as “Kubernetes Ingress Controller Fake Certificate“. Nếu không có certificate khả dụng hoặc Ingress TLS cấu hình sai, ta sẽ thây thông báo "Your connection is not private" và nếu kiểm tra thông tin về certificate ta có thể thấy tên certificate là "Kubernetes Ingress Controller Fake Certificate"
Đó là SSL certificate mặc định của Nginx Ingress Controller. Nếu bạn kiểm tra nginx.conf
của Nginx controller bạn có thể thấy certificate mặc định như dưới đây:
Ingress SSL Termination
Mặc định SSL sẽ được terminate trong ingress controller.
Vì vậy mọi traffic từ controller đến pod sẽ không có TLS.
Nếu bạn muốn sử dụng toàn bộ traffic trên SSL, bạn có thể thêm annotation của Ingress controller bạn đang sử dụng. Ví dụ trong Nginx Ingress Controller để cho phép SSL traffic bạn có thể dùng nginx.ingress.kubernetes.io/backend-protocol:"HTTPS"
annotation.
Kết luận
Trong bài viết này ta đã tìm hiểu về cách cấu hình Ingress TLS certificate cùng ví dụ về Ingress TLS.
Thêm vào đó ta có thể sử dụng annotation để có thêm các tham số TLS trong ứng dụng. Các annotation trong các ingress controller sẽ khác nhau.