Improves performance ให้กับ MYSQL Galera Cluster

 

หนึ่งสิ่งที่ได้เจอหลังจากใช้ Galera Cluster มาใน Production รู้สึกว่าเอ้ะทำไม Performance มันตก !!

จริงมันช้าแปลกๆอยู่ละ พึ่งสังเกตุ ถถถถถ

วันนี้เลยขอเขียนบทความนี้ เผื่อเป็นทางออกให้หลายๆคนที่กำลังใช้ Galera Cluster อยู่

” binary logging ” และ ” innodb_flush_log_at_trx_commit  ” คือพระเอก ในวันนี้

ซึ่งเจ้าสองตัวนี้เราจะต้องไปจัดการมันในไฟล์ .cnf หรือ galera.cnf ขึ้นอยู่กับเราจัดการไฟล์ Config สำหรับ mysql galera cluster ของเรายังไง

 

innodb_flush_log_at_trx_commit

เป็น Option ที่ให้เรา config ได้ โดยจะเป็นสิ่งที่เกี่ยวข้องกับการ Write และ Flush log

โดยจะมีทั้งหมด 3 options ด้วยกัน

  • innodb_flush_log_at_trx_commit = 0 จะทำการ Write และ Flush log 1 ครั้งต่อ 1 วินาที
  • innodb_flush_log_at_trx_commit = 1 [Default]  จะทำการ Write และ Flush log ทุกๆ transaction
  • innodb_flush_log_at_trx_commit = 2  จะทำการ Write ทุกๆ transation แต่จะ Flush log ทุกๆ 1 วินาที

*Transation ใดๆ ที่ไม่ได้ Write แต่ไม่ได้ Flush อาจจะทำให้ข้อมูลหายได้ ถ้าเกิด crash ! ใน Database ปกติ ซึ่งหากเป็นปกติผมจะแนะนำให้ใช้เป็น innodb_flush_log_at_trx_commit = 1

แต่สำหรับ Galera cluster นั้นเป็น synchronous replication แปลว่า ทุก Commit ของแต่ละ transaction ที่ได้ commit ลง Node แรกนั้นได้ Sync ไปยัง Node อื่นๆ ใน Cluster อยู่แล้ว ทำให้ในเคสนี้เราเปิดเป็น innodb_flush_log_at_trx_commit = 2 ได้เลย!! ยกเว้น node ทั้งหมดใน Cluster เราจะพังพร้อมกัน ถถถ

 

binary logging

เป็นสิ่งที่จะเก็บการเปลี่ยนแปลงต่างๆ ไม่ว่าจะเป็นในแง่ของ Data หรือ structure เช่น CREATE, ALTER, INSERT, UPDATE and DELETE ซึ่งเป็น statements ที่จะทำให้เกิดการเปลี่ยนแปลงกับข้อมูลใน Table  จะทำการ Log ทั้งหมด

แต่ถ้าเป็นพวก SELECT  หรือ SHOW จะไม่ได้มีการ Log ใดๆ

ซึ่งสิ่งที่เราต้องทำคือการเปิดเจ้า Binary logging ตัวนี้ พอเราไปไล่ Code ใน Database เราจะเจอว่า ไม่ว่าเราเปิดหรือปิด Bin-log มันก็ยังคงไปเรียก function log_and_order แต่เป็นการมาจาก class ที่แตกต่างกัน

  • จาก TC_LOG_BINLOG ในกรณีที่ Binary logging ได้ทำการ enabled
  • จาก TC_LOG_MMAP ในกรณีที่ Binary logging ได้ทำการ disabled

ซึ่งไอ้เจ้า innodb_flush_log_at_trx_commit มันจะถูกเรียกใช้เฉพาะเมื่อมี Class TC_LOG_BINLOG หรือแปลอีกทีคือ เราจำเป็นที่จะต้องเปิด Binary logging เพื่อให้สามารถใช้ Option innodb_flush_log_at_trx_commit ได้

หากเป็นการเรียกผ่าน TC_LOG_MMAP สิ่งที่เกิดขึ้นคือมันจะไปผ่าน TC_LOG_MMAP::log_one_transaction แปลว่าจะมีการ Log ทุกๆ Transation นั้นเป็นสาเหตุที่ทำให้ Write preformane ของเราช้าลง

 

ซึ่งสรุปได้ว่า ถ้าจะทำให้  Write performance ของเราดีขึ้น จะต้องปรับเป็น innodb_flush_log_at_trx_commit  = 2 และ เปิดใช้งาน Binary logging ด้วย

ซึ่งเราจำเป็นที่จะต้องปรับ Config นี้ไปยังทุกๆ node ใน Cluster ด้วย

 

หลังจากนั้นผลที่ได้จากการทดสอบจาก Record ใน Table จำนวน 2,000,000 ด้วย Tools sysbench โดยมีการ Setup Lab สำหรับการทดสอบ ดังนี้

3 Servers สำหรับ Mysql Galera cluster โดย Memory 2GB

และ 1 Servers สำหรับการยิง Load test จาก Sysbench

 

 

ซึ่งทำให้ได้ผลว่า Performance โดยรวมดีขึ้นประมาณ 15% ทั้งนี้ขึ้นอยู่กับจำนวน Record ด้วย

 

จบฮะ ใครมีอะไรสงสัยส่ง Message มาคุยกันได้ที่ Facebook : Issaret Prachitmutita

