การสร้างบัญชีผู้ใช้ใน Kubernetes Cluster


บทความนี้จะแนะนำเกี่ยวกับการสร้างบัญชีผู้ใช้สำหรับจัดการ Kubernetes Cluster เพื่อให้มีสิทธ์ใช้โปรแกรม kubectl, Kubernetes Dashboard, หรือโปรแกรมอื่น ๆ ในการจัดการคลัสเตอร์ได้ โดยจะประกอบไปด้วยขั้นตอนสำหรับผู้ใช้ใหม่ (user) 2 ขั้นตอน (U1-U2) และขั้นตอนสำหรับผู้ดูแลระบบ (administrator) 5 ขั้นตอน (A1-A5) ตามแผนภาพด้านล่าง

แผนภาพ Flow Diagram ขั้นตอนการสร้างบัญชีผู้ใช้ใน Kubernetes Cluster

U1. สร้างไฟล์ private key และ CSR และส่งไฟล์ CSR ให้ผู้ดูแลระบบ

ในขั้นตอนนี้ผู้ใช้จะสร้างไฟล์ private key และ Certificate Signing Request (CSR) ซึ่งไฟล์ที่ประกอบไปด้วยข้อมูลเกี่ยวกับผู้ใช้ (เช่น ชื่อ หน่วยงาน อีเมล ฯลฯ) และ public key โดยผู้ดูแลระบบจะใช้ข้อมูลจากไฟล์ CSR เพื่อออกใบรับรองสำหรับพิสูจน์ตัวตนของผู้ใช้ โดยในบริบทนี้ คือใบรับรองที่ใช้พิสูจน์ตัวตนว่าเป็นผู้ใช้ที่ได้รับอนุญาตให้เข้าถึง Kubernetes Cluster

การสร้างไฟล์ private key

การสร้างไฟล์ private key สามารถทำได้หลายวิธี บทความนี้จะยกตัวอย่างวิธีสร้างไฟล์ด้วยคำสั่งสำหรับโปรแกรม openssl

openssl genpkey -out john.key -algorithm Ed25519

เมื่อรันคำสั่งด้านบนแล้ว จะได้ไฟล์ private key ชื่อ john.key ขึ้นมา สำหรับใช้ในการสร้างไฟล์ CSR ต่อไป

การสร้างไฟล์ CSR

เมื่อมีไฟล์ private key แล้ว สามารถนำไปใช้ประกอบการสร้างไฟล์ CSR ได้โดยใช้คำสั่งด้านล่าง

openssl req -new -key john.key -out john.csr

หลังจากรันคำสั่ง จะพบแบบสอบถามให้กรอก รหัสประเทศ จังหวัด อำเภอ/แขวง ชื่อหน่วยงาน อีเมล ฯลฯ ให้ตอบเท่าที่จำเป็น โดยอย่างน้อยควรจะประกอบไปด้วย

  • Country: รหัสประเทศ เช่น TH
  • Organization: ชื่อหน่วยงาน
  • Common Name (CN): ชื่อ-นามสกุล (ภาษาอังกฤษ)

จากนั้นจึงส่งไฟล์ CSR ให้ผู้ดูแลระบบดำเนินการต่อไป เมื่อผู้ดูแลระบบดำเนินการแล้วเสร็จแล้ว ผู้ใช้จะได้รับไฟล์ใบรับรองอิเล็กทรอนิกส์ ใ้ห้ใช้ private key, certificate, และ root certificate ไปสร้าง kubeconfig

A1. สร้าง Role/ClusterRole

