docker网络

本文涉及的产品
公网NAT网关,每月750个小时 15CU
简介:

h

一、 Docker 中的网络功能介绍

默认情况下,容器可以建立到外部网络的连接,但是外部网络无法连接到容器。

Docker 允许通过外部访问容器或容器互联的方式来提供网络服务

外部访问容器:

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过  -P  或  -p  参数来指定端口映射。

构建镜像模板

1) 创建一个sshd_dockerfile工作目录

1
2
3
4
5
[root@localhost ~] # mkdir sshd_dockerfile
[root@localhost ~] # cd sshd_dockerfile/
[root@localhost sshd_dockerfile] # touch dockerfile run.sh
[root@localhost sshd_dockerfile] # ls
dockerfile  run.sh

编辑run.sh文件

1
2
3
4
[root@localhost sshd_dockerfile] # cat run.sh 
#!/bin/bash
/usr/sbin/sshd
/usr/sbin/httpd  -DFOREGROUND

在主机上生成ssh秘钥对,并创建authorized_keys文件

1
2
3
4
5
6
7
[root@localhost sshd_dockerfile] # ssh-keygen -t rsa
Generating public /private  rsa key pair.
Enter  file  in  which  to save the key ( /root/ . ssh /id_rsa ): 
Created directory  '/root/.ssh' .
Enter passphrase (empty  for  no passphrase): 
Enter same passphrase again: 
[root@localhost sshd_dockerfile] # cat ~/.ssh/id_rsa.pub > /root/sshd_dockerfile/authorized_keys
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost sshd_dockerfile] # cat dockerfile 
FROM docker.wang.com /centos :centos7
MAINTAINER from cyh@example.com
RUN yum -y  install  openssh-server  sudo  httpd
RUN  useradd  admin
RUN  echo  "admin:admin"  | chpasswd
RUN  echo  "admin ALL=(ALL) ALL"  >>  /etc/sudoers
RUN  ssh -keygen -t dsa -f  /etc/ssh/ssh_host_dsa_key
RUN  ssh -keygen -t rsa -f  /etc/ssh/ssh_host_rsa_key
RUN  mkdir  -p  /var/run/sshd
RUN  mkdir  -p  /home/admin/ . ssh
RUN  sed  -ri  's/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g'  /etc/pam .d /sshd
ADD authorized_keys  /home/admin/ . ssh /authorized_keys
RUN  sed  -ri  's/#ServerName www.example.com:80/ServerName www.benet.com/g'  /etc/httpd/conf/httpd .conf
ADD run.sh  /run .sh
RUN  chmod  755  /run .sh
EXPOSE 22 80 443
CMD [ "/bin/bash" , "/run.sh" ]

二载入centos

1
2
[root@localhost src] # docker load < centos7.tar
0fe55794a0f7: Loading layer [==================================================>]

1)sshd_dockerfile目录下,使用docker  build命令来创建镜像,注意:在最后还有一个.,表示使用当前目录中的dockerfile

1
2
3
4
5
6
7
[root@localhost sshd_dockerfile] # docker build -t centos:http .
Sending build context to Docker daemon 4.608 kB
Step 1 : FROM docker.wang.com /centos :centos7
  ---> 50dae1ee8677
Step 2 : MAINTAINER from cyh@example.com
  ---> Using cache
  ---> 62fedfca03bd

当使用P(大写)标记时,Docker 会随机映射一个随机的端口到内部容器开放的网络端口。

注:-P使用时需要指定--expose选项dockerfile中用expose指令容器要暴露的端口,指定需要对外提供服务的端口

使用  docker ps  可以看到,本地主机的32770被映射到了容器的22端口,本地主机的32769被映射到了容器的80端口,本地主机的32768被映射到了容器的443 端口。

1
2
3
4
5
[root@localhost sshd_dockerfile] # docker run -d -P centos:http
131e12661bc10f0bc441784d64e65038ac0263d6beff1d55bf2cd28d4082c948
[root@localhost sshd_dockerfile] # docker ps
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS                                                                  NAMES
131e12661bc1        centos:http          "/bin/bash /run.sh"    22 seconds ago      Up 21 seconds       0.0.0.0:32770->22 /tcp , 0.0.0.0:32769->80 /tcp , 0.0.0.0:32768->443 /tcp    trusting_rosalind