และเร็วๆนี้จะมี Class Jump into DevOps รอบ 2 ซึ่งครอบคลุมเนื้อหา Docker , Rancher , Circleci, ELK for logging , API Gateway with KONG  ใครสนใจทักแชทมาลงชื่อไว้ฮะ ได้วันเวลาที่แน่นอนจะแจ้งไป

 

ขอบคุณครับ.

 

อ่านต่อ:

https://lists.launchpad.net/maria-developers/msg10086.html

https://jira.mariadb.org/browse/MDEV-3861

http://worklog.askmonty.org/worklog/Server-Sprint/?tid=116

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

 

 

 

เมื่อวันอาทิตย์ที่ผ่านมา (10/06/2018) มีโอกาสได้ไปเล่า การทำ CI/CD ด้วยตัวเองมาที่งาน Code Mania 111: Diversity Makes Us Stronger 

ซึ่งเป็นที่มาของ Blog นี่ที่มีมูลค่าถึง 25,000+ บาท ไว้จะเล่าต่อว่าทำไม??

ไหนๆก็เตรียมสไลด์มาละ มีภาพประกอบละ ก็ถือโอกาสมาเล่าอีกครั้งในบล็อกร้างๆที่นี่ เผื่อสรุปให้ใครที่ไม่ได้เข้าฟัง

โดยคอนเซป ของครั้งนี้คือ ” ใครๆ ก็ทำ CI/CD ของตัวเองได้ด้วย Rancher และ CircleCI “

 

 

What is CI/CD ? 

ที่นี่ก่อนเราจะไปไกล เรามาตั้งคำถาม และ ตอบคำถามกันให้ชัดๆว่าเจ้า CI/CD นี่มันคืออะไร

Continuous integration , Continuous Delivery , Continuous Deployment  ก็คือชื่อเต็มๆของมัน และ เดววนะ แค่ CD ก็มีตัวย่อถึงสองคำ

แต่จริงๆจะบอกว่า เราอย่าไปสนใจชื่อมันเลย ดูรูป ก็น่าจะเข้าใจได้ในระดับหนึ่ง สำคัญคือ เรามองว่ามันคือ Process ตั้งแต่ Source ของเรา ในที่นี่ อาจจะเป็น GITHUB ไปจนถึงไหน เช่น CI เรา Focus กระบวนการต่างๆ ในขั้นตอน Build  หากให้เจาะภาพชัดขึ้น ก็คือ การทำ รวมไฟล์ การ Build ต่างๆนาๆ
แต่สำหรับ CD เรามองมันเป็น Process ที่ต่อเนื่องยาวไปจนถึงปลายทางซึ่งคือ Server ( Production หรือ Staging ) ก็ว่ากันไป

สรุป เราจะมาพาเอา Code ของเรา ไม่ว่ามันจะอยู่ที่ GITHUB หรือ ใครกำลังจะย้ายไป GITLAB เราจะถีบมันขึ้น Production อย่าง Automatic ว่างั้นเหอะ

 

Why we need CICD? 

โอเคมาลองดูว่า  Process ถ้าเราจะ Deploy Application ของเราคร่าวๆ เป็นยังไง ยกตัวอย่างถ้าเราเขียน Node.js สิ่ง basic สุดที่เราจะทำการ Deploy App ของเรานั้นก็คือการเริ่มที่จะ SSH ไปยัง Server จากนั้นรัน Git clone, npm install เพื่อติดตั้งสิ่งต่างที่จำเป็น , npm start สั่งรัน App ของเรา

 

ซึ่งมันอาจจะมองเร็วๆ เหมือนเออ ก็จริง ก็น่าจะมีแค่นี้ ไม่ใช่หรอ จะมาเสียเวลาเข้าฟัง Session นี้ หรือ เสียเวลาอ่านบทความนี้ต่อทำไม

โอเค ถ้าผมลอง เพิ่ม Process อีกหน่อย ถ้าเรามี Test ด้วยเราก็ควรรัน Test ก่อนขึ้น Production ถูกมั้ยครับ

 

มันก็ดูยังไม่ได้แย่อะไร ก็แค่พิมคำสั่งเพิ่มขึ้นบรรทัดนึง จะไปหนักหนาอะไร   ถูกมั้ย ก็ดูสบายๆ

 

 

แต่ถ้าเป็นภาพนี้ละ ? ถ้าเราไม่ได้ Deploy ไปแค่ Server เดียว แต่เราต้อง Deploy ไปอีก 4-5 Server ต่อ 1 Service

มันจะเริ่มไม่สนุกละ นึกภาพว่า หากเราแค่แก้ Bug หรือ อะไรเล็กน้อยๆ แต่ต้องรีบอัพเดทให้ user เราได้ใช้งาน

เราอาจจะ Fix Issue แค่ 10-15 นาที แต่เสียเวลาอีกเท่าไหร่ ในการไล่ SSH ไป Deploy App เราทีละ Server ละ

เรื่องนี้จะเริ่มมีบทดราม่าละ เริ่มจะไม่สนุกอีกต่อไป เชื่อเรา เราเจอมาแล้ว Y_Y

 

 

และยัง มันยังไม่จบ ถ้าหากคุณใช้ Docker แล้วด้วย Step ในการ Deploy ก็ยิ่งเพิ่มขึ้นอีกหลายขั้นเลย ไม่ว่าจะเป็น Build , push , pull , run

แค่คิดก็เหนื่อยแทนแล้วเอาจริงๆ

 

แนะนำพระเอกของเรา 2 คน

 

 

พระเอกคนแรก : CircleCI

