Category: Cluster & Load Balancing

  • Ambari #02 ติดตั้ง Ambari Agent

    ต่อจาก Ambari #01: ติดตั้ง Ambari Server

    ในบทความนี้ จะขอนำเสนอการติดตั้ง Ambari version 2.5.1 จาก HortonWorks ซึ่งจะทำงานกับ Hortonworks Data Platform (HDP)  2.6 โดยติดตั้งบน Ubuntu 16.04 ในส่วนของ “Ambari Agent” [2]

    1. ติดตั้ง Ubuntu 16.04 Server 64bit
    2. สิ่งที่สำคัญมากคือ FQDN หรือการอ้างชื่อเต็มของ host ดังนั้น ในไฟล์ /etc/hosts บรรทัดแรกต้องเป็น Fully Qualified Domain Name เช่น (ห้ามเป็น localhost เด็ดขาด) และถ้าจะให้ดี ควรมี DNS Record บน Name Server ด้วย
      127.0.0.1       ambari02.example.com ambari02
      192.168.1.122   ambari02.example.com ambari02

      ต้องทดสอบใช้คำสั่ง

      hostname -f

      แล้วได้ชื่อ FQDN ถึงจะใช้งานได้

    3. ตั้งค่า Ambari Public Repository
      sudo su
      wget -O /etc/apt/sources.list.d/ambari.list http://public-repo-1.hortonworks.com/ambari/ubuntu16/2.x/updates/2.5.1.0/ambari.list
      apt-key adv --recv-keys --keyserver keyserver.ubuntu.com B9733A7A07513CAD
      apt-get update -y
      sudo dpkg --configure -a
      echo never > /sys/kernel/mm/transparent_hugepage/enabled
      apt-cache showpkg ambari-server
    4. ติดตั้ง Ambari Agent
      apt-get install -y ambari-agent
    5. แก้ไขไฟล์
      /etc/ambari-agent/conf/ambari-agent.ini

      ให้ระบบ hostname ไปยัง ambari server ในที่นี้คือ ambari01.example.com

      hostname=ambari01.example.com
      ...
      run_as_user=ambari
    6. เนื่องจากเป็นการติดตั้งแบบ non-root จึงต้องทำการแก้ไข visudo ด้วย
      โดยเพิ่มบรรทัดต่อไปนี้เข้าไป

      # Ambari Customizable Users
      ambari ALL=(ALL) NOPASSWD:SETENV: /bin/su hdfs *,/bin/su ambari-qa *,/bin/su ranger *,/bin/su zookeeper *,/bin/su knox *,/bin/su falcon *,/bin/su ams *, /bin/su flume *,/bin/su hbase *,/bin/su spark *,/bin/su accumulo *,/bin/su hive *,/bin/su hcat *,/bin/su kafka *,/bin/su mapred *,/bin/su oozie *,/bin/su sqoop *,/bin/su storm *,/bin/su tez *,/bin/su atlas *,/bin/su yarn *,/bin/su kms *,/bin/su activity_analyzer *,/bin/su livy *,/bin/su zeppelin *,/bin/su infra-solr *,/bin/su logsearch *
    7. Start Ambari Agent
      ambari-agent start
  • Ambari #01: ติดตั้ง Ambari Server

    Apache Ambari เป็นเครื่องมือที่ทำให้การจัดการ Hadoop ง่ายขึ้น [1] แต่การติดตั้ง Apache Ambari เองนั้น (จาก Apache Project) ก็มีความยุ่งยากเล็กน้อย เพราะต้อง Build Source เอง จึงมีบริษัท HortonWorks เค้าไปทำตัว Binary มาให้ download และติดตั้งได้ง่ายกว่า

    Ambari ประกอบด้วย Ambari Server และ Ambari Agent ซึ่ง Server จะเป็นตัวสั่งการให้ติดตั้ง Hadoop Component ต่างๆลงไปบน Agent

    ในบทความนี้ จะขอนำเสนอการติดตั้ง Ambari version 2.5.1 จาก HortonWorks ซึ่งจะทำงานกับ Hortonworks Data Platform (HDP)  2.6 โดยติดตั้งบน Ubuntu 16.04 ในส่วนของ “Ambari Server” [2]

    1. ติดตั้ง Ubuntu 16.04 Server 64bit
    2. สิ่งที่สำคัญมากคือ FQDN หรือการอ้างชื่อเต็มของ host ดังนั้น ในไฟล์ /etc/hosts บรรทัดแรกต้องเป็น Fully Qualified Domain Name เช่น (ห้ามเป็น localhost เด็ดขาด) และถ้าจะให้ดี ควรมี DNS Record บน Name Server ด้วย
      192.168.1.121   ambari01.example.com ambari01

      ต้องทดสอบใช้คำสั่ง

      hostname -f

      แล้วได้ชื่อ FQDN ถึงจะใช้งานได้
      UPDATE: ในการระบบทดสอบ ซึ่งประกอบด้วยเครื่องไม่เกิน 5 เครื่อง อาจจะใช้ /etc/hosts บันทึก IP Address และ FQDN ของทุกเครื่องใน Cluster และต้องสร้าง /etc/hosts ให้เหมือนกันทุกเครื่องด้วยเช่นกัน แต่หากต้องทำระบบขนาดใหญ่ แนะนำให้ใช้ DNS ซึ่งต้องทำ Reverse DNS ด้วย กล่าวคือ ต้อง nslookup 192.168.1.2 แล้วกลับมาเป็น ambari01.example.com ได้
      แต่หากไม่สามารถจัดการ DNS หลักขององค์กรได้ ก็พอจะใช้งาน dnsmasq ช่วยได้ โดยวิธีการติดตั้งและใช้งานมีดังนี้

       apt install dnsmasq

      แก้ไขไฟล์ /etc/dnsmasq.conf
      เพิ่มบรรทัดต่อไปนี้

      interface=eth0
      address=/ambari01.example.com/192.168.1.121
      ptr-record=121.1.168.192.in-addr.arpa,ambari01.example.com
      address=/ambari02.example.com/192.168.1.122
      ptr-record=122.1.168.192.in-addr.arpa,ambari02.example.com
      ....
      address=/ambari99.example.com/192.168.1.219
      ptr-record=219.1.168.192.in-addr.arpa,ambari99.example.com
      

      จากนั้น ให้แก้ไขไฟล์ /etc/network/interfaces ของทุกเครื่อง ให้ชี้มาที่ IP ของ Ambari Server ในที่นี้คือ 192.168.1.121
      ก็จะใช้งานได้อย่างราบรื่น

    3. ตั้งค่า Ambari Public Repository
      sudo su
      wget -O /etc/apt/sources.list.d/ambari.list http://public-repo-1.hortonworks.com/ambari/ubuntu16/2.x/updates/2.5.1.0/ambari.list
      apt-key adv --recv-keys --keyserver keyserver.ubuntu.com B9733A7A07513CAD
      apt-get update -y
      sudo dpkg --configure -a
      echo never > /sys/kernel/mm/transparent_hugepage/enabled
      apt install -y ntp
      apt-cache showpkg ambari-server
    4. ติดตั้ง Ambari Server
      apt-get install -y ambari-server
    5. จากนั้นเป็นการ Setup
      ambari-server setup
      
      Customize user account for ambari-server daemon [y/n] (n)? n
      
      Checking JDK...
      [1] Oracle JDK 1.8 + Java Cryptography Extension (JCE) Policy Files 8
      [2] Oracle JDK 1.7 + Java Cryptography Extension (JCE) Policy Files 7
      [3] Custom JDK
      ==============================================================================
      Enter choice (1): 1
      
      Do you accept the Oracle Binary Code License Agreement [y/n] (y)? y
      
      Enter advanced database configuration [y/n] (n)? n
      # Default PostgreSQL Database: ambari
      # Default Username/Password:   ambari/bigdata
    6. Start Ambari
      ambari-server start

    ต่อไป สามารถเปิดการทำงานของ Ambari Server จาก

    http://ambari01.example.com:8080
    Default Username/Password = admin/admin

     

    Reference:

    [1] http://ambari.apache.org/

    [2] https://docs.hortonworks.com/HDPDocuments/Ambari/Ambari-2.5.1.0/index.html

     

  • วิธีสร้าง Docker Swarm

    หลายคนคงจะได้ใช้งาน Docker มาแล้ว แต่อาจจะลองใช้งานบน 1 Physical Server กล่าวคือ สร้างหลายๆ container อยู่บนเครื่องคอมพิวเตอร์เครื่องเดียว

    >> ติดตั้ง docker 17.06.0 CE บน Ubuntu

    Docker Swarm เป็นเครื่องมือที่ติดมากับ Docker รุ่นตั้งแต่ 1.12 เป็นต้นมา (ปัจจุบัน ชื่อรุ่นคือ 17.06.0 CE) ก่อนอื่น มาตรวจสอบว่า เรากำลังใช้ Docker รุ่นไหนด้วยคำสั่ง

    docker version

    Docker Swarm ประกอบไปด้วย Master Node และ Worker Node โดยใน 1 Swarm สามารถมีได้ หลาย Master และ หลาย Worker

    ในตัวอย่างนี้ จะแสดงการเชื่อมต่อ Ubuntu 16.04 ทั้งหมด 4 เครื่อง เข้าไปใน 1 Swarm (ทุกเครื่องสามารถเชื่อมต่อถึงกันได้ และต่อ Internet ได้ และติดตั้ง Docker ไว้เรียบร้อยแล้ว)

    [Master Node]

    1. ใช้คำสั่งต่อไปนี้ เพื่อสร้าง Swarm Master Node บนเครื่องนี้
      docker swarm init

      จะได้ผลดังภาพ

    2. ให้ Copy คำสั่ง ตั้งแต่ “docker swarm join –token …..” เป็นต้นไป เพื่อเอาไปสั่งให้ Work Node เข้ามา Join ใน Swarm

    [Worker Node]

    นำคำสั่งจาก Master Node ข้างต้น มาใช้

    จากนั้น ทำเช่นเดียวกันนี้ กับ Worker Node ที่เหลือ (และหากในอนาคตต้องการเพิ่ม Worker Node อีก ก็เอาคำสั่งนี้ไปใช้)

    ตัวอย่างการนำไปใช้
    (หากสนใจ ลอง git clone https://github.com/nagarindkx/elk ไปดูได้)

    1. สร้าง “Stack File” ซึ่งจะคล้ายๆกับการสร้าง Compose File แต่มีรายละเอียดต่างกันเล็กน้อย
    2. ใช้คำสั่ง ต่อไปนี้ เพื่อสร้าง Stack ของ Software ให้กระจายไปใน Worker Nodes
      docker stack deploy -c $(pwd)/elk.yml k1

      ผลที่ได้

    3. วิธีดูว่า ตอนนี้มี Stack อะไรอยู่บ้าง ใช้คำสั่ง
      docker stack ls
      ผลที่ได้
    4. วิธีดูว่า ตอนนี้มีการไปสร้าง Container ไว้ที่ใดใน Docker Swarm บ้าง ด้วยคำสั่ง (สั่งการได้บน Master Node เท่านั้น)
      docker service ps k1
      ผลที่ได้
    5. ต่อไป อยากจะเพิ่ม Scale ให้บาง Service ใน Stack ใช้คำสั่ง
      docker service scale k1_elasticsearch=4
      ผลที่ได้

     

    ในตัวอย่างนี้ จะสามารถใช้งาน Kibana ซึ่งจากภาพจะเห็นได้ว่า อยู่ที่ Node “docker04” แต่เราสามารถเรียกใช้งานได้ที่ Master Node “docker01” ได้เลย เช่น Master Node มี IP เป็น 192.168.xxx.111 ที่ port 5601 ได้

    คร่าวๆแค่นี้ก่อนครับ

  • ติดตั้ง docker 17.06.0 CE บน Ubuntu

    ล่าสุด วิธีการติดตั้ง Docker รุ่น 17.06.0 CE ซึ่งรองรับ docker-compose version 3.3 ให้ติดตั้งด้วยวิธีนี้

    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo apt update
    sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    sudo apt-get update
    sudo apt-get install docker-ce
  • ELK #04

    คราวนี้มาติดตั้งบน Docker บ้าง

    1. ถ้าเครื่อง Server เป็น Ubuntu 16.04 ทำตามขั้นตอนนี้เพื่อให้สามารถใช้งาน Docker ได้
      วิธีการติดตั้ง Docker บน Ubuntu 16.04
    2. เนื่องจาก Elasticsearch 5.x ใช้ Virtual Memory มากขึ้น ลองใช้คำสั่งนี้ดูค่าปัจจุบัน
       sysctl vm.max_map_count

      ค่า Default น่าจะประมาณนี้
      vm.max_map_count = 65530 ให้ทำการเพิ่มด้วยคำสั่งนี้

      sudo -i
      sudo echo "vm.max_map_count=262144" >> /etc/sysctl.conf
      exit

      จากนั้นให้ทำการ Reboot

    3. ติดตั้ง docker image ของ sebp/elk ด้วยคำสั่ง
       sudo docker pull sebp/elk

      โดย Default จะได้ Lastest Version

    4. ใช้คำสี่งต่อไปนี้ เพื่อ Start ELK ขึ้นมา โดยเปิด port ให้ Kibana: 5601, Elasticsearch: 9200, Logstash: 5044 และทำงานเป็นแบบ Detach หรือ Background นั่นเอง
      sudo docker run -d -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk

      หรือถ้าจะใช้ Docker Compose ก็สามารถใช้งานด้วยวิธีการนี้
      เริ่มจาก ติดตั้ง Docker Compose ด้วยคำสั่ง

      sudo -i
      curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
      chmod +x /usr/local/bin/docker-compose
      exit

      จากนั้น สร้างไฟล์ /path/to/your/config/elk.yml เนื้อหาดังนี้

      elk:
       image: sebp/elk
       ports:
       - "5601:5601"
       - "9200:9200"
       - "5044:5044"

      จากนั้นก็ Start

      sudo /usr/local/bin/docker-compose -f /path/to/your/config/elk.yml  up -d elk

      หากต้องการให้ container ทำการ start ทุกครั้งที่ Reboot ใช้คำสั่ง

      sudo crontab -e

      แล้วใส่บรรทัดนี้ต่อท้ายไฟล์

      @reboot /usr/local/bin/docker-compose -f /home/mama/elk.yml up -d elk
    5. ทดสอบว่า Container ที่กำลังทำงานอยู่มีอะไรบ้าง
      sudo docker ps

      วิธีดูว่า มี Container อะไรบ้าง (ทั้งที่ทำงานและไม่ทำงาน)

      sudo docker ps -a

      วิธีดูว่าเกิดอะไรขึ้นกับ Container (ในที่นี้ ชื่อ elk)

      sudo docker logs elk
    6. ถึงจุดนี้ ก็สามารถใช้งาน Kibana ทาง web url: http://your.host:5601 ได้แล้ว

     

    Reference:

    https://elk-docker.readthedocs.io/

     

  • ELK #03

    วิธีการติดตั้ง Kibana บน Ubuntu 16.04

    1. ก่อนอื่น Update
      sudo apt -y update ; sudo apt -y upgrade
    2. ติดตั้ง Java JDK
      sudo apt -y install default-jdk
    3. Download และติดตั้ง
      wget https://artifacts.elastic.co/downloads/kibana/kibana-5.4.2-amd64.deb
      sudo dpkg -i kibana-5.4.2-amd64.deb
    4. จากนั้นแก้ไขไฟล์ /etc/kibana/kibana.yml
      เพิ่มบรรทัดสุดท้าย

      server.host: "192.168.xxx.yyy"
      elasticsearch.url: "http://your.elastic.host:9200"
    5. จากนั้น Start Service
      sudo service kibana start
    6. เปิด Web Browser ไปที่
      http://192.168.xxx.yyy:5601
  • ELK #02

    ขั้นตอนการติดตั้ง Logstash บน Ubuntu 16.04

    1. ก่อนอื่น Update
      sudo apt -y update ; sudo apt -y upgrade
    2. ติดตั้ง Java JDK
      sudo apt -y install default-jdk
    3. Download และติดตั้ง
      wget https://artifacts.elastic.co/downloads/logstash/logstash-5.4.2.deb
      sudo dpkg -i logstash-5.4.2.deb
    4. Start Logstash Service
      sudo service logstash start
    5. ต่อไป สร้าง Configuration ไว้ใน /etc/logstash/conf.d/
      เช่น จะสร้าง Pipeline ที่อ่านจาก File /tmp/test.log แล้ว ส่งไปที่ Elasticsearch โดยตรง
      ให้สร้างไฟล์ /etc/logstash/conf.d/file.conf ดังนี้

      input {
              file {
                      path => "/tmp/test.log"
                      type=> "test"
              }
      }
      output {
              file {
                      path => "/tmp/output.txt"
              }
      }
      
    6. เมื่อลองใช้คำสั่ง
       echo "$(date): New World" >> /tmp/test.log
      

      ก็จะปรากฏไฟล์ /tmp/output.txt ขึ้น

    7. ต่อไป ลองเปลี่ยน Output เป็น Elasticsearch โดยการสร้างไฟล์ /etc/logstash/conf.d/es.conf
      input {
              file {
                      path => "/tmp/test.log"
                      type=> "test"
              }
      }
      output {
              elasticsearch {
                      hosts => ["http://your.elastic.host:9200"]
              }
      }
      
      
    8. เมื่อลองใช้คำสั่ง
       echo "$(date): New World" >> /tmp/test.log
      

      ก็จะปรากฏบรรทัดใหม่ใน /tmp/output.txt และ มีการเขียนไปบน Elasticsearch ด้วย

    9. ลองเปิด Web Browser แล้วใช้คำสั่งต่อไปนี้
      http://your.elastic.host:9200/_cat/indices?v
      ก็จะได้ผลลัพธ์ประมาณนี้
    10. จากนั้น วิธีที่จะแสดงผลที่เก็บไว้ใน Elasticsearch ให้เปิด URL นี้
      http://your.elastic.host:9200/logstash-2017.06.24/_search?q=*
      ก็จะได้ผลลัพธ์ประมาณนี้

    แล้วยังไง ??? รอดูตอนต่อไป

  • ELK #01

    ELK = ElasticSearch + LogStash + Kibana

    วิธีการติดตั้ง ElasticSearch บน Ubuntu 16.04

    1. ก่อนอื่น Update
      sudo apt -y update ; sudo apt -y upgrade
    2. ติดตั้ง Java JDK
      sudo apt -y install default-jdk
    3. Download และติดตั้ง
      wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.4.2.deb
      sudo dpkg -i elasticsearch-5.4.2.deb
      sudo update-rc.d elasticsearch defaults 95 10
    4. แก้ไขไฟล์ /etc/elasticsearch/elasticsearch.yml โดยเพิ่มบรรทัดสุดท้าย
      cluster.name: my-cluster-name
      network.host: [_site_]
      node.name: ${HOSTNAME}
    5. เริ่มทำงาน
      sudo -i service elasticsearch start
    6. ทดสอบการทำงาน โดยใช้คำสั่ง
      curl -XGET “${HOSTNAME}:9200/?pretty”
    7. ดู Log ได้ที่
      sudo tail -f /var/log/elasticsearch/my-cluster-name.log
  • รู้จักกับ Kubernetes และวิธีติดตั้ง Kubernetes ด้วย CoreOS (ตอนที่ 1 Master Node)

    ถ้าต้องการระบบจัดการ docker container สักตัวต้องทำอย่างไร

                เมื่อกล่าวถึงระบบจัดการ docker container สักตัวหนึ่ง มักจะกล่าวถึง opensource ตัวหนึ่งชื่อ kubernetes ซึ่งเป็นเครื่องมือที่พัฒนาขึ้นมาด้วย Google[1] ซึ่งสามารถรองรับทั้งในส่วนของ Google Container Engine และ CoreOS จริง ๆ ลงได้บนอีกหลาย platform แต่สำหรับ CoreOS ได้ออกแบบมาให้รองรับ Kubernetes ทำให้การติดตั้งง่ายและสมบูรณ์มากขึ้น (อ่านไปเรื่อย ๆ จะสงสัยนี่ง่ายแล้วเหรอ แต่หลังจากเขียนบทความนี้เสร็จก็มีตัวติดตั้งตัวใหม่ชื่อ Tectonic[6] น่าจะเป็นตัวที่ทำให้การติดตั้งง่ายขึ้นครับ)

                Kubernetes เป็นเครื่องมือที่ช่วย build, deploy และ scale ให้เป็นเรื่องง่าย ๆ และสามารถ replicate containner ได้ง่ายมาก การติดตั้ง Kubernetes บน Google Container Engine ง่ายมาก แต่การติดตั้งบน CoreOS จะยากกว่า ซึ่งสามารถติดตั้งแบบ Single Node และ Multi-Node ซึ่งถ้าจะทำ Multi-Node ต้องเชื่อมต่อไปยัง etcd service ที่ติดตั้งบน CoreOS Cluster ด้วยก็จะดีครับ (ไม่งั้นเป็น Cluster ที่ไม่สมบูรณ์) สามารถอ่านเพิ่มเติมได้ที่วิธีการติดตั้ง CoreOS Cluster[2] (ในบทความใช้ก่อนหน้านี้ CoreOS Cluster เขียนในส่วน ETCD Version 2 แต่การใช้งานกับ Kubernetes ต้องใช้ ETCD Version 3 ตอนนี้ยังไม่มีบทความเสริมในส่วนนี้ อาจจะต้องหาข้อมูลเองก่อนครับ จริง ๆ มีวิธีแต่ยังยากในการเขียนบทความ ไว้ค่อยเขียนเพิ่มให้อีกทีครับ) ซึ่งแน่นอนระหว่าง master node และ worker node มีการตรวจสอบเรื่อง certificate ระหว่าง service ด้วย

                ตัวอย่าง Diagram ของระบบทั้งหมด[3]

    เรียนรู้การค่าเบื้องต้นก่อนการติดตั้ง[4]

    • MASTER_HOST : คือ ชื่อ host ที่ node ลูกเอาไว้ติดต่อและให้เข้าถึงจาก external client  เช่นเวลาสั่งสร้างเครื่องก็จะสั่งผ่านตัวนี้ ในกรณที่ต้องการทำ HA MASTER_HOST จะถูกใช้เป็น load balance โดยใช้ร่วมกับ DNS name โดยการคุยกันระหว่าง MASTER_HOST และ worker (node ลูก) จะใช้ port 443 และมีการเข้ารหัสและยืนยันด้วย TLS Certificate
    • ETCD_ENDPOINT : คือ บริการของ etcd service ซึ่งมีใน CoreOS Cluster ที่ติดตั้งไว้ ให้ใส่ไปให้หมดว่ามีเครื่องอะไรบ้าง คั่นด้วย , (ในที่นี้ไม่ได้ใช้ fleet สร้างเครื่อง หลังจากลงเสร็จจะใช้ kubectl สร้างแทน)
    • POD_NETWORK : เช่น 10.2.0.0/16 ใช้สำหรับกำหนดวง IP ของ pod (pod คือ ชื่อเรียก container อาจจะแค่ 1 container เหรือเรียกเป็นกลุ่มของหลาย ๆ container ที่สร้างด้วย kubernetes)
    • SERVICE_IP_RANGE : เช่น 10.3.0.0/24 ใช้สำหรับ service cluster VIPs ซึ่งควรจะอยู่คนละวงกับ pod_network ซึ่งเป็น ip ที่ไว้ให้ข้างนอกวงเข้าถึง มักจะเป็น IP สำหรับให้บริการ Service ต่าง ๆ และไว้สำหรับใช้งานคู่กับ kube-proxy
    • K8S_SERVICE_IP : เช่น 10.3.0.1 เป็น IP หนึ่งในวง SERVICE_IP_RANGE เพื่อให้บริการ Kubernetes API Service
    • DNS_SERVICE_IP : เช่น 10.3.0.10 เป็น IP หนึ่งในวง SERVICE_IP_RANGE ใช้สำหรับเป็น VIP ของ DNS Service เพื่อให้บริการ DNS ให้กับ worker แต่ละตัว

    วิธีการตั้งค่า TLS สำหรับ Kubernetes[4]

    • ทำการสร้าง Cluster Root CA  (ทุกไฟล์ต่อจากนี้ทำเก็บไว้ที่ CoreOS สักเครื่องหนึ่ง ถึงเวลาติดตั้ง Master, Worker ค่อยมาโหลดมาใช้ครับ)
      sudo openssl genrsa -out ca-key.pem 2048
      sudo openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"

    • ตั้งค่า openssl config สำหรับ api-server โดยการสร้างไฟล์ดังนี้
      vim openssl.cnf

      โดยมีเนื้อหาในไฟล์ดังนี้ (ให้ระบุ IP Service และ Master Host ลงไปด้วย)
      *หมายเหตุ : แทนที่เลข IP ใน <….>

      [req]
      req_extensions = v3_req
      distinguished_name = req_distinguished_name
      [req_distinguished_name]
      [ v3_req ]
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment
      subjectAltName = @alt_names
      [alt_names]
      DNS.1 = kubernetes
      DNS.2 = kubernetes.default
      DNS.3 = kubernetes.default.svc
      DNS.4 = kubernetes.default.svc.cluster.local
      IP.1 = <K8S_SERVICE_IP>
      IP.2 = <MASTER_HOST>
    • จากนั้นทำการสร้าง API Server Keypair ดังนี้
      sudo openssl genrsa -out apiserver-key.pem 2048
      sudo openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config openssl.cnf
      sudo openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile openssl.cnf

    • ต่อไปเป็นส่วนของสร้าง Cer ในเครื่องลูกทุกเครื่อง (สร้างทีละเครื่องนะครับ) ทำการสร้างไฟล์ดังนี้
      vim worker-openssl.cnf

      เนื้อหาในไฟล์ดังนี้ แทนที่ WORKER_IP ด้วยเครื่องที่ต้องการ

      [req]
      req_extensions = v3_req
      distinguished_name = req_distinguished_name
      [req_distinguished_name]
      [ v3_req ]
      basicConstraints = CA:FALSE
      keyUsage = nonRepudiation, digitalSignature, keyEncipherment
      subjectAltName = @alt_names
      [alt_names]
      IP.1 = <WORKER_IP>
    • จากนั้นทำการสร้าง Keypair ในแต่ละ Worker ดังนี้ (WORKER_FQDN คือชื่อที่จด domain ไว้ ไม่มีก็ใส่ /etc/hosts เอาก็ได้ครับ แต่ต้องใส่เองทุกเครื่อง)
      sudo openssl genrsa -out ${WORKER_FQDN}-worker-key.pem 2048
      sudo WORKER_IP=${WORKER_IP} openssl req -new -key ${WORKER_FQDN}-worker-key.pem -out ${WORKER_FQDN}-worker.csr -subj "/CN=${WORKER_FQDN}" -config worker-openssl.cnf
      sudo WORKER_IP=${WORKER_IP} openssl x509 -req -in ${WORKER_FQDN}-worker.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out ${WORKER_FQDN}-worker.pem -days 365 -extensions v3_req -extfile worker-openssl.cnf
    • สุดท้ายคือการสร้าง Keypair ของ Cluster Admin
       sudo openssl genrsa -out admin-key.pem 2048
       sudo openssl req -new -key admin-key.pem -out admin.csr -subj "/CN=kube-admin"
       sudo openssl x509 -req -in admin.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out admin.pem -days 365
    • ทำได้ครบแล้วก็จะได้ประมาณดังรูป (ยกตัวอย่างมี  4 worker ใช้วิธีเขียน gen-worker-keypair.sh เพื่อรันหลาย ๆ รอบ ลองหาวิธีเขียนดูเองนะครับ)

    วิธีการตั้งค่า Kubernetes บน CoreOS Cluster[5]

    เพื่อให้การติดตั้งง่ายขึ้น อย่าลืมกำหนดค่าต่าง ๆ จดไว้ก่อน ไม่งั้นจะงงได้ ประมาณนี้ครับ

    ETCD_ENDPOINT=http://a.b.c.d:2379,http://a.b.c.e:2379,http://a.b.c.f:2379
    SERVER_IP_NETWORK=?
    K8S_SERVICE_IP=?
    MASTER_HOST=?
    DNS_SERVICE_IP=?
    POD_NETWORK=?

    ทำการติดตั้ง Master Node

    • ทำการติดตั้ง CoreOS บน Master Node
    • สร้าง directory ดังนี้
      sudo mkdir -p /etc/kubernetes/ssl
    • ทำการ copy ที่สร้างไว้ก่อนหน้านี้มาไว้ใน folder ดังนี้
      File: /etc/kubernetes/ssl/ca.pem
      File: /etc/kubernetes/ssl/apiserver.pem
      File: /etc/kubernetes/ssl/apiserver-key.pem
    • เปลี่ยน permission และ owner file เฉพาะไฟล์ -key* ดังนี้
      sudo chmod 600 /etc/kubernetes/ssl/*-key.pem
      sudo chown root:root /etc/kubernetes/ssl/*-key.pem
    • จากนั้นตั้งค่า flannel network[3] เป็น network ที่เอาไว้เชื่อมแต่ละ pod ให้สามารถคุยกันได้ข้ามเครื่อง (ต้องทำทุก node รวม worker ด้วย) เพื่อสร้างวง virtual ip ให้กับ pod ดังนี้
      sudo mkdir /etc/flannel

      ทำการสร้างไฟล์ option.env

      sudo vim /etc/flannel/options.env

      เนื้อหาในไฟล์ดังนี้

      FLANNELD_IFACE=<Master IP>
      FLANNELD_ETCD_ENDPOINTS=http://<Master IP>:2379,http://<Node1 IP>:2379,http://<Node2 IP>:2379
    • จากนั้นทำการสร้าง flannel service ดังนี้
      sudo mkdir -p /etc/systemd/system/flanneld.service.d/
      sudo vim /etc/systemd/system/flanneld.service.d/40-ExecStartPre-symlink.conf

      เนื้อหาในไฟล์ดังนี้

      [Service]
      ExecStartPre=/usr/bin/ln -sf /etc/flannel/options.env /run/flannel/options.env
    • จากนั้นทำการตั้งค่า docker เพื่อกำหนดให้ใช้งานผ่าน flannel โดยสร้างไฟล์ config ดังนี้
      sudo mkdir -p /etc/systemd/system/docker.service.d
      sudo vim /etc/systemd/system/docker.service.d/40-flannel.conf

      เนื้อหาในไฟล์ดังนี้

      [Unit]
      Requires=flanneld.service
      After=flanneld.service
      [Service]
      EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env

      โดยที่ทำสร้างไฟล์ docker_opts_cni.env ขึ้นมาประกอบดังนี้

      sudo mkdir -p /etc/kubernetes/cni
      sudo vim /etc/kubernetes/cni/docker_opts_cni.env

      เนื้อหาในไฟล์ดังนี้

      DOCKER_OPT_BIP=""
      DOCKER_OPT_IPMASQ=""
    • จากนั้นทำการ restart docker service สักรอบดังนี้
      sudo systemctl restart docker
    • หนังจากนั้นทำการสร้าง config ไฟล์สุดท้ายสำหรับ flannel ดังนี้
      sudo mkdir -p /etc/kubernetes/cni/net.d
      sudo vim /etc/kubernetes/cni/net.d/10-flannel.conf

      เนื้อหาในไฟล์ดังนี้

      {
       "name": "podnet",
       "type": "flannel",
       "delegate": {
       "isDefaultGateway": true
       }
      }
    • ทำการ start flannel service และตรวจสถานะการทำงานดู
      sudo systemctl start flanneld
      sudo systemctl enable flanneld
      sudo systemctl status flanneld
    • จากนั้นทำการสั่งให้ทำ vxlan ผ่าน etcdctl ให้กับทุก node ดังนี้ (เปลี่ยน IP เป็นวงที่ต้องการ)
      sudo etcdctl set /coreos.com/network/config "{\"Network\":\"10.2.0.0/16\",\"Backend\":{\"Type\":\"vxlan\"}}"
    • จากนั้นทำการสร้าง kubelet service ดังนี้
      sudo vim /etc/systemd/system/kubelet.service

      เนื้อหาในไฟล์ดังนี้ (KUBELET_IMAGE_TAG version สามารถตรวจสอบล่าสุดได้ที่ https://quay.io/repository/coreos/hyperkube?tab=tags)

      [Service]
      Environment=KUBELET_IMAGE_TAG=v1.6.2_coreos.0
      Environment="RKT_RUN_ARGS=--uuid-file-save=/var/run/kubelet-pod.uuid \
        --volume var-log,kind=host,source=/var/log \
        --mount volume=var-log,target=/var/log \
        --volume dns,kind=host,source=/etc/resolv.conf \
        --mount volume=dns,target=/etc/resolv.conf"
      ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
      ExecStartPre=/usr/bin/mkdir -p /var/log/containers
      ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/run/kubelet-pod.uuid
      ExecStart=/usr/lib/coreos/kubelet-wrapper \
        --api-servers=http://127.0.0.1:8080 \
        --container-runtime=docker \
        --allow-privileged=true \
        --pod-manifest-path=/etc/kubernetes/manifests \
        --cluster_dns=<DNS_SERVICE_IP> \
        --cluster_domain=<CLUSTER_DNS_NAME>
      ExecStop=-/usr/bin/rkt stop --uuid-file=/var/run/kubelet-pod.uuid
      Restart=always
      RestartSec=10
      
      [Install]
      WantedBy=multi-user.target
    • ทำการ start kubelet service และตรวจสถานะการทำงานดู (ต้องรอสักพักเพราะ service จะต้องโหลด image มาติดตั้งให้ในการ start ครั้งแรก สามารถใช้คำสั่ง journalctl -xe เพื่อตรวจสอบสถานะการทำงาน) ซึ่งจะพบว่ายัง error เพราะยังไม่ได้ลง kube-apiserver (แนะนำลงตัวอื่นให้เสร็จให้หมดแล้วค่อยมา start kubelet service ก็ได้)
      sudo systemctl start kubelet
      sudo systemctl enable kubelet
      sudo systemctl status kubelet
    • ขั้นตอนต่อไปเป็นการสร้าง Rest API สำหรับจัดการ kubernetes (รวมถึงสามารถติดตั้งหน้าจอ GUI เพื่อควบคุมผ่าน Web ได้) โดยสร้างไฟล์ดังนี้
      sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml

      เนื้อหาในไฟล์มีดังนี้ (ระวังเรื่องวรรคด้วยนะครับ ถ้าจะพิมพ์เองไม่แนะนำ copy ไปแก้ดีกว่า)

      apiVersion: v1
      kind: Pod
      metadata:
        name: kube-apiserver
        namespace: kube-system
      spec:
        hostNetwork: true
        containers:
        - name: kube-apiserver
          image: quay.io/coreos/hyperkube:v1.6.2_coreos.0
          command:
          - /hyperkube
          - apiserver
          - --bind-address=0.0.0.0
          - --etcd-servers=${ETCD_ENDPOINTS1},${ETCD_ENDPOINTS2},${ETCD_ENDPOINTS3}
          - --allow-privileged=true
          - --service-cluster-ip-range=${SERVICE_IP_RANGE}
          - --secure-port=443
          - --advertise-address=${ADVERTISE_IP}
          - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota
          - --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem
          - --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
          - --client-ca-file=/etc/kubernetes/ssl/ca.pem
          - --service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem
          - --runtime-config=extensions/v1beta1/networkpolicies=true
          - --anonymous-auth=false
          livenessProbe:
            httpGet:
              host: 127.0.0.1
              port: 8080
              path: /healthz
            initialDelaySeconds: 15
            timeoutSeconds: 15
          ports:
          - containerPort: 443
            hostPort: 443
            name: https
          - containerPort: 8080
            hostPort: 8080
            name: local
          volumeMounts:
          - mountPath: /etc/kubernetes/ssl
            name: ssl-certs-kubernetes
            readOnly: true
          - mountPath: /etc/ssl/certs
            name: ssl-certs-host
            readOnly: true
        volumes:
        - hostPath:
            path: /etc/kubernetes/ssl
          name: ssl-certs-kubernetes
        - hostPath:
            path: /usr/share/ca-certificates
          name: ssl-certs-host
      
    • เพื่อให้สมบูรณ์ไปในคราวเดียว ต่อด้วยติดตั้ง kube-proxy ดังนี้
      sudo vim /etc/kubernetes/manifests/kube-proxy.yaml

      มีเนื้อหาในไฟล์ดังนี้

      apiVersion: v1
      kind: Pod
      metadata:
        name: kube-proxy
        namespace: kube-system
      spec:
        hostNetwork: true
        containers:
        - name: kube-proxy
          image: quay.io/coreos/hyperkube:v1.6.2_coreos.0
          command:
          - /hyperkube
          - proxy
          - --master=http://127.0.0.1:8080
          securityContext:
            privileged: true
          volumeMounts:
          - mountPath: /etc/ssl/certs
            name: ssl-certs-host
            readOnly: true
        volumes:
        - hostPath:
            path: /usr/share/ca-certificates
          name: ssl-certs-host
      
    • ยังไม่หมดต่อด้วย kube-controller-manager ใช้ในการทำ scale, replica โดยเป็นตัวควบคุม API อีกชั้นหนึ่ง ทำการสร้างไฟล์ดังนี้
      sudo vim /etc/kubernetes/manifests/kube-controller-manager.yaml

      มีเนื้อหาในไฟล์ดังนี้

      apiVersion: v1
      kind: Pod
      metadata:
        name: kube-controller-manager
        namespace: kube-system
      spec:
        hostNetwork: true
        containers:
        - name: kube-controller-manager
          image: quay.io/coreos/hyperkube:v1.6.2_coreos.0
          command:
          - /hyperkube
          - controller-manager
          - --master=http://127.0.0.1:8080
          - --leader-elect=true
          - --service-account-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem
          - --root-ca-file=/etc/kubernetes/ssl/ca.pem
          resources:
            requests:
              cpu: 200m
          livenessProbe:
            httpGet:
              host: 127.0.0.1
              path: /healthz
              port: 10252
            initialDelaySeconds: 15
            timeoutSeconds: 15
          volumeMounts:
          - mountPath: /etc/kubernetes/ssl
            name: ssl-certs-kubernetes
            readOnly: true
          - mountPath: /etc/ssl/certs
            name: ssl-certs-host
            readOnly: true
        volumes:
        - hostPath:
            path: /etc/kubernetes/ssl
          name: ssl-certs-kubernetes
        - hostPath:
            path: /usr/share/ca-certificates
          name: ssl-certs-host
    • สำหรับอันสุดท้ายก็จะเป็น kube-scheduler (สำหรับการใช้งานเนื่องจากยังไม่ได้ลองใช้งาน ยังไม่เข้าใจว่าทำงานอย่างไร ถ้าว่างจะมาแก้อีกทีครับ) ทำการสร้างไฟล์ดังนี้
      sudo vim /etc/kubernetes/manifests/kube-scheduler.yaml

      มีเนื้อหาในไฟล์ดังนี้

      apiVersion: v1
      kind: Pod
      metadata:
        name: kube-scheduler
        namespace: kube-system
      spec:
        hostNetwork: true
        containers:
        - name: kube-scheduler
          image: quay.io/coreos/hyperkube:v1.6.2_coreos.0
          command:
          - /hyperkube
          - scheduler
          - --master=http://127.0.0.1:8080
          - --leader-elect=true
          resources:
            requests:
              cpu: 100m
          livenessProbe:
            httpGet:
              host: 127.0.0.1
              path: /healthz
              port: 10251
            initialDelaySeconds: 15
            timeoutSeconds: 15
      
    • ในส่วนของ Calico จะใช้สำหรับทำ Network Policy เนื่องจากเป็น Optional จึงขอยังไม่ตั้งค่าสำหรับบริการนี้
    • ในกรณีที่ต้องการแจ้ง systemd ว่าเรามีการเปลี่ยนข้อมูลใน config และต้องการ rescan ทุกอย่างอีกครั้งให้สั่งดังนี้
      sudo systemctl daemon-reload
    • จากนั้นทดสอบ restart kubelet service ใหม่อีกครั้งและตรวจสอบ status หรือ journalctl -xe เพื่อดูว่าการทำงานปกติหรือไม่ ถ้าไม่แก้ให้ถูกต้องแล้ว restart ใหม่อีกครั้งไปเรื่อย ๆ จนกว่าจะปกติ
      sudo systemctl restart kubelet

      จบตอนแรกไปก่อนนะครับ ตอนต่อไปจะต่อด้วย worker node และ addon อื่น ๆ

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

    Reference :

    [1] [Kubernetes] Deploy Docker Container บน Google Container Engine : https://www.nomkhonwaan.com/2016/04/12/deploy-docker-container-on-google-container-engine

    [2] วิธีสร้าง CoreOS Cluster : https://sysadmin.psu.ac.th/2017/05/04/setup-coreos-cluster/

    [3] How to Deploy Kubernetes on CoreOS Cluster : https://www.upcloud.com/support/deploy-kubernetes-coreos/

    [4] CoreOS -> Cluster TLS using OpenSSL : https://coreos.com/kubernetes/docs/latest/openssl.html

    [5] CoreOS -> CoreOS + Kubernetes Step By Step : https://coreos.com/kubernetes/docs/latest/getting-started.html

    [6] CoreOS -> Tectonic, Kubernetes cluster orchestrator with enterprise integration  : https://coreos.com/tectonic/docs/latest/