当前位置: 首页 > news >正文

docker容器网络配置及常用操作

Linux内核实现名称空间的创建

ip netns(网络名称空间)命令

可以借助ip netns命令来完成对 Network Namespace 的各种操作。ip netns命令来自于iproute安装包,一般系统会默认安装,如果没有的话,请自行安装。

注意:ip netns命令修改网络配置时需要 sudo 权限。

可以通过ip netns命令完成对Network Namespace 的相关操作,可以通过ip netns help查看命令帮助信息:

[root@localhost ~]# rpm -qa|grep iproute
iproute-4.11.0-14.el7.x86_64
[root@localhost ~]# ip netns help
Usage: ip netns list        // 列出所有的名称空间ip netns add NAME    // 添加名称空间ip netns set NAME NETNSIDip [-all] netns delete [NAME]ip netns identify [PID]ip netns pids NAMEip [-all] netns exec [NAME] cmd ...ip netns monitorip netns list-id

默认情况下,Linux系统中是没有任何 Network Namespace的,所以ip netns list命令不会返回任何信息。

创建Network Namespace

通过命令创建一个名为ns0的命名空间:

[root@localhost ~]# ip netns list
[root@localhost ~]# ip netns add ns0
[root@localhost ~]# ip netns list
ns0

通过命令删除一个名为ns0的命名空间:

[root@localhost ~]# ip netns delete ns0

新创建的 Network Namespace 会出现在/var/run/netns/目录下。如果相同名字的 namespace 已经存在,命令会报Cannot create namespace file “/var/run/netns/ns0”: File exists的错误。

[root@localhost ~]# ls /var/run/netns
ns0[root@localhost ~]# ip netns add ns0
Cannot create namespace file "/var/run/netns/ns0": File exists

错误示范:手动创建一个名称空间(名称空间不可以手动去创建)

[root@localhost ~]# touch /var/run/netns/ns1
[root@localhost ~]# ip netns list
RTNETLINK answers: Invalid argument
RTNETLINK answers: Invalid argument
ns1
ns0

对于每个 Network Namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。

操作Network Namespace

ip命令提供了ip netns exec子命令可以在对应的 Network Namespace 中执行命令。

查看新创建 Network Namespace 的网卡信息

[root@localhost ~]# ip netns exec ns0 ip a     // 进入ns0这个名称空间里面去执行ip a这条命令
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

可以看到,新创建的Network Namespace中会默认创建一个lo回环网卡,此时网卡处于关闭状态。此时,尝试去 ping 该lo回环网卡,会提示Network is unreachable