ว่ากันสั้นๆ เจ้า CircleCI มันคือ online service (tools) ที่ออกแบบมาเพื่อ CI/CD โดยเฉพาะ จะเหมือนพวก Drone.io หรือ อื่นๆต่างๆนาๆ แต่ แต่

จะไม่เหมือนกับ Jenkins ที่ตาลุงนั้นถูกออกแบบมาให้เพื่อ Task Automate ซึ่งไม่ได้เจาะจงแค่ CI/CD ส่วนตัวเคยใช้รู้สึกว่ายังเหนื่อยเกินไป

ที่เราจะมาใช้มันเพื่อ CI/CD ไม่คุ้มสักเท่าไหร่

และ เจ้า circleCI ประสิทธิ์ภาพค่อนข้างดี Build เร็วสุดดด ใช้งานง่ายด้วยการเขียน Config เป็นหลัก

แถมมม สิ่งที่ชอบที่สุดคือ เราเขียน Config ใน sourcecode ของเรา แปลว่าเรา Commit มันไปกับ GIT ของเราด้วย เราสามารถเห็นการเปลี่ยนแปลง

จากอดีตถึงปัจจุบันได้ ไม่ต้องห่วงว่าอยู่ๆใกล้จะเปลี่ยนอะไรบน Service แล้วเราไม่รู้  เพราะหลักการของมันคือ ตัว CircleCI มันจะมาอ่านไฟล์ Config

ที่อยู่ใน Repo ของเราเอง

 

 

พระเอกคนที่สอง : Rancher

ถ้าจะให้นิยามมัน เราคงเรียกได้ว่ามันคือ Tools ที่รวมความสามารถในการบริหารจัดการ สร้าง ลบ ต่างๆนาๆ สำหรับ Server และ บริหารจัดการ Docker Container สำหรับ Deploy แอปของเรา ไว้ในตัวเดียว

แปลว่าอะไร แปลว่าเราสามารถใช้มันในการสั่งสร้าง Cloud service ขึ้นใหม่ หรือ สั่งลบ ได้จากตัว Rancher เอง โดย Official สามารถเชื่อมต่อได้หลายเจ้า ร่วมถึง DigitalOcean ด้วย  ที่นี่การจะใช้ Rancher Deploy แอปของเรา เราจะต้องผ่านการเตรียม Docker Image ที่พร้อมใช้งานก่อน

เพราะ Rancher มันทำหน้าที่แค่หยิบไอ้ Docker Image ไป Build ไป Deploy บน Server ต่างๆที่มันจัดการให้เรา

 

โดย Rancher ตอนนี้ มี 2 Version หลักๆ

  • Rancher 1.6 โดย นี้เปิดให้เราเลือกได้ว่าส่วนจัดการ Docker Contrainer เราจะใช้อะไร Cattle , Docker swarm, Kubernetes
  • Rancher 2.0 โดย เวอร์ชั่นนี้ Rancher ได้เปลี่ยนมา Focus ที่การใช้ร่วมกับ Kubernete เป็นหลัก เรียกได้ว่ามัน ในส่วนที่จัดอการ Docker contrainer มันผลักภาระไปใช้ Kubenete นั้นแหละ

โดยในบทความนี่เราจะ Focus ที่ Rancher 1.6 ด้วยความที่เราใช้ Rancher มาปีกว่าละ เริ่มจาก Version นี้มา ยังไม่ได้เปลี่ยนไป Rancher 2.0 ที่พึ่งจะเปิดตัวมาได้เดือนเศษ ส่วนตัวยังมีความกังวลในหลายๆจุด ด้วยความที่เป็นของใหม่ แน่นอนบัคต้องมาแน่นอนน ด้วยความที่ CI/CD ควรเป็นระบบที่เราต้องวางใจมันได้ระดับหนึ่ง ไม่ควรสร้างปัญหาเพิ่ม เราเอามันมาใช้เพราะต้องการลดเวลางานเรา ไม่ใช่มารับมือกับบัคที่ไม่รู้จะโผล่มาตอนไหน

 

สรุปภาพรวม

  • เราเก็บ Code ของเราไว้ที่ github / gitlab โดยใน Code ของเราจะมี config ของ circle ci ด้วย 1 ไฟล์
    • ทุกครั้งที่มีการ commit ,  push ขึ้น github จะส่ง webhook ไปบอก circle ci ให้ทำงาน
  • Circleci รับบทเป็นผู้ทำงานถึกแทนเราทั้งหมด
    • ไม่ว่าจะเป็น npm install , Docker build image , push  ทุกอย่าง
    • รวมถึงเป็นคนไปสะกิดบอก Rancher ให้ไปหยิบของ Docker image ไป Deploy ด้วย
  • Rancher ผู้ control ทุกอย่างที่เกี่ยวกับ Server
    • เมื่อ circleci มาสะกิด  rancher จะทำการ Deploy service เราไปยัง Server ต่างที่มันดูแลอยู่

 

และ Rancher ไม่ได้ใช้ Spec server สูงอะไร แค่แรม 2 GB ก็เพียงพอแล้ววว เอาจริงๆ

ซึ่งหากเรารัน Rancher ของเราที่ Scaleway


เพียง 150 บาทต่อเดือน ก็เพียงพอสำหรับการที่เราจะมี CI/CD ของตัวเองแล้วว
ส่วน Circleci Plan Free สามารถใช้งานได้มากพอระดับหนึ่งเลย ถ้าจำไม่ผิดน่าจะ 1500 นาทีสำหรับการ build ต่อเดือน

 

4 Steps for making your pipeline

  1. Prepare your Rancher server
  2. Add new server (worker)
  3. Dockerfile
  4. Circleci config

 

