我的环境:
- OS: CentOS 7.9
- Docker:20.10.7
要想在Docker容器或者Swarm服务中使用ipv6,首先需要在Docker守护进程中启用对ipv6的支持,具体做法如下:
编辑docker守护进程的配置文件/etc/docker/daemon.json (若不存在需要手动创建该文件)
{
"experimental": true,
"ip6tables": true,
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
ipv6设置为true,启用对ipv6的支持。
fixed-cidr-v6,配置ipv6子网。
ip6tables,启用ip6tables,docker会在ip6tables中配置docker网络相关的规则链。
experimental,启用实验特性,ip6tables是docker的一个实验功能,所以需要设为true。
重载配置文件
sudo systemctl reload docker && sudo systemctl restart docker
现在你可以使用docker network create --ipv6 ... 创建一个支持ipv6的网络了。另外你也可以在启动容器时使用--ip6参数来使容器支持ipv6。
审查默认bridge网络
sudo docker network inspect bridge

可以看到已经配置成功!
接下来就可以在容器中使用ipv6了!
注意:以下演示依赖于上一步的配置
使用nginx做演示:
启动一个容器,此处并没有指定网络所以默认使用名为bridge的网络,该网络在上一步已经支持ipv6了!
docker run --name test -p 81:80 -d nginx:1.21.6
进入容器内部查看网阔配置:
$ docker exec -it test ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.156.10.2 netmask 255.255.255.0 broadcast 10.156.10.255
inet6 fe80::42:aff:fe9c:a02 prefixlen 64 scopeid 0x20<link>
inet6 2001:db8:1::242:a9c:a02 prefixlen 64 scopeid 0x0<global>
ether 02:42:0a:9c:0a:02 txqueuelen 0 (Ethernet)
RX packets 3923 bytes 9184337 (8.7 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2836 bytes 192127 (187.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
容器内部已经分配了一个ipv6地址!
在上一步容器已经有一个ipv6地址了,但是如果宿主机没有一个合适的ipv6地址还是不能通过ipv6与宿主机通信。比如下面我用的宿主机网络配置:
$ ifconfig ens192
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.30.72 netmask 255.255.0.0 broadcast 192.168.255.255
inet6 fe80::54f2:a4e2:f5cc:711a prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c7:26:f5 txqueuelen 1000 (Ethernet)
RX packets 38098236 bytes 6981689290 (6.5 GiB)
RX errors 0 dropped 3567426 overruns 0 frame 0
TX packets 953026 bytes 578286181 (551.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
尽管该接口有一个ipv6地址fe80::54f2:a4e2:f5cc:711a但是它是本地链路上的私有地址(fe80开头的地址属于私有地址)。私有地址是允许在本地链路上使用,且数据包不会跨链路转发。
所以,容器要想和宿主机通信,宿主机必须有一个非私有ipv6地址,如果默认没有就需要手动配置一个:
编辑网络接口配置文件/etc/sysconfig/network-scripts/ifcfg-ifName,例如我的测试宿主机网卡名称为ens192,那就编辑/etc/sysconfig/network-scripts/ifcfg-ens192:
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6_DEFROUTE=yes
IPV6_PRIVACY=no
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
IPV6ADDR=2018::27
NAME=ens192
UUID=08b8bead-340c-4708-8656-2af2394a7c1c
DEVICE=ens192
ONBOOT=yes
IPADDR=192.168.30.72
PREFIX=16
GATEWAY=192.168.30.1
DNS1=223.5.5.5
保存,执行网络服务重启:
sudo systemctl restart network
查看网卡配置:
$ ifconfig ens192
ens192: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.30.72 netmask 255.255.0.0 broadcast 192.168.255.255
inet6 2018::27 prefixlen 64 scopeid 0x0<global>
inet6 fe80::54f2:a4e2:f5cc:711a prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:c7:26:f5 txqueuelen 1000 (Ethernet)
RX packets 38106119 bytes 6982319769 (6.5 GiB)
RX errors 0 dropped 3568059 overruns 0 frame 0
TX packets 953451 bytes 578328655 (551.5 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
再次进行容器内ping宿主机:
$ sudo docker exec -it test ping6 2018::27
PING 2018::27(2018::27) 56 data bytes
64 bytes from 2018::27: icmp_seq=1 ttl=64 time=0.135 ms
64 bytes from 2018::27: icmp_seq=2 ttl=64 time=0.137 ms
64 bytes from 2018::27: icmp_seq=3 ttl=64 time=0.145 ms
64 bytes from 2018::27: icmp_seq=4 ttl=64 time=0.137 ms
64 bytes from 2018::27: icmp_seq=5 ttl=64 time=0.152 ms
^C
--- 2018::27 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.135/0.141/0.152/0.006 ms
已经通了!
以下操作也须在docker引擎开启ipv6下进行。
对于版本2的编排文件,可以直接在networks配置节点下启用ipv6,下面是个例子:
version: '2'
# 其他services定义省略。。。
networks:
example:
enable_ipv6: true
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"
ipam:
config:
- subnet: 172.23.0.0/16
- subnet: "2607:f0d0:1002:51:4000::/66"
对于版本3的编排文件,无法像上边那样直接在编排文件中配置网络并开启ipv6,需要按照下面的方式进行:
首先需要通过命令行创建一个网络并启用ipv6:
$ sudo docker network create -d bridge \
--ipv6 --subnet 2001:db8:1::1/64 \
--subnet 10.156.11.0/24 extnetwork
通过上面的命令创建了一个子网为2001:db8:1::1/64的名字为extnetwork的ipv6网络且支持ipv4。
编排文件:
version: '3'
services:
app:
image: app:7.16.1
container_name: app
restart: always
privileged: true
networks:
- extnetwork
#省略其他服务。。。
networks:
extnetwork:
external: true
在启用Rack::Deflater来gzip我的响应主体时偶然发现了一些奇怪的东西。也许我遗漏了一些东西,但启用此功能后,响应被压缩,但是资源的ETag在每个请求上都会发生变化。这会强制应用程序每次都响应,而不是发送304。这在没有启用Rack::Deflater的情况下有效,我已经验证页面源没有改变。我正在运行一个使用thin作为Web服务器的Rails应用程序。Gemfile.lockhttps://gist.github.com/2510816有没有什么方法可以让我从Rack中间件获得更多的输出,这样我就可以看到发生了什么?提前致谢。 最佳答案
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我已经按照https://github.com/wayneeseguin/rvm#installation上的说明通过RVM安装了Ruby.有关信息,我有所有文件(readline-5.2.tar.gz、readline-6.2.tar.gz、ruby-1.9.3-p327.tar.bz2、rubygems-1.8.24.tgz、wayneeseguin-rvm-stable.tgz和yaml-0.1.4.tar.gz)在~/.rvm/archives目录中,我不想在任何目录中重新下载它们方式。当我这样做时:sudo/usr/bin/apt-getinstallbuild-essent
我的Ruby-on-Rails项目中有以下文件结构,用于规范:/spec/msd/serviceservice_spec.rb/support/my_modulerequests_stubs.rb我的request_stubs.rb有:moduleMyModule::RequestsStubsmodule_functiondeflist_clientsurl="dummysite.com/clients"stub_request(:get,url).to_return(status:200,body:"clientsbody")endend在我的service_spec.rb我有:re
Ruby是否支持(找不到更好的词)非转义(逐字)字符串?就像在C#中一样:@"c:\ProgramFiles\"...或者在Tcl中:{c:\ProgramFiles\} 最佳答案 是的,您需要在字符串前加上%前缀,然后是描述其类型的单个字符。你想要的是%q{c:\programfiles\}。镐书很好地涵盖了这一点here,部分是通用分隔输入。 关于ruby-Ruby是否支持逐字字符串?,我们在StackOverflow上找到一个类似的问题: https:/
我正在编写一个Rubygem,在我的代码中使用{key:'value'}哈希语法。我的测试都在1.9.x中通过,但我(可以理解)在1.8.7中得到syntaxerror,unexpected':',expecting')'。是否有支持1.8.x的最佳实践?我是否需要使用我们的老friend=>重写代码,还是有更好的策略? 最佳答案 我认为你运气不好,如果你想支持1.8,那么你必须使用=>。像往常一样,我会提到在1.9的某些情况下您必须使用=>:如果键不是一个符号。请记住,任何对象(符号、字符串、类、float……)都可以是Ruby哈
我正在尝试使用docker运行一个Rails应用程序。通过github的sshurl安装的gem很少,如下所示:Gemfilegem'swagger-docs',:git=>'git@github.com:xyz/swagger-docs.git',:branch=>'my_branch'我在docker中添加了keys,它能够克隆所需的repo并从git安装gem。DockerfileRUNmkdir-p/root/.sshCOPY./id_rsa/root/.ssh/id_rsaRUNchmod700/root/.ssh/id_rsaRUNssh-keygen-f/root/.ss
在Rails中,什么是集成更新模型某些元素的UDP监听过程的最佳方式(特别是它将向其中一个表添加行)。简单的答案似乎是在同一个进程中使用UDP套接字对象启动一个线程,但我什至不清楚我应该在哪里做适合Rails方式的事情。有没有一种巧妙的方法来开始收听UDP?具体来说,我希望能够编写一个UDPController并在每个数据报消息上调用一个特定的方法。理想情况下,我希望避免在UDP上使用HTTP(因为它会浪费一些在这种情况下非常宝贵的空间),但我完全控制消息格式,因此我可以为Rails提供它需要的任何信息。 最佳答案 Rails是一个
出于某种原因,我必须为Firefox禁用javascript(手动,我们按照提到的步骤执行http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript)。使用Ruby的SeleniumWebDriver如何实现这一点? 最佳答案 是的,这是可能的。而是另一种方式。您首先需要查看链接Selenium::WebDriver::Firefox::Profile#[]=
我在Heroku上构建了一个必须在Docker容器内运行的RoR应用程序。为此,我使用officialDockerfile.因为它在Heroku中很常见,所以我需要一些附加组件才能使这个应用程序完全运行。在生产中,变量DATABASE_URL在我的应用程序中可用。但是,如果我尝试其他一些使用环境变量(在我的例子中是Mailtrap)的加载项,变量不会在运行时复制到实例中。所以我的问题很简单:如何让docker实例在Heroku上执行时知道环境变量?您可能会问,我已经知道我们可以在docker-compose.yml中指定一个environment指令。我想避免这种情况,以便能够通过项目