Bài viết trước chúng ta đã tìm hiểu:
Các bạn có thể tìm hiểu lại bài viết tại đây. Bài viết tiếp theo sẽ nói về Docker nâng cao
Dockerfile
Dockerfile là file config cho Docker để build ra image. Nó dùng một image cơ bản để xây dựng lớp image ban đầu. Một số image cơ bản: python, unbutu and alpine. Sau đó nếu có các lớp bổ sung thì nó được xếp chồng lên lớp cơ bản. Cuối cùng một lớp mỏng có thể được xếp chồng lên nhau trên các lớp khác trước đó.
Các config :
Demo tạo file Dockerfile
Một số bước thực hiện:
- Đầu tiên chúng ta sẽ viết Dockerfile để tạo nên image rồi tạo nên container, sau khi tạo được container rồi thì đồng nghĩa là đã tạo ra được máy ảo để bạn có thể khởi chạy ứng dụng của bạn trên máy ảo đó.
- Thư mục webroot chứa mã nguồn chương trình, có thể là một c++ app, java app hoặc web app được viết bằng php hoặc ruby,.... (Ở đây, để cho đơn giản, chúng ta chỉ đặt file hello.html, chạy trên trình duyệt sẽ hiển thị dòng Hello Word)
- Sau này, bạn dùng editor để lập trình trên máy thật, chỉnh sửa mã nguồn trong thư mục này, mọi sự thay đổi được cập nhật ngay lập tức trên máy ảo.
- File start.sh chứa những câu lệnh được chạy khi bật container (có thể dùng để start mysql, nginx, redis ...)
Nội dung file Dockerfile
FROM ubuntu:22.04
MAINTAINER HauTran<hautph@gmail.com>
RUN DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y nginx
RUN echo "mysql-server mysql-server/root_password password root" | debconf-set-selections \
&& echo "mysql-server mysql-server/root_password_again password root" | debconf-set-selections \
&& apt-get install -y mysql-server
WORKDIR /venv
COPY start.sh /venv
RUN chmod a+x /venv/*
ENTRYPOINT ["/venv/start.sh"]
EXPOSE 80
Tạo file hello.html trong thư mục webroot:
<h1>Hello word</h1>
Tạo file start.sh như sau
#!/bin/bash
service nginx start
exec $@
Tiến hành build file Dockerfile
$ sudo docker build -t ubuntu-nginx .
Tạo container từ image:
sudo docker run -v <forder_in_computer>:<forder_in_container> -p <port_in_computer>:<port_in_container> -it <image_name> /bin/bash
Trong đó:
- -v : Thể hiện việc mount volume, dữ liệu từ thư mục từ máy thật có thể được truy cập từ thư mục của máy ảo.
- -p: Cổng mạng từ máy thật để dẫn tới cổng mạng của máy ảo đang chạy.
- -t: Chạy container và mở terminal bằng /bin/bash
Ví dụ vào localhost mặc định của nginx:
sudo docker run -p 9000:80 -it ubuntu-nginx /bin/bash
hoặc
sudo docker run -v /home/webroot:/var/www/html -p 9000:80 -it ubuntu-nginx /bin/bash
Các lệnh thường dùng
Build container từ image
$ docker run --name {container_name} -it {image_id/name:tag} /bin/bash
Một số option:
- -it để cho phép container vừa tạo ra có thể nhận tương tác (-i), và kết nối với terminal (-t).
- --name container_name của container mà bạn muốn sau khi khởi chạy. Mặc định khi không có thì nó sẽ tự đặt tên cho container là 1 tên nào đó, nên tốt nhất mình tự đặt cho dễ nhớ
- -p {host_port}:{container_port} , -h {container_host} optional
- Còn nhiều option khác, các bạn có thể tìm hiểu thêm
start/stop một container khởi chạy container đã build
docker start {container_id/name} # Khởi động lại container
docker attach {container_id/name} # access vào container đang start
docker exec -it {container_id/name} /bin/bash #khởi động container và access vào container đó luôn
docker start {container_id/name}
Note:
- Có thể dùng docker exec để đứng từ host và chỉ định cho container thực thi lệnh.
- Vd: Đứng từ host, và liệt kê tất cả các file có trong container_1 thì ta có lệnh: docker exec container_1 ls
Thoát khỏi container đang access
exit # thoát và stop luôn container
ctrl + d # thoát và stop luôn container
ctrl + p, ctrl + q # dùng cả 2 tỏ hợp phím này để thoát contraner mà vẫn giữ cho container chạy
Liệt kê các container
docker ps # Liệt kê các container đang chaỵ
docker ps -a #Liệt kê tất các container bao gồm container đã tắt
Xóa một container
docker rm -f {container_id/name}
Đổi tên một container
docker rename {old_container_name} {new_container_name}
Xem các thay đổi trên container
docker diff {container_name}
Lưu container thành image: trong trường hợp bạn muốn lưu container của bạn thành image để thuận tiện share cho ng khác hoặc đem đi cài trên máy khác thì bạn dùng lệnh sau
docker commit {container_id/name} {image_name}:{tag}
Note:
- Phải stop container trước khi bạn lưu.
- {image_name}:{tag} đặt tên image và version cho container sau khi lưu.
Lưu image thành file để tiện share
docker save --output filename.tar {image_id/name}
Note: filename.tar sẽ được lưu ở vị trí bạn đang đứng trong terminal
Load image từ file ra để sử dụng
docker load -i filename.tar
Note: khi load image từ file thì image_name và image_tag sẽ là rỗng để đặt tên và tag cho image ta dùng lệnh
docker tag {image_id} {new_name:new_version}
Data Volume
Data volume dùng để chia sẻ dữ liệu, thông thường ta sẽ dùng cho những trường hợp sau:
Chia sẻ dữ liệu thông qua thư mục
Giữa host và container
docker run -it -v {host path}:{container path} --name {container name} {image_id/name}
docker run -it -v /home/hautp/share_data:/home/share_data --name C1 ubuntu:22.04 # vd minh họa
Giữa containter với nhau:
Để tạo ra một container có tên là C2 và cũng cùng chia sẻ giữ liệu của C1 (/home/share_data) ta dùng lệnh
docker run -it --name C2 --volumes-from C1 ubuntu:22.04
Chia sẻ dữ liệu thông qua ổ đĩa
Kiểm tra ổ đĩa hiện có
docker volume ls
Tạo mới ổ đĩa Volume
docker volume create {volume name}
Kiểm tra thông tin ổ đĩa Volume
docker volume inspect {volume name}
Xóa ổ đĩa Volume
docker volume rm {volume name}
Chia sẻ dữ liệu thông qua ổ đĩa Volume
docker run -it --name C1 --mount source=Disk_1,target=/home/disk_1 ubuntu:22.04
Note:
- --mount tham số để gán ổ đĩa vào
- source=Disk_1 tên ổ đĩa mà mình muốn gán
- target=/home/disk_1 vị trí mà ổ đĩa Disk_1 ánh xạ vào thư mục /home/disk_1 của container
Chia sẻ dữ liệu ổ đĩa Volume với host và containter
Tạo ổ đĩa ánh xạ với host
docker volume create --opt device={host path} --opt type=none --opt o=bind {volume name}
Gán ổ đĩa cho container
docker run -it --name C2 -v Disk_2:/home/disk_2 ubuntu:22.04
Note: Khi đã ánh xạ ổ đĩa với host thì mình sẽ ko sử dụng --mount mà dùng
Khái niệm và các default Docker Network
Docker network là nơi sẽ đảm nhiệm nhiệm vụ cho container kết nối vào network
Có 3 loại networks được tự động tạo ra trong docker là bridge, none, host ta có thể xem bằng lệnh
docker network ls
Tạo docker network
Tạo network
docker network create --driver bridge network1
Lệnh trên tạo ra mạng network1 ta kiểm tra bằng lệnh
docker network ls
Xóa network
docker network rm name_network
Tạo container kết nối vào một network được chỉ định
docker run -it --name B4 --network network1 busybox
Lệnh trên ta tạo một container tên là B4 từ image busybox và có kết nối trong mạng network1 mới tạo ở trên
kiểm tra bằng lệnh
docker network inspect network1
sẽ thấy có container B4 kết nối
Kết nối một container đang chạy với một mạng khác
Ví dụ: ta có 2 network là network1 và network2 có một container B5 đang kết nối với mạng network1 và ta muốn container này kết nối với cả network2 thì ta chạy lệnh
docker network connect network2 B5
Lệnh trên là kết nối container B5 vào mạng network2
Docker Hub
Docker Hub là một dịch vụ do Docker cung cấp, cho phép tìm kiếm và chia sẻ các container images. Các tính năng chính của Docker Hub là:
Để sử dụng Docker Hub, bạn hãy đăng ký một tài khoản tại đây.
Docker compose
Là công cụ giúp ta thiết lập và quản lý nhiều container, network, volume (gọi chung là các service) và thiết lập cấu hình cho các service một cách nhanh chóng và đơn giản bằng việc chạy theo các chỉ định trong file docker-compose.yml
Những tính năng chính của Compose bao gồm:
Docker-compose.yml
Là một file lưu dạng yaml, file này lưu các chỉ thị để docker compose đọc file này và thực thi các chỉ thị đó, các chỉ thị như tạo container từ image, tạo network, cấu hình cho các dịch vụ. VD: file docker-compose.yml như sau
version: "3" #là phiên bản docker composer
#Tạo mạng tên là my-network
networks:
my-network:
driver: bridge
# Tạo các dịch vụ (container)
services:
#Tạo container my-php từ imgae php:latest có kết nối với mạng my-network
my-php:
container_name: php-product
image: 'php:latest'
hostname: php
restart: always
networks:
- my-network
#Tạo container my-httpd từ imgae httpd:latest có kết nối với mạng my-network, ánh xạ cổng 9999 của máy host vào cổng 80
my-httpd:
container_name: c-httpd01
image: 'httpd:latest'
hostname: httpd
restart: always
networks:
- my-network
ports:
- "9999:80"
- "443:443"
#Tạo container my-mysql từ imgae mysql:latest có kết nối với mạng my-network,config các biến môi trường
my-mysql:
container_name: myql-product
image: "mysql:latest"
hostname: mysql
restart: always
networks:
- my-network
environment:
- MYSQL_ROOT_PASSWORD=123abc
- MYSQL_DATABASE=db_site
- MYSQL_USER=sites
- MYSQL_PASSWORD=123abc
Vào thư mục chứa file docker-compose.yml và chạy lệnh
docker-compose up
Vậy là xong rồi, giờ ta bật một terminal khác để kiểm tra xem đã có các container và network theo như mục tiêu đề ra hay chưa
Chạy lệnh docker ps và docker network ls để xem danh sách container đang chạy và network
Muốn dừng các services đang chạy thì ta dùng lệnh
docker-compose stop
Để kết thúc các services đang chạy và xóa hoàn toàn container ta dùng lệnh
docker-compose down
Theo dõi Logs các services
docker-compose logs [SERVICES]
Tài liệu tham khảo
18 posts | 5 followers
FollowRegional Content Hub - November 4, 2024
Alibaba Cloud Vietnam - December 21, 2023
Nong The Hoang - March 5, 2024
Nong The Hoang - March 5, 2024
Tran Phuc Hau - March 22, 2024
Nong The Hoang - March 7, 2024
18 posts | 5 followers
FollowAccelerate software development and delivery by integrating DevOps with the cloud
Learn MoreAn enterprise-level continuous delivery tool.
Learn MoreMore Posts by Tran Phuc Hau