Prepare your Rancher server

ในหน้าเว็บของ Rancher มีหลากหลายวิธีสำหรับการ Deploy มาก

  • SINGLE CONTAINER
  • SINGLE CONTAINER – EXTERNAL DATABASE
  • SINGLE CONTAINER – BIND MOUNT MYSQL VOLUME
  • Full Active/Active HA

แต่ในบทความนี้ เราจะโฟกัสกันที่ SINGLE CONTAINER – EXTERNAL DATABASE คือการ Deploy และเชื่อมให้เจ้า Rancher ไปใช้ Mysql ภายนอก

เพื่อไม่ให้ลำบากมานั่งดูว่าจะ setup ยังไง เราได้เตรียม docker-compose สำหรับงานนี้ให้เรียบร้อย

https://github.com/Ima8/Make-your-own-CI-CD-pipelines

แค่เอาไป docker-compose up -d จบ

Rancher ของขึ้นจะพร้อมทำงานที่ Port :8080 ในเวลาไม่นาน

 

!! คำเตือนกรุณา เปลี่ยน Password ใน Docker-compose.yml ก่อนนำไปใช้งานจริง 

 

Rancher first time

 

เรื่องที่สำคัญเรื่องหนึ่งเลยคือ หลังจากที่เข้ามาครั้งแรก กรุณา ได้โปรด เข้าไป Set access control ด้วยครัชชช ผมเจอหลายเคสที่เปิด โล่งๆ ไม่มีการ Set access control นานหลายเดือน

นั้นหมายความว่า ใครก็สามารถ Access มาจัดการ Server ของคุณได้อย่างอิสระนะ อย่าลืมว่าเราใช้ Rancher คุม server ของเรา ฉะนั้น ป้องกันอย่าให้ใครมา Access เจ้า Rancher.

และล่าสุดหลังจากที่เราไปบรรยายที่ CodeMania เนื่องจากเวลาเหลือน้อยเลยข้ามตรงนี้ไป เลยเป็นที่มาของงงง

 

มีใครสักคนเข้ามาที่ Rancher ที่เราไม่ได้ Set access control วันนั้น เนื่องจากตั้งใจว่าจะปิดหลังจากจบ Session แต่ด้วยความหมดพลังและลืมมันไป
สุดท้ายจึงเป็นที่มาของ 25 servers ที่งอกตามมา และ เลือก Package ที่แพงที่สุดดด!! WTF!! โกรธอะไรฉันนนนน  $885.92 พอคำนวณเป็นเงินไทยแล้วลมจับเลยยย

 

ฉะนั้นใครที่อ่านบทความนี้ จงเซ็ท Access control สะ

 

 

ส่วนประกอบหลักของ Rancher

 

  1. Environment : เป็นสร้างสภาพแวดล้อม โดยเราสามารถแยกสภาพแวดล้อมออกจากกันเป็นส่วนๆได้ และในจุดนี้เองเป็นตัวกำหนดว่าเราจะใช้อะไรในการ Manage Docker contrainer ของเรา ซึ่งส่วนตัวผมและบทความนี้เราจะใช้ Cattle กันครับ ซึ่งเป็น Product ที่ Rancher เป็นคนทำออกมาเอง
  2. Stack: เป็นการกรุ๊ป Service ไว้ด้วยกัน เช่น เราใช้สำหรับ Stack staging , หรือ Stack RabbitMQ เป็นต้น
  3. Service: คือตัว Service ที่เราจะรัน มองว่ามันคือ Docker image ที่เราจะรันก็ได้
  4. Container:  1 service สามารถเอาไปรันได้หลาย Container อาจจะ 1 server 1 container หรือ 1 server หลาย container ก็ได้ ขึ้นอยู่กับเราออกแบบยังไง เช่น ตัว Application เราอาจจะจำกัดว่า 1 contrainer ใช้ CPU ได้ 1 core ดังนั้นถ้าจะสเกลให้ใช้ได้หลาย CPU Core ก็จำเป็นที่จะต้อง Deploy หลาย Contrainer ใน 1 server เป็นต้น

 

Environment

โดยในการสร้าง Environment นั้น หลักการค่อนข้างตรงไปตรงมา เราต้องการ Environment ชื่ออะไร และ จะให้จัดการ Docker Contrinner ด้วย Platform ใด ไม่ว่าจะเป็น Cattle( ส่งที่ Rancher เป็นคนทำเอง) หรือเจ้าอื่นๆ ไม่ว่าจะเป็น Kubernetes ก็เช่นกัน ซึ่งในบทความวันนี้เราจะโฟกัสไปที่การใช้ Cattle ซึ่งมันค่อนข้างง่ายและตรงไปตรงมา ปัจจุบันผมใช้เจ้านี้มาก็ไม่เจอปัญหาจุกจิกกวนใจอะไร 

 

 

Add new stack

 

การ Add stack ก็เสมือนการที่เรากรุ๊ป Service ของเราเป็นส่วนๆนั้นเอง เช่น Stack สำหรับ Message queue อย่าง RabbitMQ , Stack สำหรับ web frontend เป็นต้น

โดยการสร้าง Stack ใหม่เราจะสร้างแบบง่ายๆ แค่ตั้งชื่อ อย่างเดียวก็ได้ หรือ เราอยากจะสร้าง Stack พร้อมกับ สร้าง Service ภายใน Stack ของเราด้วยการใช้ Docker-compose และ Rancher-compose ในครั้งเดียวเลยก็ได้

