ทำให้นักเทียบท่าใช้ IPv4 สำหรับการเชื่อมพอร์ต


108

ฉันมีโฮสต์นักเทียบท่าและข้างในฉันมีตู้คอนเทนเนอร์หนึ่งตู้

โฮสต์ Docker กำลังผูกพอร์ตบนอินเตอร์เฟส IPv6 เท่านั้นไม่ใช่บน IPv4

นี่คือผลลัพธ์

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:55082           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::40280                :::*                    LISTEN      -
tcp6       0      0 :::5432                 :::*                    LISTEN      -
tcp6       0      0 :::40122                :::*                    LISTEN      -
tcp6       0      0 :::36378                :::*                    LISTEN      -
tcp6       0      0 :::40543                :::*                    LISTEN      -
tcp6       0      0 :::111                  :::*                    LISTEN      -

ตอนนี้ฉันมีพอร์ต 40122 บนโฮสต์เพื่อเชื่อมโยงกับพอร์ต 22 บนคอนเทนเนอร์

ฉันต้องการ SSH ลงในคอนเทนเนอร์นั้น แต่ฉันไม่สามารถทำได้เนื่องจากมีเพียง IPv6 เท่านั้น

นี่คือเวอร์ชันนักเทียบท่าของฉัน Docker version 1.5.0, build a8a31ef

docker ps

201bde6c839a        myapp:latest   "supervisord -n"    3 weeks ago         Up 2 hours          0.0.0.0:40122->22/tcp, 0.0.0.0:40280->80/tcp, 0.0.0.0:40543->443/tcp   myapp

ฉันวิ่งโดยใช้ docker run -d -P -p 40122:22

netstat -tlna

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3031          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::6379                 :::*                    LISTEN

ps aux

root         1  0.0  0.8  52440 16668 ?        Ss   00:53   0:03 /usr/bin/python /usr/bin/supervisord -n
root        49  0.0  0.1  17980  3048 ?        S    01:32   0:00 bash
root        64  0.0  0.1  46632  2712 ?        S    01:32   0:00 su -l vagrant
vagrant     65  0.0  0.1  21308  3760 ?        S    01:32   0:00 -su
root       288  0.0  0.1  17980  3088 ?        S    02:01   0:00 bash
root       304  0.0  0.1  46632  2720 ?        S    02:01   0:00 su -l vagrant
vagrant    305  0.0  0.1  21304  3804 ?        S    02:01   0:00 -su
vagrant    308  0.0  3.7 429616 75840 ?        Sl+  02:01   0:05 python ./manage.py shell_plus
root       654  0.0  0.4  47596  9848 ?        S    03:12   0:01 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       655  0.0  0.3  90280  7732 ?        S    03:12   0:00 nginx: master process /usr/sbin/nginx
www-data   656  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   657  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   658  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   659  0.0  0.2  90940  4500 ?        S    03:12   0:00 nginx: worker process
root       660  0.0  0.2  61372  5332 ?        S    03:12   0:00 /usr/sbin/sshd -D
root       669  0.0  0.4  37004  8892 ?        Sl   03:12   0:01 redis-server *:6379
root       856  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       857  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       858  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       859  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
vagrant    889  0.0  0.1  18692  2508 ?        R+   04:11   0:00 ps aux

คุณใช้คำสั่งอะไรในการเริ่มคอนเทนเนอร์ โพสต์ผลลัพธ์docker psเมื่อคอนเทนเนอร์กำลังทำงานด้วย
แดเนียลที.

คุณสามารถยืนยันได้ว่า sshd กำลังทำงานบนคอนเทนเนอร์จริงหรือไม่ เรียกใช้docker exec -ti 201bde6c839a /bin/bashเมื่อคุณอยู่ในโพสต์ผลลัพธ์ของps aux และnetstat -taln
Daniel t.

ในโฮสต์ Docker ของฉันพอร์ต Docker ทั้งหมดกำลังฟังบน IPv6 และไม่มีปัญหาในการเชื่อมต่อกับ ssh บนคอนเทนเนอร์
แดเนียลที.

@ แดเนียล. ฉันได้เพิ่มข้อมูลแล้ว ฉันสามารถ ssh โดยใช้ exec แต่ฉันไม่สามารถ ssh ลงในคอนเทนเนอร์โดยตรงจากภายนอกโดยใช้พอร์ตโฮสต์ 40122 จาก mac
user3214546

คุณสามารถกดปุ่มgithub.com/docker/docker/issues/2174นี้ได้ฉันไม่แน่ใจว่าจะได้รับการแก้ไขหรือไม่ คุณสามารถแบ่งปันวิธีที่คุณพยายามเชื่อมต่อผ่าน ssh และข้อผิดพลาดที่คุณได้รับได้หรือไม่?
แดเนียลที.

คำตอบ:


81

ดังที่ @ daniel-t ชี้ให้เห็นในความคิดเห็น: github.com/docker/docker/issues/2174เป็นเรื่องเกี่ยวกับการแสดงการเชื่อมโยงกับ IPv6 netstatเท่านั้น แต่นั่นไม่ใช่ปัญหา เนื่องจากปัญหา github ระบุว่า:

เมื่อตั้งค่าพร็อกซีนักเทียบท่าจะร้องขอที่อยู่ลูปแบ็ค '127.0.0.1' ลินุกซ์จะรู้ว่านี่คือที่อยู่ที่มีอยู่ใน IPv6 (เป็น :: 0) และเปิดขึ้นบนทั้งสอง (แต่เป็นซ็อกเก็ต IPv6 อย่างเป็นทางการ) เมื่อคุณเรียกใช้ netstat จะเห็นสิ่งนี้และบอกคุณว่าเป็น IPv6 - แต่ยังคงฟังอยู่บน IPv4 หากคุณเล่นกับการตั้งค่าของคุณเล็กน้อยคุณอาจปิดการใช้งานเคล็ดลับนี้ที่ Linux ทำ - โดยตั้งค่า net.ipv6.bindv6only = 1

