Basics of Docker

Tuyen
Written by Tuyen on
Basics of Docker

Một số định nghĩa cơ bản:

Docker image

Là file chứa tất cả các thông tin của chương trình, kể cả system, dependency,… được đóng gói vào.

Bạn có thể xem các image đã tạo trong folder /var/lib/docker/images kết hợp sudo tree <path trên>

Cách diễn giải khác thì đây là một file bất biến - không thay đổi, chứa các source code, libraries, dependencies, tools và các files khác cần thiết cho một ứng dụng để chạy.

Docker container:

Là 1 môi trường tách biệt (như 1 container) được đặt trên máy ở 1 không gian riêng và không liên quan đến các chương trình khác.

Cách diễn giải khác là một run-time environment mà ở đó người dùng có thể chạy một ứng dụng độc lập. Những container này rất gọn nhẹ và cho phép bạn chạy ứng dụng trong đó rất nhanh chóng và dễ dàng.

Sự liên quan:
  • Image có thể tồn tại mà không cần container, trong khi container chạy thì cần có image đã tồn tại. Vì vậy, container phụ thuộc vào image và sử dụng nó để tạo ra run-time environment và chạy ứng dụng trên đó.

  • Cả image và container đều là thành phần quan trọng để tạo ra 1 running container. Docker image là cực kì quan trọng để chi phối và định hình 1 Docker container.

Cách RUN image trên UBUNTU

docker run ubuntu //nếu chưa pull ubuntu image về thì sẽ pull rồi start, còn nếu pull rồi thì nó sẽ start container này luôn => nếu khi start mà thấy chưa có interact gì thì nó sẽ stop container lại luôn

docker ps //xem list các tiến trình đang chạy của container hoặc các container đang chạy

docker ps -a //xem các container đã dừng lại

docker run -it ubuntu // start container với interaction mode và load ubuntu image lên trong cái container này

Các câu lệnh: history !2 //để output cmd thứ 2 trong list history ls -1 //líst ds theo dạng dọc

ls -l //list ds chi tiet

touch <tên file> //lệnh tạo file

mkdir <tên thư mục> //lệnh tạo thư mục

mv <tên file hoặc địa chỉ> <tên file hoặc địa chỉ> //đổi tên hoặc di chuyển

cat <tên file>

more <tên file hoặc địa chỉ> //xem nội dung theo từng page, bấm phím space để qua trang tiếp theo nhưng ko scroll up lên được, nhấn enter để chạy từng line để xem

less <tên file hoặc địa chỉ> //

cat <tên file> > <tên file khác> //copy nội dung file này vào file khác

cat <tên file> <tên file khác> > <tên combined file> //combine nội dung 2 file vào file khác

dấu > áp dụng cho hầu hết các câu lệnh vd: echo hello > hello.txt ls -l /etc > hello.txt sẽ cho kết quả ra file hello.txt trên.

Trong Linux, mọi thứ đều ở duới dangj file, từ process, devices, hoặc địa chỉ thư mục đều là files

Cấu trúc Linux:

  • /
  • bin: chưa các file binaries, chương trình
  • boot: các file liên quan booting
  • dev: devices
  • etc: editable text configuration, chứa file config
  • home: thư mục của user
  • root: chỉ có root mới vào được thư mục này
  • lib: libary files như software library dependencies
  • var: như biến, chứa các file được update thường xuyên như log,…
  • proc: chứa các tiến trình đang running

Các bước để sử dụng Docker

  • Cài đặt Docker
  • Tạo 1 program và Tạo file plain text Dockerfile ghi hướng dẫn để đưa cho docker đóng gói ứng dụng thành 1 image. Image chứa tất cả mọi thứ để chương trình chạy. IMAGE bao gồm:
    • A cut-down OS
    • Môi trường runtime (vd như Node, Python)
    • File ứng dụng
    • Thư viện thứ 3
    • Biến môi trường => Sau khi có cái Image này, ta sẽ nói với Docker để start container Container như 1 process, nhưng là process đăc biệt vì nó có file system được cung cấp bởi Image. Ứng dụng của chúng ta sẽ được chạy trong cái process/container này.

Ok giờ chúng ta start docker. Thay vì chạy ứng dụng như bình thường, ta gọi Docker để chạy bên trong cái container nhé

docker run ..

Ví dụ sự khác nhau :

Để chạy 1 chương trình JS đơn giản, ta cần phải qua 4 bước:

  • Start OS
  • Cài Node
  • Copy file ứng dụng
  • Chạy node app.js

Với docker, ta chỉ cần:

  • Bước 1:

    • Vào thư mục project trên vscode code . Tạo file Dockerfile không ext, và input các thông tin sau:

FROM node:alpine

Chọn image node trên trang docker hub và : distribution của linux, ở đây chọn alpine vì nó nhẹ nhất .

COPY . /app

copy tất cả file execute vào thư mục app tạo mới, vào rồi copy vào trong image

hoặc có thể hiểu là trong cái image có file system, và chúng ta tạo thư mục app bên trong file system đó, trong thư mục app chứa tất cả các file của program.

