ข้ามไปที่เนื้อหาหลัก

Docker ทำอะไรได้มากกว่า run container มาหาคำตอบกัน — Part 1


จริงๆ แล้ว Docker ทำอะไรได้มากกว่า run container มาหาคำตอบกัน — Part 1

0.เกริ่นนำ

หลายคนอาจจะเคยใช้ Docker กันไม่มากก็น้อย
docker pull
docker images
docker ps
docker run
แต่จริงๆ แล้วนั้น docker ทำอะไรได้บ้างเราจะมาดูกัน
โดยใน Series นี้เอามาจาก katacoda ที่ผมได้ลองทำแล้วเก็บไว้
จุดประสงค์ในการเขียนไว้กันลืม
*ถ้าใครยังไม่เข้าใจ images กับ container ให้ลองอ่านก่อน เพราะจะไม่ได้อธิบายไว้
สมัยก่อนหากเราจะต้องใช้ ฐานข้อมูลหรือโปรแกรมอะไรสักอย่างก็ต้อง install ติดตั้งลงเครื่องเอง ซึ่งแต่ละโปรแกรมก็มี step ที่แตกต่างกัน ทำให้เสียเวลาในการ setup เครื่องอย่างมาก เพราะการติดตั้ง software ใน environment ที่แตกต่างกันของแต่ละเครื่องไม่ว่าจะทั้ง OS หรือ version ที่ติดตั้งไม่เท่ากัน
การมาของ Docker ทำให้ Developer ทำงานง่ายขึ้น
หากใครสนใจลองเล่นด้วยตัวเอง แนะนำที่นี่เลยครับ

1.Deploy container ตัวแรก

หากเราอยากจะใช้ database สักตัว อย่าง redis เราสามารถใช้
docker search redis
ในการ หาชื่อ image ที่มีอยู่บน registry.hub.docker.com ได้
หลังจากเมื่อได้ชื่อของ images ที่ต้องการใช้แล้วก็ใช้คำสั่ง
docker run -d redis // ชื่อ image official
เมื่อ run ด้วย image redis แล้ว docker จะสร้าง container ขึ้นมา
ถ้าอยากรู้ว่าโอเคไหม ก็
docker ps
หากต้องการดูว่า container มี information อะไรบ้าง สามารถใช้คำสั่ง
docker inspect <ชื่อcontainer|id>
หรือหากต้องการดู log ของ container ก็ใช้คำสั่ง
docker log <ชื่อcontainer|id>
แต่ redis ที่รันขึ้นมานี้เรายังไม่สามารถ access เข้าไปได้เนื่องจากยังไม่ได้เปิด port
เราจะต้องใช้ option -p สำหรับเชื่อม port ของเครื่องเราและ container ด้วย
docker run -d -p 6379:6379 redis
แต่ถ้าอยากให้ docker random port ของเครื่องเราให้ก็ไม่ต้องใส่ 6379:6379 แค่ระบุ port ของ container แล้ว docker จะจัดการ map port ให้เอง
docker run -d -p 6379 redis
แต่ถ้าใช้วิธีนี้ จะต้องลองหา port ที่ random ให้โดยใช้
docker port <ชื่อ container|id> 6379
จึงจะโชว์ port ที่เชื่อมออกมาด้านนอก
เป็นอันเรียบร้อย
แตถ้าเราสั่งปิด container ข้อมูลจะหายไปทันที จากเราต้องการ persist ข้อมูลไว้ เราสามารถใช้ option -v ในการ map ข้อมูลออกมาเก็บไว้ในเครื่องที่ run docker อยู่ได้
ทำให้ข้อมูลถูกเก็บไว้ภายนอก container ไม่ต้องกลัวว่าข้อมูลจะหายอีกต่อไป
docker run -d -v /path/data/redis:/data redis

2. สร้าง static web server ด้วย nginx

เวลาที่เขียน web ปัญหาหนึ่งที่มักพบกันคือ ต้องการ web server มาแสดงผล html ก็จะไปจบกันที่ software รุ่นดึกดำบรรพ์อย่าง appserv ที่ไม่มีคนใช้แล้ว หรือ xamp กันนั่นเอง ซึ่ง software เหล่านี้มันไม่มีความใกล้เคียงกับ environment จริงๆ บน production เลย
เราจะมาสร้าง web server ใช้เองด้วย Docker กัน
//project structure
/
 -> index.html