โดยความแตกต่างระหว่าง Docker-compose และ Rancher-compose คือ

  • Docker-compose เป็นตัวจัดการด้าน Image สิ่งที่เราจะ Deploy ว่า Deploy อะไร หรือ Service ไหน link กับ Service ไหน เสมือนเราเขียน Docker-compose ปกติเลย
  • Rancher-compose แต่สิ่งที่เพิ่มขึ้นมาอย่างเจ้านี้คือ การที่จะมาเป็นตัว Control ภาพรวมอีกที เช่น กำหนดว่าจะให้ Deploy service ใน Docker-compose นั้นกี่ contrainer  หรือ การเขียน config สำหรับ
    health_check เพื่อให้ตัว Rancher คอยเช็คได้ว่า Service ที่เรากำลัง Deploy นั้น ให้ดู health check ที่ port ไหน หรือ Path ไหนอะไรยังไง เป็นต้น

 

จากภาพเป็นตัวอย่าง Stack ที่ชื่อ “Staging” ซึ่งเราทำการกรุ๊ป Service ต่างๆ สำหรับ Staging ไว้ตรงนี้ เผื่อให้ง่ายต่อการ Monitor และ จัดการ ต่างๆนาๆ  โดยในหน้านี้เราจะเห็นได้ว่ามันจะแสดงเลยว่า Service ของเรานั้น ชื่ออะไร , รันด้วย Docker image อะไร , รันอยู่กี่ Containner

 

 

ตัวอย่างการสร้าง Service ใหม่ ซึ่งเพื่อนๆสามารถไปลองเล่น ลองสร้างได้เลย ซึ่งในงานก็มีการทำ Demo เพื่ออธิบายสเตปการสร้างต่างๆนา โดยหลักๆ ตรงนี้ แค่เราตั้งชื่อ และ ระบุว่าจัด Deploy ด้วย Docker Image อะไร ซึ่งประกอบอื่นๆเราสามารถค่อยๆเล่น ค่อยๆศึกษาได้ภายหลัง

 

Add new server (worker)

 

ด้วยหนึ่งในความสามารถหลักของ Rancher นั้นคือการจัดการ Server (Cloud server) ให้เราด้วย ไม่ว่าจะเป็นการ สร้าง ลบ และ แก้ไขบางอย่าง ทำให้เราแทบไม่ต้องขยับไปข้างนอก Rancher เลย

วิธีการค่อนข้างง่ายและตรงไปตรงมาเสมือนเราใช้งานผ่านหน้าเว็บของ Cloud เจ้านั้นๆเลย

 

ยกตัวอย่างเช่น ถ้าหากต้องการจะให้ Rancher ไปสร้าง Server ที่ DigitalOcean ให้ เราแค่ไปนำ Access Token จากหน้าเว็บมาผ่านการคลิกลิงค์ “Apps & API” แล้วนำ Access Token นั้นมากรอก จากนั้นเราก็แค่คลิกๆ เลือกๆ แต่ละ option เช่น Region ไหน , Size ไหน เป็นต้น

 

ในการสร้าง Server เจ้า Rancher จะทำการสร้าง Private-Public key ให้เองเลย แล้วทำการไปผูกกับ DigitalOcean ให้เรียบร้อย ทำให้มีความปลอดภัยสูงมาก เนื่องจากจะล็อกอินเข้า Server ที่สร้างใหม่นั้น ทำได้เพียงต้องอาศัย Pair key ดังกล่าวเท่านั้น

 

ฉะนั้นย้ำอีกครั้ง เราต้องรักษาให้ Server Rancher ของเรารอดปลอดภัย มีความปลอดภัยมากที่สุด ไม่ว่าจะเป็นการอย่าลืมตั้งรหัส ทั้งตัว Rancher เอง และ รหัสสำหรับตัว Server ที่ Rancher อยู่ก็ควรมีความปลอดภัยที่เพียงพอ

 

Dockerfile

การที่จะ Deploy application ของเราด้วย Rancher นั้น ทุกอย่างจะต้องถูก Deploy ผ่าน Docker เท่านั้น  นั้นหมายความว่าเราจะต้องเตรียม Docker image ของเราที่ภายในประกอบไปด้วย Application ที่พร้อมรันเลย

 

ตัวอย่าง Dockerfile นี้ คือการสร้าง Docker image สำหรับ Nodejs application   ซึ่งข้อสำคัญคือ จะต้องทำการ Build และ Push Docker image นี้ขึ้นไปยัง Dockerhub หรือ Docker registry ใดๆ ก่อน เนื่องจากตัว Rancher เองจะไม่ได้สามารถ Build Docker ได้ จะทำเพียงการหยิบ Docker image มาใช้ตรงๆเลย ซึ่งตรงนี้ละเราจะผลักหน้าที่ให้ Circleci เป็นคนจัดการ Build และ Push Docker image ให้กับเรา

 

Circleci

พระเอกอีกคนหนึ่งของเรา ที่จะมาจัดการงานน่าเบื่อ ซ้ำๆ ให้เรา เป็นคนที่จัดระเบียบทุกอย่างให้เข้าที่อย่างง่ายดายและไม่ต้องเสียเวลาอีกต่อไป ให้คุณได้โฟกัสกับงานเดฟอย่างเต็มที่

 

ก่อนอื่นเลย ข้อดีอย่างหนึ่งที่ชอบของ circleci คือเราไม่ต้องมานั่งเขียนหรือกำหนดสิ่งที่จะให้มันทำที่อื่น เช่น Jenkins เราก็ไปเขียน Task ต่างๆที่จะให้ทำบนตัว Jenkins เอง แต่เจ้า Circleci เราแค่สร้างไฟล์ config ไว้ในโฟลเดอร์โปรเจ็คเราเลย จากนั้นมันจะหยิบไปอ่านเอง

