Thứ Sáu, 4 tháng 11, 2022

Sử dụng Kustomize

 

P1. Kustomize là gì?

Helm hỗ trợ chỉnh sửa nâng cao từng vị trí của yaml trên 1 môi trường nhất địnhKustomize lại có điểm mạnh là hỗ trợ nhiều môi trường (prod, stag, dev1, dev2.....) qua việc dùng overlays. (Ngoài ra, ta vẫn có thể kết hợp kustomize và helm cùng nhau)

  1. Cài đặt
# curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
# mv kustomize /usr/local/bin/

#----Thêm bash-completion cho kustomize----
# yum install bash-completion
# kustomize completion bash > /etc/bash_completion.d/kustomize
> thoát phiên ssh và vào lại.
  1. Cấu trúc thư mục của Kustomize

  1. Hướng dẫn tạo kustomization.yaml
# mkdir -p 01.resouce/base
# cd 01.resouce/base
# kustomize init  #(Lệnh này sẽ tạo ra file kustomization.yaml mặc định)

# cat kustomization.yaml 
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

YAML mẫu toàn bộ bài viết, các bạn có thể tham khảo ở đây https://github.com/worldhello12/kustomize-sample

P2: Resources

Khái niệm: Resources gồm 1 hoặc nhiều file .yaml k8s > Là đầu vào input cho kustomize xào nấu.

Ví dụ về sử dụng Resources 

  1. Sửa file kustomization.yaml vừa init
# vim kustomization.yaml 
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - api-depl.yaml
  - api-service.yaml
  1. Chuẩn bị deployment và service mẫu: api-depl.yaml và api-service.yaml
# cd 01.resouce/base
# kubectl create deployment nginx-api --image=nginx:alpine --replicas=3 --dry-run=client -o yaml > api-depl.yaml

# vim api-service.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx-api
  name: nginx-api
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30181
  selector:
    app: nginx-api
  type: NodePort
status:
  loadBalancer: {}
  1. Chạy Test build Kustomize
# kustomize build .
> Kết quả ta có yaml final để chạy k8s

# kustomize build .  | kubectl apply -f -
service/nginx-api created
deployment.apps/nginx-api created

# kustomize build .  | kubectl delete -f -

P3: Transformer common

