การพัฒนาคอนเทนเนอร์ด้วย Dockerfile

1. ภาพรวม

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

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

คอนเทนเนอร์ Docker สามารถใช้ใน Kubernetes ได้โดยตรง ซึ่งทำให้เรียกใช้ใน Kubernetes Engine ได้อย่างง่ายดาย หลังจากเรียนรู้ข้อมูลสำคัญของ Docker แล้ว คุณจะได้ชุดทักษะเพื่อเริ่มพัฒนา Kubernetes และแอปพลิเคชันที่สร้างโดยใช้คอนเทนเนอร์

สิ่งที่คุณจะได้เรียนรู้

ในห้องทดลองนี้ คุณจะได้ศึกษาวิธีทำสิ่งต่อไปนี้

  • สร้าง Dockerfile สำหรับแอปพลิเคชันตัวอย่าง
  • สร้างอิมเมจ
  • เรียกใช้อิมเมจเป็นคอนเทนเนอร์ในเครื่อง
  • เปลี่ยนลักษณะการทำงานของคอนเทนเนอร์
  • พุชอิมเมจไปยัง Artifact Registry

ข้อกำหนดเบื้องต้น

นี่คือห้องทดลองระดับแนะนำ ไม่เคยมีประสบการณ์กับ Docker และคอนเทนเนอร์มาก่อนเลย มีความคุ้นเคยกับ Cloud Shell และบรรทัดคำสั่ง แต่ไม่แนะนำให้ใช้

การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก

  1. ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • ชื่อโครงการคือชื่อที่แสดงของผู้เข้าร่วมโปรเจ็กต์นี้ เป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้และคุณอัปเดตได้ทุกเมื่อ
  • รหัสโปรเจ็กต์ต้องไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ปกติแล้วคุณไม่สนว่าอะไรเป็นอะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (ซึ่งปกติระบุไว้ว่าเป็น PROJECT_ID) ดังนั้นหากไม่ชอบ ให้สร้างรหัสแบบสุ่มขึ้นมาอีกรหัสหนึ่ง หรือคุณจะลองใช้รหัสโปรเจ็กต์ของคุณเองแล้วดูว่ารหัสโปรเจ็กต์พร้อมใช้งานหรือไม่ แล้วก็ "แช่แข็ง" หลังจากสร้างโปรเจ็กต์แล้ว
  • มีค่าที่ 3 คือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าได้ในเอกสารประกอบ
  1. ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของระบบคลาวด์ การใช้งาน Codelab นี้น่าจะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ให้ทำตาม "การล้าง" ดูได้ที่ตอนท้ายของ Codelab ผู้ใช้ใหม่ของ Google Cloud จะมีสิทธิ์เข้าร่วมโปรแกรมทดลองใช้ฟรี$300 USD

2. แอปพลิเคชันตัวอย่าง

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

ซอร์สโค้ด

ซอร์สโค้ดสำหรับห้องทดลองนี้มีอยู่ในที่เก็บ GoogleCloudPlatform/container-developer-workshop พร้อมกับตัวอย่างเอกสารประกอบแอปพลิเคชัน

กำหนดค่า Git

git config --global user.name ${USER}
git config --global user.email ${USER}@qwiklabs.net

โคลนแอปพลิเคชันตัวอย่างที่เก็บซอร์สของ Cloud

gcloud source repos clone sample-app ${HOME}/sample-app &&
cd ${HOME}/sample-app &&
git checkout main

เอาต์พุต

Cloning into '/home/student_03_49720296e995/sample-app'...
remote: Finding sources: 100% (16/16)
remote: Total 16 (delta 0), reused 16 (delta 0)
Receiving objects: 100% (16/16), 47.23 KiB | 681.00 KiB/s, done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

Project [qwiklabs-gcp-02-4327c4e03d82] repository [sample-app] was cloned to [/home/student_03_49720296e995/sample-app].
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'

สร้างแอปพลิเคชันตัวอย่าง

cd ${HOME}/sample-app
./mvnw compile

เอาต์พุต

[INFO] Scanning for projects...
...
[INFO] Compiling 1 source file to /home/student_03_49720296e995/sample-app/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.080 s
[INFO] Finished at: 2022-02-23T17:14:30Z
[INFO] ------------------------------------------------------------------------

เรียกใช้แอปพลิเคชันตัวอย่าง

cd ${HOME}/sample-app
./mvnw exec:java

เอาต์พุต

