Small Scale Kubernetes Part I: สร้างคลัสเตอร์ใน GKE

หลังจากเขียนเรื่อง Kubernetes ไปในบล็อคที่แล้ว ก็มีคนรีเควสมาว่าอยากให้เขียนเกี่ยวกับการใช้ Kubernetes สักหน่อย

จริงๆ เนื้อหาในบล็อคจะพยายามไม่เน้น howto อย่างนึงคือผมมองว่าบล็อคส่วนตัวไว้เขียนเรื่องส่วนตัวว่าเราทำอะไร เจออะไรมาดีกว่า แล้วก็วิธีการใช้งานก็อยากให้ศึกษาจากคู่มือของเค้าเองซะมากกว่า แต่สำหรับ Kubernetes นี่ต้องยกเว้นไว้หน่อยเพราะเว็บมันอ่านยากจริงๆ

ทีนี้ถัดมาก็นึกอยู่ว่าจะเขียนที่ไหนดี ที่บล็อคบริษัทก็น่าเขียน เพราะผมก็ implement Kubernetes ไว้ให้ แต่คิดว่าในสเกลนั้นถ้าเขียนออกไปคนอ่านอาจจะอยากรู้เรื่องการใช้งานใน scale ใหญ่มากกว่า ซึ่งก็ยังไม่คิดว่าพร้อมจะเล่าเท่าไร ก็เลยอยากจะเล่าในมุมของเว็บเล็กๆ ที่ใช้ Kubernetes ใน Production ซะมากกว่า

เปิดใช้ GKE

สำหรับการติดตั้ง Kubernetes ผมคงไม่เขียนถึงเพราะหลายๆ เหตุผลครับ

  1. ผมเคยใช้ kube-up ติดตั้งใน AWS แล้วอัพเกรดไม่ได้ (ของบริษัทใช้วิธีนี้อยู่) ซึ่งตอนหลัง Kubernetes ออกของใหม่มาแล้วแต่ผมยังไม่ได้ทดลอง
  2. ตอนนี้ Google Cloud และ Azure มีบริการ managed Kubernetes แล้ว (10 ปีก่อนถ้าบอกผมว่าผมจะมาเขียนขายของ Microsoft นี่ผมไม่เชื่อเลยนะ)
  3. บริการ managed Kubernetes ใน Google Cloud นั้นถ้าคลัสเตอร์ของเราขนาดไม่เกิน 5 nodes จะไม่คิดค่า master node ซึ่งถ้าไปลงเองก็จะต้องเสีย 1 เครื่องมาทำ นอกจากนี้ของ Google Cloud นี่ master มี SLA 99.95% เช่นเดียวกับ Compute Engine ด้วย เรียกได้ว่าทั้งประหยัดเงินและเสถียรกว่าด้วย

ฉะนั้นแล้วมาใช้ Google Cloud เถอะครับ ฮ่าๆ ซึ่งตัวบริการ managed Kubernetes ของ Google Cloud นั้นจะเรียกว่า Google Container Engine แต่ย่อว่า GKE เพราะถ้าเรียก GCE มันจะไปซ้ำกับ Compute Engine ก็เลยใช้ K จาก Kubernetes

