Tháng sáu 1, 2023
Bạn không sử dụng Ubuntu 20.04?
Chọn một phiên bản hoặc bản phân phối khác.
Docker là một ứng dụng giúp đơn giản hóa quá trình quản lý các tiến trình ứng dụng trong container. Bộ chứa cho phép bạn chạy các ứng dụng của mình trong các quy trình cách ly tài nguyên. Chúng tương tự như các máy ảo, nhưng các container có tính di động cao hơn, thân thiện với tài nguyên hơn và phụ thuộc nhiều hơn vào hệ điều hành máy chủ.
Để được giới thiệu chi tiết về các thành phần khác nhau của bộ chứa Docker, hãy xem Hệ sinh thái Docker: Giới thiệu về các thành phần phổ biến.
Trong hướng dẫn này, bạn sẽ cài đặt và sử dụng Docker Community Edition (CE) trên Ubuntu 20.04. Bạn sẽ tự cài đặt Docker, làm việc với các container và hình ảnh và đẩy hình ảnh vào Docker Repository.
Để làm theo hướng dẫn này, bạn sẽ cần những điều sau đây:
Gói cài đặt Docker có sẵn trong kho lưu trữ Ubuntu chính thức có thể không phải là phiên bản mới nhất. Để đảm bảo chúng tôi có được phiên bản mới nhất, chúng tôi sẽ cài đặt Docker từ kho lưu trữ Docker chính thức. Để làm điều đó, chúng tôi sẽ thêm một nguồn gói mới, thêm khóa GPG từ Docker để đảm bảo các bản tải xuống hợp lệ, sau đó cài đặt gói.
Trước tiên, hãy cập nhật danh sách các gói hiện có của bạn:
$ sudo apt update
apt
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
Sau đó thêm khóa GPG cho kho lưu trữ Docker chính thức vào hệ thống của bạn:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Thêm kho lưu trữ Docker vào nguồn APT:
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
Điều này cũng sẽ cập nhật cơ sở dữ liệu gói của chúng tôi với các gói Docker từ repo mới được thêm vào.
Đảm bảo rằng bạn sắp cài đặt từ repo Docker thay vì repo Ubuntu mặc định:
$ apt-cache policy docker-ce
Bạn sẽ thấy đầu ra như thế này, mặc dù số phiên bản cho Docker có thể khác:
Đầu ra của apt-cache policy docker-ce
docker-ce:
Installed: (none)
Candidate: 5:19.03.9~3-0~ubuntu-focal
Version table:
5:19.03.9~3-0~ubuntu-focal 500
500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
Lưu ý rằng chưa được cài đặt, nhưng ứng cử viên để cài đặt là từ kho lưu trữ Docker cho Ubuntu 20.04 ().docker-ce
focal
Cuối cùng, cài đặt Docker:
$ sudo apt install docker-ce
Docker bây giờ sẽ được cài đặt, daemon bắt đầu và quá trình được kích hoạt để bắt đầu khi khởi động. Kiểm tra xem nó có đang chạy không:
$ sudo systemctl status docker
Đầu ra phải tương tự như sau, cho thấy rằng dịch vụ đang hoạt động và đang chạy:
Output
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2020-05-19 17:00:41 UTC; 17s ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 24321 (dockerd)
Tasks: 8
Memory: 46.4M
CGroup: /system.slice/docker.service
└─24321 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Cài đặt Docker giờ đây cung cấp cho bạn không chỉ dịch vụ Docker (daemon) mà còn cả tiện ích dòng lệnh hoặc máy khách Docker. Chúng ta sẽ khám phá cách sử dụng lệnh sau trong hướng dẫn này .docker-ce
focal
Mặc định, lệnh chỉ có thể được chạy cho root user hoặc bởi một user trong docker group, được tạo tự động trong quá trình cài đặt của Docker. Nếu bạn cố gắng chạy lệnh mà không có tiền tố có hoặc không nằm trong nhóm docker, bạn sẽ nhận được kết quả như sau: docker
docker
sudo
Output
docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.
Nếu bạn muốn tránh nhập bất cứ khi nào bạn chạy lệnh, hãy thêm tên người dùng của bạn vào nhóm: sudo
docker
docker
$ sudo usermod -aG docker ${USER}
Để áp dụng tư cách thành viên nhóm mới, hãy đăng xuất khỏi máy chủ và đăng nhập lại hoặc nhập thông tin sau:
$ su - ${USER}
Bạn sẽ được nhắc nhập mật khẩu người dùng để tiếp tục.
Xác nhận rằng người dùng của bạn bây giờ đã được thêm vào nhóm docker bằng cách gõ:
$ groups
Output
sammy sudo docker
Nếu bạn cần thêm người dùng vào nhóm mà bạn chưa đăng nhập, hãy khai báo rõ ràng tên người dùng đó bằng cách sử dụng: docker
$ sudo usermod -aG docker username
Phần còn lại của bài viết này giả định bạn đang chạy lệnh với tư cách là người dùng trong nhóm docker. Nếu bạn chọn không, vui lòng thêm các lệnh bằng: .docker
sudo
Hãy khám phá lệnh tiếp theo.docker
Sử dụng bao gồm truyền cho nó một chuỗi các tùy chọn và lệnh theo sau là các đối số. Cú pháp có dạng sau: docker
$ docker [option] [command] [arguments]
Để xem tất cả các lệnh con có sẵn, hãy nhập:docker
$ docker
Kể từ Docker 19, danh sách đầy đủ các lệnh con có sẵn bao gồm:
Output
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Để xem các tùy chọn có sẵn cho một lệnh cụ thể, hãy nhập:
$ docker docker-subcommand --help
Để xem thông tin trên toàn hệ thống về Docker, hãy sử dụng:
$ docker info
Hãy cùng khám phá một số lệnh này. Chúng ta sẽ bắt đầu bằng cách làm việc với hình ảnh.
Bộ chứa Docker được xây dựng từ hình ảnh Docker. Theo mặc định, Docker lấy những hình ảnh này từ Docker Hub, một sổ đăng ký Docker được quản lý bởi Docker, công ty đứng sau dự án Docker. Bất kỳ ai cũng có thể lưu trữ hình ảnh Docker của họ trên Docker Hub, vì vậy hầu hết các ứng dụng và bản phân phối Linux bạn cần sẽ có hình ảnh được lưu trữ ở đó.
Để kiểm tra xem bạn có thể truy cập và tải xuống hình ảnh từ Docker Hub hay không, hãy nhập:
$ docker run hello-world
Đầu ra sẽ chỉ ra rằng Docker đang hoạt động chính xác:
Output
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
Docker ban đầu không thể tìm thấy hình ảnh cục bộ, vì vậy nó đã tải xuống hình ảnh từ Docker Hub, đây là kho lưu trữ mặc định. Sau khi image được tải xuống, Docker đã tạo một container từ image và ứng dụng bên trong container được thực thi, hiển thị thông báo: .hello world
Bạn có thể tìm kiếm hình ảnh có sẵn trên Docker Hub bằng cách sử dụng lệnh với lệnh con. Ví dụ: để tìm kiếm hình ảnh Ubuntu, hãy nhập: docker
search
$ docker search ubuntu
Tập lệnh sẽ thu thập dữ liệu Docker Hub và trả về danh sách tất cả các hình ảnh có tên khớp với chuỗi tìm kiếm. Trong trường hợp này, đầu ra sẽ tương tự như thế này:
Output
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
ubuntu Ubuntu is a Debian-based Linux operating sys… 10908 [OK]
dorowu/ubuntu-desktop-lxde-vnc Docker image to provide HTML5 VNC interface … 428 [OK]
rastasheep/ubuntu-sshd Dockerized SSH service, built on top of offi… 244 [OK]
consol/ubuntu-xfce-vnc Ubuntu container with "headless" VNC session… 218 [OK]
ubuntu-upstart Upstart is an event-based replacement for th… 108 [OK]
ansible/ubuntu14.04-ansible Ubuntu 14.04 LTS with
...
Trong cột CHÍNH THỨC, OK cho biết một hình ảnh được xây dựng và hỗ trợ bởi công ty đứng sau dự án. Khi bạn đã xác định được hình ảnh mà bạn muốn sử dụng, bạn có thể tải nó xuống máy tính của mình bằng lệnh phụ .pull
Bạn có thể tìm kiếm hình ảnh có sẵn trên Docker Hub bằng cách sử dụng lệnh với lệnh con. Ví dụ: để tìm kiếm hình ảnh Ubuntu, hãy nhập: ubuntu
$ docker pull ubuntu
Bạn sẽ thấy kết quả sau:
Output
Using default tag: latest
latest: Pulling from library/ubuntu
d51af753c3d3: Pull complete
fc878cd0a91c: Pull complete
6154df8ff988: Pull complete
fee5db0ff82f: Pull complete
Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
Sau khi hình ảnh đã được tải xuống, bạn có thể chạy vùng chứa bằng hình ảnh đã tải xuống bằng lệnh con. Như bạn đã thấy với ví dụ, nếu một image chưa được tải xuống khi được thực thi bằng lệnh con, trước tiên Docker client sẽ tải xuống image, sau đó chạy một container bằng cách sử dụng nó .run
hello world
docker
run
Để xem hình ảnh đã được tải xuống máy tính của bạn, hãy nhập:
$ docker images
Đầu ra sẽ trông giống như sau:
Output
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 1d622ef86b13 3 weeks ago 73.9MB
hello-world latest bf756fb1ae65 4 months ago 13.3kB
Như bạn sẽ thấy ở phần sau của hướng dẫn này, hình ảnh mà bạn sử dụng để chạy container có thể được sửa đổi và sử dụng để tạo hình ảnh mới, sau đó có thể được tải lên (đẩy là thuật ngữ kỹ thuật) lên Docker Hub hoặc các đăng ký Docker khác.
Hãy xem cách chạy container chi tiết hơn.
Vùng chứa bạn đã chạy ở bước trước là ví dụ về vùng chứa chạy và thoát sau khi phát ra thông báo kiểm tra. Các thùng chứa có thể hữu ích hơn thế nhiều và chúng có thể tương tác. Xét cho cùng, chúng tương tự như máy ảo, chỉ thân thiện với tài nguyên hơn.hello world
Ví dụ: hãy chạy một container bằng hình ảnh mới nhất của Ubuntu. Sự kết hợp của các switch -i và -t cho phép bạn truy cập shell tương tác vào container:
$ docker run -it ubuntu
Dấu nhắc lệnh của bạn sẽ thay đổi để phản ánh thực tế rằng bạn hiện đang làm việc bên trong container và sẽ có dạng sau:
Output
root@d9b100f2f636:/#
Lưu ý id vùng chứa trong dấu nhắc lệnh. Trong ví dụ này, nó là . Bạn sẽ cần ID vùng chứa đó sau này để xác định vùng chứa khi bạn muốn xóa vùng chứa.hello world
Bây giờ bạn có thể chạy bất kỳ lệnh nào bên trong container. Ví dụ: hãy cập nhật cơ sở dữ liệu gói bên trong container. Bạn không cần phải tiền tố bất kỳ lệnh nào với , bởi vì bạn đang hoạt động bên trong container với tư cách là người dùng root: sudo
root@d9b100f2f636:/# apt update
Sau đó cài đặt bất kỳ ứng dụng nào trong đó. Hãy cài đặt Node.js:
root@d9b100f2f636:/# apt install nodejs
Điều này cài đặt Node.js trong container từ kho lưu trữ Ubuntu chính thức. Khi quá trình cài đặt hoàn tất, hãy xác minh rằng Node.js đã được cài đặt:
root@d9b100f2f636:/# node -v
Bạn sẽ thấy số phiên bản được hiển thị trong thiết bị đầu cuối của mình:
Output
v10.19.0
Bất kỳ thay đổi nào bạn thực hiện bên trong vùng chứa chỉ áp dụng cho vùng chứa đó.
Để thoát khỏi vùng chứa, hãy nhập tại dấu nhắc.exit
Hãy xem xét việc quản lý các container trên hệ thống của chúng ta tiếp theo.
Vùng chứa bạn đã chạy ở bước trước là ví dụ về vùng chứa chạy và thoát sau khi phát ra thông báo kiểm tra. Các thùng chứa có thể hữu ích hơn thế nhiều và chúng có thể tương tác. Xét cho cùng, chúng tương tự như máy ảo, chỉ thân thiện với tài nguyên hơn.hello world
Sau khi sử dụng Docker một thời gian, bạn sẽ có nhiều container hoạt động (đang chạy) và không hoạt động trên máy tính. Để xem những cái đang hoạt động, hãy sử dụng:
$ docker ps
Bạn sẽ thấy đầu ra tương tự như sau:
Output
CONTAINER ID IMAGE COMMAND CREATED
Trong hướng dẫn này, bạn đã bắt đầu hai container; một từ hình ảnh và một từ hình ảnh. Cả hai container không còn chạy, nhưng chúng vẫn tồn tại trên hệ thống của bạn.hello world
ubuntu
Để xem tất cả các vùng chứa — hoạt động và không hoạt động, hãy chạy bằng công tắc: docker ps
-a
$ docker ps -a
Bạn sẽ thấy đầu ra tương tự như thế này:
1c08a7a0d0e4 ubuntu "/bin/bash" 2 minutes ago Exited (0) 8 seconds ago quizzical_mcnulty
a707221a5f6c hello-world "/hello" 6 minutes ago Exited (0) 6 minutes ago youthful_curie
Để xem vùng chứa mới nhất bạn đã tạo, hãy chuyển nó sang công tắc:-1
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c08a7a0d0e4 ubuntu "/bin/bash" 2 minutes ago Exited (0) 40 seconds ago quizzical_mcnulty
Để khởi động vùng chứa đã dừng, hãy sử dụng , theo sau là ID vùng chứa hoặc tên của vùng chứa. Hãy khởi động container dựa trên Ubuntu với ID của:dock start
1c08a7a0d0e4
$ docker start 1c08a7a0d0e4
Bộ chứa sẽ khởi động và bạn có thể sử dụng để xem trạng thái của nó:dock ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c08a7a0d0e4 ubuntu "/bin/bash" 3 minutes ago Up 5 seconds quizzical_mcnulty
docker stop
quizzical_mcnulty
$ docker stop quizzical_mcnulty
Khi bạn đã quyết định không cần vùng chứa nữa, hãy xóa vùng chứa đó bằng lệnh, một lần nữa sử dụng ID vùng chứa hoặc tên. Sử dụng lệnh để tìm ID vùng chứa hoặc tên cho vùng chứa được liên kết với hình ảnh và xóa nó.docker rm
docker ps -a
hello-world
$ docker rm youthful_curie
Khi bạn đã quyết định không cần vùng chứa nữa, hãy xóa vùng chứa đó bằng lệnh, một lần nữa sử dụng ID vùng chứa hoặc tên. Sử dụng lệnh để tìm ID vùng chứa hoặc tên cho vùng chứa được liên kết với hình ảnh và xóa nó.docker rm
docker ps -a
hello-world
Container có thể được chuyển thành hình ảnh mà bạn có thể sử dụng để xây dựng các container mới. Hãy xem nó hoạt động như thế nào.
Khi bạn khởi động hình ảnh Docker, bạn có thể tạo, sửa đổi và xóa tệp giống như bạn có thể làm với máy ảo. Những thay đổi bạn thực hiện sẽ chỉ áp dụng cho vùng chứa đó. Bạn có thể bắt đầu và dừng nó, nhưng một khi bạn phá hủy nó bằng lệnh, những thay đổi sẽ bị mất vĩnh viễn.docker rm
Phần này hướng dẫn bạn cách lưu trạng thái của bộ chứa dưới dạng hình ảnh Docker mới.
Sau khi cài đặt Node.js bên trong container Ubuntu, bây giờ bạn có một container chạy ra khỏi một image, nhưng container khác với hình ảnh bạn đã sử dụng để tạo ra nó. Nhưng bạn có thể muốn sử dụng lại vùng chứa Node.js này làm cơ sở cho hình ảnh mới sau này.
Sau đó, commit các thay đổi cho một Docker image instance mới bằng lệnh sau.
$ docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name
Công tắc -m dành cho thông báo cam kết giúp bạn và những người khác biết những thay đổi bạn đã thực hiện, trong khi -a được sử dụng để chỉ định tác giả. Đây là cái bạn đã lưu ý trước đó trong hướng dẫn khi bạn bắt đầu phiên Docker tương tác. Trừ khi bạn đã tạo các kho lưu trữ bổ sung trên Docker Hub, tên người dùng thường là Docker Hub của bạn.container_id
repository
Ví dụ: đối với user sammy, với container ID của , lệnh sẽ là: d9b100f2f636
$ docker commit -m "added Node.js" -a "sammy" d9b100f2f636 sammy/ubuntu-nodejs
Khi bạn cam kết một hình ảnh, hình ảnh mới được lưu cục bộ trên máy tính của bạn. Ở phần sau của hướng dẫn này, bạn sẽ tìm hiểu cách đẩy hình ảnh vào sổ đăng ký Docker như Docker Hub để người khác có thể truy cập nó.
Liệt kê lại các hình ảnh Docker sẽ hiển thị hình ảnh mới, cũng như hình ảnh cũ mà nó được lấy từ:
$ docker images
Bạn sẽ thấy kết quả đầu ra như thế này:
Output
REPOSITORY TAG IMAGE ID CREATED SIZE
sammy/ubuntu-nodejs latest 7c1f35226ca6 7 seconds ago 179MB
...
Trong ví dụ này, là hình ảnh mới, được lấy từ hình ảnh hiện có từ Docker Hub. Sự khác biệt về kích thước phản ánh những thay đổi đã được thực hiện. Và trong ví dụ này, thay đổi là NodeJS đã được cài đặt. Vì vậy, lần tới khi bạn cần chạy một container bằng Ubuntu với NodeJS được cài đặt sẵn, bạn chỉ có thể sử dụng hình ảnh mới.ubuntu-nodejs
ubuntu
Bạn cũng có thể xây dựng Hình ảnh từ , cho phép bạn tự động cài đặt phần mềm trong một hình ảnh mới. Tuy nhiên, điều đó nằm ngoài phạm vi của hướng dẫn này.Dockerfile
Bây giờ hãy chia sẻ hình ảnh mới với những người khác để họ có thể tạo vùng chứa từ nó.
Bước hợp lý tiếp theo sau khi tạo một hình ảnh mới từ một hình ảnh hiện có là chia sẻ nó với một vài người bạn được chọn của bạn, cả thế giới trên Docker Hub hoặc sổ đăng ký Docker khác mà bạn có quyền truy cập. Để đẩy hình ảnh lên Docker Hub hoặc bất kỳ sổ đăng ký Docker nào khác, bạn phải có tài khoản ở đó.
Phần này hướng dẫn bạn cách đẩy hình ảnh Docker lên Docker Hub. Để tìm hiểu cách tạo sổ đăng ký Docker riêng của bạn, hãy xem Cách thiết lập sổ đăng ký Docker riêng trên Ubuntu 18.04.
Để đẩy hình ảnh của bạn, trước tiên hãy đăng nhập vào Docker Hub.
$ docker login -u docker-registry-username
Bạn sẽ được nhắc xác thực bằng mật khẩu Docker Hub. Nếu bạn đã chỉ định mật khẩu chính xác, xác thực sẽ thành công.
Ghi: Nếu tên người dùng đăng ký Docker của bạn khác với tên người dùng cục bộ mà bạn đã sử dụng để tạo hình ảnh, bạn sẽ phải gắn thẻ hình ảnh bằng tên người dùng đăng ký của mình. Đối với ví dụ được đưa ra trong bước cuối cùng, bạn sẽ nhập:
$ docker tag sammy/ubuntu-nodejs docker-registry-username/ubuntu-nodejs
Sau đó, bạn có thể đẩy hình ảnh của riêng bạn bằng cách sử dụng:
$ docker push docker-registry-username/docker-image-name
Để đẩy hình ảnh vào kho lưu trữ sammy, lệnh sẽ là:ubuntu-nodejs
$ docker push sammy/ubuntu-nodejs
Quá trình này có thể mất một chút thời gian để hoàn thành khi tải lên hình ảnh, nhưng khi hoàn tất, đầu ra sẽ như thế này:
Output
The push refers to a repository [docker.io/sammy/ubuntu-nodejs]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed
...
Sau khi đẩy một hình ảnh vào sổ đăng ký, nó sẽ được liệt kê trên bảng điều khiển tài khoản của bạn, như hiển thị trong hình ảnh bên dưới.
Nếu một nỗ lực đẩy dẫn đến lỗi thuộc loại này, thì bạn có thể đã không đăng nhập:
Output
The push refers to a repository [docker.io/sammy/ubuntu-nodejs]
e3fbbfb44187: Preparing
5f70bf18a086: Preparing
a3b5c80a4eba: Preparing
7f18b442972b: Preparing
3ce512daaf78: Preparing
7aae4540b42d: Waiting
unauthorized: authentication required
Đăng nhập và lặp lại nỗ lực đẩy. Sau đó, xác minh rằng nó tồn tại trên trang kho lưu trữ Docker Hub của bạn.docker login
Bây giờ bạn có thể sử dụng để kéo hình ảnh sang một máy mới và sử dụng nó để chạy một container mới. docker pull sammy/ubuntu-nodejs
Trong hướng dẫn này, bạn đã cài đặt Docker, làm việc với hình ảnh và vùng chứa, đồng thời đẩy một hình ảnh đã sửa đổi vào Docker Hub. Bây giờ bạn đã biết những điều cơ bản, hãy khám phá các hướng dẫn Docker khác trong Cộng đồng DigitalOcean.
Dùng thử DigitalOcean miễn phí
Nhấp vào bên dưới để đăng ký và nhận $200 tín dụng Để dùng thử sản phẩm của chúng tôi trong 60 ngày!
ĐC : Số 1014 Phạm Văn Đồng, Phường Hiệp Bình Chánh, Thành phố Thủ Đức, Thành phố Hồ Chí Minh, Việt Nam
MST : 0317305145
HT : [email protected]
Bản quyền thuộc về Hank Technologies 2023.