Keywords: How to setup an Nginx Ingress and Cert Manager on Kubernetes
Ingress trong k8s là gì ? đây là câu hỏi mà hình như khi mình đi phỏng vấn DevOps tại các công ty yêu cầu kubernetes điều hỏi mình, vậy nó thật sự là gì ? theo một lý thuyết của phong cách google thì nó là một định nghĩa rất dài nhưng với mình thì mình đã trả lời các nhà tuyển dụng, những người phỏng vấn mình nó là một config dùng để trỏ domain đến một service trong k8s
Câu trả lời đơn giản theo nghĩa mà mình hiểu, có rất nhiều Ingress Controller được hổ trợ như HaProxy Ingress, Nginx Ingress, Kong Ingress,... Nhưng phổ biến nhất vẫn là Nginx Ingress và Kong Ingress, hôm nay mình sẻ hướng dẫn cho các bạn cài đặt nó cũng như thực hiện tạo thử demo với domain cùng với http và https, vậy để có được https ta cần làm gì ? chúng ta phải thực hiện cài đặt Let's Encrypt cùng với Cert Manager để quản lý các Certificates, ok chúng ta phải làm thử từng bước trước đã, đầu tiên là tạo service để chạy một pod demo trước chứ nhỉPhần 1: Cài đặt một services để demo thử
apiVersion: v1 kind: Service metadata: name: http-test-svc spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: http-test-app sessionAffinity: None type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: run: http-test-svc name: http-test-svc spec: replicas: 2 selector: matchLabels: run: http-test-app template: metadata: labels: run: http-test-app spec: containers: - image: httpd imagePullPolicy: IfNotPresent name: http ports: - containerPort: 80 protocol: TCP resources: {}Sau khi chạy xong bạn sẻ thấy như hìnhĐiều này có nghĩa rằng mình đã tạo xong một service đang chạy 2 pods và tên service đó là http-test-svc nhưng bây giờ mình để type service là ClusterIP vậy để truy cập vào đó mà không cần đến NodePort thì chúng ta cần phải làm gì ? đó là trỏ domain đến services đó, việc trỏ domain đến service đó thì sẻ do thằng Ingress Controller quản lý vì vậy mình sẻ chọn thực hiện cài đặt 1 trong các Ingress Controller, mình sẻ chọn Nginx Ingress
Phần 2: Cài đặt Nginx Ingress cho Kubernetes
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/do/deploy.yamlHoặc chúng ta có thể sử dụng cách sau
git clone [email protected]:nginxinc/kubernetes-ingress.git # vào thư mục tải về cd kubernetes-ingress/deploymentsCác menifest điều nằm ở thư mục deployments trong kubernetes-ingress vừa clone về, sau khi đã truy cập vào rồi thì ta chỉ việc apply một vài file sau thôi:
kubectl apply -f common/ns-and-sa.yaml kubectl apply -f common/default-server-secret.yaml kubectl apply -f common/nginx-config.yaml kubectl apply -f common/ingress-class.yaml kubectl apply -f common/crds/k8s.nginx.org_virtualservers.yaml kubectl apply -f common/crds/k8s.nginx.org_virtualserverroutes.yaml kubectl apply -f common/crds/k8s.nginx.org_transportservers.yaml kubectl apply -f common/crds/k8s.nginx.org_policies.yaml kubectl apply -f rbac/rbac.yaml kubectl apply -f daemon-set/nginx-ingress.yaml kubectl create -f service/nodeport.yamlSau khi thực hiện cài đặt Inginx Ingress xong thì chúng ta chỉ còn việc test nữa thôi là ok, nếu như version k8s của bạn nhỏ hơn 1.18 thì có thể sử dụng cách 1 nhưng nếu như version của bạn lớn hơn 1.18 thì mình khuyên các bạn sử dụng cách 2 nhé
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app # namespace: ingress-nginx annotations: nginx.ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: nginx spec: # backend: # serviceName: nginx-ingress-default-backend # servicePort: 80 rules: - host: thanhphatit.local http: paths: - path: / pathType: Prefix backend: service: name: http-test-svc port: number: 80Sau đó chạy câu lệnh apply nó, như các bạn biết đấy, để truy cập domain thì ta phải trỏ DNS Record đến IP của k8s cái đã, ở đây mình sẻ trỏ tạm ở file host nhéThực hiện kiểm tra thử app ingress mà ta đã apply ở trên xem nó đã chạy chưa nhéOk bây giờ ta test thử domain nàoNgon lành rồi đấy, bây giờ chúng ta tới phần khá quan trọng đấy, http thì ngon rồi tiếp đến phải là https chứ nhỉCó 2 hình thức sử dụng https
- Thứ 1: Sử dụng default-server-secret của nginx lúc nảy ta config nhưng điều này đồng nghĩa với việc là config ingress phải cùng namespace với nginx-ingress và pods đang chạy cũng phải nằm ở namespace nginx-ingress, giả sử trường hợp mình sử dụng default-server-secret nhưng pods của mình đang chạy lại nằm ở namespace defaults không nằm ở nginx-ingress thì vấn đề sẻ như thế nào ?
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app namespace: nginx-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / kubernetes.io/ingress.class: nginx spec: # backend: # serviceName: nginx-ingress-default-backend # servicePort: 80 tls: - hosts: - thanhphatit.local secretName: default-server-secret rules: - host: thanhphatit.local http: paths: - path: / pathType: Prefix backend: service: name: http-test-svc port: number: 80
- Thứ 2: Do vấn đề ở trên quá phức tạp và rờm rà nên vì thế mình sẻ sử dụng cách 2 đó là cài đặt cert manager và để nó tự tạo certificate cho pods đó trên cùng namespace
Phần 3: Cài đặt và config Cert Manager
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.2.0/cert-manager.yamlKiểm tra lại mọi thứ nàoTới đây được rồi thì chưa xong đâu, chúng ta thực hiện apply 2 file
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-staging namespace: cert-manager spec: acme: # The ACME server URL server: https://acme-staging-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: [email protected] # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-staging # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: nginxletsencrypt-staging.yaml:
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod namespace: cert-manager spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration email: [email protected] # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider solvers: - http01: ingress: class: nginxSau khi đã apply 2 file letsencrypt ta tiếp tục chỉnh sửa lại 1 chút file ingress nữa là xong, các bạn nên chú ý việc sử dụng letsencrypt với một domain không đăng ký là hoàn toàn không thể, vì vậy cần chú ý phần email trong 2 file letsencrypt trên bởi lẻ mình sẻ không làm tiếp cho các bạn và show kết quả ra cho các bạn thấy mà chỉ hướng dẫn bằng cách viết ví dụ trên đây thôi, do mình không có domain thật để giải quyết
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app annotations: cert-manager.io/cluster-issuer: letsencrypt-staging certmanager.k8s.io/acme-challenge-type: http01 kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: / spec: # backend: # serviceName: nginx-ingress-default-backend # servicePort: 80 tls: - hosts: - test.itblognote.com secretName: app-tls-cert rules: - host: test.itblognote.com http: paths: - path: / pathType: Exact backend: service: name: http-test-svc port: number: 80Như các bạn thấy mình đã thêm annotations và tls cho file ingress, như vậy mình đã config xong cho phần ingress https rồi, nói chung sorry các bạn vì mình không thực hiện ví dụ cụ thể cho các bạn được bởi lẽ cần domain và ví dụ rõ ràng sẻ tốt hơn nhưng do mình không có domain để test, sử dụng domain ảo bằng cách add hosts thì thằng letsencrypt nó không cho, thành ra mình chỉ copy những config tượng trưng thôi, nhưng nếu như anh em có domain rõ ràng rồi thì chỉ việc thay thế trong config và run là chạy liền ak mà yên tâm.
0 Comments
Vài lời muốn nói:
* Không được nhận xét thô tục bởi mình biết các bạn là những người văn minh.
* Pass giải nén mặt định là itblognote hoặc itblognote.com nếu có Pass khác thì mình sẽ ghim trong bài viết.
* Click vào quảng cáo và chia sẻ bài viết để mình có thêm động lực viết bài nhé.