Series về Docker trong thực thành & sản xuất - Thành phần cơ bản của docker và một số khái niệm thường gặp

Series về Docker trong thực thành & sản xuất - Thành phần cơ bản của docker và một số khái niệm thường gặp

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Puppeteer thì chắc ai cũng biết rồi - Một thư viện JavaScript cung cấp API cấp cao để điều khiển Chrome hoặc Firefox. Thường thì nó sẽ mở trình duyệt trên máy tính để chạy tác vụ tự động. Cơ mà mới đây steel-browser được giới thiệu để đưa Puppeteer lên đám mây. Tức là thay vì mở trình duyệt trên máy thì mở trình duyệt trên đám mây.

    Cách làm cũng đơn giản, chỉ cần sửa lại một chút đoạn khởi chạy:

    const browser = await puppeteer.launch({...});

    Thành:

    const browser = await puppeteer.connect({ browserWSEndpoint: 'wss://connect.steel.dev?apiKey=MY_STEEL_API_KEY', });

    À phiên bản miễn phí thì đang giới hạn 100 giờ chạy mỗi tháng á các bạn 😄

    » Xem thêm
  • Đây! Một vấn đề mà từ xưa đến nay mình cứ thắc mắc mãi, và cho đến hôm qua thì mọi thứ đã sáng tỏ.

    Bình thường mọi người dùng height: 100vh để đặt chiều cao bằng với viewport của màn hình. Trên máy tính thì không vấn đề gì, thậm chí giả lập kích thước của điện thoại thông minh thì mọi thứ vẩn ổn. Nhưng khi mở trên điện thoại thì height 100vh lúc nào cũng vượt quá viewport. Ủa!? Là sao???

    Lý giải cho điều này là do trên thiết bị di động có cách tính viewport khác với máy tính. Nó thường bị can thiệp hay ảnh hưởng bởi thanh địa chỉ, thanh điều hướng của nền tảng mà bạn đang sử dụng. Vậy nên nếu muốn 100vh trên di động đúng bằng viewport thì cần phải làm thêm một bước thiết lập lại viewport.

    Dễ lắm, đầu tiên cần tạo một css variable --vh ở ngay thẻ script đầu trang.

    function updateViewportHeight() { const viewportHeight = globalThis.innerHeight; document.documentElement.style.setProperty('--vh', `${viewportHeight * 0.01}px`); } updateViewportHeight(); window.addEventListener('resize', updateViewportHeight);

    Sau đó thay vì dùng height: 100vh thì chuyển thành height: calc(var(--vh, 1vh) * 100). Thế là xong.

    » Xem thêm
  • Cả ngày hôm nay mình dành thời gian để làm giao diện tiếp thị cho gói hội viên của 2coffee.dev. Vậy là cuối cùng thì cũng chính thức đi vào vào con đường mà 5 năm trước cũng không ngờ đến được: "Bán một cái gì đó". Người ta thường nói "Cho đi để nhận lại", bên cạnh đó cũng có câu "Nếu giỏi một cái gì đó, đừng làm nó miễn phí". Nếu theo dõi đủ lâu, bạn đọc sẽ thấy chẳng có gì mình giấu giếm. Biết gì viết nấy, và đôi khi nhờ viết ra mà nhận lại được sự góp ý của độc giả. Từ đó giúp mình hoàn thiện bản thân nhiều hơn.

    Membership là tính năng mà mình sắp sửa giới thiệu. Trở thành hội viên của blog, bạn sẽ có một số đặc quyền nhất định, ví dụ như truy cập vào các bài viết chỉ dành riêng cho hội viên. Các bài viết này về các chủ đề chuyên sâu và được hệ thống hoá sao cho dễ đọc và dễ nắm bắt nhất. Qua đó cung cấp thêm nhiều kiến thức và trau dồi kỹ năng cho bạn đọc.

    Để đạt được đến ngày hôm nay là công rất lớn của các bạn đọc giả, của những người yêu mến 2coffee.dev. Nhờ các bạn mà blog mới có ngày hôm nay. Bên cạnh đó, bản thân mình cũng phải thay đổi liên tục, phải vượt ra khỏi vùng an toàn, làm những điều mà trước nay không dám. Dù sao đi nữa thì đây cũng mới là khởi đầu cho mọi sự gian nan. Nhưng đừng bao giờ nản nha các bạn ơi 😄

    » Xem thêm

