在使用 Docker 和 Kubernetes 时,我们经常需要访问 gcr.io 和 quay.io 镜像仓库,由于众所周知的原因,这些镜像仓库在中国都无法访问,唯一能访问的是 Docker Hub,但速度也是奇慢无比。gcr.azk8s.cn 是 gcr.io 镜像仓库的代理站点,原来可以通过 gcr.azk8s.cn 访问 gcr.io 仓库里的镜像,但是目前 *.azk8s.cn 已经仅限于 Azure 中国的 IP 使用,不再对外提供服务了。国内其他的镜像加速方案大多都是采用定时同步的方式来缓存,不能保证及时更新,ustc 和七牛云等镜像加速器我都试过了,非常不靠谱,很多镜像都没有。

为了能够顺利访问 gcr.io 等镜像仓库,我们需要在墙外自己搭建一个类似于 gcr.azk8s.cn 的镜像仓库代理站点。直接反代可以保证获取到的镜像是最新最全的,比缓存靠谱多了。

1. 前提条件

  • 一台能够施展魔法的服务器(你懂得,可以直接访问 gcr.io)

  • 一个域名和域名相关的 SSL 证书(docker pull 镜像时需要验证域名证书),一般用 Let's Encrypt 就够了。

2. 代理方案

quay.ioDocker Hub 很好代理,可以直接使用 Envoy 的 host_rewrite_literal 参数(这是新版本的参数,如果你使用旧版本的 Envoy,参数应该是 host_rewrite),当 Envoy 将请求转发给上游集群时,会直接将头文件中的 host 改为指定的值。比如,如果上游集群是 quay.io,就将头文件改为 quay.io。我之前写过的 使用 Envoy 反向代理谷歌搜索 用的就是此方案。什么?你是 Envoy 小白?莫慌,我已经为你们准备了一本 Envoy 从入门到放弃 的电子书,快快扫描下方的二维码学习去吧(记得给我一个 star 哦)~~

你也可以直接打开链接:https://github.com/yangchuansheng/envoy-handbook

gcr.io 稍微有点难办,因为它在连接的时候需要二次认证,即使你通过反代服务器 pull 镜像,它还是会再次访问 gcr.io 进行验证,然后才可以通过反代服务器 pull 镜像。这就有点尴尬了,我特么要是能访问 gcr.io,还要什么反代啊。。。话说 Docker 官方不是有一个 registry 镜像吗,可以通过设置参数 remoteurl 将其作为远端仓库的缓存仓库,这样当你通过这个私有仓库的地址拉取镜像时,regiistry 会先将镜像缓存到本地存储,然后再提供给拉取的客户端(有可能这两个步骤是同时的,我也不太清楚)。我们可以先部署一个私有 registry,然后将 remoteurl 设为 https://gcr.io,最后再通过 Envoy 反代,基本上就可以了。

3. 代理配置

方案确定了之后,就可以动手配置了。还是使用我之前反复提到的方法:通过文件动态更新配置。如果你不是很清楚我在说什么,请参考 Envoy 基础教程:基于文件系统动态更新配置。这里我就直接贴配置了。

bootstrap 配置:

# envoy.yaml
node:id: node0cluster: cluster0
dynamic_resources:lds_config:path: /etc/envoy/lds.yamlcds_config:path: /etc/envoy/cds.yaml
admin:access_log_path: "/dev/stdout"address:socket_address:address: "0.0.0.0"port_value: 15001

LDS 的配置:

# lds.yaml
version_info: "0"
resources:
- "@type": type.googleapis.com/envoy.config.listener.v3.Listenername: listener_httpaddress:socket_address:address: 0.0.0.0port_value: 80filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: ingress_httpcodec_type: AUTOaccess_log:name: envoy.access_loggers.filetyped_config:"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLogpath: /dev/stdoutroute_config:name: http_routevirtual_hosts:- name: defaultdomains:- "*"routes:- match:prefix: "/"redirect:https_redirect: trueport_redirect: 443response_code: "FOUND"http_filters:- name: envoy.filters.http.router
- "@type": type.googleapis.com/envoy.config.listener.v3.Listenername: listener_httpsaddress:socket_address:address: 0.0.0.0port_value: 443listener_filters:- name: "envoy.filters.listener.tls_inspector"typed_config: {}filter_chains:- transport_socket:name: envoy.transport_sockets.tlstyped_config:"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContextcommon_tls_context:alpn_protocols: h2,http/1.1tls_certificates:- certificate_chain:filename: "/root/.acme.sh/xxx.com/fullchain.cer"private_key:filename: "/root/.acme.sh/xxx.com/xxx.com.key"filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: ingress_httpscodec_type: AUTOuse_remote_address: trueaccess_log:name: envoy.access_loggers.filetyped_config:"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLogpath: /dev/stdoutroute_config:name: https_routeresponse_headers_to_add:- header:key: Strict-Transport-Securityvalue: "max-age=15552000; includeSubdomains; preload"virtual_hosts:- name: gcrdomains:- gcr.xxx.comroutes:- match:prefix: "/"route:cluster: gcrtimeout: 600s- name: quaydomains:- quay.xxx.comroutes:- match:prefix: "/"route:cluster: quayhost_rewrite_literal: quay.io- name: dockerdomains:- docker.xxx.comroutes:- match:prefix: "/"route:cluster: dockerhubhost_rewrite_literal: registry-1.docker.iohttp_filters:- name: envoy.filters.http.routertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

友情提醒:我这里使用的是 v3 版本的 API,v2 版本的 API 即将被废弃,请奔走相告。

CDS 的配置:

# cds.yaml
version_info: "0"
resources:
- "@type": type.googleapis.com/envoy.config.cluster.v3.Clustername: gcrconnect_timeout: 1stype: strict_dnsdns_lookup_family: V4_ONLYlb_policy: ROUND_ROBINload_assignment:cluster_name: gcrendpoints:- lb_endpoints:- endpoint:address:socket_address:address: gcr.defaultport_value: 5000
- "@type": type.googleapis.com/envoy.config.cluster.v3.Clustername: dockerhubconnect_timeout: 15stype: logical_dnsdns_lookup_family: V4_ONLYdns_resolvers:socket_address:address: 8.8.8.8port_value: 53lb_policy: ROUND_ROBINload_assignment:cluster_name: dockerhubendpoints:- lb_endpoints:- endpoint:address:socket_address:address: registry-1.docker.ioport_value: 443transport_socket:name: envoy.transport_sockets.tlstyped_config:"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContextsni: registry-1.docker.io
- "@type": type.googleapis.com/envoy.config.cluster.v3.Clustername: quayconnect_timeout: 15stype: logical_dnsdns_lookup_family: V4_ONLYdns_resolvers:socket_address:address: 8.8.8.8port_value: 53lb_policy: ROUND_ROBINload_assignment:cluster_name: quayendpoints:- lb_endpoints:- endpoint:address:socket_address:address: quay.ioport_value: 443transport_socket:name: envoy.transport_sockets.tlstyped_config:"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContextsni: quay.io

各个字段的含义我实在是懒得解释,可以直接去看上面提到的电子书。

配置好了 Envoy 之后,就可以通过代理服务器拉取 Docker Hubquay.io 的镜像了。最后来解决 gcr.io 镜像的难题。

4. registry 配置

首先需要部署一个私有的 registry,如果你只有一台服务器(我想大多数人应该只会买一台吧),可以使用 docker-compose,我这里是使用 Kubernetes 部署的,首先需要准备一个部署清单:

# registry-proxy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: gcrlabels:app: gcr
spec:replicas: 1 selector:matchLabels:app: gcrtemplate:metadata:labels:app: gcrspec:nodeSelector:kubernetes.io/hostname: blog-k3s03tolerations:- key: node-role.kubernetes.io/ingressoperator: Existseffect: NoSchedulehostNetwork: false containers:- name: gcrimage: findsec/registry-proxy:latest env:- name: PROXY_REMOTE_URLvalue: https://gcr.ioports:- containerPort: 5000hostPort: 5000protocol: TCPvolumeMounts:- mountPath: /etc/localtimename: localtime- mountPath: /var/lib/registryname: registryvolumes:- name: localtimehostPath:path: /etc/localtime- name: registryhostPath:path: /var/lib/registry
---
apiVersion: v1
kind: Service
metadata:name: gcrlabels:app: gcr
spec:sessionAffinity: ClientIPselector:app: gcrports:- protocol: TCPname: httpport: 5000 targetPort: 5000

然后将其部署到 Kubernetes 集群中:

$ kubectl apply -f registry-proxy.yaml

现在再回过头来看看 Envoy 的配置中关于 gcr 的部分,先来看看 LDS

