การพัฒนาคอนเทนเนอร์ด้วย 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 ของ Cloud การทำตาม Codelab นี้ไม่ควรมีค่าใช้จ่ายมากนัก หรืออาจไม่มีเลย หากต้องการปิดแหล่งข้อมูลเพื่อไม่ให้มีการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ ให้ทำตามวิธีการ "ล้างข้อมูล" ที่ตอนท้ายของ Codelab ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD

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

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

ซอร์สโค้ด

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

กำหนดค่า Git

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

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

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>

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

COPY . /app

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

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

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

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

RUN ./mvnw compile assembly:single

เริ่มสมัคร

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

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

สำหรับแล็บนี้ เราจะเรียกใช้ไฟล์ 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 build

สร้างอิมเมจ

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 run คำสั่งนี้จะเปิดใช้คอนเทนเนอร์ในเบื้องหน้าของ Command Prompt สำหรับการทดสอบหรือการแก้ไขข้อบกพร่อง ดูข้อมูลเพิ่มเติมได้ที่เอกสารอ้างอิงของ docker run

เรียกใช้คอนเทนเนอร์โดยใช้รูปภาพ

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 Run จะใช้การกำหนดค่าเริ่มต้นใน 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 ไปยังที่เก็บ sample-app

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