解决无法从dockerhub拉取镜像

[up主专用,视频内嵌代码贴在这]

从dockerhub拉取镜像

该教程解决的是大陆用户无法从dockerhub拉取镜像的问题

使用Github Action将国外的Docker镜像转存到阿里云私有仓库,供国内服务器使用,免费易用

方案一:利用Github和阿里云拉取

1. 准备工作:

  • 登录阿里云,找到容器镜像服务,创建一个个人版实例。(第一次使用的话,会让设置访问密码。记住,后面会用)

  • 找到仓库管理-命名空间,新建一个命名空间且设置为公开

  • 不要创建镜像仓库,回到访问凭证

    1
    2
    3
    sudo docker login --username=7949*****@qq.com registry.cn-beijing.aliyuncs.com
    #7949*****@qq.com是阿里云用户名
    #registry.cn-beijing.aliyuncs.com是仓库地址

2. 配置GitHub

  • fork项目到自己的github,地址: docker_image_pusher (感谢tech-shrimp提供的工具)

  • 在fork后的项目中通过Settings->Secret and variables->Actions->New Repository secret路径,配置4个环境变量(这里已经配置好啦)
    ALIYUN_NAME_SPACE
    ALIYUN_REGISTRY
    ALIYUN_REGISTRY_PASSWORD
    ALIYUN_REGISTRY_USER

    1
    2
    3
    4
    ALIYUN_NAME_SPACE的值是k8s-liujunwei(前面步骤中创建的命名空间)
    ALIYUN_REGISTRY的值是registry.cn-beijing.aliyuncs.com(是前面的仓库地址)
    ALIYUN_REGISTRY_PASSWORD的值是访问凭证中设置的密码
    ALIYUN_REGISTRY_USER的值是自己的阿里云用户名

  • 配置要拉取的镜像 打开项目,编辑images.txt,每一行配置一个镜像,格式:name:tag 比如

    1
    2
    3
    4
    5
    6
    7
    nginx  #没有tag拉取最新版本
    #支持私库
    #k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0
    #xhofe/alist:latest
    #支持指定架构
    #--platform=linux/arm64 xiaoyaliu/alist
    nginx:1.24.0 #有tag按照指定版本拉取

  • 提交修改的文件,则会自动在Actions中创建一个workflow。等待片刻即可

  • 回到阿里云容器镜像服务控制台-镜像仓库

3. 验证拉取

1
2
3
kubectl run nginx-run --image=registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0
#--image=nginx:1.24.0 #是从dockerhub拉取镜像
#--image=registry.cn-beijing.aliyuncs.com/k8s-liujunwei/nginx:1.24.0 #从指定地址拉取,这个地址也就是阿里云的个人镜像仓库,镜像是从dockerhub同步过来的

至此教程结束!!!

方案二:利用共享科学上网

1.使用共享代理

此方法适用于自己电脑测试使用,或者局域网内的同事使用,首先在自己的电脑上安装代理软件,实现科学上网,开启代理软件的局域网共享,打开“允许来自局域网的连接” 按钮,如下图:

打开后软件会显示局域网使用的端口:

查看本地电脑的ip(也就是安装代理软件的电脑ip),我这里是192.168.0.4

