วิธีสร้าง CoreOS Cluster

จะสร้าง CoreOS ให้กลายเป็น Cluster Docker Container ได้อย่างไร

             จากบทความที่แล้วที่แนะนำเกี่ยวกับ CoreOS และการติดตั้งบน Vmware[1] ไปแล้วนั้น เราก็สามารถสร้างให้เป็นในรูปแบบ Cluster ได้ โดยมองว่าเครื่องแต่ละเครื่องที่สร้างนั้นเป็น Node หนึ่ง ๆ ใน Cluster โดยใช้ etcd เป็นตัวเก็บข้อมูลของ Node และ Fleet เป็นตัว Deploy docker ให้กระจายไปยัง Node ต่าง ๆ อย่างเหมาะสม โดยที่จะสามารถย้ายตัวเองได้เมื่อมีเครื่องใดเครื่องหนึ่งมีปัญหา (Recommend จำนวนเลขคี่ และอย่างต่ำต้อง 3 node ขึ้นไป ยิ่งเยอะ โอกาสล่มก็ยิ่งต่ำ)


            etcd ในปัจจุบันเป็น Version 3 ซึ่งจะมีประสิทธิภาพเพิ่มขึ้นจาก Version 2 (แต่ใน document web ยังเป็น etcd2 เป็นส่วนมาก) โดยใช้สำหรับเก็บข้อมูลแต่ละ Node ทำให้รู้ว่าในแต่ละ Cluster มีเครื่องใด IP อะไรบ้าง มีทั้งหมด 3 วิธีคือ 

  1. Static เป็นวิธีที่ระบุลงไปเลยในแต่ละเครื่องว่ามีเครื่องไหนบ้างที่อยู่ใน Cluster วิธีการนี้ข้อเสียคือถ้าเพิ่มต้องเพิ่มทุกเครื่อง
  2. etcd Discovery เป็นวิธีที่จะให้ Discovery Service เป็นคนทำหน้าที่เก็บข้อมูล (เหมือน tracker torrent) เมื่อเพิ่มเครื่องใหม่ ก็แค่ชี้ไป Discovery URL ก็เสร็จ
  3. DNS Discovery เป็นวิธีการใช้วิธีการจด DNS ในรูปแบบ SRV record เพื่อบอกว่า บริการนี้มีเครื่องอะไรอยู่บ้าง ซึ่งจะมีการอ้างอิงอยู่กับ Domain Name โดยวิธีนี้จำเป็นต้องจดชื่อ Domain ทุกเครื่อง

            ในบทความนี้จะอธิบายวิธีที่ 1 ซึ่งแม้ยุ่งยาก แต่เหมาะกับระบบที่ Internet Public ไม่ค่อยเสถียร และ ถ้าใครต้องการลองวิธีอื่นสามารถตามอ่านได้ใน Web CoreOS[2] ครับ

  วิธีการตั้งค่า etcd2

  • ทำการสร้าง service etcd2 service ด้วย systemd ดังนี้
    sudo vim /etc/systemd/system/etcd2.service
  • ข้อความในไฟล์มีดังนี้ (ถ้าต้องการความปลอดภัยสามารถใช้ https ได้ครับ แต่ต้องมีการทำ certificate เพิ่มเติม ซึ่งไม่ขออธิบายครับ)
    [Unit]
    Description=etcd2
    Conflicts=etcd.service
    
    [Service]
    User=etcd
    Type=notify
    Environment=ETCD_DATA_DIR=/var/lib/etcd
    ExecStart=/usr/bin/etcd2 --name node01 --initial-advertise-peer-urls http://[IP]:2380 \
     --listen-peer-urls http://[IP]:2380 \
     --listen-client-urls http://[IP]:2379,http://127.0.0.1:2379 \
     --advertise-client-urls http://[IP]:2379 \
     --initial-cluster-token etcd-cluster-1 \
     --initial-cluster node01=http://[IP_node01]:2380,node02=http://[IP_node02]:2380,node03=http://[IP_node03]:2380 \
     --initial-cluster-state new
    
    Restart=always
    RestartSec=10s
    LimitNOFILE=40000
    TimeoutStartSec=0
    
    [Install]
    WantedBy=multi-user.target
    
  • Enable etcd2 service เพื่อให้รันทุกครั้งที่เปิดเครื่อง
    sudo systemctl enable etcd2
  • Start etcd2 service
    sudo systemctl start etcd2
  • ตรวจดูสถานะการทำงานของ etcd2 service
    sudo systemctl status etcd2
  • เราสามารถดูข้อมูลสมาชิกได้ดังนี้
    etcdctl member list

 วิธีการตั้งค่า Fleet

  • ทำการสร้าง service fleet โดยการตั้งค่าใน systemd ดังนี้
    sudo vim /etc/systemd/system/fleet.service
  • ข้อความในไฟล์มีดังนี้ (จะเห็นว่า config ตั้งค่าให้ Start หลัง etcd2)
    [Unit]
    Description=fleet daemon
    
    After=etcd2.service
    
    Wants=fleet.socket
    After=fleet.socket
    
    [Service]
    User=fleet
    Environment=GOMAXPROCS=1
    Environment="FLEET_PUBLIC_IP=[IP]"
    ExecStart=/usr/bin/fleetd
    Restart=always
    RestartSec=10s
    
    [Install]
    WantedBy=multi-user.target
  • Enable fleet service เพื่อให้รันทุกครั้งที่เปิดเครื่อง
    sudo systemctl enable fleet
  • Start fleet service
    sudo systemctl start fleet
  • ตรวจดูสถานะการทำงานของ fleet service
    sudo systemctl status fleet
  • วิธีตรวจดูสถานะแต่ละ Node ทำได้ดังนี้
    fleetctl list-machines
  • จะได้ผลลัพธ์หน้าตาประมาณนี้ครับ

       ให้ทำการติดตั้งไปเรื่อย ๆ ทั้ง CoreOS->Etcd2->Fleet จนครบ 3 เครื่อง หรือ 5,7,9 เครื่องแล้วแต่จะต้องการว่าจะสร้างกี่ Node ครับ ยกตัวอย่างถ้าครบ 3 เครื่องก็จะได้ประมาณนี้ครับ