virtual_hosts:
- name: gcrdomains:- gcr.xxx.comroutes:- match:prefix: "/"route:cluster: gcrtimeout: 600s

很简单,不需要解释,再来看看 CDS:

- "@type": type.googleapis.com/envoy.config.cluster.v3.Clustername: gcrconnect_timeout: 1stype: strict_dnsdns_lookup_family: V4_ONLYlb_policy: ROUND_ROBINload_assignment:cluster_name: gcrendpoints:- lb_endpoints:- endpoint:address:socket_address:address: gcr.defaultport_value: 5000

这里的 address 使用的是 Kubernetes 集群内部域名,其他部署方式请自己斟酌。

最后,给服务器换个新内核,开启 BBR 加速不过分吧?不然你的镜像拉取仍然是龟速。

5. Docker 配置

现在你就可以通过代理服务器来拉取公共镜像了。

对于 Docker Hub 来说,只需要将 docker.io 换成 docker.xxx.com 就行了,比如你想拉取 nginx:alpine 镜像,可以使用下面的命令:

???? → docker pull docker.xxx.com/library/nginx:alpine

对于 quay.io 来说,只需要将 quay.io 换成 quay.xxx.com 就行了,比如你想拉取 quay.io/coreos/kube-state-metrics:v1.5.0 镜像,可以使用下面的命令:

???? → docker pull quay.xxx.com/coreos/kube-state-metrics:v1.5.0

对于 gcr.io 来说,只需要将 gcr.io 换成 gcr.xxx.com 就行了,比如你想拉取 gcr.io/google-containers/etcd:3.2.24 镜像,可以使用下面的命令:

???? → docker pull gcr.xxx.com/google-containers/etcd:3.2.24

当然,Docker 是可以设置 registry mirror 的,但只支持 Docker Hub。可以修改配置文件 /etc/docker/daemon.json,添加下面的内容:

{"registry-mirrors": ["https://docker.xxx.com"]
}

然后重启 Docker 服务,就可以直接拉取 Docker Hub 的镜像了,不需要显示指定代理服务器的地址,Docker 服务本身会自动通过代理服务器去拉取镜像。比如:

???? → docker pull nginx:alpine
???? → docker pull docker.io/library/nginx:alpine

Containerd 就比较简单了,它支持任意 registry 的 mirror,只需要修改配置文件 /etc/containerd/config.toml,添加如下的配置:

[plugins.cri.registry.mirrors][plugins.cri.registry.mirrors."docker.io"]endpoint = ["https://docker.xxx.com"][plugins.cri.registry.mirrors."quay.io"]endpoint = ["https://quay.xxx.com"][plugins.cri.registry.mirrors."gcr.io"]endpoint = ["http://gcr.xxx.com"]

重启 Containerd 服务后,就可以直接拉取 Docker Hubgcr.ioquay.io 的镜像了,不需要修改任何前缀,Containerd 会根据配置自动选择相应的代理 URL 拉取镜像。

6. 费用评估

好了,现在我们来评估一下这一切的费用。首先你得有一个会魔法的服务器,国内的肯定不用考虑了,必须选择国外的,而且到国内的速度还过得去的,最低最低不会低于 30 人民币/月 吧。除此之外,你还得拥有一个个人域名,这个价格不好说,总而言之,加起来肯定不会低于 30 吧,多数人肯定是下不去这个手的。没关系,我有一个更便宜的方案,我已经部署好了一切,你可以直接用我的服务,当然我也是自己买的服务器,每个月也是要花钱的,如果你真的想用,只需要每月支付 3 元,以此来保障我每个月的服务器费用。当然肯定不止你一个人,我可能还会赚点钱,但最多不允许超过 40 人,如果人数特别多,我可能会考虑加服务器。这个需要你自己考虑清楚,有意者扫描下方的二维码加入交流群:

你可能还喜欢

点击下方图片即可阅读

伪官宣:Envoy 中文指南新鲜出炉

云原生是一种信仰 ????

码关注公众号

后台回复◉k8s◉获取史上最方便快捷的 Kubernetes 高可用部署工具,只需一条命令,连 ssh 都不需要!

点击 "阅读原文" 获取更好的阅读体验!

❤️给个「在看」,是对我最大的支持❤️