สำหรับการสมัครนั้นก็สามารถเข้าไปที่ GKE Console กดสร้าง project แล้วสร้าง cluster ได้เลย (ถ้าสร้าง project ใหม่อาจจะต้องรอ activate ประมาณ 5 นาที) ซึ่งวิธีการก็คือ

  1. กด Create cluster กลางจอ (ในภาพผมมีเครื่องแล้วมันเลยอยู่ด้านบน)
  2. กรอกข้อมูลดังนี้
    • Name จะตั้งอะไรก็ได้
    • Zone เลือกเป็น asia-southeast1-a หรือ b ก็ได้ (ความแตกต่างแต่ละ Zone สำหรับของ asia-southeast1 หรือสิงคโปร์เนื่องจากเป็นโซนเปิดใหม่ก็จะยังไม่ต่างกันครับ)
    • Cluster version จะเลือกเป็นรุ่นล่าสุดก็ได้ หรือรุ่นเก่าก็ได้ แต่ถ้าจะใช้ของใหม่อย่าลืมอ่าน Release Note ก่อนเนื่องจากอาจจะมี bug
    • Machine type เลือกตามสะดวกครับ ปกติจะเลือกเป็น 1 vCPU มาให้ แต่เราสามารถลดลงเหลือ micro/small ก็ได้ มีข้อจำกัดคือถ้าใช้ micro จะต้องซื้อ 3 เครื่องขึ้นไป
      • 1 vCPU = 1 hyperthread
      • สำหรับเครื่อง f1-micro จะได้ 0.2 vCPU, g1-small จะได้ 0.5 vCPU ซึ่งหมายความว่า cpu usage เราจะใช้ได้ไม่เกิน 50% และอาจจะ boost เกินได้เป็นระยะสั้นๆ
      • อย่าลืมว่าเราสามารถมีหลายๆ เครื่องเป็นคลัสเตอร์ได้ ฉะนั้นไม่จำเป็นต้องเลือกใหญ่มากก็ได้ครับ คิดว่า 2 vCPU (n1-standard-2) น่าจะเหมาะที่สุดถ้ามีงบ (ซึ่งผมไม่มี) เนื่องจากจะได้ 1 physical core ไปเต็มๆ
    • Size จะเอากี่เครื่องก็ใส่ได้เลยครับ เครื่องเดียวก็ได้ ยกเว้นถ้าเลือก Machine type เป็น micro จะต้องซื้อ 3 เครื่อง
    • Node image แนะนำ Container optimized OS ครับ ซึ่งจะมีระบบ security ของ Google ด้วย แต่จะติดตั้งโปรแกรมนอก Docker ไม่ได้ ส่วน container-vm จะเป็นอิมเมจที่เบสมาจาก Debian สามารถลงโปรแกรมได้ (ความแตกต่าง)
      • Node มันอัพเกรดด้วยการลบสร้างใหม่ ฉะนั้นไม่ต้องคิดว่าจะได้ลงอะไรอยู่แล้วครับ
    • Automatic node upgrade/repair อันนี้ผมยังไม่เปิดเนื่องจาก Google บอกว่าหลังออกจาก Beta แล้วอาจจะคิดเงิน ก็เลยขอรอดูราคาก่อน
    • Legacy Authorization กด Enable ไว้
    • Logging and monitoring ถ้าลงทะเบียน Stackdriver monitoring ก็เปิดได้ครับ ถ้าไม่เคยลงทะเบียนไว้จะปิดก็ได้ หรือไปลงทะเบียนทดลองใช้ 30 วันฟรีก็ได้ (หลังหมดฟรีแล้วใช้ต่อได้ แต่จะโดนลดฟีเจอร์) ส่วน Logging ไม่แนะนำให้ปิดครับ
    • ในส่วน Advanced จะตั้งตามนี้ครับ
    • Basic Authentication/Client certificate Disable ไปได้เลย
    • Autoscaling จะเปิดไว้ก็ไม่เสียหายครับ ซึ่งถ้าเปิดจะให้ตั้งจำนวน node สูงสุดที่ต้องการได้
    • Preemptible nodes Disable ไว้ ถ้าเปิดแล้วจะใช้เครื่องราคาถูกกว่า แต่ใช้ไปสักพักจะโดนปิดเอง ซึ่งจะเหมาะกับ boost มากกว่าการใช้จริงจังครับ
    • Boot disk size in GB ปกติจะตั้งไว้ 100GB ลดได้ครับ แต่แนะนำว่าไม่ควรต่ำกว่า 30GB ไม่งั้น IO มันจะช้ามาก
    • Project access ไม่ต้องแตะส่วนนี้ครับ ถ้าเปิดสิทธิ์อะไรเพิ่มไว้มันจะทำให้ container ใน Cluster ทุกตัวสามารถใช้สิทธิ์ได้เลย ซึ่งเราควรจะแจก service account เองดีกว่า

หลังจาก create แล้วก็รอสร้างประมาณ 5 นาทีครับ ระหว่างนี้เราทำอย่างอื่นดีกว่า

ติดตั้ง Google Cloud SDK

เนื่องจากเราปิด authentication หมดทุกประเภทเลย วิธีเดียวที่เข้าได้คือจะต้องมี Google Cloud SDK ครับ ซึ่งผมใช้ Arch Linux ก็สามารถกดลงจาก AUR ได้เลย และอีกโปรแกรมหนึ่งที่ต้องลงคือ kubectl ซึ่งสามารถติดตั้งจาก Google Cloud SDK ก็ได้ หรือใน AUR ก็ได้

$ gcloud components install kubectl

(ผมไม่แน่ใจว่า Windows ลงด้วยวิธีนี้ได้หรือเปล่านะครับ)

แต่ถ้าขี้เกียจลงอะไรเยอะแยะ Google Cloud ก็มีของอำนวยความสะดวกให้เราครับ นั่นคือ Cloud Shell ซึ่งสามารถเปิดจากเมนูขวาบนได้เลยโดยไม่มีค่าใช้จ่ายใดๆ แถมลงของเล่นไว้ให้หมดแล้วด้วย

ลูกศร low cost มาก แต่คลัสเตอร์นั่นไม่ low cost เลย…

ถ้าจะใช้ Cloud Shell แนะนำให้ลง Chrome Extension ของเค้าด้วยครับ (กดจากเมนูซ้ายบนของหน้าต่าง shell ก็มีลิงค์เหมือนกัน) ซึ่งจะทำให้สามารถกดคีย์ลัดได้ทุกปุ่ม