[INFO] Scanning for projects...
...
Listening at http://localhost:8080

ดูตัวอย่างแอปพลิเคชันที่ทำงานอยู่

  • คลิกปุ่มตัวอย่างเว็บ Cloud Shell
  • คลิก "แสดงตัวอย่าง" บนพอร์ต 8080

เมื่อตั้งค่าเรียบร้อยแล้ว

  • กด Ctrl + c ใน Cloud Shell เพื่อหยุดแอปพลิเคชันที่ทำงานอยู่

3. Dockerfile

การขนส่งแอปพลิเคชันด้วย Dockerfile

วิธีหนึ่งในการบรรจุแอปพลิเคชันลงในคอนเทนเนอร์คือการใช้ Dockerfile Dockerfile คล้ายกับสคริปต์ที่จะแนะนำ Daemon เกี่ยวกับวิธีประกอบอิมเมจคอนเทนเนอร์ ดูเอกสารอ้างอิง Dockerfile) เพื่อดูข้อมูลเพิ่มเติม

สร้าง Dockerfile ที่ว่างเปล่าในที่เก็บแอปพลิเคชันตัวอย่าง

touch ${HOME}/sample-app/Dockerfile

เปิด Dockerfile ในตัวแก้ไขที่ต้องการ

vi ${HOME}/sample-app/Dockerfile

เลือกรูปภาพเริ่มต้น

การใช้เมธอด Dockerfile เพื่อสร้างคอนเทนเนอร์จำเป็นต้องมีความรู้โดยตรงเกี่ยวกับแอปพลิเคชันเพื่อที่จะประกอบคอนเทนเนอร์ ขั้นตอนแรกในการสร้าง Dockerfile คือการเลือกอิมเมจที่จะใช้เป็นพื้นฐานของรูปภาพ อิมเมจนี้ควรเป็นอิมเมจหลักหรือรูปภาพพื้นฐานที่เก็บรักษาและเผยแพร่โดยแหล่งที่มาที่เชื่อถือได้ ซึ่งโดยปกติแล้วจะเป็นบริษัทของคุณ

คำสั่ง FROM จะเริ่มต้นขั้นตอนบิลด์ใหม่และตั้งค่าอิมเมจฐานสำหรับคำสั่งตามลำดับที่ตามมา ดังนั้นคำสั่ง FROM มักจะเป็นคำสั่งแรกใน Dockerfile และจะมีได้เฉพาะคำสั่ง ARG ที่ไม่บังคับเพื่อรองรับตัวแปรเท่านั้น

ไวยากรณ์: FROM <image>[:<tag> | @<digest>] [AS <name>]

รูปแบบของรูปภาพคือ <image>:<tag> หรือ <image>@<digest> หากไม่ได้ระบุแท็กหรือไดเจสต์ ค่าเริ่มต้นจะเป็นแท็ก :latest รูปแบบของ <image> จะแตกต่างกันไปตามรีจิสทรีที่ใช้ในการจัดเก็บรูปภาพ สำหรับ Artifact Registry รูปแบบ <image> คือ <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag>

สำหรับห้องทดลองนี้ เราใช้อิมเมจ openjdk:11.0-jdk สาธารณะ ให้เพิ่มบรรทัดต่อไปนี้ลงใน Dockerfile

FROM openjdk:11.0-jdk

ตั้งค่าไดเรกทอรีที่ใช้งานอยู่

คำสั่ง WORKDIR จะกำหนดไดเรกทอรีการทำงานสำหรับคำสั่งตามลำดับที่ตามมาใน Dockerfile ดูข้อมูลเพิ่มเติมได้ที่ส่วน WORKDIR ในเอกสารอ้างอิง Dockerfile

ไวยากรณ์: WORKDIR <path>

สำหรับ Lab นี้ เราใช้ไดเรกทอรี /app เป็น WORKDIR ให้เพิ่มบรรทัดต่อไปนี้ที่ด้านล่างของ Dockerfile

WORKDIR /app

คัดลอกไฟล์แอปพลิเคชัน

คำสั่ง COPY จะคัดลอกไดเรกทอรีหรือไฟล์จากตำแหน่ง <source> ไปยังเส้นทาง <destination> ของระบบไฟล์รูปภาพ คุณสามารถระบุทรัพยากร <source> ได้หลายรายการและทรัพยากรทั้งหมดเกี่ยวข้องกับบริบทของบิลด์ เราจะกล่าวถึงบริบทของบิลด์เพิ่มเติมในส่วนบิลด์ ดูข้อมูลเพิ่มเติมได้ที่ส่วน "COPY" ของเอกสารอ้างอิง Dockerfile

