Build Kubernetes cluster on your VMs

ในยุคที่ micro services เฟื่องฟู เทคโนโลยี Container หรือที่คุ้นหูกันในชื่อ Docker กำลังได้รับความนิยมอย่างมาก การสร้าง Docker cluster มารองรับกับ work loads เป็นสิ่งจำเป็นที่หลีกเลี่ยงไม่ได้

Photo by Joseph Barrientos on Unsplash

 

การทำ Docker cluster นั้นมีอยู่หลายวิธี แต่ที่นิยมและคุ้นหูกันจะมีอยู่ 2 เจ้าใหญ่ๆ

Docker swarm (swarm mode) คือ Docker cluster ที่มีมากับตัว Docker อยู่แล้ว การใช้งานไม่ยุ่งยาก สามารถเอาไฟล์ docker-compose.yml ที่รันใน Dev มาแก้เล็กน้อย แล้วสามารถใช้งานบน Production ได้เลย แต่ข้อเสียที่เจอเมื่อรันระบบไปสักพักคือ ระบบไม่ค่อยสเถียร overlay network มีปัญหา และการ deploy image ที่ไม่ราบรื่นนัก

Kubernetes คือการทำ Docker cluster อีกรูปแบบหนึ่งที่มีมาก่อน Docker swarm เริ่มต้นขึ้นโดย Google เป็นระบบที่มีเสถียรภาพสูง ทำงานรวดเร็ว แต่ Setup ยากเนื่องจากมีความซับซ้อนสูง แต่ถ้าใช้บริการบนคราวด์ ผู้ให้บริการก็จะจัดการส่วนนี้ให้

หลังจากรัน Docker swarm มาได้ปีกว่า ก็เจอปัญหาอยู่อย่างต่อเนื่อง การแก้ปัญหาแต่ละครั้งก็ยากและดูเหมือนจะไม่จบ ถึงเวลาตัดสินใจย้ายมาใช้ Kubernetes แต่ความซับซ้อนค่อนข้างมากจึงใช้เวลาอยู่พอสมควร มาถึงโจทย์ที่ว่าเราต้องการ setup Kubernetes cluster บน server ของเราเอง เนื่องจากมีการใช้งานสูง รวมถึงต้องเชื่อมต่อกับระบบหลังบ้านอีกมากมาย หลังจากทดลองมาหลายวิธี ก็พบว่า การลงผ่าน kubespray (ansible) ง่ายสุด ผมจะแสดงตัวอย่างการติดตั้ง kubernetes 3 nodes ตามขั้นตอนข้างล่างนะครับ

Prepare server
เตรียม server ที่จะใช้งาน จะเป็น VM หรือ bare metal ก็ได้
– OS Ubuntu 16.04 ปิด swap ให้เรียบร้อย ไม่งั้นใช้ไม่ได้
– สร้าง ssh key และ sudo สำหรับ user ที่จะใช้ติดตั้ง (ให้ user นี้สามารถ ssh ไปเครื่องอื่นด้วย key ได้ และมีสิทธิ์ sudo)
– install python ($sudo apt install python python-pip)

Prepare setup
ssh เข้าไปที่เครื่องที่จะใช้ทำการ setup ตัวอย่างผมจะใช้ชื่อ ubuntu1
ทำการ clone kubespray จาก https://github.com/kubernetes-incubator/kubespray.git และเข้าไปใน kubespray directory

ทำการสร้าง inventory file

[all]
kube01 ansible_ssh_host=10.10.0.11 ip=10.10.0.11
kube02 ansible_ssh_host=10.10.0.12 ip=10.10.0.12
kube03 ansible_ssh_host=10.10.0.13 ip=10.10.0.13
#ansible_ssh_host=privateip ip=publicip
[kube-master]
kube01
kube02

[kube-node]
kube01
kube02
kube03

[etcd]
kube01
kube02
kube03

[k8s-cluster:children]
kube-node
kube-master

[vault]# use for store secret
kube01
kube02
kube03

ผมจะ save ไว้ที่ inventory/my-cluster.cfg

จากนั้นจะทำการแก้ไขไฟล์ inventory/group_vars/k8s-cluster.yml
เพื่อเปลี่ยน kube_network_plugin จาก calico เป็น flannel
และ configure cluster ip (kube_service_addresses) โดยค่าเริ่มต้นจะเป็น 10.233.0.0/18 ถ้าเราวางแผนจะใช้งานมากกว่านั้นก็สามารถขยายได้

*ถ้าไม่มี directory group_vars ให้ copy เอาจาก directory sample/group_vars

เมื่อตั้งค่าเรียบร้อยแล้ว ก็ทำการลง ansible ($pip install ansible netaddr) ต้องลงผ่าน pip นะครับ เพราะต้องการ ansible version 2.4 ขึ้นไป

พร้อมจะติดตั้งกันแล้ว
$ansible-playbook -i inventory/my-cluster.cfg cluster.yml -b -v

รอจนเสร็จเราก็จะมี Kubernetes cluster ส่วนตัวใช้กันแล้ว

รอจนเสร็จจะได้ prompt กลับมาแบบนี้

ลองรัน kubectl get node ก็จะเห็นจำนวนทั้งหมดใน cluster

เนื่องจากเราใช้ kubespray ในการ deploy ฉะนั้นจึงมี dashboard มาให้แล้ว

แต่ค่า default ที่ให้มา dashboard จะเข้าถึงได้เฉพาะภายใน cluster หรือไม่ก็ต้องใช้ kubectl proxy ในการเชื่อมต่ออีกที ซึ่งไม่ค่อยสะดวกนัก เราจะทำการ edit service kubernetes-dashboard ให้มี IP ที่สามารถเข้าถึงจากข้างนอกได้ โดยการรัน kubectl edit services kubernetes-dashboard -n kube-system

แล้วก็เติ่ม externalIPs ใน level เดียวกับ clusterIP สามารถใส่ IP ได้มากกว่า1นะครับ save ออกมาก็จะสามารถเข้าตาม IP ข้างบนได้แล้ว หรือจะเอาไป map กับ domain ก็ได้ครับ

เข้ามาแล้วเราก็จะเจอหน้า Authentication ให้เราสร้าง user ก่อน ถึงจะได้ token สำหรับ login

การสร้าง admin-user และผูกกับ cluster-admin role ให้สร้าง yaml file ตามนี้

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

รัน kubectl create -f admin-user.yml ก็จะทำการสร้าง admin-user ให้เรา

จากนั้นให้รัน kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk ‘{print $1}’)

จะได้รายละเอียดของ user รวมถึง token ที่หน้าตาดูเป็น hash ยาวๆ

copy token ไปใส่ในหน้า login dashboard เราก็สามารถ ทำงานผ่าน dashboard ได้แล้วครับ

เบื้องต้นก็ประมาณนี้ครับ เดี๋ยวคราวหน้าจะมาต่อเรื่อง ingress และการใช้งานกัน