เพราะกุญแจและความลับของคุณควรเป็นความลับนั้น
สวัสดีและยินดีต้อนรับ หยาบคาย เรากำลังเดินทางต่อใน "Kubernetes in a Nutshell" ต่อไป ในบล็อกก่อนหน้านี้ เราเห็นวิธี "กำหนดค่าแอป Kubernetes" โดยใช้ ConfigMap
object ในโพสต์นี้ เราจะสำรวจ Kubernetes Secrets
และวิธีที่สามารถใช้เพื่อจัดเก็บข้อมูลการกำหนดค่าที่ละเอียดอ่อนซึ่งจำเป็นต้องได้รับการจัดการอย่างปลอดภัย (เช่น ข้อมูลรับรองฐานข้อมูล คีย์ API ฯลฯ)
ตามปกติ สิ่งนี้จะเป็นการขับเคลื่อนด้วยตัวอย่าง และคุณจะได้เรียนรู้:
- วิธีสร้าง
Secrets
(CLI,yaml
ฯลฯ) และ - วิธีการใช้งานต่างๆ ในแอปของคุณ (ตัวแปร env, วอลุ่ม ฯลฯ)
รหัส (และ YAML
) มีให้ใช้งาน บน GitHub
งานชิ้นนี้แบ่งออกเป็นสองส่วนเชิงตรรกะ: วิธีสร้าง Secrets
และเทคนิคในการใช้ Secrets
ในแอปพลิเคชันของคุณ
ข้อกำหนดเบื้องต้น
หากต้องการดูตัวอย่างในโพสต์นี้ สิ่งที่คุณต้องมีคือคลัสเตอร์ Minikube และเครื่องมือ kubectl CLI เพื่อเข้าถึงคลัสเตอร์
ติดตั้ง "Minikube" เป็นคลัสเตอร์ Kubernetes โหนดเดียวในเครื่องเสมือนบนคอมพิวเตอร์ของคุณ บน Mac คุณสามารถ:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \ && chmod +x minikube
sudo mv minikube /usr/local/bin
ติดตั้ง kubectl เพื่อโต้ตอบกับคลัสเตอร์ Minikube บน Mac คุณสามารถ:
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
การสร้างความลับ
มาดูเทคนิคที่คุณสามารถสร้าง Secret
กัน
ใช้ส่วน data
คุณสามารถสร้าง Secret
พร้อมกับข้อมูลการกำหนดค่าที่จัดเก็บเป็นคู่คีย์-ค่าในส่วน data
ของคำจำกัดความได้
apiVersion: v1
kind: Secret
metadata:
name: service-apikey
data:
apikey: Zm9vYmFy
Secret
ประกอบด้วยข้อมูลคีย์-ค่าที่แสดงถึงข้อมูลที่ละเอียดอ่อน โดยที่ apikey
เป็นคีย์ และค่าเป็นสตริงที่เข้ารหัส base64
หากต้องการสร้าง Secret
นี้ใน Kubernetes:
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-data.yaml
เพื่อให้ทุกอย่างง่ายขึ้น ไฟล์ YAML จะถูกอ้างอิงโดยตรงจาก GitHub repo แต่คุณยังสามารถดาวน์โหลดไฟล์ลงในเครื่องของคุณและใช้งานในลักษณะเดียวกันได้
เพื่อยืนยันว่า Secret
ถูกสร้างขึ้น:
kubectl get secret/service-apikey -o yaml
คุณจะได้รับคำตอบ YAML คล้ายกับ:
apiVersion: v1
data:
apikey: Zm9vYmFy
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"apikey":"Zm9vYmFy"},"kind":"Secret","metadata":{"annotations":{},"name":"service-apikey","namespace":"default"}}
creationTimestamp: "2019-12-17T11:11:27Z"
name: service-apikey
namespace: default
resourceVersion: "113009"
selfLink: /api/v1/namespaces/default/secrets/service-apikey
uid: 671b547c-3316-4916-b6dc-be2b551b974e
type: Opaque
การดึงรายละเอียด Secret
โดยใช้ kubectl get จะไม่เปิดเผยเนื้อหา
โปรดสังเกตว่า apikey: Zm9vYmFy
คือสิ่งที่เราระบุไว้ในรายการ YAML คุณสามารถตรวจสอบรูปแบบข้อความธรรมดาได้โดยการถอดรหัส:
echo 'Zm9vYmFy' | base64 --decode
//foobar
ใช้ส่วน stringData
คุณลักษณะ data
ที่ใช้ในตัวอย่างข้างต้นใช้เพื่อบันทึกข้อมูลที่เข้ารหัส base64
หากคุณต้องการจัดเก็บข้อมูลข้อความธรรมดาอย่างปลอดภัย คุณสามารถใช้ส่วน stringData
นี่คือตัวอย่าง:
apiVersion: v1
kind: Secret
metadata:
name: plaintext-secret
stringData:
foo: bar
mac: cheese
ค่าสำหรับ foo
และ mac
ถูกส่งผ่านเป็นข้อความธรรมดา สร้าง Secret
นี้และยืนยัน:
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-plaintext.yaml
kubectl get secret/plaintext-secret -o yaml
นี่คือส่วน data
ของการตอบกลับ YAML ข้อมูลจริงจะถูกจัดเก็บในรูปแบบที่เข้ารหัส base64
data:
foo: YmFy
หากคุณถอดรหัสข้อมูล คุณสามารถยืนยันได้ว่าข้อมูลตรงกับอินพุตข้อความธรรมดาต้นฉบับ (bar
) ที่เราให้ไว้
echo 'YmFy' | base64 --decode
//bar
โปรดทราบว่าส่วนdata
ไม่ยอมรับแอตทริบิวต์ข้อความธรรมดา การพยายามทำเช่นนั้นจะส่งผลให้เกิดข้อผิดพลาดคล้ายกับสิ่งนี้:illegal base64 data at input byte 8
เนื้อหาไฟล์
คุณสามารถระบุเนื้อหาของไฟล์ทั้งหมดเป็นอินพุตในส่วน stringData
ได้เช่นกัน นี่คือสิ่งที่อาจมีลักษณะเช่นนี้:
apiVersion: v1
kind: Secret
metadata:
name: secret-in-a-file
stringData:
app-config.yaml: |-
hello: world
john: doe
สร้างสิ่งนี้ Secret
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/secret-file.yaml
ผลลัพธ์ Secret
นี้จะมีคีย์ชื่อ app-config.yaml
และเนื้อหา (ค่า) ของคีย์นั้นจะเป็นการเข้ารหัส base64
ของข้อมูลที่ให้ไว้
ตามปกติ คุณจะยืนยันสิ่งนี้ใน Kubernetes รวมถึงถอดรหัสเนื้อหาด้วย
kubectl get secret/secret-in-a-file -o yaml
echo '<"data" content in yaml response> | base64 --decode
หมายเหตุ: เมื่อคุณใช้เทคนิคนี้ แอปพลิเคชันของคุณมีหน้าที่แยกวิเคราะห์ข้อมูลที่แสดงถึงการกำหนดค่า Secret
ในกรณีนี้ เป็นคู่คีย์-ค่าที่คั่นด้วยการขึ้นบรรทัดใหม่ แต่อาจเป็นอย่างอื่นก็ได้
ใช้ kubectl
คุณสามารถใช้คำสั่ง kubectl create secret
เพื่อสร้างวัตถุ Secret
ใช้ --from-literal
คุณสามารถใช้ข้อมูลข้อความธรรมดาเพื่อสร้าง Secret
โดยใช้ CLI (ซึ่งจะถูกจัดเก็บในรูปแบบที่เข้ารหัส base64
ใน Kubernetes):
kubectl create secret generic redis-credentials --from-literal=user=poweruser --from-literal=password='f0ob@r'
การใช้ --from-file
kubectl create secret generic topsecret --from-file=api_keys.txt
ซึ่งจะสร้างความลับ (topsecret
) ด้วย
- คีย์ที่มีชื่อเดียวกันกับไฟล์ เช่น
api_keys.txt
ในกรณีนี้ - และค่าเป็นเนื้อหาของไฟล์
จากไฟล์ในไดเร็กทอรี
คุณสามารถชี้ไปที่ไดเร็กทอรีและไฟล์ทั้งหมดภายในจะถูกนำมาใช้เพื่อสร้าง Secret
kubectl create secret generic topsecrets --from-file=/home/credentials/
คุณจะจบลงด้วยการ
- หลายคีย์ซึ่งจะเหมือนกันกับชื่อไฟล์แต่ละไฟล์
- ค่าจะเป็นเนื้อหาของไฟล์ที่เกี่ยวข้อง
การใช้ความลับ
เพื่อให้ข้อมูลลับมีประโยชน์ เราต้องแน่ใจว่าข้อมูลเหล่านั้นพร้อมใช้งานในแอปพลิเคชันของเรา (เช่น พ็อด) เรามาสำรวจวิธีที่เราสามารถทำได้กันดีกว่า
ตัวแปรสภาพแวดล้อม
คุณสามารถใช้ข้อมูล Secret
เป็นตัวแปรสภาพแวดล้อมใน Pod
(เช่นเดียวกับ ConfigMap
) นี่คือตัวอย่าง:
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: nginx
image: nginx
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: service-apikey
key: apikey
เราใช้คีย์ apikey
จาก Secret
service-apikey
และตรวจสอบให้แน่ใจว่าค่าของคีย์นั้นพร้อมใช้งานเป็นตัวแปรสภาพแวดล้อม API_KEY
ภายใน Pod
สร้าง Pod
(สมมติว่าคุณมี Secret
ที่สร้างจากตัวอย่างก่อนหน้านี้) และยืนยัน
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-env.yaml
kubectl get pods -w
รอให้ Pod
เปลี่ยนเป็นสถานะ Running
จากนั้นยืนยันว่าได้แทรกตัวแปรสภาพแวดล้อมลงใน Pod
แล้ว
kubectl exec pod1 -- env | grep API_KEY
คุณควรได้รับการตอบกลับนี้ — API_KEY=foobar
แทนที่จะอ้างอิงถึงแต่ละรายการใน Secret
คุณสามารถใช้ envFrom
เพื่อใช้รายการทั้งหมดเป็นตัวแปรสภาพแวดล้อมใน Pod
ได้อย่างสะดวก นี่คือวิธีที่คุณอาจใช้สิ่งนี้:
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
containers:
- name: nginx
image: nginx
envFrom:
- secretRef:
name: plaintext-secret
เรากำลังหมายถึง plaintext-secret
Secret
using envFrom.secretRef
หากต้องการสร้าง Pod
นี้:
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-envFrom.yaml
kubectl get pods -w
รอให้ Pod
เปลี่ยนเป็นสถานะ Running
จากนั้นยืนยันการมีอยู่ของตัวแปรสภาพแวดล้อม
kubectl exec pod2 -- env | grep foo //foo=bar
kubectl exec pod2 -- env | grep mac //mac=cheese
นี่เป็นการยืนยันว่าทั้ง foo
และ mac
ถูกเพิ่มเป็นตัวแปรสภาพแวดล้อมใน the
Pod พร้อมกับค่าที่ถอดรหัสแล้ว เช่น bar
และ cheese
ตามลำดับ
ปริมาณ
คุณสามารถต่อเชื่อม Secrets
เป็น Volume
ภายใน Pod
ได้ ตัวอย่างเช่น:
apiVersion: v1
kind: Pod
metadata:
name: pod3
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: apikey-config-volume
mountPath: /secret
readOnly: true
volumes:
- name: apikey-config-volume
secret:
secretName: service-apikey
ปริมาณ apikey-config-volume
หมายถึง service-apikey
Secret
หากต้องการสร้าง Pod
นี้:
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-volume.yaml
kubectl get pods -w
รอให้ Pod
เปลี่ยนเป็นสถานะ Running
จากนั้นดำเนินการคำสั่งต่อไปนี้:
kubectl exec pod3 -- cat /secret/apikey
//foobar
นี่เป็นการยืนยันว่าคีย์ apikey
ในความลับ service-apikey
ถูกเมาท์เป็นไฟล์ (ชื่อ apikey
) ในไดเร็กทอรี /secret
(ตามที่ระบุใน Pod) เนื้อหาของไฟล์ไม่มีอะไรนอกจากค่าลับ เช่น foobar
ในกรณีนี้
การใช้ imagePullSecrets
มีวิธีใช้ Secrets
เพื่อให้แอปพลิเคชัน Pod ของคุณสามารถใช้เพื่อตรวจสอบสิทธิ์และดึงอิมเมจ Docker จากรีจิสทรี Docker ส่วนตัว
จริงๆ แล้ว Secrets
มีสามประเภท:
generic
- ใช้เพื่อจัดเก็บคู่คีย์-ค่า ดังที่เราได้เห็นในตัวอย่างแล้วtls
- เก็บข้อมูลคู่คีย์ public.private เป็นSecrets
docker-registry
- ข้อมูลรับรองสำหรับการรับรองความถูกต้องของรีจิสทรี Docker
วิธีการใช้เทคนิคนี้ง่ายมาก:
- ใช้ประเภท
docker-registry
Secret
เพื่อจัดเก็บข้อมูลรับรองรีจิสทรี Docker ส่วนตัวใน Kubernetes - จากนั้น
imagePullSecrets
(ในพ็อด) เพื่ออ้างอิงSecret
ที่มีข้อมูลรับรองรีจิสทรีนักเทียบท่า
ตัวอย่างจะช่วยได้เสมอ:
apiVersion: v1
kind: Pod
metadata:
name: pod4
spec:
containers:
- name: privateapp
image: abhirockzz/test-private-repo:latest
command: ["/bin/sh"]
args: ["-c", "while true; do date; sleep 5;done"]
imagePullSecrets:
- name: docker-repo-secret
ดูว่า imagePullSecrets.name
อ้างถึง Secret
ที่เรียกว่า docker-repo-secret
อย่างไร มาสร้างมันกันเถอะ
แต่ก่อนหน้านั้น โปรดตรวจสอบให้แน่ใจว่าคุณมีรีจิสทรี Docker ส่วนตัว ฉันใช้ DockerHub
แต่คุณสามารถเลือกอันอื่นได้
เริ่มต้นด้วยการสร้าง Secret
(ด้วยชื่อ docker-repo-secret
) ซึ่งมีข้อมูลประจำตัวนักเทียบท่าของคุณโดยใช้ kubectl create secret docker-registry
command
kubectl create secret docker-registry docker-repo-secret --docker-server=DOCKER_REG_SERVER --docker-username=DOCKER_REG_USERNAME --docker-password=DOCKER_REG_PASSWORD --docker-email=DOCKER_REG_EMAIL
สำหรับนักเทียบท่าฮับ:
kubectl create secret docker-registry docker-repo-secret --docker-server=https://index.docker.io/v1/ --docker-username=foobarbaz --docker-password=t0ps3cr3t [email protected]
kubectl get secret/docker-repo-secret -o yaml
https://index.docker.io/v1/
คือเซิร์ฟเวอร์รีจิสทรี Docker Hub
เพื่อทดสอบสิ่งต่างๆ เราจะใช้รูปภาพ busybox
และ tag
it
docker pull busybox docker tag busybox [DOCKER_REG]/[DOCKER_PRIVATE_REPO]:[IMAGE_TAG]
e.g. docker tag busybox abhirockzz/test-private-repo:latest
… และ push
มัน
docker push [DOCKER_REG]/[DOCKER_PRIVATE_REPO]:[IMAGE_TAG]
e.g. docker push abhirockzz/test-private-repo:latest
เมื่อ repo ส่วนตัวพร้อมแล้ว คุณสามารถสร้าง Pod
ซึ่งจะดึงอิมเมจจาก repo ส่วนตัวโดยใช้ข้อมูลรับรองรีจิสทรีที่มอบให้ผ่านทาง Secret
kubectl apply -f https://raw.githubusercontent.com/abhirockzz/kubernetes-in-a-nutshell/master/secrets/pod-secret-docker.yaml
kubectl get pods -w
รอให้ Pod
ย้ายไปที่สถานะ Running
หากคุณเห็นข้อผิดพลาด ErrImagePull
แสดงว่าอาจมีปัญหาในการตรวจสอบสิทธิ์รีจิสทรี Docker หากต้องการดูรายละเอียด ให้ใช้: kubectl describe pod/pod4
เพื่อยืนยันว่าพ็อดทำงานได้ดี: kubectl logs -f pod4
เนื่องจากอิมเมจ busybox
ไม่ได้ทำอะไรด้วยตัวเองจริงๆ เราจึงดำเนินการ: while true; do date; sleep 5;done
(ตามที่ระบุไว้ในข้อมูลจำเพาะ Pod
) ด้วยเหตุนี้ คุณควรเห็นบันทึก (พิมพ์ทุกๆ 5 วินาที)
Tue Dec 17 14:17:34 UTC 2019
Tue Dec 17 14:17:39 UTC 2019
Tue Dec 17 14:17:44 UTC 2019
Tue Dec 17 14:18:49 UTC 2019
ทั้งหมดดี! ความหมายก็คือ Pod สามารถดึงรูปภาพของคุณจาก repo Docker ส่วนตัวโดยใช้ข้อมูลรับรอง Docker ซึ่งถูกฉีดเข้าไปใน Pod
โดยใช้ imagePullSecrets
ซึ่งตัวมันเองอ้างอิง Secret
ดีแล้วที่รู้
ต่อไปนี้เป็นรายการ (โดยสังเขป) ที่คุณควรคำนึงถึงเมื่อใช้ Secrets
:
- จะต้องสร้าง
Secret
ก่อนPod
ใดๆ ที่ต้องการใช้ Secrets
ใช้ได้ภายในnamespace
กล่าวคือ สามารถใช้ได้โดยPods
ในnamespace
เดียวกันเท่านั้นPod
จะไม่เริ่มทำงานหากมีการอ้างอิงถึงคีย์ที่ไม่มีอยู่ในSecret
(โดยใช้secretKeyRef
)- 1MiB คือขีดจำกัดขนาดสำหรับบุคคล
Secrets
เพียงเท่านี้สำหรับซีรีส์ Kubernetes in a Nutshell ฉบับนี้ คอยติดตามข้อมูลเพิ่มเติม!
หากคุณสนใจที่จะเรียนรู้ Kubernetes และคอนเทนเนอร์โดยใช้ "Azure" เพียง "สร้างบัญชีฟรี" แล้วเริ่มต้นได้เลย จุดเริ่มต้นที่ดีคือการใช้ “การเริ่มต้นอย่างรวดเร็ว บทช่วยสอน และตัวอย่างโค้ด” ในเอกสารประกอบเพื่อทำความคุ้นเคยกับบริการ ฉันขอแนะนำให้ลองดู "เส้นทางการเรียนรู้ Kubernetes" 50 วัน ผู้ใช้ขั้นสูงอาจต้องการดู "แนวทางปฏิบัติที่ดีที่สุดของ Kubernetes" หรือดู "วิดีโอ" บางส่วนสำหรับการสาธิต คุณลักษณะเด่น และเซสชันด้านเทคนิค
ฉันหวังว่าคุณจะสนุกและเรียนรู้บางอย่างจากบทความนี้ 🙌