แต่ Path ไฟล์จะต้องตามที่มันกำหนด นั้นก็คือ “ /.circleci/config.yml”

 

โดย โครงสร้างของไฟล์ Config จะมีหน้าตาประมาณนี้

  • version ตอนนี้มีให้เลือกเขียนได้ 1 หรือ 2 แต่ตัว Circleci เองพยายามผลักดันให้เปลี่ยนไปใช้ 2 ให้หมด ฉะนั้นตัวอย่างจากนี้ไปเราก็จะใช้ Version 2 เช่นกัน
  • Jobs เป็นการ Define job หรือ สิ่งที่จะทำ เป็นส่วนๆ เพื่อเราจะแยกการทำงานให้สามารถทำพร้อมกันได้
  • workflows เป็นการ หยิบ Jobs ให้มาสามารถ ที่จะรันมันไปพร้อมกัน ได้ เช่นเรา Define Job เป็น Build และ Test เราอาจจะสั่งให้มันทำแยกกัน แล้วสุดท้ายค่อยเขียนให้ Deploy หาก Test ผ่านก็ได้

ดูเพิ่มเติม https://circleci.com/docs/2.0/configuration-reference/

 

 

ตัวอย่าง Circleci config สำหรับการ Deploy nodejs Application หลังจากที่เรามี Dockerfile ที่พร้อมใช้งานแล้ว

โดยสิ่งที่ Circleci ไฟล์นี้ทำคือ สร้าง Task ชื่อ Build

และให้มี Base ในการ Build ครั้งนี้ เป็น Docker image ที่มี Nodejs มาให้แล้ว

Branches คือเป็นการบอกว่าเราจะให้ทำการ Build หรือ ทำงานต่อจากนี้ เฉพาะ Branch ที่กำหนดเช่นในเคสนี้ก็คือ Master และ Staging เท่านั้น

จากนั้น “Step” คือสิ่งที่จะให้ circleci มันทำได้อะไรบ้าง

  • checkout เป็น keyword ที่มันจะไปทำการ Checkout code ของเราจาก GIT ออกมาให้
  • RUN คือเราสามารถเขียน shell command ได้ ตรงนี้เลย
  • setup_remote_docker เพื่อให้เราสามารถใช้งาน Docker ในนี้ได้

อย่างในเคสเราครั้งนี้ สิ่งที่เราจะให้มันทำคือ

  1. สั่ง Yarn install เพื่อติดตั้ง Dependencies สำหรับ node js project ของเรา
  2. setup_remote_docker เพื่อเตรียม Docker ให้เราสามารถใช้งานได้
  3. Docker login ….. เพื่อที่เราจะได้จัดการ Push image ที่เราจะทำต่อจากนี้ไปยัง Docker hub ได้
    1. โดยในที่นี่ผมใช้ environment ช่วยในเก็บ username และ password เพื่อไม่ให้ password หลุดไปไว้ใน Code ของเรา บางทีเราอาจจะมีทีมที่ทำงานในกันหลายคน การที่ Password ฝังไว้ใน Repo เลย ย่อมไม่ใช่เรื่องดีแน่
  4. Docker build สั่ง Build image จาก Dockerfile ของเรา
  5. Docker push ส่ง docker image ของเราไปยัง Docker hub

มาถึงจุดนี้เรา ทำให้ทุกครั้งที่เรา Push Code ไปยัง Master หรือ Staging มันจะทำการ Build image ของเรา ให้พร้อมใช้งานละ

อีกสเตปสั้นๆคือ เราจะไปกระซิบบอก Rancher ยังไง ให้จัดการเอา Docker Image อันใหม่ของเราขึ้นไป Deploy ใหม่

 

Rancher api client

https://github.com/etlweather/gaucho

อีกหนึ่งพระเอกของเราเลย เป็น Python CLI tool สำหรับไปสั่งงาน Rancher ผ่าน API ของ Rancher ให้เราสามารถที่จะกระซิบไปบอกเจ้า Rancher ให้ทำงานต่างๆนาๆได้

 

 

โดยเพื่อให้ง่ายในการจัดการ เราก็จัดการใช้เจ้า gaucho ผ่าน Docker image ที่เขาทำไว้ โดยสิ่งที่เราต้องทำคือ ไปนำ Rancher access key และ secret key มากำหนดใน environment  ด้วย ส่วน cattle_url ให้เรากำหนดเป็น url ของ rancher ตรงๆเลยก็คือ http://0.0.0.0:8080/

แต่!! สิ่งหนึ่งที่สำคัญคือ เราต้องระบุ ID ของ Service ปลายทางที่เราจะสั่ง upgrade ด้วย

โดยวิธีดูก็คือ

 

 

เข้าไปที่หน้า Service นั้นๆ แล้วดูที่ url เราจะเห็นเลขตามลูกศรที่ชี้เลย แต่ละ service เลขจะไม่เหมือนกัน ให้เราเอาค่านี้ละไปเก็บไว้ใน environment  อย่างในตัวอย่างคือชื่อ RANCHER_API_SERVICE

เพียงเท่านี้ เราก็สามารถสั่งให้มัน upgrade service ของเราได้อย่างอัตโนมัติ แล้ว

 

conclude