Container

Container là một tiến trình (process) được chạy độc lập với các tiến trình khác trên máy chủ cài docker. Nó sử dụng kernel namespaces and cgroups - những tính năng này đã có trong Linux từ lâu, docker chỉ làm cho nó dễ tiếp cận và sử dụng hơn.

Hay nói một cách cho dễ hình dung, mỗi ứng dụng bạn chạy sẽ được chứa trong một container và chúng là độc lập với nhau.

Cú pháp cơ bản để khởi tạo một container chạy ứng dụng nginx là:

docker run --name my-nginx nginx

Trong đó --name là cờ đặt tên cho container, nginx là tên của image cần sử dụng để chạy container.

Để xem danh sách container đang chạy, sử dụng:

docker ps

Image

Để khởi tạo một container thì chúng ta cần phải có một file gọi là image.

Image bao gồm cả hệ thống file của container nên nó phải chứa mọi thứ cần thiết để chạy một ứng dụng như các dependency, các cấu hình, file hệ thống…

Tưởng tượng một image để chạy một ứng dụng node.js của bạn thì bên trong nó chứa các file hệ thống của os (filesystem), node.js runtime được tích hợp sẵn và thư mục project của bạn.

Các image cũng chứa các cấu hình khác như biến môi trường, các câu lệnh mặc định khi khởi chạy image...

Để tạo ra một image ta dùng đến Dockerfile. Dockerfile là một file dạng text, bên trong chứa các lệnh giúp bạn có thể tạo ra một image chứa ứng dụng của mình.

Một số lệnh cơ bản để thao tác với image gồm có:

# xem danh sách image có trong máy

$ docker image ls

# pull một image

$ docker pull image_name:tag

# push một image

$ docker push image_name:tag

Image trong docker được đánh dấu phiên bản bằng các tag. Ví dụ với một image là nginx có rất nhiều thẻ như latest, 1, 1.19, 1.19.10..., các tag thường được đánh theo version của chúng. Mặc định các lệnh mà có thao tác với image, nếu không chỉ định tag của image nó sẽ tự lấy tag là latest.

Network

Bởi vì các container trong docker là độc lập nên nếu muốn chúng giao tiếp được với nhau qua mạng thì bạn phải cần đến network. Network trong docker hoạt động như một mạng internet kết nối chúng lại với nhau.

Mặc định docker cung cấp một số loại mạng cơ bản như bridge, host, overlay, macvlan, none và các plugin khác. Trong đó có 3 loại đáng lưu ý:
Bridge là mạng mặc định được container sử dung khi chạy ứng dụng nếu không chỉ định bất kì loại mạng nào khác. Mạng bridge cung cấp giải pháp cho các container giao tiếp với nhau nếu cùng nằm trong một mạng. Tuy nhiên nếu chỉ định container chạy với mạng bridge mà không expose port ra máy chủ thì sẽ không truy cập được vào cổng đó bằng ip của máy chủ.

Ví dụ: Bạn chạy một ứng dụng nginx bằng lệnh:

docker run --name nginx nginx

Mặc định nginx image được chạy ở cổng 80. Giả sử IP của máy chủ là 1.2.3.4 thì khi đó bạn truy cập http://1.2.3.4:80 sẽ không nhận được phản hồi từ nginx nào vì đơn giản container đang chạy ở mạng bridge và nó không được expose port 80 ra máy chủ docker.

Bây giờ hãy thử sửa lại câu lệnh chạy nginx một chút:

docker run --name nginx --port 8080:80 nginx

--port 8080:80 là cú pháp để expose port 80 của nginx ra port 8080 của máy chủ, bây giờ bạn truy cập http://1.2.3.4:8080 sẽ thấy phản hồi từ nginx.

Sử dụng mạng host thì container dùng chung mạng với máy chủ docker. Tức là nếu container chạy image nginx ở cổng 80 thì nó cũng sẽ có sẵn ở cổng 80 của máy chủ. Ví dụ.

docker run --name nginx --network host nginx

