Tìm kiếm bài viết

Docker là gì? Tìm hiểu về Docker cho dân DevOps

06.01.2020

5.0/5 (1 Reviews)

Docker là một nền tảng dành cho các developer và sysadmin để phát triển, triển khai và chạy các ứng dụng bằng các container. Việc đóng gói thành container này giúp cho việc triển khai các ứng dụng trở nên dễ dàng hơn.

    Docker là gì?

    Docker là một nền tảng dành cho các developer và sysadmin để phát triển, triển khai và chạy các ứng dụng bằng các container. Việc đóng gói thành container này giúp cho việc triển khai các ứng dụng trở nên dễ dàng hơn.

    Docker là gì?

    Công nghệ container ngày càng phổ biến bởi:

    • Linh hoạt: Có thể đóng gói từ ứng dụng đơn giản đến phức tạp
    • Nhỏ gọn: Các container tận dụng, sử dụng chung tài nguyên; kernel của host. Có thể chạy ở mọi nơi, mọi nền tảng.
    • Khả năng thay đổi linh hoạt: Cập nhật và nâng cấp nhanh chóng.
    • Khả năng mở rộng: Dễ dàng tăng và phân tán tự động các container
    • Phân tầng dịch vụ: Mỗi dịch vụ khi deploy sẽ được phân tầng, nằm trên các dịch vụ đang có sẵn. Như vậy sẽ không làm ảnh hưởng tới dịch vụ đang chạy.

    Khái niệm containers và images

    • Một container được khởi chạy từ image. Như vậy, image là một gói thực thi chứa bên trong là tất cả những gì cần thiết, liên quan để chạy ứng dụng như mã nguồn, các thư viện, runtime, các biến môi trường và các file cấu hình liên quan.
    • Một container là một instance đang chạy được khởi tạo từ image.

    So sánh giữa VM với container

    • Container chạy trực tiếp trên môi trường máy chủ như một tiến trình và chia sẻ phần kernel bên dưới dùng chung với máy chủ chứa nó
    • VM tạo ra một môi trường giả lập hoàn toàn tách biệt như 1 máy hoàn chỉnh thông qua việc phân bổ tài nguyên của máy chủ, do đó sẽ tốn tài nguyên nhiều hơn cho hệ điều hành của máy ảo

    Cấu trúc và thành phần của Docker

    Docker bao gồm:

    • Docker Client: Giao diện để tương tác giữa người dùng với Docker Daemon - HOST
    • Docker Daemon (HOST): Lưu trữ image local và khởi chạy container từ những image đó
    • Docker Hub (registry): Nơi lưu trữ các images

    Docker Client

    Docker client dùng để tương tác giữa người dùng và Docker Daemon, Daemon sẽ biên dịch và thực thi các câu lệnh đã tương tác qua Docker client.

    Xem phiên bản đang sử dụng

    docker version

    Câu lệnh sẽ trả về phiên bản của Docker client và Daemon (server)

    Client:
     Version:           18.09.6
     API version:       1.39
     Go version:        go1.10.8
     Git commit:        481bc77156
     Built:             Sat May  4 02:34:58 2019
     OS/Arch:           linux/amd64
     Experimental:      false
    
    Server: Docker Engine - Community
     Engine:
      Version:          18.09.6
      API version:      1.39 (minimum version 1.12)
      Go version:       go1.10.8
      Git commit:       481bc77
      Built:            Sat May  4 02:02:43 2019
      OS/Arch:          linux/amd64
      Experimental:     false
    

    Xem thông tin chi tiết về Docker

    Cung cấp thông tin về tài nguyên máy chủ, chi tiết về Docker.

    docker info
    Containers: 3
     Running: 3
     Paused: 0
     Stopped: 0
    Images: 7
    Server Version: 18.09.6
    Storage Driver: overlay2
     Backing Filesystem: xfs
     Supports d_type: true
     Native Overlay Diff: true
    Logging Driver: json-file
    Cgroup Driver: cgroupfs
    Plugins:
     Volume: local
     Network: bridge host macvlan null overlay
     Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
    Swarm: inactive
    Runtimes: runc
    Default Runtime: runc
    Init Binary: docker-init
    containerd version: bb71b10fd8f58240ca47fbb579b9d1028eea7c84
    runc version: 2b18fe1d885ee5083ef9f0838fee39b62d653e30
    init version: fec3683
    Security Options:
     seccomp
      Profile: default
    Kernel Version: 3.10.0-957.10.1.el7.x86_64
    Operating System: CentOS Linux 7 (Core)
    OSType: linux
    Architecture: x86_64
    CPUs: 1
    Total Memory: 991.2MiB
    Name: minion4
    ID: 6BBX:UEEB:SDZ4:LGES:HSFN:WIEY:TASR:5MRK:JMV6:7O7W:CTGY:ATPX
    Docker Root Dir: /var/lib/docker
    Debug Mode (client): false
    Debug Mode (server): false
    Registry: https://index.docker.io/v1/
    Labels:
    Experimental: false
    Insecure Registries:
     127.0.0.0/8
    Live Restore Enabled: false
    Product License: Community Engine
    

    Tìm kiếm image trên registry

    docker search python
    • NAME: Tên của Image
    • DESCRIPTION: Mô tả về image
    • STARS: Số lượt rating. Số này càng cao thì chất lượng của Image càng tốt.
    • OFFICIAL: Được cung cấp bởi Hãng hoặc Tổ chức đã được xác nhận trên Registry

    Chạy một container từ Image

    docker run -i -t --name web1 ubuntu

    Khi chạy docker pull, mặc định sẽ tìm trên localhost xem có image nào trùng với yêu cầu trong câu lệnh hay không. Nếu image không có sẵn trên localhost, Docker sẽ tìm kiếm và tải về (pull) từ Registry mặc định.

    • -i: Vào chế độ tương tác trực tiếp với Container
    • -t: Hiển thị tty
    • --name: Đặt tên cho container. Mặc định, nếu không đặt thì sẽ có tên ngẫu nhiên.

    Để thoát ra khỏi chế độ tương tác, thao tác lần lượt CTRL + P sau đó CTRL + Q

    Khởi động container ở chế độ chạy nền

    docker run -d --name web1 ubuntu

    Liệt kê các container

    docker ps -a

    -a hoặc --all: Hiển thị toàn bộ số container có trên hệ thống

    • CONTAINER ID: ID của container
    • IMAGE: Tên của Image khởi tạo
    • COMMAND: Câu lệnh chính khi khởi động của container/image
    • CREATE: Thời gian container được tạo
    • STATUS: Trạng thái của container
    • PORT: Cổng của container được ánh xạ với host (HOST:CONTAINER)
    • NAMES: Tên của container

    Liệt kê các image

    docker images

    Hoặc

    docker image list
    • REPOSITORY: Tên của image
    • TAG: Phiên bản của image

    Dừng hoạt động của container

    docker stop web1

    Khởi động của container

    docker start web1

    Có thể thêm -i để có thể tương tác trực tiếp với container.

    Tương tác với Container đang hoạt động

    docker attach web1

    Hoặc tương tác sử dụng môi trường /bin/bash

    docker exec -it web1 /bin/bash

    Xóa container

    Container chỉ bị xóa khi ở trạng thái dừng hoạt động.

    docker rm web1

    Tạo container ánh xạ port với HOST (Máy chủ)

    Ánh xạ port ngẫu nhiên với HOST

    docker run -d --name db4 -P -e MYSQL_ROOT_PASSWORD=mysql-1 mysql

    -P: Ánh xạ ngẫu nhiên
    -e: Gán biến môi trường của trong container

    Kiểm tra các port ánh xạ của container

    > docker port db4
    3306/tcp -> 0.0.0.0:32777
    33060/tcp -> 0.0.0.0:32776
    

    Chỉ định port ánh xạ giữa container với HOST

    docker run -d --name db5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysql-1 mysql

    Kiểm tra các port ánh xạ của container

    > docker port db5
    3306/tcp -> 0.0.0.0:3306
    

    Ánh xạ một thư mục trên HOST vào bên trong container

    Để ánh xạ, tùy chọn -v được sử dụng khi khởi tạo container. Ví dụ, ánh xạ thư mục lưu trữ dữ liệu của mysql trong container với một thư mục trên host.

    mkdir -p /opt/mysql_data
    docker run -d -v /opt/mysql_data:/var/lib/mysql  --name db6 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysql@123 mysql
    

    Liên kết giữa các container với nhau

    Việc liên kết các container để chúng có thể ‘trò chuyện’ với nhau thường được dùng bằng cách expose các port, điều này vô cùng bất lợi. Docker hỗ trợ liên kết các container với nhau bằng cách sử dụng tham số --link khi khởi tạo một container mới. Ví dụ, tạo một container khác để chạy ứng dụng webserver sử dụng database là container db6 vừa tạo ở bước trên:

    docker run -d --link db6:db.example.com --name wp1 -p 80:80,443:443 wordpress
    
    --link db6:db.example.com: Liên kết với container có tên là db6 và có alias là db.example.com (giá trị này tương đương với FDQN)

    Docker Hub (Registry)

    Docker Hub hay thường được gọi là Registry, nơi lưu trữ các image được cộng đồng hoặc các nhà phát triển đóng góp và cung cấp miễn phí, chúng ta có thể tìm các bản images tại đây. Điều này vô cùng tiện lợi, chúng ta chỉ cần pull (tải xuống) các image phục vụ cho nhu cầu ở mọi lúc mọi nơi.

    Chúng ta cũng có thể dễ dàng tạo ra những bản image của riêng mình phục vụ cho việc học tập, nghiên cứu, làm việc và chia sẻ chúng cho cộng đồng. Các bước để thực hiện được điều đó như sau:

    Các bước đưa (push) lên Hub

    Ở ví dụ này, ta sẽ tạo một image và tạo một vài file trong đó rồi đóng gói lại thành một image.

    Bước 1: Sử dụng một image có sẵn nhỏ gọn là alpine

    docker run -it --name myimage1 alpine

    Bước 2: Sau khi vào chế độ tương tác của container, tạo vài file bất kỳ và thoát khỏi container

    touch a b c d e f
    ls
    exit
    

    Bước 3: Lưu lại image tại Host local (commit)

    docker commit myimage1 username/myimage1

    username: Tên đăng nhập Hub
    myimage1: Tên image muốn lưu trên Hub. Có thể kèm theo Tag. VD: myimage1:latest để đánh dấu image bản mới nhất.

    Bước 4: Đăng nhập vào Docker Hub

    docker login

    Nhập user/password để đăng nhập

    • Bước 5: Đưa image lên Hub (push)

    docker push username/myimage1

    Network trong Docker

    Một trong những điểm mạnh của Docker đó là khả năng kết nối các container để chúng có thể giao tiếp được với nhau và có thể kết nối các container chạy trên các nền tảng khác nhau. (Linux, Windows,…)

    Để liệt kê danh sách Network ở Docker, ta sử dụng câu lệnh sau:

    docker network ls

    Để xem các thông tin chi tiết của một Network nào đó, sử dụng câu lệnh:

    docker network inspect <Network-name>

    Các loại Network trong Docker

    Sau khi cài đặt, Docker sẽ tạo mặc định 3 network: brigde, none và host. Khi khởi tạo container, ta có thể chỉ định cho chúng sử dụng network nào thông qua tùy chọn --network.

    • brigde: Network driver mặc định. Mặc định sử dụng brigde khi không khai báo trong lúc khởi tạo container. Nó cho phép các container riêng biệt, đơn lẻ (standalone) có thể giao tiếp được với nhau. Dải IP mặc định được cấp cho brigde là 172.17.0.0/16
    • host: Sử dụng thông tin về Network của host cho container. Được hỗ trợ từ phiên bản Docker 17.06 trở lên.
    • none: Không sử dụng Network trong container.
    • overlay: là một network driver cho phép kết nối các container nằm trên các Docker Host khác nhau, kích hoạt Swarm sử dụng để truyền thông. Các overlay network làm đơn giản hóa việc truyền thông giữa dịch vụ Swarm với container riêng biệt, đơn lẻ hay việc truyền thông giữa 2 container riêng lẻ nằm trên các Docker deamon (Host) khác nhau. Cách này sẽ xóa bỏ việc phải định tuyến (routing) phức tạp ở mức OS giữa các container với nhau.
    Giao thứcCổngMục đích
    TCP4789Truyền dữ liệu (data)
    TCP/UDP7946Điều khiển (control)
    • macvlan: Sử dụng để gán địa chỉ MAC cho container với mục đích là cho container có vai trò như một thiết bị vật lý. Docker daemon sẽ định tuyến luồng gói tin tới các container thông qua các địa chỉ MAC này. Cách này vô cùng hữu hiệu cho các ứng dụng cũ /lỗi thời (legacy app) các kết nối sẽ được chuyển trực tiếp tới lớp Vật lý thay vì phải định tuyến thông qua lớp mạng bên trong Docker.

    Tóm tắt về Network trong Docker

    • User-defined bridge networks: là sự lựa chọn tốt nhất khi muốn các container trên cùng một host có thể giao tiếp với nhau. (Bridge driver)
    • Host networks: được sử dụng trong trường hợp muốn sử dụng chung các thông tin về Network trong container nhưng tách biệt các thông tin khác.
    • Overlay network: Trong trường hợp muốn các container trên các host khác nhau có thể truyền thông qua lại hay muốn nhiều container làm việc cùng nhau khi sử dụng Swarm thì đây là một sự lựa chọn.
    • MACVlan network: Sử dụng trong trường hợp muốn container có thể giao tiếp như một thiết bị vật lý, mỗi container sẽ có một địa chỉ MAC duy nhất, không trùng lặp.

    Volume trong Docker

    Docker volumes vô cùng hữu ích với 2 TH muốn lưu trữ và chia sẻ dữ liệu của các container. Điều này vô cùng quan trọng, khi một container bị xóa bỏ có nghĩa rằng mọi dữ liệu bên trong chúng cũng đều bị ‘bốc hơi’. Do vậy, để dữ liệu đó không bị mất thì Docker Volume là một tính năng hữu hiệu.

    Để sử dụng Docker volume, khi khởi chạy một container hãy thêm tùy chọn -v vào sau câu lệnh docker run.

    Khi nào cần sử dụng Volume?

    Giả sử, ta có một container làm web server. Khi đó ta sẽ ánh xạ một thư mục trên host để chứa mã nguồn với thư mục /var/www/html (thư mục chứa mã nguồn mặc định. Điều này vô cùng hữu ích khi ta muốn cập nhật mã nguồn (thêm xóa dữ liệu) của trang web; thay vì phải vào bên trong container để thao tác, ta có thể thao tác trực tiếp ở thư mục được ánh xạ trên host.

    Docker là gì?

    Các loại Volume trong Docker

    Docker hỗ trợ 3 kiểu Volume như sau:

    • Bind mount
    • Volume
    • tmpfs mount
    Bind mount
    • Bind mount: là một kỹ thuật để ánh xạ trực tiếp một thư mục trên host với một thư mục cụ thể nào đó bên trong container. Khi container bị xóa, dữ liệu bên trong thư mục sẽ không bị ảnh hưởng.
    Volume
    • Volume: giống với bind mount nhưng thư mục ánh xạ sẽ được quản lý bởi Docker. Thư mục chứa mặc dịnh tại /var/lib/docker/volumes/
    tmpfs mount
    • tmpfs mounts được sử dụng trong các trường hợp ta không muốn dữ liệu tồn tại trên Docker host hay containers vì lý do bảo mật hoặc đảm bảo hiệu suất của containers khi ghi một lượng lớn dữ liệu một cách không liên tục.

    Dockerfile

    Dockerfile là một tập tin dạng text chứa một chuỗi các câu lệnh, chỉ thị để tạo nên một image. Dockerfile bao gồm các câu lệnh liên tiếp thực hiện tự động dựa trên một image có sẵn để tạo ra một image mới.

    Cú pháp trong Dockerfile

    # Comment
    INSTRUCTION arguments
    

    Trong đó:

    • INSTRUCTION: Là các câu lệnh, chỉ thị được Docker quy định và toàn bộ những chỉ thị này phải được viết bằng chữ IN HOA.
    • arguments: Phần nội dung của chỉ thị

    Ví dụ:

    RUN echo "Hello world!"
    

    Các câu lệnh/chỉ thị trong Dockerfile

    Dockerfile chứa một tập hợp các câu lệnh bao gồm cả của Docker và các câu lệnh của OS. Trước hết, cần tìm hiểu rõ các câu lệnh của Dockerfile.

    • FROM: Dựa trên một image có sẵn để tạo ra một image mới. Chỉ thị này phải được đặt ở đầu Dockerfile.
    • MAINTAINER: (Tùy chọn) Điền thông tin của tác giả, người tạo ra image.
    • RUN: Chỉ thị dùng để thực thi câu lệnh ở bên trong image
    • ADD: Dùng để sao chép một file hoặc folder từ Host vào trong image. Có thể sử dụng một URL, Docker sẽ tải về thư mục đích bên trong image.
    • ENV: Khởi tạo một biến môi trường bên trong image.
    • CMD: Sử dụng để thực thi một câu lệnh khi tạo container được tạo từ image.
    • ENTRYPOINT: Chỉ ra một câu lệnh được thực thi khi container chạy.
    • WORKDIR: Chỉ ra thư mục làm việc khi tạo image hoặc khi khởi chạy container
    • USER: Xác định user (UID) thực thi các câu lệnh ở các chỉ thị CMD, RUN, ENTRYPOINT,… được xác định ở phía sau nó.
    • VOLUME: Cho phép truy cập/liên kết thư mục giữa container với host.
    • EXPOSE: Khai báo các Port Container sử dụng.
    • ARG: Khai báo sử dụng tham số khi build image sử dụng câu lệnh docker build với cờ--build-arg <varname>=<value>

    Chia sẻ một số Dockerfile

    • KMS Server
    FROM alpine
    
    MAINTAINER hoangdh <github.com/hoangdh>
    
    ENV LIB python3-tkinter python3-dev sqlite-dev
    ENV DEP build-base git py-pip
    
    RUN apk update \
    	&& apk add --no-cache $LIB $DEP \
    	&& git clone https://github.com/SystemRage/py-kms /tmp/py-kms \
    	&& mv /tmp/py-kms/py-kms /opt/ \
    	&& pip install tzlocal pysqlite3 \
    	&& apk del $DEP; rm -rf /tmp/*
    
    EXPOSE 1688
    
    CMD python3 /opt/py-kms/pykms_Server.py --logfile /var/log/pykms.log --logsize 1 -w RANDOM
    FROM alpine

    MAINTAINER hoangdh <github.com/hoangdh>

    RUN apk add --no-cache build-base git \
    && git clone https://github.com/Wind4/vlmcsd /tmp/vlmcsd \
    && cd /tmp/vlmcsd \
    && make \
    && mv /tmp/vlmcsd/bin/vlmcsd /usr/sbin/vlmcsd \
    && cd / && rm -rf /tmp/* \
    && apk del build-base git

    EXPOSE 1688

    CMD /usr/sbin/vlmcsd -p /var/run/kmsd.pid -l /var/log/kmsd.log -D

    Docker-compose

    Ref: https://docs.docker.com/compose/overview/

    docker-compose là một công cụ để tạo, xác định và chạy nhiều container có mối liên quan với nhau trong cùng một thời điểm; được khai báo trong một file với định dạng YAML. Khởi động tất cả các dịch vụ chỉ với 1 câu lệnh duy nhất.

    Với 3 bước cơ bản như sau:

    • Định nghĩa các ứng dụng thông qua Dockerfile
    • Định nghĩa các ứng dụng chạy tách biệt và khởi động cùng nhau trong docker-compose.yml
    • Thực thi câu lệnh docker-compose up -d để hoàn tất

    Một file docker-compose.xml mẫu:

    version: '3'
    services:
      web:
        build: .
        ports:
        - "5000:5000"
        volumes:
        - .:/code
        - logvolume01:/var/log
        links:
        - redis
      redis:
        image: redis
    volumes:
      logvolume01: {}
    

    Sử dụng docker-compose để quản lý vòng đời ứng dụng cụ thể xem và quản lý trạng thái của các service (Start, stop, rebuild,…); chuyển log của các ứng dụng đang chạy.

    Tính năng, lợi ích

    • Tạo ra nhiều môi trường riêng biệt trên cùng 1 host
    • Dữ liệu được bảo toàn
    • Chỉ khởi tạo lại khi có sư thay đổi
    • Các thành phần và biến được sử dụng giữa các môi trường
    CÓ THỂ BẠN QUAN TÂM

    Bài Viết Cùng Chuyên Mục

    XEM THÊM
    thumbnail

    Kubernetes bài 6 - Vận hành k8s Day-Two Operations và Quản trị bằng GitOps

    22.05.2026

    Khi cụm Kubernetes của bạn đã được bảo mật cấu hình, tối ưu tài nguyên và thiết lập tự phục hồi, câu hỏi đặt ra là làm sao để duy trì sự ổn định đó trong nhiều năm tiếp theo mà không bị phụ thuộc

    thumbnail

    Kubernetes bài 5 - bảo mật Cloud Native và chuẩn DevSecOps cho K8s

    22.05.2026

    Việc siết chặt an ninh (Hardening) không phải là cấu hình một vài thông số rồi bỏ đó, mà là một tư duy phòng thủ chiều sâu.

    thumbnail

    Kubernetes bài 4 - Tối ưu Resource Auto-Healing và Scale Zero-Downtime

    22.05.2026

    Bài viết này sẽ đi sâu vào các cơ chế ở tầng Kernel giúp hệ thống tự phục hồi, chống lại các đợt tấn công cạn kiệt tài nguyên và cập nhật phiên bản mới mà người dùng không hề hay biết.

    thumbnail

    Kubernetes bài 3 - Bảo mật cấu hình k8s và config Security trên Production

    22.05.2026

    Kubernetes giải quyết bài toán này bằng hai đối tượng chuyên biệt nhưng nếu không hiểu rõ bản chất bảo mật ở tầng dưới, bạn đang tự tay dâng toàn bộ chìa khóa hệ thống cho hacker.

    thumbnail

    Kubernetes bài 2 - Mạng lưới k8s và luồng Traffic ở Packet Level

    22.05.2026

    Pod không chỉ là một container: Rất nhiều người nhầm lẫn Pod 1-1 với Container. Thực chất, Pod là đơn vị triển khai nhỏ nhất, có thể chứa một hoặc nhiều container

    Mục lục bài viết