ทดสอบการสร้าง WordPress ผ่าน Fleet[3]

  • วิธีการทำแน่นอนครับ หนีไม่พ้นไฟล์รูปแบบ systemd (อีกแล้ว) แต่ไม่ต้องรันด้วย systemctl นะครับ ทำที่เครื่องใดเครื่องหนึ่ง สร้างที่ /home/core ก็ได้ดังนี้
  • ก่อนอื่นต้องติดตั้ง docker mysql โดยสร้างไฟล์ mysql.service ดังนี้
    vim mysql.service
  • ข้อความในไฟล์ประมาณนี้ครับ
    [Unit]
    Description=MySQL DataBase
    After=etcd.service
    After=docker.service
    
    [Service]
    TimeoutStartSec=0
    ExecStartPre=-/usr/bin/docker kill mysql
    ExecStartPre=-/usr/bin/docker rm mysql
    ExecStartPre=/usr/bin/docker pull mysql:5.7
    ExecStart=/usr/bin/docker run --name mysql -e MYSQL_ROOT_PASSWORD="wordpress" -e MYSQL_DATABASE="wordpress" -e MYSQL_USER="wordpress" -e MYSQL_PASSWORD="wordpress" mysql:5.7
    ExecStop=/usr/bin/docker stop mysql
  • สร้างไฟล์ wordpress.service ดังนี้
    vim wordpress.service
  • ข้อความในไฟล์ประมาณนี้ครับ
    [Unit]
    Description=WordPress
    After=mysql.service
    
    [Service]
    TimeoutStartSec=0
    ExecStartPre=-/usr/bin/docker kill wordpress
    ExecStartPre=-/usr/bin/docker rm wordpress
    ExecStartPre=/usr/bin/docker pull wordpress
    ExecStart=/usr/bin/docker run --name wordpress --link mysql -p 8880:80 -e WORDPRESS_DB_PASSWORD=wordpress -e WORDPRESS_DB_NAME=wordpress -e WORDPRESS_DB_USER=wordpress wordpress
    ExecStop=/usr/bin/docker stop wordpress
    
    [X-Fleet]
    X-ConditionMachineOf=mysql.service
  • สั่ง Start mysql service ด้วย fleetctl ดังนี้
    fleetctl start mysql.service

  • สั่ง Start wordpress service ด้วย fleetctl ดังนี้
    fleetctl start wordpress.service

  • สั่งคำสั่งเพื่อตรวจสอบสถานะดังนี้ (ซึ่งจะบอกว่าติดตั้งที่ Node ใด และสถานะการใช้งาน หรือการติดตั้งเป็นอย่างไร)
    fleetctl list-units

  • เสร็จแล้วลองสั่ง fleetctl list-units ที่ Node อื่น ๆ ดูครับก็จะได้ผลลัพธ์เหมือน ๆ กัน
  • ก็จะได้ web wordpress เอาไว้ใช้งานแล้ว
  • จากนั้นทดสอบลองปิด Node ดูครับ สำหรับระบบที่มี 3 Node พังได้แค่ Node เดียวครับ ถ้าอยากได้มากกว่านั้นต้องเพิ่มจำนวน Node ขึ้นไป 
  • จะพบว่าเครื่องจะย้ายไป Start อีก Node ทันที (มันจะสั่ง start ใหม่นะครับ ไม่ได้ย้ายไปแบบ vmware) เท่าที่ทดสอบข้อมูลไม่ได้มาด้วยครับ อีกทั้งยังได้ ip ที่เครื่องใหม่ เพราะฉะนั้นต้องหาวิธีทำ map volume และ proxy web เอาเองครับ

(Optional) วิธีการ Fix IP แทน DHCP

  • ในกรณีที่ต้องการ Fix IP แทน DHCP ให้เข้าไปสร้าง systemd network config โดยสร้างไฟล์ดังนี้
    sudo vim /etc/systemd/network/static.network
  • ข้อความในไฟล์ประมาณนี้ครับ
    [Match]
    Name=[Interface Name]
    
    [Network]
    Address=[IP/Mask]
    Gateway=[IP Gateway]
    DNS=[DNS IP มีหลาย IP ให้เว้นวรรค เช่น 10.0.0.1 10.0.0.2]
  • จากนั้นให้ทำการ Restart เครื่อง (จริง ๆ restart service ก็น่าจะได้ แต่ลองแล้วไม่ได้ครับ)

             สำหรับ CoreOS Cluster ก็มีเท่านี้ครับ แต่จะเห็นว่ายังขาด Docker Management ที่เป็น GUI รวมถึง Docker Gateway และระบบ Storage ติดตามในตอนต่อ ๆ ไปแล้วกันครับ

==================================

Reference :

[1] มารู้จักกับ CoreOS Linux และวิธีติดตั้ง CoreOS Linux บน Vmware : https://sysadmin.psu.ac.th/2017/05/03/coreos-linux-install-vmware/

[2] CoreOS Clustering Guide : https://coreos.com/etcd/docs/latest/op-guide/clustering.html#etcd-discovery

[3] Deploy WordPress in CoreOS Cluster using Fleet : https://wenfeng-gao.github.io/2016/06/03/deploy-wordpress-in-coreos-cluster-using-fleet.html