Hướng dẫn Docker từ Cơ bản đến Nâng cao

1. Tổng quan về Docker và Ảo hóa

# Ảo hóa là gì?
Trong máy tính, ảo hóa (tiếng Anh: Virtualization) là công nghệ quản lý tài nguyên, trừu tượng hóa và chuyển đổi các tài nguyên vật lý của máy tính như máy chủ, mạng, bộ nhớ và lưu trữ. Điều này phá vỡ rào cản không thể cắt rời giữa các cấu trúc thực thể, cho phép người dùng sử dụng tài nguyên hiệu quả hơn so với cấu hình ban đầu. Các phần ảo hóa mới không bị giới hạn bởi cách bố trí tài nguyên hiện có, vị trí địa lý hoặc cấu hình vật lý. Tài nguyên ảo hóa thường bao gồm khả năng tính toán và lưu trữ dữ liệu.

Trong môi trường sản xuất thực tế, công nghệ ảo hóa chủ yếu giải quyết vấn đề dư thừa năng lực của phần cứng vật lý hiệu suất cao và tái sử dụng các thiết bị cũ có hiệu suất thấp, đồng thời làm trong suốt phần cứng vật lý bên dưới, từ đó tối đa hóa việc sử dụng tài nguyên vật lý.

Có nhiều loại công nghệ ảo hóa, ví dụ: ảo hóa phần mềm, ảo hóa phần cứng, ảo hóa bộ nhớ, ảo hóa mạng (VIP), ảo hóa máy tính để bàn, ảo hóa dịch vụ, máy ảo, v.v.

# Công nghệ ảo hóa
    VMware
    VirtualBox
    Máy chủ đám mây Alibaba
    Docker
    
# Giải thích thuật ngữ
    - KVM, VMware: KVM (Kernel-based Virtual Machine) là công nghệ ảo hóa trên Linux, cho phép ảo hóa một máy thành nhiều máy.
    - OpenStack: Được viết bằng Python, là công cụ quản lý để tạo, quản lý và hủy các máy ảo, có giao diện web quản lý, chỉ cần nhấp chuột để tạo và xóa máy ảo.
    - Giải pháp KVM + OpenStack: Khi công ty có nhiều máy chủ, OpenStack là công cụ quản lý máy ảo.
    - Docker: Công nghệ container.
    - K8s (Kubernetes): Công cụ quản lý container (Docker).
    
    - Xu hướng chính của công ty: K8s + Docker
        KVM + K8s + Docker
    
    Về chức năng: Kubernetes quản lý container, OpenStack quản lý máy ảo.
    Về nghiệp vụ: OpenStack thuộc nền tảng IaaS, Kubernetes thuộc nền tảng PaaS.
    Về thời gian: Giai đoạn 1 của giải pháp đám mây là máy ảo; giai đoạn 2 là công nghệ container.
    
# So sánh Máy ảo và Container
    - Máy ảo cần ảo hóa hệ điều hành: nặng nề, tiêu tốn nhiều tài nguyên.
    - Container: nhẹ, tiêu tốn ít tài nguyên.
    
# IAAS, PAAS, SAAS, FAAS
I. IaaS (Cơ sở hạ tầng như một dịch vụ)
IaaS: Infrastructure-as-a-Service

Lớp đầu tiên gọi là IaaS, đôi khi còn gọi là Hardware-as-a-Service. Vài năm trước, nếu bạn muốn chạy các ứng dụng doanh nghiệp trên máy chủ văn phòng hoặc trang web công ty, bạn cần mua máy chủ hoặc phần cứng đắt tiền khác để kiểm soát các ứng dụng cục bộ.

Ngày nay với IaaS, bạn có thể thuê ngoài phần cứng. Các công ty IaaS cung cấp máy chủ, lưu trữ và phần cứng mạng từ xa để bạn thuê. Điều này giúp tiết kiệm chi phí bảo trì và không gian văn phòng, cho phép công ty sử dụng phần cứng này để chạy các ứng dụng bất cứ lúc nào.

Một số công ty IaaS lớn bao gồm Amazon, Microsoft, VMWare, Rackspace và Red Hat.

# Mua máy chủ đám mây Alibaba tương đương với việc mua dịch vụ IaaS của Alibaba.