ไวยากรณ์: COPY <source>... <destination>

สำหรับ Lab นี้ เราจะคัดลอกไฟล์ทั้งหมดในที่เก็บไปยังระบบไฟล์รูปภาพ เพิ่มบรรทัดต่อไปนี้ที่ด้านล่างของ Dockerfile

COPY . /app

คอมไพล์แอปพลิเคชัน

คำสั่ง RUN จะเรียกใช้คำสั่งในเลเยอร์รูปภาพใหม่ที่ด้านบนของรูปภาพปัจจุบันและยืนยันผลลัพธ์ ระบบจะใช้อิมเมจที่คอมมิตที่ได้สำหรับขั้นตอนตามลำดับใน Dockerfile ดูข้อมูลเพิ่มเติมได้ที่ส่วน RUN ในเอกสารอ้างอิง Dockerfile

ไวยากรณ์: RUN <command>

สำหรับ Lab นี้ เราจะใช้ Maven เพื่อรวบรวมแอปพลิเคชันไปยังไฟล์ JAR ให้เพิ่มบรรทัดต่อไปนี้ที่ด้านล่างของ Dockerfile

RUN ./mvnw compile assembly:single

เริ่มแอปพลิเคชัน

คำสั่ง CMD มีคำสั่งเริ่มต้นสำหรับคอนเทนเนอร์ที่กำลังทำงานอยู่ ใน Dockerfile จะมีคำสั่ง CMD ได้เพียง 1 รายการเท่านั้น หากระบุ CMD มากกว่า 1 รายการ ก็จะมีเพียง CMD รายการสุดท้ายเท่านั้นที่จะมีผล มีฟังก์ชันขั้นสูงเพิ่มเติมที่ใช้ทั้งวิธีการของ CMD และ ENTRYPOINT แต่ไม่มีกล่าวถึงในห้องทดลองนี้ ดูข้อมูลเพิ่มเติมได้ที่ส่วน CMD ของเอกสารอ้างอิง Dockerfile

ไวยากรณ์: CMD ["executable","param1","param2"]

สำหรับ Lab นี้ เราเรียกใช้ไฟล์ JAR ที่เราคอมไพล์ ให้เพิ่มบรรทัดต่อไปนี้ที่ด้านล่างของ Dockerfile

CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

Dockerfile สุดท้าย

Dockerfile สุดท้ายจะเป็น

FROM openjdk:11.0-jdk
WORKDIR /app
COPY . /app
RUN ./mvnw compile assembly:single
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

คอมมิต Dockerfile ในเครื่อง

cd ${HOME}/sample-app
git add Dockerfile
git commit -m "Added Dockerfile"

4. สร้าง

ตอนนี้เราจะสร้างอิมเมจจาก Dockerfile โดยใช้คำสั่ง docker build คำสั่งนี้จะสั่งให้ Docker Daemon สร้างอิมเมจโดยใช้วิธีการจาก Dockerfile ดูข้อมูลเพิ่มเติมได้ที่เอกสารอ้างอิงบิลด์ของ Docker

สร้างอิมเมจ

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker build --tag sample-app:${IMAGE_TAG} .

เอาต์พุต

Sending build context to Docker daemon  221.2kB
Step 1/4 : FROM openjdk:11.0-jdk
11.0-jdk: Pulling from library/openjdk
0c6b8ff8c37e: Pull complete
412caad352a3: Pull complete
e6d3e61f7a50: Pull complete
461bb1d8c517: Pull complete
e442ee9d8dd9: Pull complete
542c9fe4a7ba: Pull complete
41de18d1833d: Pull complete
Digest: sha256:d72b1b9e94e07278649d91c635e34737ae8f181c191b771bde6816f9bb4bd08a
Status: Downloaded newer image for openjdk:11.0-jdk
---> 2924126f1829
Step 2/4 : WORKDIR /app
---> Running in ea037abb273d
Removing intermediate container ea037abb273d
---> bd9b6d078082
Step 3/4 : COPY . /app
---> b9aec2b5de51
Step 4/4 : RUN ./mvnw compile jar:jar
---> Running in 3f5ff737b7fd
[INFO] Scanning for projects...
...
[INFO] Building jar: /app/target/sample-app-1.0.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.952 s
[INFO] Finished at: 2022-02-23T18:09:08Z
[INFO] ------------------------------------------------------------------------
Removing intermediate container 331443caebd3
---> 152f65cc441e
Step 5/5 : CMD ["java", "-jar", "/app/target/sample-app-1.0.0.jar"]
---> Running in 3d595a72231c
Removing intermediate container 3d595a72231c
---> 0e40d7548cab
Successfully built 0e40d7548cab
Successfully tagged sample-app:aaa8895