สร้าง Dockerfile
// ./index.html
FROM nginx:alpine
COPY . /usr/share/nginx/html
จากนั้นเอา dockerfile ที่ได้มาสร้างเป็น image ด้วยคำสั่ง
docker build -t <ชื่อ tag:ver> .
จะได้เป็น image ขึ้นมาตามชื่อ tag ที่กำหนด ลอง docker ps ดูได้
docker ps // เพื่อดู image ใหม่
แล้วลอง run เป็น container ขึ้นมา
docker run -d -p 80:80 webserver-image:v1
ก็จะได้ web server ที่พร้อมใช้งานแล้ว

3. วิธีเลือก base image

ปกติเวลาเราจะสร้าง image ไว้ใช้เอง สิ่งที่ขาดไม่ได้คือการเลือก base image ที่จะเป็นโครง
  • หลีกเลี่ยงการใช้ tag ที่เป็น latest ควรระบุเลข version ไปเลยเพื่อไม่ให้เกิดปัญหา หากต้องการ update version ให้แก้ไข Dockerfile แทน
  • เลือกใช้ image ที่มีขนาดเล็กกระทัดรัด (lightweight) อย่าง alpine เพราะหาก image ยิ่งใหญ่ software ที่ติดตั้งยิ่งเยอะ ยิ่งเสี่ยงเรื่อง security มากขึ้น
หากมีไฟล์ที่ไม่ต้องการเอาขึ้นให้เอาใส่ไว้ใน .dockerignore ที่วางไว้ directory เดียวกันกับ Dockerfile

4. อะไรคือ OnBuild

หากในหลายๆ โปรเจ็คเรามีส่วนของการ setup ซ้ำๆ ใน dockerfile เราสามารถสร้าง base file ใหม่เป็นแบบ ONBUILD โดยคำสั่งที่เห็นใน Dockerfile นั้นจะถูกรันเฉพาะแค่ถูกเรียกใช้เป็น base image เท่านั้น
ตัวอย่าง image จาก node.js OnBuild
// dockerfile ที่เป็น base
FROM node:7
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app
CMD [ "npm", "start" ]
แล้วจึงนำไปใช้ใน project อื่นๆ
// application image
FROM node:7-onbuild
EXPOSE 3000

5. สร้าง Data Container

นอกจากเราจะสร้าง container ไว้รันให้ทำงานตลอดแล้ว เรายังสามารถสร้าง container เพื่อเก็บ data อย่างเดียวได้ด้วย
สร้าง Data Container
docker create -v /config --name dataContainer busybox
  • -v คือการระบุ directory ที่จะทำการ read/write ข้อมูล
  • busybox เป็น linux image ขนาดเล็ก
โดย data container ปกติจะไม่ได้รันทำงานอยู่ เวลาเช็คใน docker ps
เอาไฟล์เข้าไปเก็บใน data container
จากนั้นเราจะเอาไฟล์ config จากเครื่องเรา เข้าไปใน directory /config ภายใน container
docker cp config.conf dataContainer:/config/
  • dataContainer:/config
    containerName:/path/to/file
นำ data container ไปใช้ใน container อื่น
จากนั้นเราสามารถเอา data ที่เก็บไว้ใน container ไปใช้ใน container ตัวอื่นได้ โดยใช้ option -volumes-from
เช่น รัน ubuntu container ขึ้นมาโดยใช้ ข้อมูลจาก dataContainer
docker run --volumes-from dataContainer ubuntu ls /config
export/import data container
หากต้องการเอา data container ไปใช้ในเครื่องอื่นๆ สามารถทำ export และ import ได้โดยใช้คำสั่ง
// export
docker export dataContainer > dataContainer.tar
// import
docker import dataContainer.tar

6. การ communicate กันระหว่างแต่ละ container

อันนี้เป็นอีกอันที่ผมลืมไปแล้ว เพราะหลังๆ ใช้ k8s มัน link กันด้วย service เลยไม่ค่อยได้ใช้
เช่น เรามี redis-server เป็น container ที่รัน redis อยู่
// run redis-server
docker run -d --name redis-server redis
จากนั้นเราสร้าง application container ขึ้นมารัน โดยเราจะเชื่อมให้ container redis-server กับ application container โดยใช้ option link
// run application
docker run -d --link redis-server:redis alpine
  • redis-server:redis
    ชื่อ container:ชื่อที่ container application จะใช้เรียก container หา

7. Docker สามารถสร้าง Network ภายในได้

ใน docker เราสามารถกำหนด network ให้ container มองเห็นกันเองได้ด้วย
ในการสร้าง network เราสามารถสร้างได้โดยใช้ คำสั่ง
docker network create backend-network
  • backend-network เป็นชื่อของ network