II. PaaS (Nền tảng như một dịch vụ)
    Không chỉ bán máy chủ mà còn bán phần mềm.
    Ví dụ: OSS (Object Storage Service), dịch vụ MySQL đám mây Alibaba, Redis đám mây Alibaba.

III. SaaS (Phần mềm như một dịch vụ)
    - Đa người dùng (Multi-tenant).
    - Ví dụ: Phần mềm bảo hiểm xã hội.

IV. FaaS (Chức năng như một dịch vụ)
    Serverless: Không có máy chủ.

1.1 Các thuật ngữ trong vận hành phần mềm

- Đám mây lai (Hybrid Cloud): Công ty tự có máy chủ (đám mây riêng) và mua thêm máy chủ đám mây (đám mây công cộng).
- Nginx: Máy chủ web, dùng để chuyển tiếp yêu cầu và cân bằng tải.
- Ansible: Được viết bằng Python và thư viện Paramiko, là phần mềm thao tác hàng loạt trên máy chủ.
- Paramiko: Thư viện Python dùng để kết nối SSH, thường dùng cho tối đa 500 máy chủ. Hoạt động theo mô hình máy chủ - không có agent trên máy khách.
- SaltStack: Được viết bằng Python và hàng đợi tin nhắn, cũng là phần mềm thao tác hàng loạt. Yêu cầu cài đặt client trên máy bị quản lý.
- Zabbix: Được viết bằng PHP, là máy chủ web dùng để giám sát và theo dõi các tiến trình.
- Prometheus + Grafana: Được viết bằng Go, là phần mềm giám sát chủ yếu dùng cho container và các tiến trình.
- Jenkins: Được viết bằng Java, là công cụ xây dựng tự động hóa.
- CI (Tích hợp liên tục - Continuous Integration): Cho phép nhiều nhà phát triển làm việc trên các tính năng khác nhau và thường xuyên hợp nhất mã mà không ảnh hưởng lẫn nhau. Mục đích là cho phép sản phẩm lặp lại nhanh chóng và duy trì chất lượng cao. Biện pháp cốt lõi: Mã phải vượt qua kiểm thử tự động trước khi hợp nhất vào nhánh chính. Nếu bất kỳ kiểm thử nào thất bại, quá trình hợp nhất sẽ bị từ chối.
- CD (Triển khai liên tục - Continuous Deployment): Dựa trên công cụ hoặc nền tảng để tự động hóa việc xây dựng, kiểm thử và triển khai mã lên môi trường trực tuyến nhằm giao sản phẩm chất lượng cao. CD ở một mức độ nào đó đại diện cho tốc độ lặp lại cập nhật của nhóm phát triển.
- Docker: Công nghệ container.
- K8s (Kubernetes): Công cụ điều phối container, dùng cho nhiều máy chủ.

2. Cài đặt và Khởi động Docker

# Docker có thể được cài đặt trên nhiều hệ điều hành khác nhau
    - CentOS 7.5
    - Windows 10 trở lên
    - macOS
    - Tốt nhất nên cài trên máy ảo CentOS

# Giới thiệu phiên bản
    Docker-CE: Phiên bản cộng đồng, được cộng đồng duy trì và hỗ trợ kỹ thuật, là phiên bản miễn phí, phù hợp cho nhà phát triển cá nhân và nhóm nhỏ.
    Docker-EE: Phiên bản doanh nghiệp, là phiên bản trả phí, được đội ngũ hỗ trợ kỹ thuật hỗ trợ, thiết kế riêng cho doanh nghiệp và đội ngũ IT.

# Gỡ cài đặt Docker
    - Dừng dịch vụ: systemctl stop docker
    - Liệt kê các gói đã cài: yum list installed | grep docker
    - Xóa các gói: yum remove docker-ce.x86_64 docker-ce-cli.x86_64
    - Xóa thư mục dữ liệu: rm -rf /var/lib/docker

# Cài đặt Docker
    - Cài đặt các gói phụ thuộc:
        sudo yum install -y yum-utils device-mapper-persistent-data lvm2
    - Thiết lập kho lưu trữ Alibaba Cloud:
        sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    - Cài đặt Docker:
        sudo yum install docker-ce
    - Kiểm tra phiên bản Docker:
        docker -v  # Docker version 20.10.22, build 3a2c30b

# Cài đặt trên Windows và macOS: https://get.daocloud.io/#install-docker-for-mac-windows