接下来配置docker所在的服务器(docker拉取镜像的机器ip是192.168.0.150,和代理机器在同一个局域网内):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
[root@docker ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/docker.service.d
└─http-proxy.conf
Active: active (running) since 三 2025-03-19 10:49:16 CST; 22min ago
Docs: https://docs.docker.com
Main PID: 19672 (dockerd)
Tasks: 10
Memory: 242.4M
CGroup: /system.slice/docker.service
└─19672 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

3月 19 10:49:16 docker dockerd[19672]: time="2025-03-19T10:49:16.433001279+08:00" level=info msg="Docker daemon" commit=de5c9cf containerd-snaps...on=26.1.4
3月 19 10:49:16 docker dockerd[19672]: time="2025-03-19T10:49:16.433028733+08:00" level=info msg="Daemon has completed initialization"
3月 19 10:49:16 docker dockerd[19672]: time="2025-03-19T10:49:16.450476624+08:00" level=info msg="API listen on /run/docker.sock"
3月 19 10:49:16 docker systemd[1]: Started Docker Application Container Engine.
3月 19 10:49:51 docker dockerd[19672]: time="2025-03-19T10:49:51.388371933+08:00" level=info msg="Download failed, retrying (1/5): net/http: TLS... timeout"
3月 19 10:49:51 docker dockerd[19672]: time="2025-03-19T10:49:51.684160609+08:00" level=info msg="Download failed, retrying (1/5): net/http: TLS... timeout"
3月 19 10:49:59 docker dockerd[19672]: time="2025-03-19T10:49:59.916422548+08:00" level=info msg="Download failed, retrying (1/5): net/http: TLS... timeout"
3月 19 10:50:19 docker dockerd[19672]: time="2025-03-19T10:50:19.660466349+08:00" level=info msg="Download failed, retrying (2/5): tls: failed t...cker.com"
3月 19 10:50:20 docker dockerd[19672]: time="2025-03-19T10:50:20.930082538+08:00" level=info msg="Download failed, retrying (1/5): net/http: TLS... timeout"
3月 19 10:51:04 docker dockerd[19672]: time="2025-03-19T10:51:04.882344878+08:00" level=info msg="Download failed, retrying (1/5): EOF"
Hint: Some lines were ellipsized, use -l to show in full.

#docker机器的的ip是192.168.0.150
[root@docker ~]# ip a|grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.0.150/24 brd 192.168.0.255 scope global eth0

没有配置代理前拉取镜像是无法拉取的:
[root@docker ~]# docker pull nginx
Using default tag: latest
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

#接下来配置代理,让docker能从dockerhub上拉取镜像
1. 创建 Docker 守护进程的配置文件目录:
sudo mkdir -p /etc/systemd/system/docker.service.d

2.创建代理配置文件 (例如 http-proxy.conf):
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
#向http-proxy.conf中添加下面内容,根据自己实际情况修改代理地址和端口):
[Service]
Environment="HTTP_PROXY=http://192.168.0.4:10808/"
Environment="HTTPS_PROXY=http://192.168.0.4:10808/"
Environment="NO_PROXY=localhost,127.0.0.1,::1"

3.参数解释
#HTTP_PROXY 和 HTTPS_PROXY: 设置 HTTP 和 HTTPS 请求的代理服务器。 你的代理软件在 192.168.0.4 上运行,监听 10808 端口。
#NO_PROXY: 设置不需要通过代理的地址。通常包括本地地址和回环地址。 你可以根据需要添加其他不需要代理的地址或域名。

4.重新加载 systemd 配置并重启 Docker 服务:
sudo systemctl daemon-reload
sudo systemctl restart docker

5. 验证代理是否生效:
docker info | grep -i proxy
如果看到类似如下输出,说明代理配置成功:
[root@docker ~]# docker info | grep -i proxy
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
HTTP Proxy: http://192.168.0.4:10808/
HTTPS Proxy: http://192.168.0.4:10808/
No Proxy: localhost,127.0.0.1,::1

6.再次尝试拉取镜像(已经拉取成功):
[root@docker ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
6e909acdb790: Downloading 527.6kB
6e909acdb790: Pull complete
5eaa34f5b9c2: Pull complete
417c4bccf534: Pull complete
e7e0ca015e55: Pull complete
373fe654e984: Pull complete
97f5c0f51d43: Pull complete
c22eb46e871a: Pull complete
Digest: sha256:124b44bfc9ccd1f3cedf4b592d4d1e8bddb78b51ec2ed5056c52d3692baebc19
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

#镜像已经存在
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 53a18edff809 5 weeks ago 192MB

解释和补充说明:

  • 为什么使用 /etc/systemd/system/docker.service.d/ 目录? 这是 systemd 推荐的覆盖或扩展服务单元配置的方式。 放在此目录中的配置文件 (.conf 文件) 会被合并到原始的 docker.service 文件中,而不会直接修改原始文件。这使得配置更易于管理和升级。

  • NO_PROXY 的重要性: NO_PROXY 变量非常重要,因为它允许 Docker 守护进程直接访问本地资源 (例如本地 Docker registry 或其他内部服务) 而无需通过代理。

  • 如果你的代理需要认证: 如果你的代理需要用户名和密码,你需要将代理地址修改为 http://username:password@192.168.0.4:10808/ 的形式。

  • 有些代理软件使用SOCKS5协议: 如果你的代理软件是SOCKS5代理,将HTTP_PROXYHTTPS_PROXY设置成如下形式:

    [Service] Environment="HTTP_PROXY=socks5://192.168.0.4:10808/" Environment="HTTPS_PROXY=socks5://192.168.0.4:10808/" Environment="NO_PROXY=localhost,127.0.0.1,::1"

  • 如果问题仍然存在:

    • 确保你的代理软件正在运行,并且配置正确。
    • 检查 CentOS7 机器上的防火墙设置,确保允许访问代理服务器的端口 (10808)。
    • 检查 SELinux 设置。如果启用了 SELinux,可能需要进行调整以允许 Docker 通过代理访问网络。 最简单的临时测试方法是暂时禁用 SELinux (setenforce 0),然后再次尝试拉取镜像。 如果成功,则表明是 SELinux 阻止了连接。