ทั้งหมดทั้งมวล ทำให้เมื่อเรา Push โค้ดขึ้น Repo ของเรา มันจะส่ง Webhook ไปบอก Circleci และ Circleci จะไปแอบดู Config.yml แล้วทำตาม Step ต่างๆนาๆที่เรา สั่งมันไว้ ไม่ว่าจะเป็น yarn install , docker build , docker push และ กระซิบไปบอก Rancher ให้ Deploy service เรา

 

โดยทุกคนสามารถดูตัวอย่าง Code พร้อมใช้งานจริงได้ที่

github.com/Ima8/Make-your-own-CI-CD-pipelines 

 

หวังว่าทุกคนที่อ่านบทความนี้จะสามารถมี CI/CD pipelines ของตัวเองได้นะครับ 🙂

 

ขอบคุณที่อ่านจนจบ

สงสัยตรงไหน ทักเฟสมาคุยมาถามได้เลย FB: Issaret Prachitmutita

 

ขอบคุณครับ.

 

หลังจากที่ได้เปิด Class สอน Vue.js + Firebase ตั้งแต่พื้นฐานไปจนถึงเริ่มทำโปรเจ็คได้จริง

ในวันที่ 27-28 สิงหาคม 2560

 

 

——— ขออัพโหลดรูปไว้ก่อน เดียวจะหาเวลามาเขียนสรุปเนื้อหา  ———

 

เนื้อหาที่สอน :  (จะอัพโหลดภายหลัง)

สไลด์งาน :    (จะอัพโหลดภายหลัง)


 

 

 

ภาพบรรยายกาศในงาน 

 

 

” Migrate from https to https/SSL via let’s encrypt “

คือหัวข้อที่ไปพูดมาวันนี้ วันนี้คือวันแรกที่พูดในฐานะ “วิทยากร” ให้กับคนที่เราค่อนข้างมั่นใจว่า ท่านๆเหล่านั้นเก่งกว่าแน่นอนนนนนนน ถ้าจะสอนทั่วๆไป กับน้อง กับเพื่อน หรือไปเล่าประสบการณ์ มันไม่กดดันเท่า

จริงๆพี่ปิงมาให้กำลังใจวันก่อนว่า ถ้าเขาเป็นแล้วเขาไม่มาหรอก

แว๊บแรกเออ ก็ใช่เนาะ แต่พอไปเปิดรายชื่อคนที่เข้าร่วม ตู้วหู้วววววววว ” Dr. ” ก็มาาา ไหนลูกพี่ว่า คนเป็นแล้วเขาไม่มาาา

แถมก่อนเริ่ม ” Dr. ” ดังกล่าวบอก พี่มารอฟัง Session ” let’s encrypt ” เลย …….. ไม่ได้กดดันเลยครับพี่.

โชคคคคดี ที่ก่อนหน้านี้รู้ว่าตัวเอง ก็ไม่ได้แข็งขนาดนั้น จึงถือโอกาสเตรียมตัว เตรียมสไลด์ แบบหนักๆจริงๆ ไปนั่งลื้อทำความเข้าใจให้เคลียร์ ตั้งแต่เลเยอร์ล่างสุด ก่อนหน้าเป็นยังไง เทคโนโลยีนี้มาเป็นยังไง เบื้องหลังมันทำงานยังไง ใส้ในของเบื้องหลัง โปรโตคอลทำงานยังไง แล้ว Client พวกนี้ทำอะไรบ้าง เปิดหา Document ของ Tools นั่งไล่ดู Change log บลาๆ อารมณ์แบบถ้าให้มาพูดแค่ทำยังไง คือระดับพี่ๆท่านๆที่มาฟัง คือ ไปเปิด Doc ก็น่าจะเก็ต

เลยเป็นโจทย์ว่า จะทำยังไงให้ Session เราไม่ใช่แค่ทำตาม Tools แต่ต้องเข้าใจว่า Tools มันทำงานยังไง มันมีโอกาสจะ Error ตรงจุดไหนได้บ้าง จะได้ไปจัดการได้ถูก

ก็เลยนั่งคิด นอนคิด แก้สไลด์ไปๆมาๆ จนเกิดเป็นนนนนน
https://drive.google.com/file/d/0B_mVar9acb9RRUFEMXVmTy1GSWc/view?usp=sharing

คือ นั่งอ่านไปถึงจุดที่ว่า ทำเว็บ Thaiprogrammer.org เป็น A+ ได้ แบบเข้าใจเกือบกระจ่างหมด

นับว่าเป็นเรื่องน่าสนุกดี จากเดิมที่คิดว่าเข้าใจ พอจะไปพูดหรือไปถ่ายทอด ต้องทำให้มัน Make sure ว่าเราเข้าใจถูก กระจ่างลึกจริงๆ ถามมันต้องพร้อมรับได้

จริงๆคือวันนี้ สไลด์ที่ไปพูดคือ ไม่ได้ลึกมาก แต่ถ้าถามลึกกว่านี้คิดว่าในบางคำถามก็น่าจะพอจะตอบได้ แต่แลกกับวันที่ผ่านมาใช้เวลาเตรียมตัวเยอะมากกกกกกกกกกก เนื่องจากสกิลอันน้อยนิดที่มีติดตัวมา

สุดท้าย วันนี้คนฟัง ฟังเรื่องรู้มั้ย ไม่รู้ววววว ถถถถถ
#ขอบคุณที่ยังไม่ปารองเท้ามาหน้าห้องครับ

หลังจากที่ไม่ได้มีเวลาว่างมากนานนมากก พอได้มีเวลาว่างก็เลยมานั่งขีดๆเขียนๆโปรแกรมเล่นๆ