(tham khảo: https://github.com/kubernetes-sigs/kustomize/tree/master/examples/transformerconfigs)

Kustomize hỗ trợ transformer chuyển đổi những loại dưới đây:

- Sửa  (images)
- Thêm (annotations)
- Thêm (labels)
- Thêm (namespace)
- Thêm (prefix/suffix) (đầu/cuối)

Ta đi vào ví dụ về transformer:

Bước 1. Chuẩn bị deployment và service mẫu (api-depl.yaml và api-service.yaml)

# mkdir -p 02.transformer/base
# cd 02.transformer/base
# kubectl create deployment web-frontend --image=httpd:alpine --replicas=3 --dry-run=client -o yaml > api-depl.yaml


# vim api-service.yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx-api
  name: nginx-api
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30181
  selector:
    app: nginx-api
  type: NodePort
status:
  loadBalancer: {}

Bước 2. Sửa kustomization.yaml

[tuanda@master-node ]$ kustomize init
[tuanda@master-node ]$  tree
├── api-depl.yaml
├── api-service.yaml
└── kustomization.yaml

# vim kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - api-depl.yaml
  - api-service.yaml

# Gán transformer namespace cho toàn bộ .yaml
namespace: tuanda

# Đổi transformer image và tag trong deployment nếu trùng "name"
images:
  - name: httpd
    newName: nginx
    newTag: 1.21.0

#transformer Đặt tên đầu và cuối cho .yaml. 
#VD: xxx thành LAB-xxx-dev
namePrefix: LAB-
nameSuffix: -dev

#Thêm Annotations
commonAnnotations:
  branch: master

#Thêm Labels vào toàn bộ yaml
commonLabels:
  someName: someValue
  owner: tuanda
  app: bingo

Kết quả:

# kustomize build .

P3: Overlays-base

Khái niệm: Để phân tách các tham số theo từng môi trường (prod/stag/dev). Ta có thể sử dụng overlays của kustomize.

Trong đó những tham số chung sẽ đặt trong thư mục "base", những cấu hình riêng của từng môi trường (như số replicas, secret-configmap) sẽ đặt trong thư mục "overlays"

1. Tạo cây thư mục cơ bản

# cd kustomize-sample
# mkdir -p 03.overlays/overlays   #(thư mục base đã được tạo ở ví dụ 1)
# mkdir -p 03.overlays/overlays/prod
# mkdir -p 03.overlays/overlays/stag
# mkdir -p 03.overlays/overlays/dev

2. Sửa kustomization.yaml trong cả 3 thư mục con của overlays (prod/stag/dev) với nội dung như sau

# cp -rp kustomize-sample/02.transformer/base kustomize-sample/03.overlays/  #(mượn tạm thư mục base của phần 2, hoặc bạn tự tạo lại bằng kubecli)
# vim kustomize-sample/03.overlays/overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

nameSuffix: -prod #(chú ý đổi Suffix trong cả 3 file)

bases:
  - ../../base
  
resources:
  - config-map.yaml #(mỗi 1 môi trường sẽ có config-map.yaml riêng)

3. Tạo config-map.yaml ứng với từng môi trường

# vim kustomize-sample/03.overlays/overlays/prod/config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: database-cfg
data:
  password: prod-pwd-123
  username: prod-acc-123

# vim kustomize-sample/03.overlays/overlays/stag/config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: database-cfg
data:
  password: stag-pwd-123
  username: stag-acc-123

# vim kustomize-sample/03.overlays/overlays/dev/config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: database-cfg
data:
  password: dev-pwd-123
  username: dev-acc-123

4. Chạy kustomize kiểm tra khai báo BASE đã đúng chưa

# cd kustomize-sample/03.overlays/overlays/prod
kustomize build .

# cd kustomize-sample/03.overlays/overlays/stag
kustomize build .

# cd kustomize-sample/03.overlays/overlays/dev
kustomize build .

Kết quả: Mỗi môi trường ta đều deploy api-depl.yaml và api-service.yaml, nhưng config-map.yaml tài khoản và mật khẩu sẽ khác nhau từng môi trường

P4: Patches

(Tham khảo:)

Jsonpath6902: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/jsonpatch.md

Strategic merge: https://fabianlee.org/2022/04/18/kubernetes-kustomize-transformations-with-patchesstrategicmerge/

Patches có 3 chức năng chỉnh sửa vào yaml k8s: replace, delete, add

Ví dụ 1: Replace patch

Đề bài đặt ra:

- Prod tôi muốn sửa 10 pod cho nginx
- Stag tôi muốn sửa 9 pod cho nginx
- Dev tôi muốn sửa 8 pod cho nginx, thay image nginx:alpine thành httpd:alpine

Bài giải: Có 2 cách là dùng Json6092 hoặc Strategic Merge Patch

Cách giải 1: Json6902 patch


# vim kustomize-sample/04.patches/vd1-replace/json6902/overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

nameSuffix: -prod #(chú ý đổi Suffix trong cả 3 file)

bases:
  - ../../base
  
resources:
  - config-map.yaml

#patch json6902 demo replace
patches:
  - target:
      kind: Deployment
      name: nginx-api
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 10
--------------------------
# # vim kustomize-sample/04.patches/vd1-replace/json6902/overlays/stag/kustomization.yaml
> tương tự như prod trên, sửa value 10 thành 9
--------------------------
# vim kustomize-sample/04.patches/vd1-replace/json6902/overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

nameSuffix: -dev

bases:
  - ../../base
  
resources:
  - config-map.yaml

#demo patches json6902 replace dev
patches:
  - target:
      kind: Deployment
      name: nginx-api
    patch: |-
      - op: replace
        path: /spec/replicas
        value: 8
        
  - target:
      kind: Deployment
      name: nginx-api        
    patch: |-
      - op: replace
        path: /spec/template/spec/containers/0
        value:
          name: newnametest
          image: httpd:alpine

Kết quả:

> các kết quả ở stag, dev các bạn tự chạy (kustomize build .) nhé.

Cách giải 2: Strategic merge patch

# vim kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

nameSuffix: -prod #(chú ý đổi Suffix trong cả 3 file)

bases:
  - ../../base
  
resources:
  - config-map.yaml


#patch strategic-merge demo replace
patches:
  - patch: |-
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        creationTimestamp: null
        labels:
          app: nginx-api
        name: nginx-api
      spec:
        replicas: 10

(ta có 1 cách khác là load từ file path/api-depl.yaml, bạn có thể tham khảo thư mục stag trên git của tôi)  
--------------------------
# kustomize build .

Kết quả

Ta có thể áp dụng kustomize patches để thay thế bất kì tham số nào ta muốn: vd trong services chuyển type NodePort/ClusterIP/Balance theo từng môi trường

Ví dụ 2: Add patch

#VD2----JSON6902 add----#
#demo patches json6902 add
patches:
  #Patch add logstash service mesh
  - target:
      kind: Deployment
      name: nginx-api        
    patch: |-
      - op: add
        path: /spec/template/spec/containers/-
        value:
          name: logstash-mesh
          image: logstash:latest
#VD2----Strategic Merge add----#
#patch strategic-merge demo add
patches:
  - patch/api-depl.yaml
  
# vim patch/api-depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-api
spec:
  template:
    spec:
      containers:
      - image: nginx:alpine
        name: nginx
      - image: logstash:latest
        name: logstash-mesh

Kết quả chung cả 2 cách:

Ví dụ 3: Delete patch

#----JSON6902 remove----#
#demo patches json6902 delete creationTimestamp
patches:
  - target:
      kind: Deployment
      name: nginx-api        
    patch: |-
      - op: remove
        path: /spec/template/metadata
        value:
          - creationTimestamp
#----Strategic Merge remove----#
#patch strategic-merge demo replace
patches:
  - patch/api-depl.yaml
  
# vim patch/api-depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-api
spec:
  template:
    spec:
      containers:
        - $patch: delete
          name: tomcat

P6: Component

(Tham khảo: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/components.md)

Mục đích của Component sinh ra là tái sử dụng các thành phần cần dùng lại cho từng môi trường. VD ta có bảng sau

OverlaysExternal-DB historyCache
prodYesYes
stagNoYes
devOptionOption

Như bảng trên.

  • Prod cần DB phụ để lưu trữ data lịch sử người dùng, và cache để tăng load dữ liệu từ ram
  • Stag không cần DB lưu lượng lớn dữ liệu lịch sử, cần cache để test hiệu năng
  • Dev có thể add thêm DB và Cache nếu cần test, hoặc ko có cũng đc. Ta sẽ thiết kế component file như sau:

Sửa file kustomization.yaml theo từng môi trường. (Yaml mẫu: https://github.com/worldhello12/kustomize-sample/tree/main/05.component )

# vim prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
  - ../../base

components:
  - ../../components/external_db
  - ../../components/cache

File components/external_db/kustomization.yaml. Ta chú ý kind, apiVersion sẽ là Component

# vi components/external_db/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component

resources: 
  - external_db_cfg.yaml
  - external_db_depl.yaml

Chạy kustomize build trên cả 3 môi trường , ta sẽ có kết quả như bảng.

OverlaysExternal-DB historyCache
prodYesYes
stagNoYes
devOptionOption

.

Bài viết trong phạm vi kiến thức của người soạn, nếu bạn có cách giải hay hơn xin giới thiệu, góp ý. cảm ơn.

Ứng cứu khi chown -R user1:user1 /etc

1. Bài toán Gõ nhầm: chown -R user1:user1 /etc 2. Giải: Cách 1: Tìm bản backup /etc cũ (tỉ lệ phục hồi gần như ~100%) Cách 2: Tìm tạm 1 thư ...