彻底解决 gcr、quay、DockerHub 镜像下载难题相关推荐

  1. 彻底解决 gcr、quay、DockerHub 镜像下载难题!

    作者 | 米开朗基杨 来源 | https://mp.weixin.qq.com/s/GLXUgR75YAqFWC-SMEIkJg 前言 在使用 Docker 和 Kubernetes 时,我们经常需 ...

  2. 真◉彻底解决 gcr、quay、DockerHub 镜像下载难题!

    该文章随时会有校正更新,公众号无法更新,欢迎订阅博客查看最新内容:https://fuckcloudnative.io 前言 在使用 Docker 和 Kubernetes 时,我们经常需要访问 gc ...

  3. bclinux使用yum卡主解决方法、bclinux用rpm安装本地源方法、Failed to set locale, defaulting to C.UTF-8解决方法、bclinux镜像下载地址

    文章目录 环境说明 bclinux使用yum卡主解决方法 说明 解决方法 方法1 方法2 bclinux用rpm安装离线源 下载http包 安装http包 测试 Failed to set local ...

  4. k8s.gcr.io的镜像无法下载的问题

    https://github.com/NVIDIA/deepops/blob/master/docs/dgx-pod.md 在使用k8s的过程中,经常遇到k8s.gcr.io的镜像无法下载的问题,无意 ...

  5. 如何使用Aliyun容器镜像服务对海外gcr、quay仓库镜像进行镜像拉取构建?

    关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 本章目录: 0x00 前言简述 0x01 操作实践 原文地址: 如何使用Aliyun容器镜像服 ...

  6. 利用阿里云下载国外镜像,国内顺畅下载k8s.gcr.io的镜像

    国内顺畅下载k8s.gcr.io的镜像 1. 起因 配置kube-dns是3个k8s.gcr.io的镜像无法下载,报错如下 Error response from daemon: Get https: ...

  7. Docker发布/上传镜像到dockerhub下载/拉取镜像删除dockerhub镜像

    文章目录 一.注册dockerhub 二.安装docker 三.编写一个dockerfile打成镜像或者直接pull一个镜像 1.编写dockerfile 2.直接pull一个镜像 四.修改镜像标签 ...

  8. 两步操作解决Python3中openCV库安装难题(清华大学镜像源)

    两步操作解决Python3中openCV库安装难题 ways1:whl文件+pip安装: step1:下载whl包: 清华大学的下载库: https://mirrors.tuna.tsinghua.e ...

  9. docker设置http_proxy https_proxy解决gcr.io/kaniko-project/executor:v1.7.0之类的镜像拉取问题

    docker设置http_proxy https_proxy上网代理解决gcr.io/kaniko-project/executor:v1.7.0之类的镜像拉取问题 注意:一定要分成两行来写,不然不奏 ...

最新文章

  1. Java项目:CRM客户管理系统(java+SSM+jsp+mysql+maven)
  2. python去重语句_Python Dataframe 指定多列去重、求差集的方法
  3. linux 的 df命令:显示磁盘分区上的可用空间
  4. LeetCode 350. 两个数组的交集 II(哈希)
  5. [记录] --- linux上项目
  6. 我国高性能计算机发展,中国高性能计算机发展水平与趋势
  7. (08)FPGA时钟概念
  8. mysql 用数据库存储视频文件_如何用SQL数据库存放视频
  9. C++primer 16.1.2节练习
  10. 第四季-专题6-Linux内核子系统
  11. robocopy 备份_备份双雄!Robocopy和XXCOPY使用详解
  12. R语言—如何下载和使用包
  13. SQL Server 数据库之数据约束
  14. 规则引擎 clara-rules
  15. 设计模式之禅【适配器模式】
  16. 应用程序日志管理工具
  17. Oracle创建定时任务教程
  18. 【自动化办公】python处理PDF文件操作指南
  19. cdel调用方式解析
  20. 重庆培临创新计算机学校,高铁培训职业学校_重庆市涪陵创新计算机学校

热门文章

  1. idea translation翻译插件报-TKK错误
  2. 什么是数据湖?为什么需要数据湖?
  3. 抖音一姐直播笑唱国歌被封,网友:早就该封了!
  4. python,给定任意列表lst和一个任意值item,返回item在lst中第一次出现的位置
  5. oracle查询所有员工人数,oracle查询员工人数最少的部门
  6. 老照片修复清晰?父母以前的老照片还能修复吗?
  7. ios制作h5的桌面webapp的详解
  8. 一文了解上拉电阻和下拉电阻(一)
  9. The slave I/O thread stops because master and slave have equal MySQL server UUID
  10. canvas将彩色图片变为灰度图片理解问题