# Cấu hình mirror nội địa: Kho lưu trữ mặc định ở nước ngoài, tải xuống image chậm.
    - Alibaba Cloud: https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
    - Tạo thư mục: mkdir /etc/docker
    - Tạo file: vim /etc/docker/daemon.json
    - Thêm nội dung:
       {
      "registry-mirrors": ["https://x1566319.mirror.aliyuncs.com"]
        }
    - Khởi động lại Docker:
    sudo systemctl daemon-reload
    sudo systemctl restart docker

# Các lệnh Docker cơ bản
    - Khởi động Docker: systemctl start docker
    - Dừng Docker: systemctl stop docker
    - Khởi động lại Docker: systemctl restart docker
    - Kiểm tra trạng thái: systemctl status docker
    - Tự động khởi động cùng hệ thống: systemctl enable docker
    - Xem thông tin tổng quan: docker info

3. Giới thiệu các thành phần Docker

Nội dung mục này tương tự như phần cài đặt ở trên, cần được lược bỏ để tránh trùng lặp. Ở đây tôi sẽ bỏ qua và chuyển sang nội dung chính.

4. Thao tác với Image Docker

# Tìm kiếm image
    docker search [tên_image]
    Có thể tìm kiếm trực tiếp trên trang web Docker Hub.

# Tải image từ kho lưu trữ từ xa
    - docker pull centos:centos7.9.2009
    - docker pull python:3.8-slim
    - docker pull redis  # Phiên bản mới nhất
    - docker pull mysql:5.7

# Xem danh sách image cục bộ
    docker images

# Xóa image
    docker rmi [ID_image]

# Xóa tất cả image cùng lúc
    docker rmi `docker images -q`

# Xóa tất cả container cùng lúc
    docker rm `docker ps -aq`

# Các thao tác nâng cao (tham khảo thêm)
    - Gắn thẻ (tag) cho image cục bộ:
        docker tag [ID_image] [tên_mới]
    - Đăng nhập Docker Hub:
        docker login  # Nhập tên người dùng và mật khẩu
    - Đẩy image lên Docker Hub:
        docker push [tên_mới]
    - Kiểm tra trên kho lưu trữ của bạn.

# Lớp Image: Khái niệm quan trọng (câu hỏi phỏng vấn thường gặp)
    - Image được tải lên kho lưu trữ từ xa.
    - Khi tải về từ kho lưu trữ từ xa, Docker sẽ tăng tốc độ.
    - Mỗi khi thêm file vào container, một lớp mới sẽ được tạo ra.

# Các cách để có được một image:
    - Sử dụng lệnh `docker pull`.
    - Khôi phục từ file nén.
    - Đóng gói ngược từ container thành image.
    - Xây dựng bằng Dockerfile.

5. Thao tác với Container Docker

# 1. Tạo và chạy container từ image
    # Tùy chọn -it và -id: -it cho phép truy cập vào container, -id chạy container dưới dạng daemon (nền) mà không truy cập vào.
    # --name=tên: Nếu không chỉ định, Docker sẽ tự động đặt tên ngẫu nhiên.
    # [tên_image:tag]: Tên image và tag.
    # -p [port_host]:[port_container]: Ánh xạ cổng, ví dụ -p 3307:3306 ánh xạ cổng 3307 của máy chủ tới cổng 3306 của container.
    # -v [đường_dẫn_host]:[đường_dẫn_container]: Gắn kết volume, ánh xạ thư mục /root/lqz trên máy chủ vào /home trong container. Mọi thay đổi ở một bên sẽ ảnh hưởng đến bên kia.
    # exit: Thoát khỏi container kèm theo lệnh dừng container.
    
    - docker run -it --name=mycentos centos:7  # Tạo và chạy container từ image centos:7, truy cập vào container, đặt tên là mycentos.

# 2. Xem danh sách container đang chạy
    docker ps

# 3. Xem tất cả container (kể cả đã dừng)
    docker ps -a

# 4. Thực thi lệnh trong container
    docker exec [ID_container] [lệnh]
    docker exec 12a6a0281168 ls

    docker exec -it 12a6a0281168 /bin/bash  # Truy cập vào shell của container

# 5. Dừng container
    docker stop [ID_container]

# 6. Khởi động lại container đã dừng
    docker start [ID_container]