File requirements.txt chứa các thư viện mà chương trình cần. Cần COPY trước khi RUN các cài đặt trong Dockerfile. VD của file: tornado==6.1 . Với Pycharm thì ta có thể dùng Tools=>Sync Python Requirement để tự động generate.

WORKDIR /app

tạo đường dẫn rút gọn

CMD node /app.js

câu lệnh chạy ứng dụng, để docker biết mà chạy câu nào khi run

  • Bước 2: Ta nói docker đóng gói úng dụng thành image docker build -t hello-docker . trong đó, dấu . chỉ cho docker biết chỗ nào chứa Dockerfile hello-docker là tên repos docker mình tự tạo để quản lý

Để xem có bao nhiêu docker đang chạy: docker image ls kết quả câu lệnh có cột SIZE chỉ size của OS (alpine) + ứng dụng + node

  • Bước 3: Chạy thử docker image docker run hello-docker Đây là câu run cơ bản, ta có thể chạy ở thư mục nào cũng được, vì image đã chứa mọi thứ cần.

Hầu hết các docker run dùng cú pháp chuẩn này:

Cách 1:

docker  run -d -p 80:8888 shorten-link

Với 8888 ở đây là listen port của program trên container tại đây https://github.com/tuyen-nnt/shortenLink/

Với 80 là port trên máy host của mình, -d là chạy ngầm.

Sau khi docker run thì ta test container bằng cách chạy câu lệnh:

docker exec -it <CONTAINER ID> bash 

Trả về:

root@05b418a61ca3:/app# ls 

ls để list ra các file trong docker image, có thể check xem bước COPY đã đúng những file mình cần để chạy chương trình chưa?

Để test wep app trên browser, ta dùng địa chỉ ip của máy:port máy host (expose) và thêm /đường dẫn như cài đặt.

Cách 2:

Không cần port mà dùng luôn localhost, nghĩa là user bên ngoài chỉ cần dùng IP gateway:port của chương trình là được:

docker run -d --net=host shorten-link

Tuy nhiên nên hạn chế cách này, vì sẽ khiến conflict với các chương trình khác nếu chẳng may host mình cũng dùng port 8888 này ở chương trình đâu đó, vì mình không quyết định và control được port map (interface) như cách 1 để tùy chỉnh. Còn để host kiểu này khó biết được.

  • Bước 4 Publish lên docker hub: hub.docker.com

Khi ở máy khác, ta muốn pull image về chạy:

  • Bước 1: Kiểm tra version docker, nếu chưa download thì chạy lệnh install docker vesion

  • Bước 2: Kéo image về docker pull senrie/hello-docker

Kiểm tra lại = cách: docker image ls

  • Bước 3: Chạy chương trình trên machine docker run senrie/hello-docker

Về PORTS trong Docker

Ta có thể xem các container đã build bằng lệnh docker ps : danh sách container đang chạy, và lệnh docker ps -a: tất cả container đã build.

Ta thấy có cột PORTS, ví dụ:

0.0.0.0:80->8888/tcp, :::8888->8888/tcp

Mình sẽ giải thích từng chỉ số:

  • 0.0.0.0: nghĩa là có thể dùng tất cả các IP của máy (IP card mạng LAN, IP wifi,.. có thể check bằng ifconfig) để làm gateway cho bên ngoài truy cập vào thông qua port cụ thể bên dưới.
  • 80 (layer ngoài): là port của máy host expose cho bên ngoài dùng để truy cập vào, như cánh cổng mở ra
  • 8888 (layer trong): là listen port của chương trình trên container trong máy host của chúng ta.

    Port 80 sẽ được setup trên tất cả các gateway và centralize lại để link với container có port 8888. Nghĩa là ta dùng IP gateway:80 thì sẽ tiếp cận được đến chương trình container.

Để check xem máy chúng ta đang chạy các port nào tránh conflict, ta dùng lệnh: sudo netstat -plunt

Xem qua về Docker run để hiểu hơn: https://docs.docker.com/engine/reference/commandline/run/


Xem cấu hình

Các cmd thường dùng:

  • docker inspect <containerID> : xem các gateway, ip, network,… của container để biết nó đang xài network nào
    • Nếu cài port khi run thì network là “bridge” (khi netstat sẽ ra docker-proxy)
    • Nếu dùng –net=host thì network là “host”
  • wrk -t4 -c400 -d30s <url> : xem perform mance của web (tham khảo thêm tại https://github.com/wg/wrk)

    Các bước fix bugs

  • Bước 1: Xác định xem lỗi gì (dùng curl, Postman hoặc F12)
  • Bước 2: Coi log. Ví dụ:
    docker logs -f $(docker ps | grep "83->" | awk '{print $1}')
    

    Thêm tag -f để xem log real time không cần in hết log.

  • Bước 3: Debug
    • Dynamic Analysis: dùng break point hoặc print ra console,… => Cách này áp dụng tốt cho các trường hợp phức tạp và đơn giản cũng ok nếu đoán được code chỗ nào lỗi.
    • Static Analysis: đọc code chay (khi không biết chỗ nào run function đó, thường thì trong hướng đối tượng hay gặp phải)

Tìm hiểu về Volumn trong Docker

Tuyen

Tuyen

Author of this blog, mostly about Technical which is the field I am interested in.

Comments

comments powered by Disqus