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

Tự động cập nhật ứng dụng khi có thay đổi Secret, Configmap trên Kubernetes với Reloader

0 0 9

Người đăng: Hoàng Việt

Theo Viblo Asia

Bài toán

image.png

Nếu anh em đã làm việc với Kubernetes thì chắc sẽ biết được 1 điều, đối với một số loại ứng dụng khi ta thay đổi cấu hình được lưu trữ trong Configmap hay Secret thì application sẽ không tự động cập nhật mà đòi hỏi chúng ta sẽ phải có hành động bằng tay thực hiện xóa pod đi tạo lại hay thực hiện Rollout restart thì application mới lấy lại được cấu hình mới. Đây mình nghĩ rằng là một tính năng để giảm thiểu sự thay đổi hạ tầng một cách vô ý, tuy nhiên việc này đôi khi lại gây sự bất tiện cho một số anh em DevOps ,SRE khi muốn ứng dụng sẽ tự động cập nhật cấu hình mới mà không cần phải thêm 1 bước Rollout trong CI/CD hay phải làm bằng tay.

Ngoại lệ có 1 số ứng dụng như NGINX có thể tự động nhận diện được sự thay đổi và load vào cấu hình mới mà không cần restart

Tự động cập nhật ứng dụng khi có thay đổi về cấu hình trong Configmap, Secret sẽ hữu ích trong trường hợp:

  • Trong các môi trường không yêu cầu độ ổn định cao (Dev, Staging)
  • Trong các môi trường thay đổi cấu hình thường xuyên.
  • Trong các môi trường mà Dev quản lý cấu hình ứng dụng, DevOps/SRE quản lý hạ tầng => Tự động reload sẽ giảm gánh nặng công việc tay chân cho DevOps/SRE.
  • Đối với các ứng dụng có đã cấu hình Readiness, Liveness,... chuẩn chỉ, không gặp downtime khi Rollout update.
  • ...

Khi có nhu cầu thì sẽ có giải pháp! Vô tình được ông anh chia sẻ cho một công cụ khá hay có thể tự động hóa việc cập nhật ứng dụng khi Configmap hay Secret thay đổi, thấy rằng công cụ khá hay nhưng chưa nhiều anh em biết nên lên ngay 1 bài chia sẻ cho anh em cho nóng 🤣🤣🤣

Pod LifeCycle

Công cụ Reloader

image.png

https://github.com/stakater/Reloader

Công cụ Reloader là một công cụ Open Source được phát triển bởi stakater.

Reloader là một Kubernetes Controller, nó sẽ liên tục giám sát sự thay đổi các Configmaps và Secrets được chỉ định. Nếu có sự thay đổi diễn ra, Controller sẽ thực hiện cập nhật lại Deployment/StatefulSet/Deamonset/Rollout đang sử dụng Configmap/Secret đó để ứng dụng chạy với cấu hình mới nhất.

Cài đặt Reloader

Vì là Kubernetes Controller, Reloader sẽ được cài đặt trên chính cụm Kubernetes mà bạn muốn áp dụng công cụ này. Reloader cài đặt khá dễ dàng, bạn có thể cài bằng cách apply trực tiếp file manifest

kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml

Hoặc ngoài ra bạn có thể cài đặt sử dụng Kustomize hay Helm Charts với nhiều cấu hình tùy chọn hơn.

Tham khảo thêm tại document chính thức của công cụ nhé :

https://github.com/stakater/Reloader?tab=readme-ov-file#deploying-to-kubernetes

Trong bài này để đơn giản mình sẽ cài đặt bằng cách apply trực tiếp file manifest:

image.png

Từ trên hình bạn có thể thấy có 1 Deployment trên reloader-reloader được tạo và cùng với đó là serviceAccount - ClusterRole - ClusterRoleBinding phục vụ cho việc cấp quyền cho công cụ trên toàn bộ Cluster.

Mặc định công cụ này sẽ giám sát sự thay đổi configmap và secret trên toàn bộ cluster nha. Chính vì thế nó cần tạo ClusterRole.

Thử nghiệm

Trong phần này mình cùng các bạn sẽ thử nghiệm liệu công cụ này sẽ hoạt động thế nào với một demo đơn giản.