# 7. Xóa container (không thể xóa container đang chạy)
    docker rm [ID_container]

# 8. Sao chép file giữa máy chủ và container
    - Sao chép từ máy chủ vào container:
        docker cp [đường_dẫn_file_máy_chủ] [ID_container]:[đường_dẫn_trong_container]
    - Sao chép từ container ra máy chủ:
        docker cp [ID_container]:[đường_dẫn_file_trong_container] [/đường_dẫn/đích]

# 9. Xem thông tin chi tiết của container
    docker inspect [ID_container]
    docker inspect --format='{{.NetworkSettings.IPAddress}}' [ID_container]  # Xem địa chỉ IP

# Bạn có thể tạo container từ image CentOS, sau đó cài đặt Python interpreter bên trong.

6. Triển khai Ứng dụng

6.1 Triển khai MySQL

# Không cần cài đặt MySQL trên máy chủ, chỉ cần tải image MySQL và chạy nó dưới dạng container.

# Các bước triển khai:
    - 1. Tạo các thư mục cần thiết:
        mkdir /root/mysql
        mkdir /root/mysql/conf.d
        mkdir /root/mysql/data/

    - 2. Chạy container từ image MySQL với ánh xạ cổng và volume:
        docker run -id --name=mysql3 -p 3306:3306 -v /root/mysql/conf.d:/etc/mysql/conf.d -v /root/mysql/data/:/var/lib/mysql -v /root/mysql/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7 
        # Biến môi trường MYSQL_ROOT_PASSWORD dùng để thiết lập mật khẩu cho tài khoản root.

    - 3. Tạo file cấu hình MySQL:
        touch /root/mysql/my.cnf

    - 4. Chạy lệnh ở bước 2.

    - 5. Kết nối từ xa đến MySQL, tạo database và bảng.

    - 6. Kết nối đến MySQL trong container để xác nhận.

    - 7. Xóa container cũ và tạo container mới; dữ liệu vẫn còn nếu đã ánh xạ volume.
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

6.2 Triển khai Redis

# Các bước:
    - 1. Tải image Redis.
    - 2. Tạo thư mục và file cấu hình:
        mkdir redis
        mkdir redis/conf
        mkdir redis/data
        vim ./redis/conf/redis.conf
    - 3. Nội dung file cấu hình redis.conf:
        bind 0.0.0.0
        daemonize NO
        protected-mode no
        requirepass 123456

    - 4. Lệnh Docker để chạy Redis với cấu hình (có ánh xạ volume):
        docker run -id -p 6379:6379 --name redis_6379 -v /root/redis/conf/redis.conf:/etc/redis/redis.conf -v /root/redis/data:/data redis:latest redis-server /etc/redis/redis.conf --appendonly yes

    # Lưu ý: Có một cách đơn giản hơn là chạy mà không có ánh xạ volume:
    # docker run -di --name=myredis -p 6379:6379 redis

6.3 Triển khai Nginx

# Các bước:
    - 1. Tải image Nginx.
    - 2. Chạy container Nginx:
        docker run -id --name=nginx -p 80:80 nginx
    - 3. Truy cập từ trình duyệt: http://địa_chỉ_máy_chủ:80
    - 4. Vào container và sửa file index.html: /usr/share/nginx/html/index.html
    - 5. Sửa file index.html:
        - Có thể không có `vi` hoặc `vim`, cần cài đặt:
            apt-get update
            apt-get install vim
    - 6. Làm mới trình duyệt để thấy thay đổi.

7. Di chuyển và Sao lưu

7.1 Đóng gói Container thành Image

# Đóng gói container (đã cài đặt phần mềm) thành image.
    - Ví dụ: Image Python dựa trên Debian.
    - Hoặc có thể tạo image từ CentOS, cài Python 3.8, sau đó đóng gói thành image mới để chia sẻ.

# Ví dụ: Đóng gói container Nginx đã cài vim và sửa index.html.
    - Tìm ID container: docker ps
    - Chạy lệnh: docker commit [ID_container] nginx_vim

# Chạy container từ image mới tạo:
    docker run -id --name=mynginx -p 8080:80 nginx_vim:latest

7.2 Sao lưu Image thành file nén

# Xuất image thành file tar:
    docker save -o mynginx.tar nginx_vim

# Tải file tar thành image:
    docker load -i mynginx.tar