อย่างแรกที่จะต้องทำก็คือ login เข้า Google Cloud ก่อนครับ ซึ่งถ้าใครใช้ Cloud Shell ก็ข้ามไปได้เลย

$ gcloud auth login
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?redirect_uri=....

WARNING: `gcloud auth login` no longer writes application default credentials.
If you need to use ADC, see:
  gcloud auth application-default --help

You are now logged in as [email].
Your current project is [project].  You can change this setting by running:
  $ gcloud config set project PROJECT_ID

พอพิมพ์คำสั่งนี้แล้วจะเด้ง browser ขึ้นมา ก็ให้ login และอนุมัติ API access ครับ เสร็จแล้วก็ปิดหน้าต่างกลับไปที่ shell ต่อได้เลย

ขั้นถัดมาเราจะเลือก project ที่เราสร้าง cluster ไว้ครับ โดยดู project ID ได้จากใน URL ของเว็บ (https://console.cloud.google.com/kubernetes/list?project=my-project)

$ gcloud config set project my-project
Updated property [project].
$ gcloud config set compute/zone asia-southeast1-a
Updated property [compute/zone].

และสุดท้ายก็ login เข้า Kubernetes ครับ โดยตรง cluster-1 ให้กรอกชื่อ cluster ที่เราตั้งไว้

$ gcloud container clusters get-credentials cluster-1
Fetching cluster endpoint and auth data.
kubeconfig entry generated for cluster-1.

สุดท้ายลองเช็คดูว่าสามารถใช้ Kubernetes ได้จริงแล้ว

$ kubectl describe nodes
NAME                         STATUS    AGE       VERSION
gke-tipme-n1-a7ee1a90-mwzz   Ready     1h        v1.7.2

ติดตั้งของเล่น

ก่อนจะจบตอนไปมาลงอะไรเล่นดูก่อนดีกว่าครับ เอาเป็นว่าเรามาลอง hello world หน่อยแล้วกัน

อย่างแรกก็จะต้องสร้าง Pod ขึ้นมาก่อนครับ โดยเขียนไฟล์ helloworld.yaml ดังนี้

apiVersion: v1
kind: Pod
metadata:
  name: helloworld
spec:
  hostNetwork: true
  containers:
  - name: helloworld
    image: kitematic/hello-world-nginx
    ports:
    - containerPort: 80

ก็แปลว่า Pod นี้จะใช้ hostNetwork (เหมือน --net=host ใน Docker) และใช้อิมเมจ kitematic/hello-world-nginx

(ProTip: แนะนำให้ทำ Git repo มาเก็บ YAML ทั้งหมดที่ใช้ไว้ครับ จะสามารถ track changes ได้ง่ายตามสไตล์ Infrastructure as Code เลย)

เสร็จแล้วก็โหลดเข้าไปใน Kubernetes

$ kubectl create -f helloworld.yaml
pod "helloworld" created

$ kubectl get pods
NAME         READY     STATUS    RESTARTS   AGE
helloworld   1/1       Running   0          1m

เสร็จแล้วก็สามารถเข้าเว็บได้จาก IP ของเครื่องเลยครับ ซึ่งสามารถหา IP ภายนอกได้จากในหน้า External IP Address หรือจะกดที่เครื่องในหน้า Compute Engine ก็ได้ (ไม่สามารถหาจาก kubectl ได้เนื่องจาก GCE จะทำ 1:1 NAT ด้านนอกเครื่องเราทำให้เครื่องไม่ทราบ IP ตัวเอง)

ซึ่งไหนๆ เข้าไปหน้า External IP Address แล้ว สามารถจอง IP ที่ใช้อยู่ให้เป็น IP ถาวร (ปกติถ้าปิดเครื่อง IP จะสุ่มใหม่) เพียงแค่กด Type เป็น Static ซึ่งจะต่างกับใน AWS คือของ AWS ไม่สามารถจอง IP ที่ใช้อยู่ได้ ต้องกดขอ IP ใหม่มาใส่ตลอด

(Note: IP static ที่ไม่ได้ต่อกับเครื่องจะคิดเงินรายชั่วโมง ถ้าจะลบเครื่องออกอย่าลืมมาลบ IP ด้วยครับ)

สรุป

สำหรับตอนนี้เราก็ได้สร้างคลัสเตอร์ด้วย GKE และติดตั้งโปรแกรมแบบพื้นฐานไปแล้ว แต่นี่ยังแค่ความสามารถระดับพื้นๆ ของ Kubernetes ครับ ตอนหน้าเราจะมาพูดถึงคอนเซปต์ต่างๆ ใน Kubernetes กัน