Mình sẽ thử nghiệm thay đổi cấu hình của một ứng dụng web Python echo ra biến môi trường có tên RANDOM_ENV. Biến môi trường này sẽ được mount vào trong deployment thông qua 1 secret. Các bước chúng ta sẽ phải làm là:

1, Code python webserver (Flask) 2, Dockerize 3, Push Image lên Dockerhub 4, Tạo các resource k8s cần thiết (Secret, Deployment, Service) 5, Thử nghiệm thay đổi secret khi chưa có Reloader 6, Cài đặt Reloader và cấu hình reloader cho deployment 7, Thử nghiệm thay đổi secret khi đã cài đặt Reloader.

1, Code Python webserver

from flask import Flask
import os app = Flask(__name__) @app.route('/')
def echo_random_env(): random_env_value = os.environ.get('RANDOM_ENV', 'Environment variable RANDOM_ENV is not set.') return f'The value of RANDOM_ENV is: {random_env_value}' if __name__ == '__main__': app.run(debug=True, host='0.0.0.0') 

Đoạn code trên sẽ chạy 1 web server và hiển thị ra giá trị của biến môi trường RANDOM_ENV được lưu trong pod. Bạn có thể dùng câu lệnh export RANDOM_ENV = "foo" rồi chạy webserver bằng python main.py sẽ thấy nội dung được hiển thị có dạng

image.png

2, Dockerize

Dockerfile dùng để dockerize ứng dụng này sẽ như sau:

# Use an official Python runtime as a parent image
FROM python:3.9-slim # Set the working directory in the container
WORKDIR /app # Copy the current directory contents into the container at /app
COPY . /app # Install any needed packages specified in requirements.txt
RUN pip install flask # Make port 5000 available to the world outside this container
EXPOSE 5000 # Run app.py when the container launches
CMD ["python", "main.py"]

3, Build và push image lên Registry (Dockerhub)

Build và đẩy image ứng dụng python lên Dockerhub để có thể pull về được trong Kubernetes.

docker build -t docker.io/nguyenhoangviet3/reloader-test:latest . docker push docker.io/nguyenhoangviet3/reloader-test:latest

Image của thử nghiệm này là docker.io/nguyenhoangviet3/reloader-test:latest bạn có thể cấu hình luôn để chạy nếu không muốn build lại.

4, Tạo resource trên K8s

Để có thể thực hiện thử nghiệm mình sẽ cần tạo 3 resource bao gồm:

  • Secret (lưu trữ giá trị RANDOM_ENV)
  • Deployment (Resource chạy ứng dụng python)
  • Service (dùng để expose dịch vụ ra ngoài để test)

Manifest Secret

apiVersion: v1
kind: Secret
metadata: name: random-env-secret
type: Opaque
data: RANDOM_ENV: "Zm9vCg==" # giá trị Zm9vCg== là mã hóa base64 của từ foo

Deployment manifest

apiVersion: apps/v1
kind: Deployment
metadata: name: flask-app
spec: replicas: 1 selector: matchLabels: app: flask-app template: metadata: labels: app: flask-app spec: containers: - name: flask-app image: nguyenhoangviet3/reloader-test:latest ports: - containerPort: 5000 env: - name: RANDOM_ENV valueFrom: secretKeyRef: # Định nghĩa lấy giá trị từ secret phía trên name: random-env-secret key: RANDOM_ENV volumeMounts: - name: secret-volume mountPath: /var/run/secrets/random-env-secret readOnly: true volumes: - name: secret-volume secret: secretName: random-env-secret

Service Manifest

apiVersion: v1
kind: Service
metadata: name: flask-app-service
spec: selector: app: flask-app ports: - protocol: TCP port: 5000 targetPort: 5000 type: NodePort

Khi tạo xong các resource trên ta có pod và service như trong hình.

image.png

5, Thử nghiệm thay đổi secret khi chưa có Reloader

Để thay đổi secret ta dùng câu lệnh sau để sửa trực tiếp secret đã tạo trước đó

kubectl edit secret random-env-secret

image.png

Ta se thay đổi phần giá trị trong mục data từ "Zm9vCg==" (foo) thành "YmFyCg==" (bar) và truy cập ứng dụng thông qua NodePort ở địa chỉ NodeIP:NodePort để xem có thay đổi không.

Trong môi trường của mình, địa chỉ để truy cập vào ứng dụng thông qua NodePort là http://192.168.49.2:32496/ với 192.168.49.2 là Node IP, 32496 là NodePort của service đã tạo.

Mặc dù đã thay đổi secret thành bar nhưng giá trị hiện thị bạn thấy sẽ vẫn là foo

image.png

6, Cài đặt Reloader và cấu hình reloader cho deployment

Phần cài đặt mình đã hướng dẫn bên trên, bạn lựa chọn cách cài đặt phù hợp nhé

Ngoài ra để kích hoạt tính năng tự động cập nhật khi có thay đổi secret hay configmap cho deployment/Statefulset/Deamonset/Rollout thì bạn cần thêm annotation cho resource đó. Cụ thể bạn sẽ cần thêm annoation sau cho deployment:

 annotations: reloader.stakater.com/auto: "true"

Bạn có thể edit trực tiếp deployment hoặc sử dụng câu lệnh sau để gắn annoation cho deployment

kubectl annotate deployment flask-app reloader.stakater.com/auto="true"

Đơn giản như vậy thôi là ta đã yêu cầu controller Reloader giám sát tự động thay đổi cấu hình cho deployment flask-app này.

7, Thử nghiệm thay đổi cấu hình khi đã cấu hình Reloader

Tương tự như bước 5, giờ ta sẽ thay đổi từ "bar" thành "foo-bar". Base64 của 'foo-bar' là "Zm9vLWJhcgo="

kubectl edit secret random-env-secret

Manifest secret sau khi thay đổi. Tiến hành lưu lại thay đổi.

image.png

Ta nhận thấy pod đã được tạo lại mới ngay sau khi secret được thay đổi:

image.png

Tiến hành get log của pod Reloader Controller ta cũng thấy sự kiện Controller bắt được sự thay đổi của secret

image.png

Và khi truy cập lại ứng dụng thông qua broswer, nội dung hiển thị cũng đã được tự động thay đổi thành foo-bar 😸😸😸

image.png

Như vậy ta đã thử nghiệm thành công việc tự động cập nhật ứng dụng khi có sự thay đổi về cấu hình nằm trong secret mà ứng dụng đang sử dụng.

Kết

Ngoài ra Reloader còn hỗ trợ bạn cấu hình theo dõi ứng dụng, cấu hình theo namespace, label,... Các bạn tìm hiểu và đọc thêm trên document ở Github nhé.

Hy vọng bài viết này đã giúp ích cho bạn một chút gì đó trong công việc. Nếu thấy bài viết hữu ích hãy UpvoteFollow mình để đọc thêm nhiều bài viết khác về chủ đề DevOps, SRE nữa nhé 😄 !!!

Have a nice day!

Bình luận

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

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

Deploying A Containerized Web Application On Kubernetes

1. Overview. Kubernetes is an open source project (available on kubernetes.io) which can run on many different environments, from laptops to high-availability multi-node clusters; from public clouds to on-premise deployments; from virtual machines to bare metal.

0 0 55

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

Kubernetes - Học cách sử dụng Kubernetes Namespace cơ bản

Namespace trong Kubernetes là gì. Tại sao nên sử dụng namespace.

0 0 113

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

[Kubernetes] Kubectl và các command cơ bản

Mở đầu. Kubectl là công cụ quản trị Kubernetes thông qua giao diện dòng lệnh, cho phép bạn thực thi các câu lệnh trong Kubernetes cluster.

0 0 59

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

Triển khai EFK Stack trên Kubernetes

EFK stack on K8S. Giới thiệu. Một hệ thống có thể chạy nhiều dịch vụ hoặc ứng dụng khác nhau, vì vậy việc. theo dõi hệ thống là vô cùng cần thiết.

0 0 72

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

Thực hành Kubernetes (K8S) bằng cách sử dụng lệnh Command

Bài hướng dẫn hôm nay sẽ hướng dẫn sử dụng K8S bằng cách sử dụng câu lệnh thay vì UI trên web. Có 2 lựa chọn để thực hiện:. . Sử dụng Cloud Shell.

0 0 56

- 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 49