Cách nhận địa chỉ IP vùng chứa Docker - Giải thích với các ví dụ

Docker cung cấp khả năng đóng gói và chạy một ứng dụng trong một môi trường cô lập lỏng lẻo được gọi là vùng chứa.

Tôi biết bạn có thể đang nghĩ gì - thôi nào, không phải một bài đăng khác giải thích Docker là gì, nó ở khắp mọi nơi ngày nay!

Nhưng đừng lo lắng, chúng tôi đang bỏ qua phần giới thiệu cơ bản đó. Đối tượng mục tiêu của bài viết này đã có hiểu biết cơ bản về Docker và Container là gì.

Nhưng bạn đã bao giờ tự hỏi làm thế nào để có được Địa chỉ IP vùng chứa Docker chưa?

Mạng Docker giải thích

Trước tiên, hãy hiểu cách hoạt động của mạng Docker. Vì điều đó, chúng tôi sẽ tập trung vào bridgemạng mặc định . Khi bạn đang sử dụng Docker, nếu bạn không chỉ định trình điều khiển thì đây là loại mạng bạn đang sử dụng.

Các bridgemạng hoạt động như một mạng riêng nội bộ để các máy chủ để container trên đó có thể giao tiếp. Quyền truy cập bên ngoài được cấp bằng cách để lộ các cổng cho các container.

Mạng cầu nối được sử dụng khi các ứng dụng của bạn chạy trong các vùng chứa độc lập cần giao tiếp.

Trong hình trên dbwebcó thể giao tiếp với nhau trên một mạng cầu nối do người dùng tạo ra mybridge.

Nếu bạn chưa bao giờ thêm mạng trong Docker, bạn sẽ thấy một cái gì đó tương tự như sau:

$ docker network ls NETWORK ID NAME DRIVER SCOPE c3cd46f397ce bridge bridge local ad4e4c24568e host host local 1c69593fc6ac none null local

Mạng mặc định bridgeđược liệt kê, cùng với hostnone. Chúng tôi sẽ bỏ qua hai cái còn lại và sử dụng bridgemạng khi xem các ví dụ.

Địa chỉ IP vùng chứa Docker

Theo mặc định, vùng chứa được chỉ định địa chỉ IP cho mọi mạng Docker mà nó kết nối. Và mỗi mạng được tạo với một mặt nạ mạng con mặc định, sử dụng nó như một nhóm sau này để cung cấp địa chỉ IP.

Thông thường Docker sử dụng 172.17 mặc định . Mạng con 0.0 / 16 cho mạng vùng chứa.

Bây giờ để hiểu rõ hơn về nó, chúng ta sẽ thực thi một trường hợp sử dụng thực.

đang vẽ

Ví dụ về Docker

Để minh họa điều này, chúng tôi sẽ sử dụng môi trường Hive và Hadoop, chứa 5 Docker Containers.

Kiểm tra docker-compose.ymltệp chúng tôi sắp thực thi:

version: "3" services: namenode: image: bde2020/hadoop-namenode:2.0.0-hadoop2.7.4-java8 volumes: - namenode:/hadoop/dfs/name environment: - CLUSTER_NAME=test env_file: - ./hadoop-hive.env ports: - "50070:50070" datanode: image: bde2020/hadoop-datanode:2.0.0-hadoop2.7.4-java8 volumes: - datanode:/hadoop/dfs/data env_file: - ./hadoop-hive.env environment: SERVICE_PRECONDITION: "namenode:50070" ports: - "50075:50075" hive-server: image: bde2020/hive:2.3.2-postgresql-metastore env_file: - ./hadoop-hive.env environment: HIVE_CORE_CONF_javax_jdo_option_ConnectionURL: "jdbc:postgresql://hive-metastore/metastore" SERVICE_PRECONDITION: "hive-metastore:9083" ports: - "10000:10000" hive-metastore: image: bde2020/hive:2.3.2-postgresql-metastore env_file: - ./hadoop-hive.env command: /opt/hive/bin/hive --service metastore environment: SERVICE_PRECONDITION: "namenode:50070 datanode:50075 hive-metastore-postgresql:5432" ports: - "9083:9083" hive-metastore-postgresql: image: bde2020/hive-metastore-postgresql:2.3.0 volumes: namenode: datanode: 

Từ docker-hive GitHub

Không ai muốn đọc một tệp cấu hình KHỔNG LỒ , đúng không? Vì vậy, đây là một hình ảnh:

Tốt hơn nhiều! Bây giờ hãy bắt đầu các vùng chứa đó:

docker-compose up -d 

Chúng ta có thể thấy 5 container:

$ docker ps --format \ "table {{.ID}}\t{{.Status}}\t{{.Names}}" CONTAINER ID STATUS NAMES 158741ba0339 Up 1 minutes dockerhive_hive-metastore-postgresql 607b00c25f29 Up 1 minutes dockerhive_namenode 2a2247e49046 Up 1 minutes dockerhive_hive-metastore 7f653d83f5d0 Up 1 minutes (healthy) dockerhive_hive-server 75000c343eb7 Up 1 minutes (healthy) dockerhive_datanode