此时访问本机的 32770端口即可访问容器内 ssh 应用

1
2
3
[root@localhost sshd_dockerfile] # ssh admin@192.168.100.46 -p 32770
The authenticity of host  '[192.168.100.46]:32770 ([192.168.100.46]:32770)'  can't be established.
Are you sure you want to  continue  connecting ( yes /no )?  yes

注:192.168.1.102是宿主主机地址。

查看容器运行的httpd进程

1
2
3
4
5
6
7
[admin@131e12661bc1 ~]$ pgrep httpd
7
8
9
10
11
12

此时访问本机的 32769端口即可访问容器内 web 应用

-p(小写)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort

注意:

容器有自己的内部网络和 ip 地址(使用  docker inspect  可以获取所有的变量。)

-p 标记可以多次使用来绑定多个端口

1
2
3
4
5
6
[root@localhost sshd_dockerfile] # docker run -d -p 10111:22 -p 801:80 centos:http
e0c4edcb03ed524d6d9ebfeac62178761910719e3eac7f6e7058cf0e655e8636
[root@localhost sshd_dockerfile] # docker ps
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS                                                                  NAMES
e0c4edcb03ed        centos:http          "/bin/bash /run.sh"    16 seconds ago      Up 15 seconds       443 /tcp , 0.0.0.0:10111->22 /tcp , 0.0.0.0:801->80 /tcp                     grave_albattani
131e12661bc1        centos:http          "/bin/bash /run.sh"    5 minutes ago       Up 5 minutes        0.0.0.0:32770->22 /tcp , 0.0.0.0:32769->80 /tcp , 0.0.0.0:32768->443 /tcp    trusting_rosalind

测试访问:

1) ssh测试:

使用xshell工具: 账号密码为 admin

wKiom1ma212iJDDPAABVXHdrYXU463.png-wh_50

测试web访问

wKiom1ma223jHAckAAGAUEtWubY962.png-wh_50

映射到指定地址的指定端口

可以使用 ip:hostPort:containerPort 格式,指定映射使用一个特定地址,比如宿主机网卡配置的一个地址192.168.100.46

1
2
root@localhost sshd_dockerfile] # docker run -dit -p 192.168.100.46:10112:22 -p 192.168.100.46:800:80 centos:http
fd41ea4d576f9a337df993b1e39db40274a16289eda134646abd385138216b0f

1. 映射到指定地址的任意端口

1
2
[root@localhost sshd_dockerfile] # docker run -d -p 192.168.100.46::80 --name webserver centos:http
c15abaf81039fb58f3104e7a8d6f854f640cc2ea8ed67615a8388866abf0c649

1 udp端口

1
2
[root@localhost sshd_dockerfile] # docker run -d -p 192.168.100.46:5000:5000/udp --name db4 centos:http
fadedde03f89a235e6cf7dd5412dba7a6870844625d498290126c05e68961335

1. 端口端口映射配置

1
2
[root@localhost sshd_dockerfile] # docker port webserver
80 /tcp  -> 192.168.100.46:32771

Docker NAT iptables实现

默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器

 

容器访问外部实现

容器所有到外部网络的连接,源地址都会被 NAT 成本地系统的 IP 地址(即docker0地址)。这是使用 iptables 的源地址伪装操作实现的

查看主机的 NAT 规则

1
2
3
4
[root@localhost sshd_dockerfile] # iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 3 packets, 234 bytes)
  pkts bytes target     prot opt  in      out      source                destination         
   242 19323 PREROUTING_direct  all  --  *      *       0.0.0.0 /0             0.0.0.0 /0

外部访问容器实现

容器允许外部访问,可以在 docker run 时候通过 -p 或 -P 参数来启用,不管用那种办法,其实也是在本地的 iptable nat 表中添加相应的规则

使用 -P 时:

1
2
[root@localhost sshd_dockerfile] # docker run -d -P centos:http
f2f3ca6d96693b2223d4011e770c3d2b8359219f13e5e617f2263a6bc4298f18