ขั้นตอนนี้ ผู้ดูแลระบบจะกำหนดบทบาทของผู้ใช้ขึ้นมา เช่น ผู้ดูแลคลัสเตอร์, ผู้ดูแล namespace, ผู้บำรุงรักษาระบบ, นักพัฒนา, ฯลฯ พร้อมกำหนดว่าแต่ละบทบาทมีสิทธิ์ทำอะไรได้บ้าง โดยกำหนดรายละเอียดเป็นไฟล์ YAML และใช้คำสั่ง kubectl apply เพื่อสร้าง Role/ClusterRole จากไฟล์ดังกล่าว ตัวอย่างไฟล์ YAML:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: maintainer
  namespace: system1 # Replace with your target namespace
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["delete", "get", "list", "patch", "update", "watch"]
  - apiGroups: [""]
    resources: ["pods/log", "services", "persistentvolumeclaims", "configmaps"]
    verbs: ["get", "list", "patch", "update", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "statefulsets"]
    verbs: ["get", "list", "patch", "update", "watch"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses"]
    verbs: ["get", "list", "patch", "update", "watch"]

จากไฟล์ด้านบน จะเห็นได้ว่ามีการกำหนดบทบาทผู้บำรุงรักษาระบบ maintainer ให้จัดการทรัพยากรที่อยู่ใน namespace ชื่อ system1 เท่านั้น โดยสามารถ:

  • ดำเนินการทุกอย่างกับ pods ได้ ยกเว้น การสร้าง (create) หรือลบทีละหลายรายการ (deletecollection)
  • แสดงรายละเอียด (get) แสดงรายการ (list) แก้ไขทีละหลายรายการ (patch) แก้ไข (update) และติดตาม (watch) pods/log (ข้อมูลจราจรคอมพิวเตอร์ของ pods), services, persistentvolumeclaims, configmaps, deployments.apps, statefulsets.apps, และ ingresses.networking.k8s.io ได้

โดยการจะทราบได้ว่าทรัพยากรใด อยู่ใน apiGroups ใด และมี verbs ใดให้ใช้บ้างนั้น สามารถใช้คำสั่ง kubectl api-resources -o wide ได้ ตัวอย่างเช่น หากใช้คำสั่ง kubectl api-resources -o wide | grep deployments จะเห็นผลลัพธ์ดังนี้

deployments deploy apps/v1 true Deployment [create delete deletecollection get list patch update watch]

ทำให้ทราบว่า deployments อยู่ใน apiGroups apps โดยมี verbs ให้เลือกใช้ ได้แก่ create, delete, deletecollection, get, list, patch, update, และ watch

ทั้งนี้ Role มีข้อแตกต่างจาก ClusterRole คือ Role จะต้องระบุ namespace และสามารถจัดการได้เฉพาะทรัพยากรที่อยู่ใน namespace นั้น ส่วน ClusterRole จะเป็นบทบาทที่สามารถจัดการทรัพยากรได้ทุก namespace ตามเงื่อนไขที่ได้ระบุไว้ใน rules

A2. สร้าง CertificateSigningRequest

เมื่อผู้ดูแลระบบได้รับไฟล์ CSR จากผู้ใช้ใหม่แล้ว ให้ตรวจสอบไฟล์ โดยอาจจะใช้คำสั่งต่อไปนี้

openssl x509 -req -in john.csr

หากเห็นว่าข้อความใน CSR เป็นไปตามข้อกำหนดแล้ว เข้ารหัสไฟล์ให้อยู่ในรูปแบบ Base64 โดยอาจจะใช้โปรแกรม Cat ร่วมกับ Base64 ดังนี้

cat john.csr | base64 -w0

จากนั้นจึงกำหนดรายละเอียดเป็นไฟล์ YAML ตามตัวอย่างด้านล่าง

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: john
spec:
  request: LS0tLS1CRUdJTiBD...
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 7776000 # 90 days
  usages:
  - client auth

โดยให้ระบุชื่อผู้ใช้ใน metadata.name คัดลอก CSR ในรูปแบบ Base64 ไปไว้ใน spec.request และกำหนดระยะเวลาก่อนที่ใบรับรองจะหมดอายุ จากนั้นจึงใช้คำสั่ง kubectl apply เพื่อสร้าง CertificateSigningRequest

A3. อนุมัติ CertificateSigningRequest

ผู้ดูแลระบบสามารถตรวจสอบรายการ CertificateSigningRequest ทั้งหมดได้โดยใช้คำสั่ง

kubectl get csr

หากต้องการอนุมัติรายการใด ให้ใช้คำสั่ง kubectl certificate approve เช่น

kubectl certificate approve john

โดยสามารถตรวจสอบผลการอนุมัติได้โดยใช้คำสั่ง เช่น kubectl describe csr/john

Name:         john
Labels:       <none>
Annotations:  ...
CreationTimestamp:   Tue, 19 Mar 2024 14:43:38 +0700
Requesting User:     system:admin
Signer:              kubernetes.io/kube-apiserver-client
Requested Duration:  90d
Status:              Approved,Issued
Subject:
         Common Name:    john
         Serial Number:
         Organization:   Internet Widgits Pty Ltd
         Country:        AU
         Province:       Some-State
Events:  <none>

จะเห็นได้ว่าสถานะ (status) ถูกเปลี่ยนจาก Pending เป็น Approved,Issued แสดงว่าได้รับการอนุมัติ และระบบได้ออกใบรับรองให้แล้ว

A4. สร้าง RoleBinding/ClusterRoleBinding

RoleBinding/ClusterRoleBinding เป็นการกำหนดว่าจะให้ผู้ใช้รายใดมีบทบาทอะไร โดยใช้คำสั่ง เช่น

kubectl -n system1 create rolebinding john-binding --role=maintainer --user=john

หรือกำหนดรายละเอียดเป็นไฟล์ YAML ตามตัวอย่างด้านล่าง และใช้คำสั่ง kubectl apply เพื่อสร้าง RoleBinding/ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: john-binding
  namespace: system1
subjects:
- kind: User
  name: john
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: maintainer

โดย RoleBinding จะใช้กับ Role ส่วน ClusterRoleBinding จะใช้กับ ClusterRole

A5. เตรียมไฟล์ certificate และ root certificate ส่งให้ผู้ใช้ใหม่

ผู้ดูแลระบบสามารถจัดเตรียม certificate โดยใช้คำสั่ง

kubectl get csr/john -o jsonpath="{.status.certificate}" | base64 -d > john.crt

และจัดเตรียม root certificate โดยใช้คำสั่ง

kubectl get configmap kube-root-ca.crt -o jsonpath='{.data.ca\.crt}' > kube-root-ca.crt

จะได้ไฟล์ john.crt และ kube-root-ca.crt เพื่อจัดส่งให้ผู้ใช้นำไปสร้าง kubeconfig ต่อไป

นอกจาก 2 ไฟล์ข้างต้นแล้ว มีข้อมูลที่ผู้ดูแลระบบต้องแจ้งให้ผู้ใช้ใหม่ทราบด้วย คือ URL ของ Kubernetes control plane โดยสามารถใช้คำสั่ง kubectl cluster-info เพื่อตรวจสอบได้ ตัวอย่างผลลัพธ์:

Kubernetes control plane is running at https://192.168.0.200:6443
CoreDNS is running at https://192.168.0.200:6443/api/v1/namespaces/kube-system/services/rke2-coredns-rke2-coredns:udp-53/proxy

จากตัวอย่างผลลัพธ์ จะเห็นได้ว่า URL ของ Kubernetes control plane คือ https://192.168.0.200:6443 ทั้งนี้ แต่ละคลัสเตอร์จะมี URL แตกต่างกันออกไป

U2. ใช้ private key, certificate, และ root certificate สร้าง kubeconfig

หลังจากที่สร้าง private key และจัดส่ง CSR ให้ผู้ดูแลระบบแล้ว จะได้รับไฟล์ certificate, และ root certificate กลับมา ผู้ใช้จะต้องใช้ private key, certificate, root certificate, และ URL ของ Kubernetes control plane ในการสร้าง kubeconfig โดยจะประกอบไปด้วย 3 ขั้นตอนย่อย ได้แก่ การเพิ่ม cluster, การเพิ่ม user, และการเพิ่ม context

การเพิ่ม cluster

ใช้ URL ของ Kubernetes control plane และไฟล์ root certificate เพื่อเพิ่ม cluster โดยใช้คำสั่งต่อไปนี้

kubectl config set-cluster cluster1 --server=https://192.168.0.200:6443 --embed-certs --certificate-authority=kube-root-ca.crt

ทั้งนี้ ให้เปลี่ยน https://192.168.0.200:6443 เป็น URL ที่ได้รับแจ้งจากผู้ดูแลระบบ

การเพิ่ม user

ใช้ private key และ certificate เพื่อเพิ่ม user โดยใช้คำสั่งต่อไปนี้

kubectl config set-credentials john --client-key=john.key --client-certificate=john.crt --embed-certs=true

การเพิ่ม context

kubectl config set-context john@cluster1 --cluster=cluster1 --user=john --namespace=system1

เมื่อดำเนินการแล้วเสร็จ สามารถเปลี่ยนไปใช้ context ใหม่ได้โดยใช้คำสั่ง kubectl config use-context เช่น

kubectl config use-context john@cluster1

อ้างอิง

  • https://kubernetes.io/docs/reference/access-authn-authz/rbac/
  • https://aungzanbaw.medium.com/a-step-by-step-guide-to-creating-users-in-kubernetes-6a5a2cfd8c71

แสดงความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *