Giới Thiệu Về Custom Resources trong Kubernetes
Kubernetes là một nền tảng nổi bật cho việc triển khai và quản lý container. Một vấn đề thường gặp trong Kubernetes là việc quản lý các ConfigMap cho nhiều Deployment. Trong bài viết này, chúng ta sẽ cùng tìm hiểu về cách sử dụng Custom Resources và Custom Resource Definitions (CRD) để tự động hóa quy trình này.
Tình Huống Thực Tế
Giả sử bạn có khoảng 10 Deployment, mỗi Deployment gắn liền với một ConfigMap. Khi chúng ta thay đổi giá trị trong ConfigMap, các Pods trong Deployment cần phải được khởi động lại để áp dụng giá trị mới. Với một số lượng ít các Deployment, chúng ta có thể thực hiện thủ công. Tuy nhiên, khi số lượng Deployment và ConfigMap tăng lên, việc này trở nên khó khăn.
Để giải quyết vấn đề này, chúng ta có thể tạo ra một Custom Resource giúp tự động theo dõi những thay đổi trong ConfigMap và khởi động lại các Pods tự động.
Custom Resource là gì?
Theo tài liệu từ Kubernetes, Custom Resource là một phần mở rộng của Kubernetes API. Nó cho phép người quản trị định nghĩa và quản lý các loại tài nguyên mới mà không có sẵn trong mặc định Kubernetes. Thông qua Custom Resource, Kubernetes có thể được mở rộng và tùy chỉnh theo nhu cầu cụ thể của ứng dụng hoặc hệ thống.
Các Bước Tạo Custom Resource
Bước 1: Tạo một ConfigMap đơn giản
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
namespace: default
data:
app-config: "Hello, this is version 1"
Bước 2: Tạo một Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
namespace: default
spec:
replicas: 20
selector:
matchLabels:
app: app-configmap
template:
metadata:
labels:
app: app-configmap
spec:
containers:
- name: app-container
image: nginx:latest
volumeMounts:
- name: config-volume
mountPath: /usr/share/nginx/html/index.html
subPath: app-config
volumes:
- name: config-volume
configMap:
name: my-configmap
Mục tiêu là gán giá trị trong ConfigMap my-configmap
vào /usr/share/nginx/html/index.html
bên trong Pod. Sau khi triển khai, bạn có thể kiểm tra nội dung trong file index.html
.
Bước 3: Tạo CustomResourceDefinition (CRD)
yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: configmaprestarters.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
configMapName:
type: string
namespace:
type: string
scope: Namespaced
names:
plural: configmaprestarters
singular: configmaprestarter
kind: ConfigMapRestarter
shortNames:
- cmr
Bước 4: Tạo Custom Resource
yaml
apiVersion: example.com/v1
kind: ConfigMapRestarter
metadata:
name: restart-pod-on-config-change
namespace: default
spec:
configMapName: my-configmap
namespace: default
Bước 5: Viết Script Theo Dõi Thay Đổi ConfigMap
Chúng ta sẽ sử dụng Python để viết script theo dõi sự thay đổi của ConfigMap. Dưới đây là ví dụ về đoạn mã:
python
from kubernetes import client, config, watch
config.load_incluster_config()
v1 = client.CoreV1Api()
namespace = "default"
configmap_name = "my-configmap"
def restart_pods(namespace, configmap_name):
print(f"Restarting pods that use ConfigMap: {configmap_name}")
pods = v1.list_namespaced_pod(namespace)
for pod in pods.items:
for volume in pod.spec.volumes:
if volume.config_map and volume.config_map.name == configmap_name:
print(f"Deleting pod: {pod.metadata.name}")
v1.delete_namespaced_pod(pod.metadata.name, namespace)
def watch_configmap(namespace, configmap_name):
w = watch.Watch()
for event in w.stream(v1.list_namespaced_config_map, namespace=namespace):
cm = event['object']
if cm.metadata.name == configmap_name:
print(f"ConfigMap {configmap_name} has changed. Event: {event['type']}")
restart_pods(namespace, configmap_name)
if __name__ == "__main__":
print(f"Watching ConfigMap: {configmap_name} in namespace: {namespace}")
watch_configmap(namespace, configmap_name)
Sau đó, chúng ta cần tạo một Deployment cho script này và cấp quyền cần thiết để nó có thể tương tác với Pods và ConfigMaps.
Bước 6: Tạo ServiceAccount và RBAC
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: restart-controller-sa
namespace: default
Tạo Role và RoleBinding để cấp quyền cho ServiceAccount:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: restart-controller-role
namespace: default
rules:
- apiGroups: [""]
resources: ["pods", "configmaps"]
verbs: ["get", "list", "watch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: restart-controller-rolebinding
namespace: default
subjects:
- kind: ServiceAccount
name: restart-controller-sa
namespace: default
roleRef:
kind: Role
name: restart-controller-role
apiGroup: rbac.authorization.k8s.io
Sau khi apply các tài nguyên này, hãy tạo Deployment cho Controller:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: restart-controller
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: restart-controller
template:
metadata:
labels:
app: restart-controller
spec:
serviceAccountName: restart-controller-sa
containers:
- name: restart-controller
image: kiettran164/crds:cm-controller-v2
imagePullPolicy: IfNotPresent
Kết Quả
Khi bạn thay đổi ConfigMap, Controller sẽ tự động phát hiện và xóa các Pods sử dụng ConfigMap đó để chúng được khởi động lại với cấu hình mới. Điều này giúp chúng ta tiết kiệm thời gian và công sức, đặc biệt là khi làm việc với nhiều Deployment.
Hy vọng bài viết này đã giúp bạn hiểu rõ hơn về cách sử dụng Custom Resource trong Kubernetes để quản lý ConfigMaps. Chúc bạn thành công trong việc áp dụng kiến thức này vào thực tế!
source: viblo