Google Cloud Run - deploy docker แบบง่าย ๆ ราคาถูก แต่รับ traffic คนได้ทั้งประเทศ!
Tags: webdev, googlecloud, devops, tutorial
Published: 2020-06-27 14:42:43

อย่างที่ทราบกันว่า **Google Cloud** นี่มี services ให้เล่นกันเยอะมาก สำหรับทั้งงานในด้านเว็บ ทำระบบ data science และอื่น ๆ วันนี้จะมาแนะนำ service ตัวหนึ่งครับ เอาไว้สำหรับ deploy docker container ของ web app เรา ซึ่งเหมาะสำหรับทั้ง dev มือใหม่ที่อยากจะลอง deploy web app ดูเล่น ๆ ยันมือโปรที่จะเอาไปใช้งานบน production จริง เนื่องจากการใช้งานค่อนข้างง่าย แต่สามารถ scale ให้รองรับงานใหญ่ ๆ ระดับทั้งประเทศได้สบาย และที่สำคัญยังราคาไม่แพงอีกด้วย ก็คือตัว **Google Cloud Run** นี่เองครับ

![google-serverless-devops.png](https://dev-to-uploads.s3.amazonaws.com/i/qgeftym98h5pzyevxciz.png)
_ตัวอย่าง products ต่าง ๆ ของ Google ที่เกี่ยวข้อง สำหรับการ deploy apps แบบ serverless จาก [Journey to Serverless on Google Cloud Platform](https://medium.com/google-cloud/journey-to-serverless-on-google-cloud-platform-67b8d392ffa2)_

# **Google Cloud Run**
Google Cloud Run เป็น serverless service ตัวหนึ่ง ในกลุ่มของ **Compute Platform** คล้าย ๆ กับพวก _Google App Engine_ หรือ _Google Kubernetes Engine_ ที่หลาย ๆ ท่านอาจจะคุ้นเคยกันดี คือเป็น product ที่ให้เราใช้เป็นส่วนของ compute เพื่อ deploy application ของเราเช่นเดียวกัน โดย Cloud Run นี้เป็น service ใหม่ที่ Google เพิ่งออกมาไม่นานนี้ครับ

ซึ่งจะมีส่วนคล้ายกับตัว Kubernetes ตรงที่จะ **deploy โดยใช้ Docker image ทำให้สามารถ scale เพื่อเพิ่มจำนวนของ container ให้รับ traffic จำนวนมากได้เหมือนกัน** แต่ต่างกันตรงที่ Cloud Run App หนึ่ง ๆ จะสามารถ deploy Docker image ได้แค่ image เดียวเท่านั้น ในขณะที่ Kubernetes สามารถ deploy หลาย ๆ image เพื่อมาทำงานร่วมกันได้ในทีเดียวครับ ทำให้ในบาง app ที่มีหลาย ๆ image ทำงานร่วมกัน เราก็ต้อง deploy ลง Cloud Run ทีละ image

แต่สิ่งที่ Cloud Run จะได้เปรียบกว่า Kubernetes ก็คือ Cloud Run นั้น **มีความซับซ้อนน้อยกว่า** และก็ **ไม่ต้องเขียน config ให้ยุ่งยาก** แบบ Kubernetes ครับ ซึ่งไม่ว่าจะเรื่องของการทำ auto-scaling หรือ load-balancing นี่ **Google Cloud Run จัดการให้เองทั้งหมดครับ**

# **จุดเด่น**
**1.** คือ Google Cloud Run สามารถ **deploy ได้ง่ายมาก** ไม่ต้อง config เพียงแค่เรา push docker image ขึ้นไปใน project เรา จากนั้นก็สั่ง deploy คำสั่งเดียว ก็จบครับ

**2. ทำ auto-scaling ให้อัตโนมัติ** สามารถเพิ่มจำนวน instances จำนวนมากได้ภายในเวลาอันสั้น

![auto-scaling-test.png](https://dev-to-uploads.s3.amazonaws.com/i/vaxpci3e35ogck72z4rs.png)
_ภาพการทดสอบ auto-scaling ของ Cloud Run จาก [คลิปงาน Cloud Next '19](https://youtu.be/xVuuvZkYiNM?t=1638) โดยใช้วิธีการจำลอง user ขึ้นมา แล้วให้ยิง request ไปที่ Cloud Run App เดียวกัน ไปเรื่อย ๆ โดยจำนวนของ user จะค่อย ๆ เพิ่มขึ้นเรื่อย ๆ จนไปถึง 15,000 คน!_

จากกราฟ แกนตั้งคือเวลาที่ใช้ในการ request (latency) ส่วนแกนนอนคือเวลาที่ผ่านไป จะเห็นว่าในช่วงแรก latency ค่อนข้างสูง เนื่องจากว่าอยู่ ๆ user ก็เพิ่มจำนวนขึ้นกระทันหัน และยังเพิ่มขึ้นเรื่อย ๆ แต่เมื่อผ่านไปสักพัก ที่ประมาณวินาทีที่ 25 latency ก็ drop ลง และค่อนข้างจะคงที่หลังจากนั้น นั่นคือ **Google Cloud Run สามารถ handle burst ของ load หลักหมื่นได้ภายในไม่กี่วินาที!**

**3. เป็น Serverless Service** หมายความว่า Google จะ manage ตัว infrastructure ให้หมด ทำให้เราไม่ต้องสนใจว่าจะต้อง setup เครื่องยังไง หรือจะเอาไปลงเครื่องไหน ให้เราคิดเสมือนว่าไม่มี server อยู่นั่นเองครับ

**4.** เนื่องจากว่าเป็น serverless การคิดราคาจึงไม่ได้คิดจากเวลาที่เครื่อง server ทำงาน แบบ service อื่น ๆ (เช่น App Engine) **แต่จะคิดเงินเฉพาะจากเวลาที่ใช้งานจริงเท่านั้น** หมายความว่าถ้าวันไหนไม่มีคนเข้าเว็บเรา เราก็ไม่เสียเงินเลยครับ

![billable-time.png](https://dev-to-uploads.s3.amazonaws.com/i/s5sda0c9lgcpdftfdy1h.png)
_ภาพของช่วงเวลาที่จะคิดเงิน คือจะคิดเงินช่วงที่มีคนยิง request เข้ามาและประมวลผลเท่านั้น (สีฟ้า) ช่วงที่ไม่มี request ก็ไม่คิดเงิน (สีเทา)_

**5. รองรับโค้ดทุกภาษา** เนื่องจากว่าใช้ docker image ในการ deploy ครับ ดังนั้นจะโค้ดด้วยภาษาอะไร ถ้าเอาใส่ docker ได้ ก็จบ ซึ่งต่างกับตัว App Engine ที่ Support แค่บางภาษาเท่านั้น

# **วิธี deploy**

## **สิ่งที่ต้องเตรียม**

**1. Google Cloud project** ซึ่งเปิดอนุญาตการ Billing ไว้แล้ว; ถ้ายังไม่เปิด สามารถทำตามขั้นตอนใน [link นี้](https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_an_existing_project) ได้ครับ แค่คลิก ๆ ไม่นาน

**2. Google Cloud SDK** เพื่อความสะดวกในการใช้งาน products ทุก product ของ Google ควรจะต้องติดตั้ง program นี้ไว้ครับ เมื่อติดตั้งแล้ว เราจะสามารถควบคุม services ต่าง ๆ ของ Google ได้ผ่านคำสั่งใน command line สามารถติดตั้งได้ตาม [link นี้](https://cloud.google.com/sdk/docs) เลยครับ

## **การ deploy**
**1. submit docker image** ให้เข้าไปที่ directory ที่มี **Dockerfile** ที่เราเตรียมเอาไว้อยู่ครับ เสร็จแล้ว run คำสั่งนี้ เพื่อทำการ submit โค้ดต่าง ๆ ขึ้นไป และ build Container Image บน Google Cloud ด้วย service ที่ชื่อ **Cloud Build** ครับ

```bash
gcloud builds submit --tag asia.gcr.io/PROJECT_ID/IMAGE_NAME
```
ให้เปลี่ยน `PROJECT_ID` เป็น _ชื่อ Google Cloud project ของเรา_ และเปลี่ยน 
`IMAGE_NAME` เป็น _ชื่อ app ของเรา_ นะครับ

ถ้าใช้ Cloud Build ครั้งแรก มันจะถามว่าให้ enable API `cloudbuild.googleapis.com` ของ Cloud Build ไหม ก็ให้กด `y` แล้ว ENTER ไป มันก็จะทำงานต่อ

Cloud Build จะทำการ build ตาม Dockerfile ที่เราเขียนไว้ แล้ว push image ไปที่ registry ใน project ของเรา (ที่ **asia.gcr.io/PROJECT_ID/IMAGE_NAME**)

_note: ผมใช้ hostname เป็น **asia.gcr.io** หมายความว่า เราจะเก็บ image ของเราไว้ใน registry ที่อยู่ใน asia ครับ ซึ่งเราสามารถเปลี่ยน location ไปที่อื่น ๆ ได้ เช่น us.gcr.io, หรือ eu.gcr.io ตาม location ที่เราใช้งานครับ_

**2. deploy image ลง Cloud Run** ตอนนี้เรา build app ของเราเป็น container image ไปเก็บเอาไว้แล้วนะครับ ทีนี้ก็แค่บอก Google Cloud Run ว่าเอา image อันนี้ไปใช้ที เท่านั้นครับ

```bash
gcloud run deploy IMAGE_NAME \
    --image asia.gcr.io/PROJECT_ID/IMAGE_NAME \
    --platform managed \
    --region asia-east1 \
    --allow-unauthenticated \
    --port PORT
```
**อธิบายคำสั่งทีละบรรทัด**
**1.** ให้ deploy โดยใช้ชื่อ _**IMAGE_NAME**_  
**2.** ด้วย image จาก _**asia.gcr.io/PROJECT_ID/IMAGE_NAME**_  
**3.** ด้วย mode _**managed**_ คือให้ Google managed ให้อัตโนมัติ ซึ่งจะมี mode อื่น ๆ ที่ไปใช้ cluster ที่เรามีมารันแทน แต่ง่ายสุด ก็ใช้ managed ไปก่อนครับ  
**4.** ไปที่ region _**asia-east1**_ จะอยู่ที่ Taiwan ซึ่งเป็นที่ location หนึ่งที่ไม่ไกลจากไทยมาก ที่สามารถใช้ Google Cloud Run ได้ (location ที่ใกล้ไทยที่สุดคือ _**asia-southeast2**_ ที่ Jakarta แต่ ณ ตอนนี้ยังไม่สามารถใช้ Cloud Run ได้ครับ)
**5.** allow-unauthenticated คือ อนุญาตคนอื่นสามารถใช้ app นี้ได้ แต่ถ้าอยากทำเพื่อใช้เฉพาะ dev ที่ได้รับอนุญาตเท่านั้น ก็สามารถเปลี่ยนเป็น `--no-allow-unauthenticated` แทนได้ครับ  
**6.** application เราจะรันจาก port _**PORT**_ แทนค่า PORT เป็น port ที่เราจะใช้งานนะครับ

อันนี้ก็เหมือนกัน คือถ้าเราไม่เคยใช้ Cloud Run มาก่อน มันก็จะถามว่าให้ enable API `run.googleapis.com` ของ Cloud Run ไหม ก็กด `y<ENTER>` ไป

_note: เพิ่มเติมนิดนึง คือมี options อื่น ๆ ที่ปรับได้อีกนะครับเช่นจำนวน **CPU ว่าจะเอากี่ตัว** หรือ ขนาดของ **RAM ว่าจะใช้กี่ MB** สามารถดูเพิ่มเติมได้ใน [link นี้](https://cloud.google.com/sdk/gcloud/reference/run/deploy) เลยครับ_

ถ้า deploy สำเร็จ ก็จะ message ประมาณนี้ขึ้นมา
```bash
Done.                                                                                                                                                                                                             
Service [myapp] revision [myapp-00003-gej] has been deployed and is serving 100 percent of traffic at https://myapp-cee6n4roda-de.a.run.app
```

เราก็เอา link ที่มันให้มา มาเปิดดูใน browser ได้เลยครับ ก็จะเห็น app ของที่เราเขียนไว้ อย่างของผม ลิ้งคือ `https://myapp-cee6n4roda-de.a.run.app` พอไปเปิดใน browser ก็จะเป็น Django app ขึ้นมาแบบนี้

![deployed-app.png](https://dev-to-uploads.s3.amazonaws.com/i/a5s3mu51oycvfanh42kf.png)

ก็เป็นอันเสร็จสิ้นครับ แค่ 2 ขั้นตอน สามารถแชร์ลิ้งให้เพื่อนไปเล่น หรือนำไปใช้งานจริงได้เลย

# **หน้า UI สำหรับจัดการต่าง ๆ**
เราได้ลอง deploy โดยใช้ command line ไปแล้วนะครับ ซึ่งโดยปกติเราก็คงจะใช้วิธีนั้นการทำงานจริงใช่ไหมครับ ทั้งเวลาทำ ci/cd เขียน pipeline ให้ deploy อัตโนมัติ ก็จะใช้คำสั่งตามด้านบนในการทำ

แต่ Google Cloud ก็ยังมีหน้า GUI ให้ใช้ผ่าน browser เพื่ออำนวยความสะดวกทุกคน ให้สามารถ deploy และตั้งค่าต่าง ๆ ได้แบบง่าย ๆ อีกด้วย สามารถเข้าผ่าน link นี้ได้เลยครับ [https://console.cloud.google.com/run](https://console.cloud.google.com/run)

![cloud-run-ui-1.png](https://dev-to-uploads.s3.amazonaws.com/i/8ua6klfgd3a6az5r0lm8.png)

จะเห็นว่ามีปุ่มให้ _สร้างบริการ_ (สร้าง service) ก็คือทำการ deploy ผ่าน UI นี้ได้ และสามารถที่ดู แก้ไข หรือลบ service ที่เราสร้างเอาไว้แล้วได้ง่าย ๆ ผ่านหน้านี้เลยครับ

# **การเก็บเงิน**
อย่างที่ทราบคือ Cloud Run นั้นเป็น serverless service ดังนั้นการเก็บเงิน ก็จะเก็บตามปริมาณที่เราใช้ไปเท่านั้น โดยจะมีด้วยกัน 4 ส่วนครับ
**1. CPU** ก็คือ ยิ่งเราใช้ CPU แรง และทำการคำนวณนานใน request แต่ละครั้ง ราคาก็จะแพงครับ

โดย Google จะใจดี **ให้ฟรีเดือนละ 180,000 vCPU-seconds**
หลังจากนั้นก็จะคิดราคา **$0.00002400 / vCPU-seconds**

_note: หน่วย **vCPU-seconds** หมายถึงจำนวน CPU ที่ app เราใช้ คูณกับเวลาที่ใช้รันทั้งหมดครับ อย่างที่บอกด้านบนว่าจำนวน CPU และ RAM ที่เราจะ allocate ไว้นี่ สามารถปรับได้_

ตัวอย่างเช่น ถ้าเราเลือก **2 CPU** แล้วในเดือนหนึ่งเรารันไปเป็นเวลา **100,000 วินาที**
ก็จะคิดเป็น _**2 vCPU x 100,000 seconds = 200,000 vCPU-seconds**_ ครับ
ซึ่ง **Google ให้ฟรีมา 180,000 vCPU-seconds**
เพราะฉะนั้นในเดือนนั้นเราก็ต้องจ่ายที่เหลือ _**20,000 vCPU-seconds x $0.00002400 = $0.48**_ เท่านั้นครับ

**2. Memory** อันนี้ก็คิดคล้าย ๆ กับ CPU เลยครับ คือนับเป็นหน่วย **GiB-seconds** ก็คือเอา GB ของ RAM ที่เราจองไว้ มาคูณเวลาที่ใช้นั่นเอง

โดย Google จะให้ฟรีเดือนละ **360,000 GiB-seconds**

แล้วหลังจากนั้น จะคิดราคา **$0.00000250 / GiB-second**

**3. จำนวนครั้งที่ Requests** ฟังดูงกหน่อย ๆ นะครับ ที่คิดเวลาที่รัน แล้วยังมาคิดจำนวนครั้งอีก 555

แต่ Google ก็ให้ **ฟรีตั้ง 2 ล้านครั้งต่อเดือน** ครับ

แล้วหลังจากนั้น ก็แค่ **$0.40 / หนึ่งล้านครั้ง** เท่านั้น

ทั้ง 3 ข้อด้านบนสามารถสรุปได้ตามตารางนี้ครับ
![pricing-table.png](https://dev-to-uploads.s3.amazonaws.com/i/2yhh8v9326r9xzpbekwf.png)
\*rate นี้ไม่รวม australia และ northamerica นะครับ อ่านเพิ่มเติม ได้ที่ [link นี้](https://cloud.google.com/run/pricing#tables)

**4. Network** ส่วน network นี่จะคิดเงินแค่ขาออก คือจาก application ออกไปข้างนอกเท่านั้น แต่จะค่อนข้างซับซ้อน เพราะขึ้นกับ geo location ของทั้ง source และ destination ตามภาพครับ

![pricing-table-network.png](https://dev-to-uploads.s3.amazonaws.com/i/of9hx85t09pjil75e70l.png)
อ่านเพิ่มเติมได้ที่ [link นี้](https://cloud.google.com/network-tiers/pricing#premium-pricing) ครับ

# **Summary**
คิดว่าผู้อ่านคงพอได้เห็นภาพคร่าว ๆ ของตัว Cloud Run นี้ไปแล้วนะครับ ทั้งในเรื่องการทำงานของ service นี้, auto-scaling, วิธีการ deploy, และการคิดราคา

โดย Cloud Run นี่เหมาะกับงานหลายอย่างมากครับ ทั้งในการทำ microservice ที่ไม่ซับซ้อนมาก หรือพวก frontend หรือเป็น job เล็ก ๆ ที่ตั้งเวลาให้รัน ผ่าน [Cloud Scheduler](https://cloud.google.com/scheduler) ก็ได้ครับ

ซึ่งด้วยความที่มันสามารถ deploy ได้ง่าย ไม่ต้อง config มาก คิดว่าอาจจะเหมาะกับนักศึกษาที่ต้องการ deploy งาน หรือทำ prototype แบบไว ๆ ด้วยครับ

แต่ข้อเสียก็มีเช่นมันบังคับให้ access ผ่าน HTTP เท่านั้น แล้วยังจำกัดเวลาในการรันแต่ละ request ไว้ที่ 15 นาทีเท่านั้น

ในระบบที่ซับซ้อนหน่อย Kubernetes ก็อาจจะยังเป็นตัวเลือกที่ดี

ถ้ามีเรื่องไหนที่สนใจเพิ่มเติมสามารถ comment เอาไว้ได้นะครับ

FB Page: [Copy Paste Engineer](https://www.facebook.com/CopyPasteEng)

<center>**- ขอบคุณที่อ่านครับ -**</center>

**อ้างอิง**
[https://cloud.google.com/run](https://cloud.google.com/run)
[https://cloud.google.com/run/pricing](https://cloud.google.com/run/pricing)
[https://www.youtube.com/watch?v=xVuuvZkYiNM](https://www.youtube.com/watch?v=xVuuvZkYiNM)
[https://cloud.google.com/blog/products/containers-kubernetes/when-to-use-google-kubernetes-engine-vs-cloud-run-for-containers](https://cloud.google.com/blog/products/containers-kubernetes/when-to-use-google-kubernetes-engine-vs-cloud-run-for-containers)