docker0  网桥

Docker服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。

1
2
3
[root@localhost ~] # brctl show
bridge name    bridge  id       STP enabled    interfaces
docker0     8000.02429a3b4e3e   no      veth3855536

注意(brctl可以使用yum install bridge-utils)

容器

1
2
3
[root@localhost ~] # docker exec -it e0c4edcb03ed /bin/bash
[root@e0c4edcb03ed /]
[root@e0c4edcb03ed /] # sudo yum -y install iproute

进入运行的容器使用exec;之后安装iproute包。

1
2
3
[root@e0c4edcb03ed /] # ip r
default via 172.17.0.1 dev eth0 
172.17.0.0 /16  dev eth0  proto kernel  scope link  src 172.17.0.3

会看到容器的ip/默认网关。

Docker 网络配置

Docker 四种网络模式

docker run 创建 Docker 容器时,可以用 --net 选项指定容器的网络模式,Docker 有以下 4 种网络模式:

· host 模式,使用 --net=host 指定。

· container 模式,使用 --net=container:NAMEorID 指定。

· none 模式,使用 --net=none 指定。

· bridge 模式,使用 --net=bridge 指定,默认设置。

host 模式

如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。

查看httpd进程

1
[root@localhost ~] # pgrep httpd

启动容器 host模式

1
2
root@localhost sshd_dockerfile] # docker run -dit --net=host centos:http
b4f57f10bbc3da6aeefaf435613f7832d152d60cd971613e7d8da30b3b5b2c29

放行80端口

1
2
[root@localhost sshd_dockerfile] # firewall-cmd --add-port=80/tcp
success

wKiom1ma3NCT8MS_AACb3DAswOg419.png-wh_50

container 模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

运行一个容器:查看容器的IP

1
2
root@localhost sshd_dockerfile] # docker run -it docker.wang.com/centos:centos7
[root@17cd70302107 /] #

将容器切换到后台运行:ctrl+p  ctrl+q

在运行一个容器使用container模式:查看新容器的地址

docker run -it --ent=container:d86194948685(上个容器id) 镜像名

查看ip,发现与上个容器ip一致。

none模式

这个模式和前两个不同。在这种模式下,Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。

1. none模式(容器拥有自己的Network namespace)

需自己为容器添加网卡、配置ip等。

2. bridge模式(docker0网卡、桥接到容器的网卡。)

所有的veth*的接口都会桥接到docker0(虚拟共享网)

wKioL1ma3KzDCjyTAAEev0Y3vAQ029.png-wh_50

查看桥接网络的详细信息

1
[root@localhost sshd_dockerfile] # docker network inspect

wKiom1ma3PeyhwLJAAAijPSr6hs687.png-wh_50

自定义网桥

除了默认的  docker0  网桥,用户也可以指定网桥来连接各个容器。在启动 Docker 服务的时候,使用  -b BRIDGE  或 --bridge=BRIDGE  来指定使用的网桥。

Docker 允许你管理 docker0 桥接或者通过-b选项自定义桥接网卡,需要安装bridge-utils软件包。

基本步骤如下:

1.确保 docker 的进程是停止的

2.创建自定义网桥

3.给网桥分配特定的 ip

4. -b 的方式指定网桥

如果服务已经运行,那需要先停止服务,并删除旧的网桥

1
2
3
4
5
6
[root@localhost sshd_dockerfile] # systemctl stop docker
[root@localhost sshd_dockerfile] # ip link set dev docker0 down
[root@localhost sshd_dockerfile] # brctl delbr docker0
[root@localhost sshd_dockerfile] # brctl show
bridge name    bridge  id       STP enabled    interfaces
virbr0      8000.000000000000    yes    

1. 创建网桥,分配ip。

1
2
3
[root@localhost sshd_dockerfile] # brctl addbr bridge0
[root@localhost sshd_dockerfile] # ip addr add 192.168.1.1/24 dev bridge0
[root@localhost sshd_dockerfile] # ip link set dev bridge0 up

查看确认网桥成功与否