Thì lập tức port 80 của nginx được expose ra port 80 của máy chủ, đơn giản bởi vì khi chỉ định container chạy với mạng host thì nó dùng chung mạng với máy chủ. Bây giờ bạn truy cập http://1.2.3.4:80 sẽ thấy phản hồi từ nginx.

Overlay là mạng cho phép các container giao tiếp với nhau khi triển khai ở chế độ swarm. Khi docker ở chế độ swarm (nhiều máy chủ docker kết nối với nhau) các container sẽ được phân tán trên các máy chủ, lúc này để kết nối chúng thì chúng ta cần đến mạng overlay.

Registry

Registry là một kho lưu trữ các image của docker, ngoài registry của docker cung cấp docker hub thì cũng có rất nhiều những registry của các nhà cung cấp khác, thậm chí bạn cũng có thể tự tạo một máy chủ registry cho riêng mình.

Sử dụng registry giúp bạn có thể lưu trữ & phân phối ứng dụng của mình đến cho người khác, hoặc đơn giản là phục vụ cho cá nhân, trong nội bộ…

Một số thành phần khác

Dockerfile

Dockerfile là một file text bên trong chứ những lệnh giúp chúng ta build một image.
Trong Dockerfile có một cơ số lệnh đễ hỗ trợ việc tạo một image, bạn có thể tham khảo tại đây.

Ví dụ đây là một Dockerfile để build một app viết bằng node.js.

FROM node:12
ENV NODE_ENV=production

WORKDIR /app

COPY ["package.json", "package-lock.json*", "./"]

RUN npm install --production

COPY . .  

CMD [ "node", "server.js" ]

Sau đó tại thư mục có chứa Dockerfile, build image với tên là my-node-app:

docker build -t my-node-app .  

docker-compose

docker-compose là một công cụ cho phép khởi chạy ứng dụng gồm nhiều container docker-compose được viết bằng một file .yaml. Sau đó chỉ bằng một lệnh bạn có thể khởi động tất cả các service được cấu hình trong file.

Tưởng tượng ứng dụng node.js của bạn phải cần cả một máy chủ mysql để hoạt động, thay vì khởi chạy lần lượt node.js server, mysql server thì giờ đây bạn có thể đưa hết vào file docker-compose.yaml để khởi động tất cả cùng lúc.

Ví dụ:

version: "3.9"
services:  
  node:  
    image: my-node-app
    ports:  
      - "3000:3000"
    depends_on:  
      - mysql
  mysql:  
    image: mysql
    environment:  
      - MYSQL_USER=hoaitx
      - MYSQL_PASSWORD=password

Sau đó tại thư mục chứa file docker-compose.yaml vừa tạo hãy chạy nó bằng docker-compose:

docker-compose up -d

Lưu ý: Để dùng được lệnh docker-compose thì bạn cần phải cài đặt đó vì mặc định file cài đặt docker không bao gồm nó. Tham khảo tại đây.

Đừng quá lo lắng nếu như bạn chưa thực sự hiểu những những gì ở trong file yaml kia. Các lệnh là nhiều nhưng bạn chỉ cần hiểu ý nghĩa của một số lệnh cơ bản là có thể sử dụng được rồi.

Cũng giống như Dockerfile, docker-compose cũng sở hữu cho mình khối câu lệnh khổng lồ. Bạn có thể tham khảo tại đây. Mình sẽ có một bài nói về docker-compose & giới thiệu một số lệnh hay dùng của nó.

docker swarm

Docker swarm là một chế độ cho phép nhiều máy chủ docker kết nối với nhau để tạo nên một môi trường có khả năng scale và chịu lỗi.

Trong docker swarm, một máy chủ (node) có thể làm manager hoặc là worker. Nhiệm vụ của manager là quản lý các worker node còn nhiệm vụ của các worker là chạy các container.

Docker swarm là cần thiết trong việc triển khai production vì nó tạo ra môi trường đáng tin cậy.

Tổng kết

Trên đây là một số thành phần cơ bản của docker mà một số thuật ngữ hay gặp khi sử dụng docker. Đừng lo lắng nếu bạn chưa thể hiểu hết những thứ trên vì tôi sẽ cùng bạn đi lần lượt từng khái niệm trong cái bài viết tiếp theo.

Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

Bạn thấy bài viết này có ích?
Không

Bình luận (0)

Nội dung bình luận...