กล่าวอีกนัยหนึ่งเพียงเพราะคุณเห็นว่าเป็น IPv6 เท่านั้นจึงยังสามารถสื่อสารบน IPv4 ได้เว้นแต่คุณจะตั้งค่า IPv6 ให้ผูกกับ IPv6 ด้วยการตั้งค่า net.ipv6.bindv6only เท่านั้น เพื่อความชัดเจน net.ipv6.bindv6only ควรเป็น 0 - คุณสามารถเรียกใช้sysctl net.ipv6.bindv6onlyเพื่อตรวจสอบ


5
นี่เป็นปัญหาใหญ่จริง ระบบคลาวด์สาธารณะเช่น Azure ไม่พูด IPV6 ได้เป็นอย่างดีตัวอย่างเช่นตัวโหลดบาลานซ์ Azure สาธารณะพยายามให้ IPV4 เป็นแบ็กเอนด์
Thomas Decaux

1
ดูเหมือนว่าคุณอาจต้องติดตั้ง "Docker VM Extension" ใน Azure และใช้ Ubuntu 14.04 LTS อย่างไรก็ตามฉันไม่คิดว่าจะมีปัญหากับ ipv6 เนื่องจากเป็นเฉพาะในโฮสต์ภายในไม่ใช่เครือข่าย
Michael

คุณพูดถูกปัญหาอยู่ใน config ของฉัน (การปิด IPV6 ไม่ใช่ความคิดที่ดี ^^)
Thomas Decaux

1
@bigdong คุณต้องการ ipv6 บน
Michael

1
@ ไมเคิลคุณเป็นคนประหยัดเวลาของฉัน :)
lv0gun9

6

การตั้งค่าnet.ipv6.conf.all.forwarding=1จะช่วยแก้ปัญหาได้

ซึ่งสามารถทำได้ในระบบถ่ายทอดสดโดยใช้ sudo sysctl -w net.ipv6.conf.all.forwarding=1


คำตอบนี้มีข้อดีอย่างหนึ่งคือช่วยให้คุณ "แก้ไข" ปัญหาได้โดยไม่ต้องรีสตาร์ท Docker daemon (คำตอบเมื่อเปลี่ยนการกำหนดค่านักเทียบท่าด้านล่าง) เกี่ยวกับด้านบนคำตอบที่เลือก: จริงๆแล้วฉันมีsysctl net.ipv6.bindv6only=0การเปลี่ยนแปลงการกำหนดค่านี้ไม่ได้ช่วยอะไร
pkoperek

2

ตามค่าเริ่มต้นนักเทียบท่าจะใช้ซ็อกเก็ต AF_INET6 ซึ่งสามารถใช้ได้ทั้งการเชื่อมต่อ IPv4 และ IPv6 สิ่งนี้ทำให้ netstat รายงานที่อยู่ IPv6 สำหรับที่อยู่การรับฟัง

จาก RedHat https://access.redhat.com/solutions/3114021


2

ปัญหาที่ได้รับการแก้ไข :

ใช้ docker run -it -p 80:80 --name nginx --net=host -d nginx

นั่นคือปัญหาที่เราเผชิญกับ VM ในบางครั้งแทนที่จะลองใช้เครือข่ายบริดจ์กับโฮสต์ที่จะทำงานให้คุณ

tcp     0    0 0.0.0.0:80            0.0.0.0:*             LISTEN      - 
tcp6    0    0 :::80                 :::*                  LISTEN      -  

0

หากคุณต้องการให้พอร์ตคอนเทนเนอร์ของคุณเชื่อมโยงกับที่อยู่ ipv4 ของคุณเพียงแค่:

  • ค้นหาไฟล์การตั้งค่า
    • / etc / sysconfig / docker-network บน RedHat เหมือนกัน
    • / etc / default / docker-network บน Debian ans เหมือนกัน
  • แก้ไขการตั้งค่าเครือข่าย
    • เพิ่ม DOCKER_NETWORK_OPTIONS = -ip = xx.xx.xx.xx
    • xx.xx.xx.xx เป็น ipv4 จริงของคุณ (ไม่ใช่ 0.0.0.0)
  • รีสตาร์ท Docker deamon

ทำงานให้ฉันบนนักเทียบท่า 1.9.1


1
สิ่งนี้ใช้ได้กับเดเบียนหรือไม่ ไม่ควรเป็น / etc / default / docker?
Dimitri Kopriwa

1
@BigDong ขอบคุณสำหรับความคิดเห็นฉันใช้ RedHat เหมือนกับ OS ดังนั้นเส้นทางจึงแตกต่างจากระบบปฏิบัติการหนึ่งไปยังอีกระบบหนึ่งเล็กน้อยฉันพยายามสะท้อนความคิดเห็นของคุณในคำตอบ
Sylvain

0

สำหรับผู้ใช้ CentOS

ฉันมีปัญหาเดียวกันใน CentOS7 และการตั้งค่า net.ipv4.ip_forward เป็น 1 ช่วยแก้ปัญหาได้ โปรดดูที่Docker Networking Disabled: คำเตือน: การส่งต่อ IPv4 ถูกปิดใช้งาน ระบบเครือข่ายจะไม่ทำงานสำหรับรายละเอียดเพิ่มเติม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.