1
2
3
4
[root@localhost sshd_dockerfile] # brctl show
bridge name    bridge  id       STP enabled    interfaces
bridge0     8000.000000000000   no     
virbr0      8000.000000000000    yes    

wKioL1ma3Tbg0zIgAAAhCqBcK9o424.png-wh_50

1. 修改/etc/sysconfig/docker文件。

wKiom1ma3U_iCb1mAAAgvMotc_w176.png-wh_50

1. 启动服务。

1
[root@localhost sshd_dockerfile] # systemctl start docker

1. 新建容器。

wKioL1ma3WXwpFlyAAAjWhkDW3g646.png-wh_50

1. 进入容器查看。

1
2
3
4
[root@localhost sshd_dockerfile] # docker attach 1481b536c081462aade6e8c7b590142057e6fb29a649011a983672044ea8b609
[root@1481b536c081 /] # yum -y install iproute
[root@localhost sshd_dockerfile] # 'rpm' -qf `which ifconfig`
net-tools-2.0-0.17.20131004git.el7.x86_64

查询下ifconfig命令所需软件包

1
[root@1481b536c081 /] # yum -y install net-tools

wKiom1ma3aqAYuZNAAAnctBPTJU892.png-wh_50





     本文转自柴鑫旺 51CTO博客,原文链接:http://blog.51cto.com/chaixinwang/1958172,如需转载请自行联系原作者


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
5月前
|
Docker 容器
Docker网关冲突导致容器启动网络异常解决方案
当执行`docker-compose up`命令时,服务器网络可能因Docker创建新网桥导致IP段冲突而中断。原因是Docker默认的docker0网卡(172.17.0.1/16)与宿主机网络地址段重叠,引发路由异常。解决方法为修改docker0地址段,通过配置`/etc/docker/daemon.json`调整为非冲突段(如192.168.200.1/24),并重启服务。同时,在`docker-compose.yml`中指定网络模式为`bridge`,最后通过检查docker0地址、网络接口列表及测试容器启动验证修复效果。
|
11月前
|
NoSQL 关系型数据库 MySQL
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
408 56
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
|
9月前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
300 20
|
12月前
|
安全 网络安全 数据安全/隐私保护
利用Docker的网络安全功能来保护容器化应用
通过综合运用这些 Docker 网络安全功能和策略,可以有效地保护容器化应用,降低安全风险,确保应用在安全的环境中运行。同时,随着安全威胁的不断变化,还需要持续关注和研究新的网络安全技术和方法,不断完善和强化网络安全保护措施,以适应日益复杂的安全挑战。
363 61
|
11月前
|
安全 Docker 容器
docker的默认网络模式有哪些
Docker 默认网络模式包括:1) bridge:默认模式,各容器分配独立IP,可通过名称或IP通信;2) host:容器与宿主机共享网络命名空间,性能最优但有安全风险;3) none:容器隔离无网络配置,适用于仅需本地通信的场景。
494 6
|
11月前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
1058 7
|
Docker 容器
docker swarm启动服务并连接到网络
【10月更文挑战第16天】
292 5
|
Docker 容器
【赵渝强老师】Docker的None网络模式
Docker容器在网络方面实现了逻辑隔离,提供了四种网络模式:bridge、container、host和none。其中,none模式下容器具有独立的网络命名空间,但不包含任何网络配置,仅能通过Local Loopback网卡(localhost或127.0.0.1)进行通信。适用于不希望容器接收任何网络流量或运行无需网络连接的特殊服务。
218 0
|
Docker 容器
【赵渝强老师】Docker的Host网络模式
Docker容器在网络环境中是隔离的,可通过配置不同网络模式(如bridge、container、host和none)实现容器间或与宿主机的网络通信。其中,host模式使容器与宿主机共享同一网络命名空间,提高性能但牺牲了网络隔离性。
448 0
|
Kubernetes Docker 容器
【赵渝强老师】Docker的Container网络模式
Docker容器在网络环境中彼此隔离,但可通过配置不同网络模式实现容器间通信。其中,container模式使容器共享同一网络命名空间,通过localhost或127.0.0.1互相访问,提高传输效率。本文介绍了container模式的特点及具体示例。
278 0