Tiếp theo, hãy kiểm tra các mạng Docker của chúng tôi:

$ docker network ls NETWORK ID NAME DRIVER SCOPE c3cd46f397ce bridge bridge local 9f6bc3c15568 docker-hive_default bridge local ad4e4c24568e host host local 1c69593fc6ac none null local

Chờ một chút ... có một mạng mới được gọi docker-hive_default!

Theo mặc định, trình soạn thư docker thiết lập một mạng duy nhất cho ứng dụng của bạn. Và mạng của ứng dụng của bạn được đặt tên dựa trên “tên dự án”, bắt nguồn từ tên của thư mục mà nó nằm trong đó.

Vì vậy, vì thư mục của chúng tôi được đặt tên docker-hive, điều này giải thích cho mạng mới.

Tiếp theo một số ví dụ về cách lấy Địa chỉ IP Docker.

Cách lấy địa chỉ IP vùng chứa Docker - ví dụ

Và bây giờ tôi đã nhận được sự chú ý của bạn, chúng tôi sẽ tiết lộ bí ẩn.

đang vẽ

1. Sử dụng Docker Kiểm tra

Kiểm tra Docker là một cách tuyệt vời để truy xuất thông tin cấp thấp trên các đối tượng Docker. Bạn có thể chọn bất kỳ trường nào từ JSON trả về một cách khá đơn giản.

Vì vậy, chúng ta sẽ sử dụng nó để lấy Địa chỉ IP từ dockerhive_datanode?

$ docker inspect -f \ '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \ 75000c343eb7 172.18.0.5

Không phải bạn đã nói rằng Docker sử dụng 172.17 mặc định . 0.0 / 16 mạng con cho mạng vùng chứa? Tại sao Địa chỉ IP trả về: 172.18.0.5 lại  nằm ngoài nó?

Để trả lời điều đó, chúng tôi phải xem cài đặt mạng của mình:

$ docker network inspect -f \ '{{range .IPAM.Config}}{{.Subnet}}{{end}}' 9f6bc3c15568 172.18.0.0/16

Chúng tôi đã thực thi ví dụ này trong máy ảo Compute Engine và trong thử nghiệm này, mạng docker đã được chỉ định một mạng con khác: 172.18.0.0/16 . Giải thích nó!

Hơn nữa, chúng tôi cũng có thể tra cứu tất cả các Địa chỉ IP bên trong docker-hive_defaultmạng.

Vì vậy, chúng tôi không cần phải tra cứu từng IP riêng lẻ của Container:

$ docker network inspect -f \ '{{json .Containers}}' 9f6bc3c15568 | \ jq '.[] | .Name + ":" + .IPv4Address' "dockerhive_hive-metastore-postgresql:172.18.0.6/16" "dockerhive_hive-metastore:172.18.0.2/16" "dockerhive_namenode:172.18.0.3/16" "dockerhive_datanode:172.18.0.5/16" "dockerhive_hive-server:172.18.0.4/16"
đang vẽ

Nếu bạn không nhận thấy, chúng tôi đã sử dụng trợ giúp jq để phân tích cú pháp Containersđối tượng bản đồ.

2. Sử dụng Docker executive

Trong ví dụ sau, chúng tôi sẽ làm việc với dockerhive_namenode.

$ docker exec dockerhive_namenode cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.18.0.3 607b00c25f29

3. Bên trong Docker Container

$ docker exec -it dockerhive_namenode /bin/bash # running inside the dockerhive_namenode container ip -4 -o address 7: eth0 inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0

Chúng tôi thậm chí có thể tìm thấy Địa chỉ IP của các vùng chứa khác nằm trong vùng chứa trong cùng một mạng:

Nút dữ liệu

# running inside the dockerhive_namenode container ping dockerhive_datanode PING dockerhive_datanode (172.18.0.5): 56 data bytes 64 bytes from 172.18.0.5: icmp_seq=0 ttl=64 time=0.092 ms

Hive mestastore

# running inside the dockerhive_namenode container ping dockerhive_hive-metastore PING dockerhive_hive-metastore_1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.087 ms

Máy chủ Hive

# running inside the container ping dockerhive_hive-server PING dockerhive_hive-server (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.172 ms

Gói (lại

Tất cả các ví dụ đã được thực thi trong máy ảo Compute Engine phân phối linux. Nếu bạn thực thi chúng trong môi trường macOS hoặc Windows, các lệnh mẫu có thể thay đổi một chút.

Cũng nên nhớ rằng các Địa chỉ IP đó trong các ví dụ được đưa ra là nội bộ của docker-hive_defaultmạng mẫu . Vì vậy, nếu bạn có trường hợp sử dụng để kết nối với các vùng chứa đó bên ngoài, bạn sẽ cần sử dụng IP bên ngoài của máy chủ (giả sử rằng bạn đang hiển thị các cổng vùng chứa một cách chính xác).

Hoặc nếu bạn đang sử dụng kubernetes, chẳng hạn, để quản lý vùng chứa Docker của mình, hãy để nó xử lý Địa chỉ IP cho bạn kubernetes-expe-external-ip-address ?.

* Hình minh họa từ icon8.com của Murat Kalkavan.