จากนั้น เราจะสร้าง container ขึ้นมาโดยทำการระบุ network ที่ container อยู่ด้วย option -net=<ชื่อ network>
docker run -d --name=redis --net=backend-network redis
โดยแต่ละ container สามารถอยู่ได้มากกว่า 1 network
เช่น เราอาจจะแบ่งวง network เป็น 2 วง
  • frontend-network
  • backend-network
docker network create frontend-network
เช่น หาก redis server ของเราอยู่ใน network ของ backend-network เราจะให้สามารถนำไปใช้ใน frontend-network ได้ด้วย โดยใช้คำสั่ง
docker network connect frontend-network redis
เพื่อเชื่อม redis เข้าไปใน network ของ frontend-network ที่มีอยู่แล้ว
ซึ่งเราสามารถ ใช้ alias ในการเปลี่ยนชื่อของ container ที่อยู่ในวงเดียวกันได้ (เบื้องหลัง container จะมี dns ที่ใช้หากันภายในอีกที) เช่น สร้าง network ชื่อ frontend-network2 ขึ้นมาโดยตั้ง alias ว่า db แทน frontend-network2
docker network create frontend-network2
docker network connect --alias db frontend-network2 redis
  • ตั้ง alias ชื่อ db ให้ container redis ในเฉพาะ network ของ frontend-network2
ซึ่งเราสามารถดู network ใน docker ทั้งหมดได้โดยใช้
docker network ls
เราสามารถดูได้
docker network inspect frontend-network
หากจะเอา container ออกจาก network ให้ใช้คำสั่ง
docker network disconnect frontend-network redis
แต่ถ้าใช้ k8s ก็ไม่ต้องมาจัดการเรื่องเหล่านี้นะครับ :)

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

Docker Crash Course

 https://www.youtube.com/watch?v=pg19Z8LL06w ▬▬▬▬▬▬ T I M E S T A M P S ⏰ ▬▬▬▬▬▬ 0:00 - Intro and Course Overview 02:54 - What is Docker? 03:51 - What problems Docker solves in development and deployment process 11:38 - Virtual Machine vs Docker 17:19 - Install Docker 21:36 - Docker Images vs Containers 26:32 - Docker Registries 29:38 - Docker Image Versions 32:02 - Main Docker Commands - Pull and Run Docker containers 39:06 - Port Binding 42:50 - Start and Stop containers 46:54 - Private Docker Registries 48:11 - Registry vs Repository 49:09 - Dockerfile - Dockerize Node.js app 58:30 - Build Image 1:02:39 - Docker UI Client 1:03:39 - Overview: Docker in complete software development lifecycle 1:06:38 - Where to go from here

ย้าย Docker Container ข้าม Cloud Provider

ย้าย Docker Container ข้าม Cloud Provider Posted on  02/12/2014   by  Anuchit Chalothorn ปัญหาเรื่องการย้าย Application ข้าม Cloud Provider เป็นปัญหาปกติที่ต้องหาทางแก้ไข ซึ่งแต่ละ Cloud Provider มีช่องทางในการบริการที่ต่างกัน เทคโนโลยีต่างกัน เครื่องมือที่ใช้งานก็ต่างกัน เรียกได้ว่าถ้าจะย้าย instance จะทำได้ยากมาก ครั้งนี้จะให้แนวคิดเรื่องการย้าย Container จาก Cloud Provider ค่ายหนึ่งไปยังอีกค่ายหนึ่งหรือจาก Local ไปยัง Cloud Provider ก็ได้ ซึ่งทำได้หลายวิธี จากภาพแนะนำการย้ายแบบง่ายๆ ผ่าน Docker อย่างเดียวไม่ได้ใช้เครื่องมือใดๆ เพิ่มเติม ถ้าจะให้สะดวกควรมี Orchestration Service อยู่ในแต่ละ Cloud Provider ด้วย ในเบื้องต้นทำความเข้าใจแบบง่ายๆ กันก่อน การทำ Migration ทำได้ 2 แบบ คือ Import / Export ไฟล์ Container ทั้งก้อนจาก Local ไปยัง Cloud วิธีนี้จะให้ความสะดวกมากกว่าแต่การสำรองข้อมูลและการย้ายไฟล์ Export จะช้าขึ้นอยู่กับความเร็วของเน็คเวิร์ก Push / Pull ให้ Commit Container State ปัจจุบันแล้ว push ขึ้น Docker Registry อาจจะเป็น Docker Hub (Private) หรือ P...

Podman

  https://medium.com/@raghavendraguttur/podman-containers-beginners-guide-830b931e66f4