[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1
connect: Network is unreachable

通过下面的命令启用lo回环网卡:

[root@localhost ~]# ip netns exec ns0 ip link set lo up
[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.033 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.041 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.032 ms

转移设备

我们可以在不同的 Network Namespace 之间转移设备(如veth)。由于一个设备只能属于一个 Network Namespace ,所以转移后在这个 Network Namespace 内就看不到这个设备了。

其中,veth设备属于可转移设备,而很多其它设备(如lo、vxlan、ppp、bridge等)是不可以转移的。

// 容器一运行,veth就会自动出现
[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever[root@localhost ~]# ip a
........此处省略多行
5: veth693f9a1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether de:b2:5d:2a:ae:f7 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet6 fe80::dcb2:5dff:fe2a:aef7/64 scope link valid_lft forever preferred_lft forever

veth pair

veth pair 全称是 Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端出来,反之也是一样。
引入veth pair是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。
在这里插入图片描述

创建veth pair

[root@localhost ~]# ip link add type veth
[root@localhost ~]# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000link/ether 00:0c:29:a8:8f:68 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:13:af:55:08 brd ff:ff:ff:ff:ff:ff
6: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/ether c6:a1:94:ea:6e:75 brd ff:ff:ff:ff:ff:ff
7: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/ether 26:ae:e5:06:62:07 brd ff:ff:ff:ff:ff:ff

可以看到,此时系统中新增了一对veth pair,将veth0和veth1两个虚拟网卡连接了起来,此时这对 veth pair 处于”未启用“状态。

实现Network Namespace间通信

下面我们利用veth pair实现两个不同的 Network Namespace 之间的通信。刚才我们已经创建了一个名为ns0的 Network Namespace,下面再创建一个信息Network Namespace,命名为ns1

[root@localhost ~]# ip netns add ns1
[root@localhost ~]# ip netns list
ns1
ns0

然后我们将veth0加入到ns0,将veth1加入到ns1

[root@localhost ~]# ip link set veth0 netns ns0
[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
6: veth0@if7: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000link/ether c6:a1:94:ea:6e:75 brd ff:ff:ff:ff:ff:ff link-netnsid 0[root@localhost ~]# ip link set veth1 netns ns1
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
7: veth1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000link/ether 26:ae:e5:06:62:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0

然后我们分别为这对veth pair配置上ip地址,并启用它们

[root@localhost ~]# ip netns exec ns0 ip link set veth0 up
[root@localhost ~]# ip netns exec ns0 ip addr add 10.0.0.1/24 dev veth0
[root@localhost ~]# ip netns exec ns1 ip link set lo up
[root@localhost ~]# ip netns exec ns1 ip link set veth1 up
[root@localhost ~]# ip netns exec ns1 ip addr add 10.0.0.2/24 dev veth1

查看这对veth pair的状态

[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
6: veth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether c6:a1:94:ea:6e:75 brd ff:ff:ff:ff:ff:ff link-netnsid 1inet 10.0.0.1/24 scope global veth0valid_lft forever preferred_lft foreverinet6 fe80::c4a1:94ff:feea:6e75/64 scope link valid_lft forever preferred_lft forever[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
7: veth1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether 26:ae:e5:06:62:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 10.0.0.2/24 scope global veth1valid_lft forever preferred_lft foreverinet6 fe80::24ae:e5ff:fe06:6207/64 scope link valid_lft forever preferred_lft forever

从上面可以看出,我们已经成功启用了这个veth pair,并为每个veth设备分配了对应的ip地址。我们尝试在ns1中访问ns0中的ip地址:

[root@localhost ~]# ip netns exec ns1 ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.050 ms

可以看到,veth pair成功实现了两个不同Network Namespace之间的网络交互。
如果跨越空间了,那么所有的属性都会被清掉。

[root@localhost ~]# ip netns add ns2
[root@localhost ~]# ip netns list
ns2
ns1
ns0
[root@localhost ~]# ip netns exec ns2 ip link set lo up
[root@localhost ~]# ip link set veth1 netns ns2
[root@localhost ~]# ip netns exec ns2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
7: veth1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether 56:85:95:f2:cc:11 brd ff:ff:ff:ff:ff:ff link-netnsid 0

veth设备重命名

[root@localhost ~]# ip netns exec ns0 ip link set veth0 down
[root@localhost ~]# ip netns exec ns0 ip link set dev veth0 name eth0
[root@localhost ~]# ip netns exec ns0 ip link set eth0 up
[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether c6:a1:94:ea:6e:75 brd ff:ff:ff:ff:ff:ff link-netnsid 1inet 10.0.0.1/24 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::c4a1:94ff:feea:6e75/64 scope link valid_lft forever preferred_lft forever[root@localhost ~]# ip netns exec ns1 ip link set veth1 down
[root@localhost ~]# ip netns exec ns1 ip link set dev veth1 name eth0
[root@localhost ~]# ip netns exec ns1 ip link set eth0 up
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
7: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000link/ether 26:ae:e5:06:62:07 brd ff:ff:ff:ff:ff:ff link-netnsid 0inet 10.0.0.2/24 scope global eth0valid_lft forever preferred_lft foreverinet6 fe80::24ae:e5ff:fe06:6207/64 scope link valid_lft forever preferred_lft forever[root@localhost ~]# ip netns exec ns1 ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.041 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.100 ms

四种网络模式配置

bridge模式配置

[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
/ # exit
[root@localhost ~]# docker container ls    // 查看运行容器# 在创建容器时添加--network bridge与不加--network选项效果是一致的
[root@localhost ~]# docker run -it --rm --network bridge busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
/ # exit

none模式配置

不用来通信,只用来做一些简单的操作

[root@localhost ~]# docker run -it --rm --network none busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
/ # exit

container模式配置

启动第一个容器

[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever

启动第二个容器

[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ffinet 172.17.0.3/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever

可以看到第二个容器的IP地址是172.17.0.3,与第一个容器的IP地址不是一样的,也就是说并没有共享网络,此时如果我们将第二个容器的启动方式改变一下,就可以使第二个容器的IP与第一个容器的IP一致,也即共享IP,但不共享文件系统。

[root@localhost ~]# docker run -it --rm --network container:72ae8bbf0c38 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
/ # hostname 
72ae8bbf0c38

此时我们在第一个容器上创建一个目录

/ # mkdir /tmp/data
/ # ls /tmp
data

到第二个容器上检查/tmp目录会发现并没有这个目录,因为文件系统是处于隔离状态,仅仅是共享了网络而已。

/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var

在第二个容器上部署一个站点

/ # ls /var/www/
/ # echo 'test page' > /var/www/index.html
/ # /bin/httpd/ -f -h /var/www/
sh: /bin/httpd/: not found
/ # /bin/httpd -f -h /var/www/[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS         PORTS     NAMES
356a28d6a9fc   busybox   "sh"      4 minutes ago   Up 4 minutes             amazing_lichterman
72ae8bbf0c38   busybox   "sh"      9 minutes ago   Up 9 minutes             serene_wing
[root@localhost ~]# docker exec -it 356a28d6a9fc /bin/sh
/ # netstat -antl
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 :::80                   :::*                    LISTEN      
/ # exit

在第一个容器上用本地地址去访问此站点

/ # wget -O - -q 127.0.0.1
test page

由此可见,container模式下的容器间关系就相当于一台主机上的两个不同进程

host模式配置

启动容器时直接指明模式为host

[root@localhost ~]# docker run -it --rm --network host busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000link/ether 00:0c:29:a8:8f:68 brd ff:ff:ff:ff:ff:ffinet 192.168.35.135/24 brd 192.168.35.255 scope global dynamic noprefixroute ens33valid_lft 1256sec preferred_lft 1256secinet6 fe80::c7db:4c9f:7bcc:55f5/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue link/ether 02:42:13:af:55:08 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:13ff:feaf:5508/64 scope link valid_lft forever preferred_lft forever
/ # ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000link/ether 00:0c:29:a8:8f:68 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue link/ether 02:42:13:af:55:08 brd ff:ff:ff:ff:ff:ff

此时如果我们在这个容器中启动一个http站点,我们就可以直接用宿主机的IP直接在浏览器中访问这个容器中的站点了。

[root@localhost ~]# ss -antl
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128     *:22                  *:*                  
LISTEN     0      100    127.0.0.1:25                  *:*                  
LISTEN     0      128    :::22                 :::*                  
LISTEN     0      100       ::1:25                 :::*   / # echo 'hello world' > /var/www/index.html
/ # /bin/httpd -f -h /var/www/[root@localhost ~]# ss -antl
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128     *:22                  *:*                  
LISTEN     0      100    127.0.0.1:25                  *:*                  
LISTEN     0      9      :::80                 :::*                  
LISTEN     0      128    :::22                 :::*                  
LISTEN     0      100       ::1:25                 :::*   

容器的常用操作

查看容器的主机名

[root@localhost ~]# docker run -it --rm busybox
/ # hostname 
68490a8f1c4e

在容器启动时注入主机名

[root@localhost ~]# docker run -it --rm --hostname lry busybox
/ # hostname 
lry
/ # cat /etc/hostname 
lry
/ # 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.17.0.2      lry      # 注入主机名时会自动创建主机名到IP的映射关系
/ # cat /etc/resolv.conf 
# Generated by NetworkManager
search localdomain
nameserver 192.168.35.2     # DNS也会自动配置为宿主机的DNS
/ # ping www.baidu.com
PING www.baidu.com (36.152.44.95): 56 data bytes
64 bytes from 36.152.44.95: seq=0 ttl=127 time=42.348 ms
64 bytes from 36.152.44.95: seq=1 ttl=127 time=44.581 ms
64 bytes from 36.152.44.95: seq=2 ttl=127 time=42.597 ms

手动指定容器要使用的DNS

[root@localhost ~]# docker run -it --rm --hostname lry --dns 114.114.114.114 busybox
/ # hostname 
lry
/ # cat /etc/resolv.conf 
search localdomain
nameserver 114.114.114.114
/ # nslookup -type=a www.baidu.com
Server:         114.114.114.114
Address:        114.114.114.114:53Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com
Name:   www.a.shifen.com
Address: 36.152.44.96
Name:   www.a.shifen.com
Address: 36.152.44.95

手动往/etc/hosts文件中注入主机名到IP地址的映射

[root@localhost ~]# docker run -it --rm --hostname lry --dns 114.114.114.114 --add-host lry1:172.17.0.3 busybox
/ # 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.17.0.3      lry1
172.17.0.2      lry

开放容器端口

执行docker run的时候有个-p选项,可以将容器中的应用端口映射到宿主机中,从而实现让外部主机可以通过访问宿主机的某端口来访问容器内应用的目的。

-p选项能够使用多次,其所能够暴露的端口必须是容器确实在监听的端口。

-p选项的使用格式:

-p <containerPort>将指定的容器端口映射至主机所有地址的一个动态端口
-p <hostPort>:<containerPort>将容器端口<containerPort>映射至指定的主机端口<hostPort>
-p <ip>::<containerPort>将指定的容器端口<containerPort>映射至主机指定<ip>的动态端口
-p <ip>:<hostPort>:<containerPort>将指定的容器端口<containerPort>映射至主机指定<ip>的端口<hostPort>

动态端口指的是随机端口,具体的映射结果可使用docker port命令查看。

第一种 - p 的使用方式

[root@localhost ~]# docker run -d --name web --rm -p 80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
e5ae68f74026: Pull complete 
21e0df283cd6: Pull complete 
ed835de16acd: Pull complete 
881ff011f1c9: Pull complete 
77700c52c969: Pull complete 
44be98c0fab6: Pull complete 
Digest: sha256:9522864dd661dcadfd9958f9e0de192a1fdda2c162a35668ab6ac42b465f0603
Status: Downloaded newer image for nginx:latest
341c1ee1b9570401c48aab26ffb0cd9e0ac6149099bb9be25019bcc01f2549f9
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                     NAMES
341c1ee1b957   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:49153->80/tcp, :::49153->80/tcp   web

以上命令执行后会一直占用着前端,我们新开一个终端连接来看一下容器的80端口被映射到了宿主机的什么端口上

[root@localhost ~]# docker port web
80/tcp -> 0.0.0.0:49153
80/tcp -> :::49153

由此可见,容器的80端口被暴露到了宿主机的32769端口上,此时我们在宿主机上访问一下这个端口看是否能访问到容器内的站点

[root@localhost ~]# curl http://127.0.0.1:49154
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>

第二种 - p 的方式:

将容器端口映射到宿主机的指定端口

[root@localhost ~]# docker run -d --name web --rm -p 80:80 nginx   // 表示把容器里面的80映射到真机里面的80;前面80是真机的,后面80是容器的
5936ad37bb3e08877274991c88be899042eeba03555ea461e4ddda40e3e655b5

在另一个终端上查看端口映射情况

[root@localhost ~]# docker port web
80/tcp -> 0.0.0.0:80
80/tcp -> :::80

iptables防火墙规则将随容器的创建自动生成,随容器的删除自动删除规则。

第三种 - p 的方式:

将容器端口映射到指定IP的随机端口

[root@localhost ~]# docker run --name web --rm -p 192.168.35.135::80 nginx

在另一个终端上查看端口映射情况

[root@localhost ~]# docker port web
80/tcp -> 192.168.35.135:49153

第四种 - p 的方式:

将指定的容器端口映射至主机指定的端口

[root@localhost ~]# docker run -d --name web --rm -p 127.0.0.1:80:80 nginx
879c0985c813727208032f7dd1dd9b1a2570576cebc27ddf398c2df33e4252e0

在另一个终端上查看端口映射情况

[root@localhost ~]# docker port web
80/tcp -> 127.0.0.1:80

自定义docker0桥的网络属性信息

官方文档相关配置https://docs.docker.com/network/bridge/
自定义docker0桥的网络属性信息需要修改/etc/docker/daemon.json配置文件

[root@localhost ~]# vi /etc/docker/daemon.json 
{"registry-mirrors": ["https://2bkybiwf.mirror.aliyuncs.com"],"bip": "192.168.1.1/24"
}
[root@localhost ~]# systemctl restart docker[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000link/ether 00:0c:29:a8:8f:68 brd ff:ff:ff:ff:ff:ffinet 192.168.35.135/24 brd 192.168.35.255 scope global noprefixroute dynamic ens33valid_lft 1169sec preferred_lft 1169secinet6 fe80::c7db:4c9f:7bcc:55f5/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:5b:66:73:8e brd ff:ff:ff:ff:ff:ffinet 192.168.1.1/24 brd 192.168.1.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:5bff:fe66:738e/64 scope link valid_lft forever preferred_lft forever

核心选项为bip,即bridge ip之意,用于指定docker0桥自身的IP地址;其它选项可通过此地址计算得出。

docker远程连接(不常用)

dockerd守护进程的C/S,其默认仅监听Unix Socket格式的地址(/var/run/docker.sock),如果要使用TCP套接字,则需要修改/etc/docker/daemon.json配置文件

docker创建自定义桥

创建一个额外的自定义桥,区别于docker0

[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
bfef3a5a370d   bridge    bridge    local
6ceb6009fa51   host      host      local
722f6ab96f26   none      null      local
[root@localhost ~]# docker network create -d bridge --subnet "192.168.2.0/24" --gateway "192.168.2.1" br0
a298744eb8b168ee11c122a301dfd44d699c9cca7bfb9177944aae51fa7cef0e
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
a298744eb8b1   br0       bridge    local
bfef3a5a370d   bridge    bridge    local
6ceb6009fa51   host      host      local
722f6ab96f26   none      null      local

使用新创建的自定义桥来创建容器:

[root@localhost ~]# docker run -it --rm --network br0 busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
23: eth0@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:c0:a8:02:02 brd ff:ff:ff:ff:ff:ffinet 192.168.2.2/24 brd 192.168.2.255 scope global eth0valid_lft forever preferred_lft forever

再创建一个容器,使用默认的bridge桥:

[root@localhost ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
25: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever

试想一下,此时的b2与b1能否互相通信?如果不能该如何实现通信?
在这里插入图片描述

/ # hostname 
bb1a030ba094[root@localhost ~]# docker network connect br0 bb1a030ba094/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
25: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ffinet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
27: eth1@if28: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:c0:a8:02:03 brd ff:ff:ff:ff:ff:ffinet 192.168.2.3/24 brd 192.168.2.255 scope global eth1valid_lft forever preferred_lft forever
/ # ping 192.168.2.2
PING 192.168.2.2 (192.168.2.2): 56 data bytes
64 bytes from 192.168.2.2: seq=0 ttl=64 time=0.204 ms
64 bytes from 192.168.2.2: seq=1 ttl=64 time=0.069 ms
64 bytes from 192.168.2.2: seq=2 ttl=64 time=0.079 ms

相关文章:

docker容器网络配置及常用操作

Linux内核实现名称空间的创建 ip netns&#xff08;网络名称空间&#xff09;命令 可以借助ip netns命令来完成对 Network Namespace 的各种操作。ip netns命令来自于iproute安装包&#xff0c;一般系统会默认安装&#xff0c;如果没有的话&#xff0c;请自行安装。 注意&am…...

GMII(Gigabit Media Independent Interface)详解

一、GMII的定义与作用 GMII&#xff08;千兆介质无关接口&#xff09;是用于千兆以太网&#xff08;1Gbps&#xff09;的标准化接口&#xff0c;连接 MAC层&#xff08;数据链路层&#xff09;与 PHY芯片&#xff08;物理层&#xff09;。其核心目标是支持高速数据传输&#x…...

Wireshark Lua 插件教程

本⽂主要介绍 Lua 脚本在 Wireshark 中的应⽤, Lua 脚本可以在 Wireshark 中完成如下功能: 从⽹络包中提取数据, 或者统计⼀些数据包(Dumper) 需要解析⼀种 Wireshark 不提供原⽣⽀持的协议(Dissector) ⽰例 协议解析 VREP 协议是 NOGD 框架对于 TRIP 协议的⼀种延伸和扩展…...

【多模态大模型】GLM-4-Voice端到端语音交互机器人VoiceAI

写在前面&#xff1a;开源选手中最能打的 GLM-4-Voice&#xff0c;由智谱 AI 和清华大学共同研发&#xff0c;并发表论文 “GLM-4-Voice: Towards Intelligent and Human-Like End-to-End Spoken Chatbot”&#xff0c;旨在打造智能且类人化的端到端语音聊天机器人。GLM-4-Voi…...

Unity 列表滚动到指定位置

使用场景 策划提出需求&#xff1a;当玩家打开领奖界面时&#xff0c;奖励列表需要自动滑动到可以领奖的奖励栏处或者正在进行的任务栏处。 思路 1、将Content设置好对齐方式和锚点 子物体的预制体和Content&#xff1a;pivot轴心点设置为(0,1),并且设置为左上角对齐。 2、主…...

使用Crawlee可破题js渲染采集数据

使用 Crawlee 实现自动化爬虫流程 1. Crawlee 简介 Crawlee 是一个强大的爬虫框架&#xff0c;用于快速构建和维护可靠的爬虫。它支持多种爬虫类型&#xff0c;包括基于 Cheerio 和 Playwright 的爬虫&#xff0c;能够高效处理静态和动态网页。 2. 项目目标 通过自动化脚本实…...

小红的字母游戏(A组)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 小红有一个长度为 nnn 的字符串 sss&#xff0c;仅包含小写字母&#xff0c;小红可以选出 kkk 个字符&#xff0c;组成一个新的字符串 ttt&#xff0c;对于 ttt 的每一个字符 tit_it…...

MFC线程

创建线程 HANDLE m_hThread; m_hThread CreateThread(NULL, 0, save_snapshot, (LPVOID)this, 0, &iThreadId);开启线程循环等待 DWORD WINAPI save_snapshot(LPVOID pVoid) {while (true){//持续循环等待事件到达。接收到事件信号后才进入if。if (::WaitForSingleObjec…...

目标检测YOLO实战应用案例100讲-面向无人机图像的小目标检测

目录 知识储备 YOLO v8无人机拍摄视角小目标检测 数据集结构 环境部署说明 安装依赖 模型训练权重和指标可视化展示 训练 YOLOv8 PyQt5 GUI 开发 主窗口代码 main_window.py 使用说明 无人机目标跟踪 一、目标跟踪的基本原理 二、常用的目标跟踪算法 基于YOLOv…...

【Java分布式】Nacos注册中心

Nacos注册中心 SpringCloudAlibaba 也推出了一个名为 Nacos 的注册中心&#xff0c;相比 Eureka 功能更加丰富&#xff0c;在国内受欢迎程度较高。 官网&#xff1a;https://nacos.io/zh-cn/ 集群 Nacos就将同一机房内的实例划分为一个集群&#xff0c;一个服务可以包含多个集…...

VSCode轻松调试运行.Net 8.0 Web API项目

1.背景 我一直都是用VS来开发.NetCore项目的&#xff0c;用的比较顺手&#xff0c;也习惯了。看其他技术文章有介绍VS Code更轻量&#xff0c;更方便。所以我专门花时间来使用VS Code&#xff0c;看看它是如何调试代码、如何运行.Net 8.0 WebAPI项目。这篇文章是一个记录的过程…...

PageHelper新发现

PageHelper 背景解决reasonablepageSizeZero 背景 今天发现了一个很有趣的现象&#xff0c;接手一个很老的项目springmvc项目、使用PageHelper分页实现常见的后端接口分页功能。但是发现当页码参数大于实际的页码数时、正常不应该返回数据&#xff0c;但是目前确一直返回数据不…...

python编写liunx服务器登陆自动巡检脚本

前言&#xff1a; 用户需要一份用Python编写的Linux系统巡检脚本&#xff0c;检查内存、磁盘、CPU使用率&#xff0c;还有网络连通性。 首先&#xff0c;我得确定用户的使用场景。可能用户是系统管理员&#xff0c;需要定期监控服务器状态&#xff0c;确保系统正常运行。 或者…...

基于 Flink CDC YAML 的 MySQL 到 Kafka 流式数据集成

本教程的演示都将在 Flink CDC CLI 中进行&#xff0c;无需一行 Java/Scala 代码&#xff0c;也无需安装 IDE。 这篇教程将展示如何基于 Flink CDC YAML 快速构建 MySQL 到 Kafka 的 Streaming ELT 作业&#xff0c;包含整库同步、表结构变更同步演示和关键参数介绍。 准备阶段…...

数据结构——并查集

AcWing - 算法基础课 Acwing——合并集合 代码如下&#xff1a; #include <bits/stdc.h>using namespace std; #define fs first #define sc second #define endl \n #define all(x) x.begin(), x.end() typedef long long ll; typedef pair<int, int> PII;cons…...

详细解析d3dx9_27.dll丢失怎么办?如何快速修复d3dx9_27.dll

运行程序时提示“d3dx9_27.dll文件缺失”&#xff0c;通常由DirectX组件损坏或文件丢失引起。此问题可通过系统化修复方法解决&#xff0c;无需重装系统或软件。下文将详细说明具体步骤及注意事项。 一.d3dx9_27.dll缺失问题的本质解析 当系统提示“d3dx9_27.dll丢失”时&…...

【STL】4.<list>

list 前言list容器一.list初始化二.常用函数三.排序 总结 前言 stl系列主要讲述有关stl的文章&#xff0c;使用STL可以大大提高程序开发的效率和代码的可维护性&#xff0c;且在算法比赛中&#xff0c;STL可以帮助我们更方便地实现各种算法。提高我们的效率。 list容器 要使用…...

小程序中头像昵称填写

官方文档 参考小程序用户头像昵称获取规则调整公告 新的小程序版本不能通过wx.getUserProfile和wx.getUserInfo获取用户信息 <van-field label"{{Avatar}}" label-class"field-label" right-icon-class"field-right-icon-class"input-class&…...

vLLM服务设置开机自启动(Linux)

要在开机时进入指定的 conda 环境并启动此 vllm 服务&#xff0c;您可以通过以下步骤设置一个 systemd 服务来自动执行脚本。 一、第一步&#xff1a;创建一个启动脚本 1.打开终端并创建启动脚本&#xff0c;例如 /home/username/start_vllm.sh&#xff08;请替换 username 为…...

Cherno 游戏引擎笔记(91~111)

好久不见&#xff01; 个人库的地址&#xff1a;&#xff08;GitHub - JJJJJJJustin/Nut: The game_engine which learned from Cherno&#xff09;&#xff0c;可以看到我及时更新的结果。 -------------------------------Saving & Loading scene-----------------------…...

面试八股文--数据库基础知识总结(1)

1、数据库的定义 数据库&#xff08;DataBase&#xff0c;DB&#xff09;简单来说就是数据的集合数据库管理系统&#xff08;Database Management System&#xff0c;DBMS&#xff09;是一种操纵和管理数据库的大型软件&#xff0c;通常用于建立、使用和维护数据库。数据库系统…...

算法系列之动态规划

动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题&#xff0c;并存储这些子问题的解来避免重复计算&#xff0c;从而提高算法的效率。本文将介绍动态规划的基本概念、适用场景、复…...

网站漏洞安全测试 具体渗透思路分析

渗透测试这些是经常谈到的问题了&#xff0c;我觉得当有了渗透接口测试之后你就会发现渗透测试这一方面也就是&#xff1a;1.基本漏洞测试&#xff1b;2.携带"低调"构思的心血来潮&#xff1b;3.锲而不舍的信念。我们在对网站&#xff0c;APP进行渗透测试的过程中会发…...

Spring Boot(七):Swagger 接口文档

1. Swagger 简介 1.1 Swagger 是什么&#xff1f; Swagger 是一款 RESTful 风格的接口文档在线自动生成 功能测试功能软件。Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。目标是使客户端和文件系统作为服务器以同样的…...

【Mac电脑本地部署Deepseek-r1:详细教程与Openwebui配置指南】

文章目录 前言电脑配置&#xff1a;安装的Deepseek版本&#xff1a;使用的UI框架&#xff1a;体验效果展示&#xff1a;本地部署体验总结 部署过程Ollama部署拉取模型运行模型Openwebui部署运行Ollama服务在Openwebui中配置ollama的服务 后话 前言 deepseek最近火的一塌糊涂&a…...

测试的BUG分析

在了解BUG之前,我们要先了解软件测试的生命周期,因为大多数BUG都是在软件测试的过程中被发现的 软件测试的生命周期 在了解 软件测试的生命周期 之前,我们要先了解 软件的生命周期 ,虽然他们之间只差了两个字,但是差距还是很大的 首先是 软件生命周期 ,这个是站在 软件 的角…...

linux里面的过滤符号 | 是如何实现的

ls -l | grep ".txt" 的实现过程涉及无名管道的创建、进程的创建&#xff08;fork()&#xff09;以及输入输出的重定向&#xff08;dup2()&#xff09;。以下是详细的实现步骤和代码示例&#xff1a; 实现步骤 创建无名管道&#xff1a; 使用pipe()系统调用创建一个无…...

结构型模式--组合模式

概念 组合人模式是结构型设计模式的一种&#xff0c;主要是用于解决代码中出现类像树一样进行组合而出现的组合结构的相关操作问题。使其树中的任意一个节点&#xff08;无论是子节点还是父节点&#xff09;都可以使用同一套接口进行操作。 使用场景 1、如果希望我们对象组合…...

drupal可以自动将测试环境的网页部署到生产环境吗

在 Drupal 中&#xff0c;自动将测试环境的网页部署到生产环境通常是通过设置合适的开发和部署流程来实现的。这种自动化部署过程通常涉及以下几个步骤&#xff1a; 1. 版本控制&#xff08;Git&#xff09; 为了保证测试环境和生产环境的一致性&#xff0c;首先需要使用 Git…...

Android应用app实现AI电话机器人接打电话

Android应用app实现AI电话机器人接打电话 --安卓AI电话机器人 一、前言 【Dialer3.0智能拨号器】Android版手机app&#xff0c;由于采用蓝牙电话的方式来调用手机SIM卡发起呼叫、接听来电&#xff0c;并接收和处理通话的声音&#xff0c;通常我们以“蓝牙电话方案”来称呼它。 …...

【面试宝典】Java中创建线程池的几种方式以及区别

强烈推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站:人工智能 创建线程池有多种方式&#xff0c;主要通过 Java 的 java.util.concurrent 包提供的 Executors 工具类来实现。以下是几…...

【数据结构】哈希表

目录 哈希表 基本思想 基本原理 哈希表工作机制简化描述 关于查找、插入和删除 HashMap 主要成员变量 主要方法 内部实现细节 注意事项 哈希表 哈希表是一种基于哈希函数的数据结构&#xff0c;它通过键值对的形式存储数据&#xff0c;并允许通过键快速查找对应的值…...

MySQL 使用 `WHERE` 子句时 `COUNT(*)`、`COUNT(1)` 和 `COUNT(column)` 的区别解析

文章目录 1. COUNT() 函数的基本作用2. COUNT(*)、COUNT(1) 和 COUNT(column) 的详细对比2.1 COUNT(*) —— 统计所有符合条件的行2.2 COUNT(1) —— 统计所有符合条件的行2.3 COUNT(column) —— 统计某一列非 NULL 的记录数 3. 性能对比3.1 EXPLAIN 分析 4. 哪种方式更好&…...

RabbitMQ系列(一)架构解析

RabbitMQ 架构解析 RabbitMQ 是一个基于 AMQP 协议的开源消息中间件&#xff0c;其核心架构通过多组件协作实现高效、可靠的消息传递。以下是其核心组件与协作流程的详细说明&#xff1a; 一、核心组件与功能 Broker&#xff08;消息代理服务器&#xff09; RabbitMQ 服务端核…...

如何让传统制造企业从0到1实现数字化突破?

随着全球制造业不断向智能化、数字化转型&#xff0c;传统制造企业面临着前所未有的机遇与挑战。数字化转型不仅是技术的革新&#xff0c;更是管理、文化、业务流程等全方位的变革。从零开始&#xff0c;如何带领一家传统制造企业走向数字化突破&#xff0c;是许多企业领导者面…...

基于Spring Boot的二手物品交易平台设计与实现(LW+源码)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

释放 Cursor 的全部潜能:快速生成智能 Cursor Rules

释放 Cursor 的全部潜能&#xff1a;使用 PromptCoder 从 package.json 快速生成智能 Cursor Rules 我们将深入探讨如何利用您项目中的 package.json 文件&#xff0c;轻松生成 Cursor Rules&#xff0c;并通过 PromptCoder 这个强大的工具&#xff0c;快速创建高质量的 curso…...

C#高级:结合Linq的SelectMany方法实现笛卡尔积效果

一、笛卡尔积定义 又称直积&#xff0c;表示为X Y&#xff0c;第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员 二、基础示例 class Program {static void Main(string[] args){try{List<List<string>> input new List<List<string&g…...

【洛谷入门赛】B4018 游戏与共同语言

题意 这里有两个队伍分别叫 A 和 B。 分别给定这两个队伍的胜利数、净胜局、平局数量。 求哪个队更厉害&#xff0c;就输出哪个。 具体比较规则如下&#xff1a; 两队中胜利数高的队伍更厉害。 若胜利数相同&#xff0c;净胜数高的队伍更厉害。 若净胜数仍然相同&#x…...

Python学习总结

客户端与服务端聊天窗口 服务端 导入 wxPython 用于创建图形界面。 socket 用于网络通信&#xff0c;AF_INET 是 IPv4 地址族&#xff0c;SOCK_STREAM 表示流式套接字&#xff08;TCP&#xff09;。 利用wxPython 创建图形界面&#xff0c;并通过 socket 与服务器通信。 主要…...

android系统_模拟ZygoteServer写一个socket通信

目录 一,模拟ZygoteServer 二,Client 代表app 三,输出结果 四,结束语 一,模拟ZygoteServer ZygoteServer&#xff0c;不断的监听来自客户端的请求 package org.study.tiger;import java.io.*; import java.net.*; import java.util.concurrent.*;import java.io.*; impor…...

LangChain教程 - RAG - PDF问答

系列文章索引 LangChain教程 - 系列文章 在现代自然语言处理&#xff08;NLP&#xff09;中&#xff0c;基于文档内容的问答系统变得愈发重要&#xff0c;尤其是当我们需要从大量文档中提取信息时。通过结合文档检索和生成模型&#xff08;如RAG&#xff0c;Retrieval-Augment…...

李代数(Lie Algebras)与Attention:深度学习中的数学之美

李代数与Attention&#xff1a;深度学习中的数学之美 引言 作为一名深度学习研究者&#xff0c;您一定对Transformer模型和其中的注意力机制&#xff08;Attention&#xff09;不陌生。Attention通过查询&#xff08;Query&#xff09;、键&#xff08;Key&#xff09;和值&a…...

docker本地镜像源搭建

最近Deepseek大火后&#xff0c;接到任务就是帮客户装Dify&#xff0c;每次都头大&#xff0c;因为docker源不能用&#xff0c;实在没办法&#xff0c;只好自己搭要给本地源。话不多说具体如下&#xff1a; 1、更改docker的配置文件&#xff0c;添加自己的私库地址&#xff0c…...

监督学习单模型—线性模型—LASSO回归、Ridge回归

目标变量通常有很多影响因素&#xff0c;通过各类影响因素构建对目标变量的回归模型&#xff0c;能够实现对目标的预测。但根据稀疏性的假设&#xff0c;即使影响一个变量的因素有很多&#xff0c;其关键因素永远只会是少数。在这种情况下&#xff0c;还用传统的线性回归方法来…...

StableDiffusion打包 项目迁移 项目分发 1

文章目录 SD项目迁移前置知识webui-user.batwebui.batlaunch_utils.py 下一篇开始实践 SD项目迁移 显卡驱动更新&#xff1a;https://www.nvidia.cn/geforce/drivers/ 下载安装三个程序&#xff1a; python3.10.6: https://www.python.org/downloads/release/python-3106/gi…...

【C++】模板初阶

文章目录 一. 泛型编程1.1 什么是模板1.2 为什么要使用模板 二. 函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.4.1 隐式实例化2.4.2 显式实例化 2.5 模板参数的匹配原则 三. 类模板3.1 类模板的定义格式3.2 类模板的实例化3.3 在类模板外…...

STM32学习【4】ARM汇编(够用)

目录 ARM汇编语言基础写在前面 1. ARM汇编的分类2. 关于指令集指令集切换Thumb2指令集统一汇编语言&#xff08;UAL&#xff09;常用汇编指令 3. 汇编格式立即数与伪指令 4. 操作内存的汇编指令LDR&#xff1a;从内存加载数据到CPU寄存器STR&#xff1a;将数据从寄存器存储到内…...

傅里叶分析

傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析不仅仅是一个数学工具&#xff0c;更是一种可以彻底颠覆一个人以前世界观的思维模式。但不幸的是&#xff0c;傅里叶分析的公式看起来太复…...

Jmeter插件下载及安装

1、在Jmeter官网&#xff08;Install :: JMeter-Plugins.org&#xff09;下载所需插件 2、将下载的插件复制到jmeter文件下的lib/ext文件里&#xff08;PS&#xff1a;D:\Jmeter\apache-jmeter-5.6.2\lib\ext&#xff09; 3、打开Jmeter&#xff0c;选择 选项----Plugins Manag…...