5. เรียกใช้

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

เรียกใช้คอนเทนเนอร์โดยใช้อิมเมจ

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG}

เอาต์พุต

Listening at http://localhost:8080

แสดงตัวอย่างแอปพลิเคชันที่ทำงานในคอนเทนเนอร์

  • คลิกปุ่มตัวอย่างเว็บ Cloud Shell
  • คลิก "แสดงตัวอย่าง" บนพอร์ต 8080
  • กด Ctrl + c ใน Cloud Shell เพื่อหยุดคอนเทนเนอร์

การเปลี่ยนลักษณะการทำงานของคอนเทนเนอร์

การดำเนินการเรียกใช้ Docker จะใช้การกำหนดค่าเริ่มต้นใน Dockerfile คุณสามารถเพิ่มวิธีการและพารามิเตอร์เพิ่มเติมเพื่อแก้ไขลักษณะการทำงานนี้ได้

เปิดใช้การบันทึก TRACE

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG} \
  java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar /app/target/sample-app-1.0.0-jar-with-dependencies.jar

แสดงตัวอย่างแอปพลิเคชันที่ทำงานในคอนเทนเนอร์

  • คลิกปุ่มตัวอย่างเว็บ Cloud Shell
  • คลิก "แสดงตัวอย่าง" บนพอร์ต 8080
  • เปลี่ยนไปที่แท็บ Cloud Shell แล้วดูว่าการบันทึกเพิ่มเติมนั้น
  • กด Ctrl + c ใน Cloud Shell เพื่อหยุดคอนเทนเนอร์

เปลี่ยนพอร์ต

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-e PORT=8081 \
-p 8081:8081 \
sample-app:${IMAGE_TAG}

แสดงตัวอย่างแอปพลิเคชันที่ทำงานในคอนเทนเนอร์

  • คลิกปุ่มตัวอย่างเว็บ Cloud Shell
  • คลิกเปลี่ยนพอร์ต
  • ป้อน 8081
  • คลิก เปลี่ยนและดูตัวอย่าง
  • กด Ctrl + c ใน Cloud Shell เพื่อหยุดคอนเทนเนอร์

6. พุช

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

พุชสัญญาผูกมัด Dockerfile ไปยังที่เก็บแอปตัวอย่าง

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
git push

ติดแท็กอิมเมจสำหรับ Artifact Registry

docker tag sample-app:${IMAGE_TAG} \
    us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

กำหนดค่าข้อมูลเข้าสู่ระบบสำหรับ Artifact Registry

gcloud auth configure-docker us-central1-docker.pkg.dev

เมื่อได้รับแจ้ง Do you want to continue (Y/n)? ตอบ y แล้วกด Enter

พุชอิมเมจไปยัง Artifact Registry

docker push us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

เอาต์พุต

 The push refers to repository [us-central1-docker.pkg.dev/qwiklabs-gcp-04-b47ced695a3c/apps/sample-app]
  453b97f86449: Pushed
  e86791aa0382: Pushed
  d404c7ee0850: Pushed
  fe4f44af763d: Pushed
  7c072cee6a29: Pushed
  1e5fdc3d671c: Pushed
  613ab28cf833: Pushed
  bed676ceab7a: Pushed
  6398d5cccd2c: Pushed
  0b0f2f2f5279: Pushed
  aaa8895: digest: sha256:459de00f86f159cc63f98687f7c9563fd65a2eb9bcc71c23dda3351baf13607a size: 2424

7. ยินดีด้วย

ยินดีด้วย คุณศึกษา Codelab จบแล้ว

สิ่งที่คุณได้ครอบคลุม

  • สร้าง Dockerfile สำหรับแอปพลิเคชันตัวอย่างแล้ว
  • สร้างรูปภาพ
  • เรียกใช้อิมเมจเป็นคอนเทนเนอร์ในเครื่อง
  • เปลี่ยนแปลงลักษณะการทำงานของคอนเทนเนอร์แล้ว
  • พุชอิมเมจไปยัง Artifact Registry แล้ว