ซึ่งในรอบนี้คือ เว็บแอปพลิเคชั่น ที่จะ Random คำออกมา แล้วสามารถสั่งให้เล่นเสียงแบบสำเนีง US หรือ UK ได้

เพื่อให้เราสามารถเปรียบเทียบได้ว่า แต่ละสำเนียงออกเสียงอย่างไร

 

และ  Side Project ที่ทำในรอบนี้มาตอบโจทย์ตัวเองล้วนๆ ที่ต้องใช้เวลากับการขับรถเยอะ แต่เสียเปล่าไป

ที่นี่ก็เลยคิดเล่นๆว่าจะดีแค่ไหน ถ้าเราขับรถไป ฝึกออกเสียงไป ก็เลยเกิดเป็น pronun.ima8.me ครัช

 

 

pronun.ima8.me

Continue reading

บ่อยครั้งที่เราจะมีปัญหาในการจัดการต่างนาๆ

 

เช่นในการอัพโหลดไฟล์ เมื่อก่อนนั้นเราอาจจะเห็นรูปแบบคำแนะนำต่างๆนาๆที่บอกว่าให้ กำหนด Permission เป็น 777
เพื่ออนุญาตให้ เจ้าของ หรือ กลุ่มเดียวกับเจ้าของ หรือ ใครก็ได้ เขียน แก้ไข เรียกใช้ ได้

ซึ่งในประเด็นนี้อาจจะมีในเรื่องของความปลอดภัยที่เกิดขึ้น

ฉะนั้นสิ่งที่ผมมักจะทำคือการ อาจจะกำหนดแค่ 755 เพื่ออนุญาตให้เฉพาะเจ้าของเรียกใช้ เขียน  หรือ แก้ไขได้

 

แต่การจะทำยังไง เราจะต้องเปลี่ยนเจ้าของไฟล์ หรือ โฟลเดอร์นั้นๆ ให้เป็น User เดียวกับที่จะมาเรียกใช้สักก่อน
ซึ่งมันไม่ได้หมายความว่ามันคือ user ที่เราจะล็อกอินไปใช้งานเสมอไป แต่โดยปกติหากเราใช้ apache มันมักจะใช้ user ที่ชื่อ “www-data”

ฉะนั้นเราต้องเปลี่ยนเจ้าของไฟล์ให้เป็นของ www-data ก่อน

 

จากนั้นตามด้วยเปลี่ยน Premission

 

หรืออีกกรณี คุณอาจอยากต้องการบอกว่า ถ้าจะให้เฉพาะ user “www-data” มันก็อาจจะลำบากเราในการจัดการไฟล์หรือของเหล่านั้นด้วย user ที่เราใช้

เราอาจจะเปลี่ยนเป็นการให้สิทธิ์ในระดับ Group ก็ได้

 

โดยเราจะต้องย้าย user ของเรา เข้าไปอยู่ในกรุ๊ปเดียวกันกับ www-data ก่อน

 

จากนั้นต้องเปลี่ยน Premission ให้เหมาะสมด้วย

 

 

Done,Happy;

หากคุณทำ web server ด้วย โดยใช้ Nginx มาเป็น Nginx มาเป็น Reverse Proxy แล้วส่งต่อไปยัง Apache

เพื่อให้ php นั้นทำงานกับ Apache

 

โดยเราะจะต้อง Config สิ่งต่างๆเพื่อให้รองรับการ Upload File เราด้วย

 

PHP

PHP.ini

เพิ่ม สิ่งเหล่านี้ลงไป เพื่อเป็นการบอกว่าเราจะอนุญาติให้อัพโหลดไฟล์ได้สูงสุดขนาดเท่าไหร่ และอนุญาติใช้ Mem ได้สูงสุดเท่าไหร่

Note : memory_limit >= post_max_size => upload_max_filesize

 

WordPress

บรรทัดแรกสุดของไฟล์ wp-config.php

จะเป็นการบอกว่า WordPress จะใช้ แรมได้สูงสุดเท่าไหร่

 

Nginx

สิ่งที่หลายคนอาจจะลืม ผมก็เช่นกัน คือการไปโฟกัสกับฝั่ง PHP จนลืมฝั่งของ Nginx ไป

เพิ่มเข้าไปยังไฟล์ /etc/nginx/nginx.conf หรือ /etc/nginx/sites-available/xxxx

 

Done. Happy;

 

หากจะทำ Rewrite URL หรือ การทำ permalinks ใน WordPress

หากใช้ Nginx เป็น reverse proxy

 

ดูให้ดี พ่วง ?$args; เพื่อรับ args ต่อท้าย Index.php ไปด้วย

 

หลังจากกระบวนการข้างบน  Request จะถึงส่งต่อไปยัง :8080 ซึ่งเราอาจจะรัน Apache ไว้ จริงๆไม่อาจจะหรอก รันเหอะ

ซึ่งสิ่งที่จะทำให้ Rewrite สำเร็จนั้นคือต้องมีไฟล์ .htaccess และ อย่าลืมเปิด Mod ใน Apache

 

.htaccess

 

Mod ของ Apache นั้นชื่อ “mod_rewrite”

วิธีการปรับ มีหลากหลายวิธีแต่ถ้าใช้ Ubuntu จัดการ

บรรทัดเดียวชีวิตจบ

 

จากนั้น Restart ทั้งสอง Service เพื่อความแฮปปี้

 

 

 

เย๊ เลิกปวดหัว  กับปัญหา 404 ของwordpress เวลาทำ permalinks ได้แล้ว!