一个由于docker无法启动引起的内网代理学习

前几天给学校实验室的一台机器装docker的时候。我接连遭遇了docker无法正常启动和docker无法构建的问题。作为一名网络工程专业的同学,我意识到问题并不简单(其实也没多难…是自己大学没好好学习orz

首先排查问题,已知:

1、这台机器的系统是centos

#输入 cat /proc/version 查看当前是是linux的什么发行版
>>> cat /proc/version
Linux version 3.10.0-1160.42.2.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Tue Sep 7 14:49:57 UTC 2021

#输入 rpm -q centos-release 查看具体版本
>>>  rpm -q centos-release
centos-release-7-9.2009.1.el7.centos.x86_64

# 如果是ubuntu 
cat /etc/issue #也可用于查询centos,但是我测试是没有输出正确值

2、这台机器可以用rpm安装一些软件和curl docker的安装文件:

curl -fsSL https://get.docker.com | bash -s docker

所以网络应该是没有问题的。

但是用docker构建镜像的时候,却提示443端口 connected refused。

因为这台机器是在学院实验室内网,我第一时间确实是想到了网络代理的问题。

找问题过程确实比较艰辛,也花了一些时间。直接说解决办法吧:

首先我们需要确定是不是代理设置的问题,需要知道一些关于docker本身一些关于网络的特性:

1、Docker的***容器*** 支持的网络类型

Docker的能够实现如此强大的跨平台的特性的原因之一是它支持多种网络连接方式。

  • 桥接([default/user-specified] bridge ):比较常用。适用于一台主机上有多个container需要通信的情况。如果是生产环境,应该尽量用自定义的桥接网络

    • 查看docker支持的网络:docker network ls

    • 默认的桥接网络名:brigde

    • # 新建自定义桥接网络,网络名称为alpine-net
      docker network create --driver bridge alpine-net
      # 新建container并指定它使用哪个网络
      docker run -dit --name alpine4 --network alpine-net alpine ash
      # 为现有仓库连接网络,一个容器可以连接多个网络,就像一个机器有多个网卡
      docker network connect bridge alpine4
      # 查看网络(也可以认为是一个虚拟的网卡)alpine-net是上面创建的网卡名,查看默认桥接网络则是bridge
      docker network inspect alpine-net
      
    • 每个网络都有一个与主机通信的网关(gateway),比如172.18.0.1。 内部的container都有自己的局域网地址,比如:172.18.0.2。

  • 与主机共享网络(host):比较常用,但只有linux主机上在能使用。docker会直接监听主机相应的端口的流量。

  • 覆盖(overlay):常用在swarm集群里。

  • 虚拟mac(macvlan):希望容器有自己的物理地址。

  • 第三方网络插件(Third-party network plugins)。

  • 无网络(none):通常会有自定义的网络驱动。不能用于swarm应用。

2、Docker的 守护进程(deamon)的网络特性

需要厘清一个概念:docker本身是一个应用,我们可以用它来做各种各样的操作,例如构建镜像(docker build)、启动容器(docker run)。docker启动容器后,容器本身又成为了一个应用。容器里的网络特性和docker守护进程的网络特性是两码事。

在构建镜像时,我们可能需要从docker hub或者其他仓库拉取base镜像。这时拉取仓库用到的是守护进程的网络设置。

在容器内部,我们可能需要下载软件或者资源,此时是docker内部网络。

配置守护进程:

  • 一般情况下是修改配置文件:/etc/docker/daemon.json,适用于配置镜像、容器、存储等

  • 但是配置环境变量不能通过deamon.json来实现。配置http/https 代理 :

    •  sudo mkdir -p /etc/systemd/system/docker.service.d
       vim /etc/systemd/system/docker.service.d/http-proxy.conf
      
    • 文件内容:把proxy.example.com:80换成自己的网络代理ip和端口

       [Service]
      Environment="HTTP_PROXY=http://proxy.example.com:80"
      Environment="HTTPS_PROXY=https://proxy.example.com:80"
      

3、 如何确定本机的网络状况

有了以上的已知条件,再来看下问题。

$ docker build -f app.docker -t deepre .

报错:

Error response from daemon: Get “https://registry-1.docker.io/v2/”: dial tcp 52.20.81.6:443: connect: connection refused

docker 守护进程拉取镜像失败了,我们拉取的仓库是https服务和443端口,基本可以确定是本机http代理的问题。

查看本机代理,这个代理地址应该是从管理员那里获得的。

$ env|grep -i proxy
http_proxy=http://proxy.cse.cuhk.edu.hk:8000
https_proxy=http://proxy.cse.cuhk.edu.hk:8000

将代理加到docker的环境变量中。

docker build成功了。

然后解决容器里的apt-get无法安装软件的问题,因为apt-get不是用的全局proxy。需要在apt的配置文件里添加代理,或者每次安装时指定代理:

修改/etc/apt/apt.conf(或者/etc/envrionment),增加

Acquire::http::proxy “http://127.0.0.1:8000/”;
Acquire::ftp::proxy “ftp://127.0.0.1:8000/”;
Acquire::https::proxy “https://127.0.0.1:8000/”;

或者在命令行临时带入

在命令行后面增加-o选项

sudo apt-get -o Acquire::http::proxy="http://127.0.0.1:8000/" update

References:

https://wadmes.github.io/2019/09/17/CUHK-apt-get-proxy-problem/

https://www.cnblogs.com/yjt1993/p/10412683.html

https://medium.com/@bennyh/docker-and-proxy-88148a3f35f7


镜像打包和容器打包

镜像打包
1.镜像打包

docker save -o /root/xxx.tar
2.导入镜像

docker load -i /root/xxx.tar
容器打包
1.容器打包

docker export -o /root/xx.tar
2.导入容器

docker import xx.tar :latest


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值