เวลาสารภาพ สภาพแวดล้อมการพัฒนาของฉันไม่ได้เปลี่ยนแปลงไปมากนักในช่วงสี่ปีที่ฉันได้ทำงานกับ Honeybadger แต่ในช่วงเวลานั้นฮันนี่แบดเจอร์มีความซับซ้อนมากขึ้น โดยขึ้นอยู่กับบริการประมาณ 10 รายการที่จะใช้งานได้
นั่นเป็นเหตุผลที่เรามุ่งสู่ Docker เพื่อพัฒนาท้องถิ่น แทนที่จะให้นักพัฒนาทุกคนต้องตั้งค่า Postgres, Cassandra, Memcached และส่วนที่เหลือ เราสามารถใช้ docker-compose เพื่อสร้างสภาพแวดล้อมที่สร้างไว้ล่วงหน้าได้ มันสุดยอดมาก
ฉันเริ่มสงสัยว่าจะปรับใช้แอปพลิเคชัน Dockerized ได้ง่ายเพียงใด
กำลังปรับใช้กับ Docker
Docker มาพร้อมกับยูทิลิตี้ต่างๆ เช่น docker-machine และ docker-swarm ซึ่งควรจะทำให้การปรับใช้ไม่เจ็บปวด จนถึงตอนนี้พวกเขายังไม่ได้ทำตามสัญญานั้น หากคุณต้องการอ่านข้อมูลทั้งหมดเกี่ยวกับข้อบกพร่อง โปรดดูโพสต์ข่าวล่าสุดของแฮ็กเกอร์
นั่นเป็นเหตุผลที่ฉันเลือกที่จะมุ่งเน้นไปที่ ECS (EC2 Container Service) ของ Amazon
ECS คืออะไร
ECS เป็นเหมือนการผสมแบบผสมระหว่างนักเทียบท่าและกลุ่มนักเทียบท่าที่พร้อมสำหรับการผลิต
ด้วย ECS คุณสามารถพูดว่า "เรียกใช้แอปพลิเคชันเว็บของฉันสามชุด" และมันจะหมุนคอนเทนเนอร์ Docker ที่เหมาะสมภายในคลัสเตอร์ของอินสแตนซ์ EC2 ของคุณอย่างชาญฉลาด
มันสามารถโหลดคำขอบาลานซ์ในคอนเทนเนอร์ของคุณ และสามารถปรับขนาดคลัสเตอร์ของคุณขึ้นหรือลงได้ขึ้นอยู่กับโหลด
การสร้างแอป Dockerized Sinatra
นี่คือแอป Sinatra ที่เรียบง่าย โดยจะพิมพ์เวลาปัจจุบัน ดังนั้นคุณจะรู้ว่าคุณเห็นเวอร์ชันแคชหรือไม่ นอกจากนี้ยังพิมพ์ชื่อคอมพิวเตอร์ที่ใช้งานแอพ ต่อมา เราจะทำการปั่นเซิร์ฟเวอร์หลายเครื่องที่เรียกใช้แอปนี้ และใช้ตัวโหลดบาลานซ์เพื่อกำหนดเส้นทางคำขอ เมื่อส่งคืนชื่อโฮสต์ เราสามารถบอกได้ว่าเซิร์ฟเวอร์ใดให้บริการตามคำขอเฉพาะ
แอป
แอป Dockerized Sinatra ที่ฉันจะแสดงให้คุณเห็นคือ tcnksm-sample/docker-sinatra เวอร์ชันที่เขียนใหม่อย่างหนัก
require 'sinatra'
require 'sinatra/base'
class App < Sinatra::Base
get '/' do
"Hello from sinatra! The time is #{ Time.now.to_i } on #{ `hostname` }!"
end
end
นี่คือ Gemfile
:
# Gemfile
source 'https://rubygems.org'
gem 'sinatra'
gem 'thin'
...และนี่คือ config.ru
ไฟล์:
$:.unshift(File.dirname(__FILE__))
require 'app'
run App
The Dockerfile
เราต้องใช้ Dockerfile เพื่อสร้างอิมเมจ Docker สำหรับแอปนี้ มันสร้างไดเร็กทอรีสำหรับแอพ คัดลอกไฟล์ และรันเว็บเซิร์ฟเวอร์บนพอร์ต 80
FROM ruby:2.3.1-slim
RUN apt-get update -qq && apt-get install -y build-essential
ENV APP_ROOT /var/www/docker-sinatra
RUN mkdir -p $APP_ROOT
WORKDIR $APP_ROOT
ADD Gemfile* $APP_ROOT/
RUN bundle install
ADD . $APP_ROOT
EXPOSE 80
CMD ["bundle", "exec", "rackup", "config.ru", "-p", "80", "-s", "thin", "-o", "0.0.0.0"]
การสร้างและเรียกใช้อิมเมจ
อันดับแรก เราจะบอกให้ Docker สร้างอิมเมจจากไฟล์ Docker ในไดเร็กทอรีปัจจุบัน จากนั้นเราจะเรียกใช้โดยจับคู่พอร์ต 80 ของคอนเทนเนอร์กับ localhost:4000
docker build -t docker-sinatra .
docker run -p 4000:80 docker-sinatra
หากต้องการตรวจสอบว่าใช้งานได้หรือไม่ ให้เปิด localhost:4000 ในเว็บเบราว์เซอร์ของคุณ คุณควรเห็นสิ่งนี้:
กำลังปรับใช้กับ ECS
ตอนนี้เรามาปรับใช้กับ ECS กัน เราจะใช้วิซาร์ดการตั้งค่าของพวกเขา โกงหรือเปล่าเนี่ย? ฉันไม่สนใจ :) ดังนั้นตรงไปที่แผงควบคุม ECS
คลิก "เริ่มต้นใช้งาน" จากนั้นคลิก "ดำเนินการต่อ" ในหน้าจอถัดไป"
การสร้างรีจิสตรี Docker ของคุณ
โดยปกติคุณจะไม่อัปโหลดอิมเมจ Docker ไปยังเซิร์ฟเวอร์ที่ใช้งานจริงจากสภาพแวดล้อมการพัฒนาของคุณ คุณส่งอิมเมจไปยังรีจิสตรีของ Docker แทน เช่น dockerhub และเซิร์ฟเวอร์จะดึงอิมเมจออกมาในการปรับใช้ Amazon จัดเตรียมรีจิสทรี Docker ส่วนตัว คุณไม่จำเป็นต้องใช้มัน แต่เรากำลังจะทำในตอนนี้
ฉันจะตั้งชื่อรีจิสทรีของฉันว่า "docker-sinatra":
การพุชรูปภาพของคุณไปยังรีจิสทรี
จากนั้น ฉันได้รับรายการคำสั่งเพื่อสร้างอิมเมจและพุชไปที่รีจิสตรี
ครั้งแรกที่ฉันลองสิ่งนี้ ตัวบล็อกโฆษณาของเบราว์เซอร์ของฉันป้องกันไม่ให้แสดงคำสั่งอย่างถูกต้อง แปลก - ฉันรู้
การสร้างคำจำกัดความของงานของคุณ
AWS ชอบสร้างคำศัพท์ใหม่ๆ ที่สับสน และสับสน "คำจำกัดความของงาน" เป็นเพียงรายการคอนเทนเนอร์ที่ควรทำงานร่วมกัน มันเหมือนกับ Procfile หรือการกำหนดค่านักเทียบท่า
ดังนั้น หากแอปพลิเคชันของคุณมีคอนเทนเนอร์หนึ่งคอนเทนเนอร์ที่รัน Nginx หนึ่งคอนเทนเนอร์ที่รัน Unicorn และอีกหนึ่งคอนเทนเนอร์ที่รัน Sidekiq ทั้งสามก็อาจอยู่ภายใน "คำจำกัดความของงาน" ของคุณ
แอพของเราง่ายกว่ามาก เรามีเพียงหนึ่งภาชนะ ดังนั้นการกำหนดค่าจึงน้อยที่สุด
- ฉันจะตรวจสอบให้แน่ใจว่าดึงรูปภาพที่ถูกต้องจากรีจิสทรีของเรา
- ฉันจะจับคู่พอร์ต 80 จากคอนเทนเนอร์กับพอร์ต 80 บนอินสแตนซ์ EC2 ที่เรียกใช้คอนเทนเนอร์
กำลังสร้างบริการของคุณ
คำศัพท์ที่สับสนมากขึ้น! การกำหนดค่า "บริการ" ให้คุณระบุจำนวน "งาน" (สำเนาแอปของคุณ) ที่ควรรัน และวิธีที่งานเหล่านั้นจะโหลดได้สมดุล
ในที่นี้ ฉันต้องการให้แอปทำงานสามชุด โดยมีการจัดสรรภาระงานบนพอร์ต 80
หมุนคลัสเตอร์ของคุณ
คลัสเตอร์คือกลุ่มของอินสแตนซ์ EC2 ทั่วไปที่กำลังเรียกใช้ซอฟต์แวร์ ECS ของ Amazon คุณสามารถทำอะไรกับมันได้ เช่นเดียวกับอินสแตนซ์ EC2 อื่น ๆ ในกรณีนี้ ฉันระบุว่าฉันต้องการอินสแตนซ์ t2.micro สามตัว
หลังจากขั้นตอนการยืนยันไม่กี่ขั้นตอนและรอประมาณ 5 นาที ทุกอย่างก็พร้อม
เมื่อบริการของคุณใช้งานได้ คุณจะเห็นหน้าจอที่มีลักษณะดังนี้:
กำลังทดสอบแอป
คุณสามารถคลิกที่ชื่อโหลดบาลานเซอร์เพื่อดึงรายละเอียดขึ้นมา ที่นั่น คุณควรหาชื่อโดเมนสาธารณะ ใส่ในเบราว์เซอร์ของคุณแล้วคุณจะเห็นแอปตัวอย่างของเรา
หากคุณรีเฟรชสองสามครั้ง คุณจะเห็นว่าชื่อโฮสต์เปลี่ยนไป นั่นเป็นเพราะตัวโหลดบาลานซ์กำลังปรับสมดุลคำขอของคุณในทั้งสามโฮสต์
การทำความสะอาด
วิซาร์ด ECS ได้สร้างทรัพยากรจำนวนมากในบัญชี AWS ของคุณในขณะนี้ คุณคงไม่อยากทิ้งพวกเขาไว้ที่นั่น พวกมันจะทำให้ยุ่งเหยิงและอาจต้องเสียเงิน
โชคดีที่ตัวช่วยสร้าง ECS ใช้ CloudFormation เพื่อสร้างทรัพยากรทั้งหมด นั่นหมายความว่าคุณสามารถลบทุกอย่างได้ง่ายๆ เพียงแค่ลบ CloudFormation stack