8. Kho lưu trữ Riêng tư

# Lệnh `docker pull` mặc định tải từ hub.docker.com. Các công ty thường tạo image riêng và muốn lưu trữ ở đâu đó thích hợp.

# `docker push` đẩy lên hub.docker. Nếu là public, ai cũng có thể tải. Công ty chỉ muốn nội bộ sử dụng.

# Giải pháp: Xây dựng kho lưu trữ riêng tư (private registry) nội bộ.
# Khi tải image, máy sẽ ưu tiên lấy từ máy chủ riêng, nếu không có mới tải từ hub.docker. Image riêng của công ty chỉ có nội bộ mới thấy.

8.1 Đẩy image của bạn lên Docker Hub

# Các bước:
    1. Gắn thẻ (tag) cho image (ID vẫn giữ nguyên):
        docker tag [ID_image] [tên_người_dùng]/[tên_kho]
        docker tag 03cf0f47aec0 liuqingzheng/django_books
    2. Đăng nhập:
        docker login  # Nhập tên người dùng và mật khẩu
    3. Đẩy image lên:
        docker push liuqingzheng/django_books

8.2 Xây dựng Kho lưu trữ Riêng tư

# Harbor: Kho lưu trữ riêng tư phổ biến trong doanh nghiệp, có giao diện web đẹp. Có thể triển khai bằng Docker.

# Registry: Phiên bản cũ hơn, không có giao diện web, đơn giản hơn. Cũng triển khai bằng Docker.

# Các bước xây dựng Registry:
    - 1. Tải image registry:
        docker pull registry
    - 2. Chạy container registry:
        docker run -di --name=registry -p 5000:5000 registry
        # Truy cập http://địa_chỉ_máy_chủ:5000/v2/_catalog để xem danh sách image.

    - 3. Chỉnh sửa file cấu hình Docker daemon:
        vi /etc/docker/daemon.json
        # Thêm (thay địa chỉ IP cho phù hợp):
        {"insecure-registries":["địa_chỉ_máy_chủ:5000"]}
    - 4. Khởi động lại Docker:
        systemctl restart docker
    - 5. Khởi động container registry:
        docker start registry
    - 6. Gắn thẻ cho image với địa chỉ của registry riêng:
        docker tag django_books địa_chỉ_máy_chủ:5000/django_books
    - 7. Đẩy image lên registry riêng:
        docker push địa_chỉ_máy_chủ:5000/django_books
    - 8. Nhân viên nội bộ có thể tải image từ registry này:
        docker pull địa_chỉ_máy_chủ:5000/django_books

9. Giới thiệu Docker Compose

# Khi sử dụng Docker, việc quản lý nhiều container (ví dụ: Django, MySQL, Redis) riêng lẻ rất phức tạp. Docker Compose ra đời để giải quyết vấn đề này.

# Docker Compose là công cụ định nghĩa và quản lý nhiều container Docker cùng lúc trên một máy (single-host container orchestration).
    - Docker Swarm: Ít được sử dụng trong công ty.
    - K8s (Kubernetes): Công cụ điều phối container đa máy chủ, viết bằng Go.

    Trong Compose, mỗi container được định nghĩa là một service.
    Compose có thể định nghĩa và khởi chạy nhiều service, thường có mối quan hệ cộng tác với nhau.
    
    Cách quản lý:
    - Sử dụng file YAML để cấu hình các service của ứng dụng.
    - Sử dụng một lệnh duy nhất (docker-compose up) để tạo và khởi động tất cả các service đã cấu hình.

# Cài đặt:
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.14.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

# Cách viết file YAML cho Docker Compose sẽ được trình bày sau.

9.1 Các lệnh Docker Compose

docker-compose up # Tự động tìm file docker-compose.yml trong thư mục hiện tại.
docker-compose up -d # Chạy nền, thường không dùng vì muốn xem log.

docker-compose stop # Dừng container, không xóa container hay image.
docker-compose down # Dừng và xóa các container liên quan.
docker-compose start # Khởi động các container được quản lý bởi file YAML.
docker-compose ps # Xem các container đang chạy.
docker-compose images # Xem các image được quản lý.

docker-compose exec [service_name] /bin/bash # Truy cập vào container của service.

Thẻ: docker containerization virtualization kvm openstack

Đăng vào ngày 26 tháng 6 lúc 09:42