Chỉnh sửa: Nếu bạn đang sử dụng Docker-for-mac hoặc Docker-for-Windows 18.03+, chỉ cần kết nối với dịch vụ mysql của bạn bằng máy chủ host.docker.internal
(thay vì 127.0.0.1
trong chuỗi kết nối của bạn).
Kể từ Docker 18.09.3, điều này không hoạt động trên Docker-for-Linux. Một bản sửa lỗi đã được gửi vào ngày 8 tháng 3 năm 2019 và hy vọng sẽ được hợp nhất với cơ sở mã. Cho đến lúc đó, một cách giải quyết là sử dụng một thùng chứa như được mô tả trong câu trả lời của qoomon .
2020-01: một số tiến bộ đã được thực hiện. Nếu mọi việc suôn sẻ, điều này sẽ hạ cánh trong Docker 20.04
TLD
Sử dụng --network="host"
trong docker run
lệnh của bạn , sau đó 127.0.0.1
trong container docker của bạn sẽ trỏ đến máy chủ docker của bạn.
Lưu ý: Chế độ này chỉ hoạt động trên Docker cho Linux, theo tài liệu .
Lưu ý về các chế độ mạng của docker container
Docker cung cấp các chế độ mạng khác nhau khi chạy container. Tùy thuộc vào chế độ bạn chọn, bạn sẽ kết nối với cơ sở dữ liệu MySQL của mình chạy trên máy chủ docker khác nhau.
docker chạy --network = "cầu" (mặc định)
Docker tạo một cây cầu được đặt tên docker0
theo mặc định. Cả máy chủ docker và container docker đều có địa chỉ IP trên cây cầu đó.
trên máy chủ Docker, nhập sudo ip addr show docker0
bạn sẽ có một đầu ra trông như:
[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::5484:7aff:fefe:9799/64 scope link
valid_lft forever preferred_lft forever
Vì vậy, ở đây máy chủ docker của tôi có địa chỉ IP 172.17.42.1
trên docker0
giao diện mạng.
Bây giờ bắt đầu một container mới và lấy shell trên nó: docker run --rm -it ubuntu:trusty bash
và trong loại container ip addr show eth0
để khám phá cách thiết lập giao diện mạng chính của nó:
root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
inet 172.17.1.192/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
valid_lft forever preferred_lft forever
Ở đây container của tôi có địa chỉ IP 172.17.1.192
. Bây giờ hãy nhìn vào bảng định tuyến:
root@e77f6a1b3740:/# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 172.17.42.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 * 255.255.0.0 U 0 0 0 eth0
Vì vậy, Địa chỉ IP của máy chủ docker 172.17.42.1
được đặt làm tuyến mặc định và có thể truy cập được từ container của bạn.
root@e77f6a1b3740:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms
docker chạy --network = "máy chủ"
Ngoài ra, bạn có thể chạy bộ chứa docker với cài đặt mạng được đặt thànhhost
. Một container như vậy sẽ chia sẻ ngăn xếp mạng với máy chủ docker và từ quan điểm của container, localhost
(hoặc 127.0.0.1
) sẽ đề cập đến máy chủ docker.
Xin lưu ý rằng bất kỳ cổng nào được mở trong bộ chứa docker của bạn sẽ được mở trên máy chủ docker. Và điều này mà không yêu cầu -p
hoặc -P
docker run
tùy chọn .
Cấu hình IP trên máy chủ docker của tôi:
[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
và từ một container docker trong chế độ máy chủ :
[vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
valid_lft forever preferred_lft forever
Như bạn có thể thấy cả máy chủ docker và container docker chia sẻ cùng một giao diện mạng và như vậy có cùng một địa chỉ IP.
Kết nối với MySQL từ container
Chế độ cầu
Để truy cập MySQL chạy trên máy chủ docker từ các thùng chứa ở chế độ cầu , bạn cần đảm bảo dịch vụ MySQL đang lắng nghe các kết nối trên 172.17.42.1
địa chỉ IP.
Để làm như vậy, hãy chắc chắn rằng bạn có bind-address = 172.17.42.1
hoặc bind-address = 0.0.0.0
trong tệp cấu hình MySQL của bạn (my.cnf).
Nếu bạn cần đặt biến môi trường với địa chỉ IP của cổng, bạn có thể chạy mã sau trong vùng chứa:
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
sau đó trong ứng dụng của bạn, sử dụng DOCKER_HOST_IP
biến môi trường để mở kết nối tới MySQL.
Lưu ý: nếu bạn sử dụng bind-address = 0.0.0.0
máy chủ MySQL của bạn sẽ lắng nghe các kết nối trên tất cả các giao diện mạng. Điều đó có nghĩa là máy chủ MySQL của bạn có thể được truy cập từ Internet; đảm bảo thiết lập các quy tắc tường lửa phù hợp.
Lưu ý 2: nếu bạn sử dụng bind-address = 172.17.42.1
máy chủ MySQL của bạn sẽ không lắng nghe các kết nối được thực hiện 127.0.0.1
. Các quy trình chạy trên máy chủ docker muốn kết nối với MySQL sẽ phải sử dụng 172.17.42.1
địa chỉ IP.
chế độ máy chủ
Để truy cập MySQL chạy trên máy chủ docker từ các container ở chế độ máy chủ , bạn có thể giữ bind-address = 127.0.0.1
cấu hình MySQL của mình và tất cả những gì bạn cần làm là kết nối 127.0.0.1
từ các container của mình:
[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
lưu ý: Không sử dụng mysql -h 127.0.0.1
và không sử dụng mysql -h localhost
; nếu không, máy khách MySQL sẽ cố gắng kết nối bằng cách sử dụng ổ cắm unix.