您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎樣徹底解決 gcr、quay、DockerHub 鏡像下載難題,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
在使用 Docker 和 Kubernetes 時(shí),我們經(jīng)常需要訪問 gcr.io
和 quay.io
鏡像倉庫,由于眾所周知的原因,這些鏡像倉庫在中國都無法訪問,唯一能訪問的是 Docker Hub,但速度也是奇慢無比。gcr.azk8s.cn
是 gcr.io
鏡像倉庫的代理站點(diǎn),原來可以通過 gcr.azk8s.cn
訪問 gcr.io 倉庫里的鏡像,但是目前 *.azk8s.cn
已經(jīng)僅限于 Azure
中國的 IP 使用,不再對外提供服務(wù)了。國內(nèi)其他的鏡像加速方案大多都是采用定時(shí)同步的方式來緩存,不能保證及時(shí)更新,ustc 和七牛云等鏡像加速器我都試過了,非常不靠譜,很多鏡像都沒有。
為了能夠順利訪問 gcr.io
等鏡像倉庫,我們需要在墻外自己搭建一個(gè)類似于 gcr.azk8s.cn
的鏡像倉庫代理站點(diǎn)。直接反代可以保證獲取到的鏡像是最新最全的,比緩存靠譜多了。
一臺(tái)能夠施展魔法的服務(wù)器(你懂得,可以直接訪問 gcr.io)
一個(gè)域名和域名相關(guān)的 SSL 證書(docker pull 鏡像時(shí)需要驗(yàn)證域名證書),一般用 Let's Encrypt 就夠了。
quay.io
和 Docker Hub
很好代理,可以直接使用 Envoy
的 host_rewrite_literal 參數(shù)(這是新版本的參數(shù),如果你使用舊版本的 Envoy,參數(shù)應(yīng)該是 host_rewrite),當(dāng) Envoy 將請求轉(zhuǎn)發(fā)給上游集群時(shí),會(huì)直接將頭文件中的 host
改為指定的值。比如,如果上游集群是 quay.io,就將頭文件改為 quay.io
。我之前寫過的 使用 Envoy 反向代理谷歌搜索 用的就是此方案。什么?你是 Envoy 小白?莫慌,我已經(jīng)為你們準(zhǔn)備了一本 Envoy 從入門到放棄 的電子書,快快點(diǎn)擊下方的鏈接學(xué)習(xí)去吧(記得給我一個(gè) star 哦)~~
https://github.com/yangchuansheng/envoy-handbook
gcr.io
稍微有點(diǎn)難辦,因?yàn)樗谶B接的時(shí)候需要二次認(rèn)證,即使你通過反代服務(wù)器 pull 鏡像,它還是會(huì)再次訪問 gcr.io
進(jìn)行驗(yàn)證,然后才可以通過反代服務(wù)器 pull 鏡像。這就有點(diǎn)尷尬了,我特么要是能訪問 gcr.io,還要什么反代啊。。。話說 Docker 官方不是有一個(gè) registry
鏡像嗎,可以通過設(shè)置參數(shù) remoteurl
將其作為遠(yuǎn)端倉庫的緩存?zhèn)}庫,這樣當(dāng)你通過這個(gè)私有倉庫的地址拉取鏡像時(shí),regiistry 會(huì)先將鏡像緩存到本地存儲(chǔ),然后再提供給拉取的客戶端(有可能這兩個(gè)步驟是同時(shí)的,我也不太清楚)。我們可以先部署一個(gè)私有 registry,然后將 remoteurl
設(shè)為 https://gcr.io
,最后再通過 Envoy 反代,基本上就可以了。
方案確定了之后,就可以動(dòng)手配置了。還是使用我之前反復(fù)提到的方法:通過文件動(dòng)態(tài)更新配置。如果你不是很清楚我在說什么,請參考 Envoy 基礎(chǔ)教程:基于文件系統(tǒng)動(dòng)態(tài)更新配置。這里我就直接貼配置了。
bootstrap
配置:
# envoy.yaml node: id: node0 cluster: cluster0 dynamic_resources: lds_config: path: /etc/envoy/lds.yaml cds_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.Listener name: listener_http address: socket_address: address: 0.0.0.0 port_value: 80 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http codec_type: AUTO access_log: name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog path: /dev/stdout route_config: name: http_route virtual_hosts: - name: default domains: - "*" routes: - match: prefix: "/" redirect: https_redirect: true port_redirect: 443 response_code: "FOUND" http_filters: - name: envoy.filters.http.router - "@type": type.googleapis.com/envoy.config.listener.v3.Listener name: listener_https address: socket_address: address: 0.0.0.0 port_value: 443 listener_filters: - name: "envoy.filters.listener.tls_inspector" typed_config: {} filter_chains: - transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext common_tls_context: alpn_protocols: h3,http/1.1 tls_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_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_https codec_type: AUTO use_remote_address: true access_log: name: envoy.access_loggers.file typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog path: /dev/stdout route_config: name: https_route response_headers_to_add: - header: key: Strict-Transport-Security value: "max-age=15552000; includeSubdomains; preload" virtual_hosts: - name: gcr domains: - gcr.xxx.com routes: - match: prefix: "/" route: cluster: gcr timeout: 600s - name: quay domains: - quay.xxx.com routes: - match: prefix: "/" route: cluster: quay host_rewrite_literal: quay.io - name: docker domains: - docker.xxx.com routes: - match: prefix: "/" route: cluster: dockerhub host_rewrite_literal: registry-1.docker.io http_filters: - name: envoy.filters.http.router typed_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.Cluster name: gcr connect_timeout: 1s type: strict_dns dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: gcr endpoints: - lb_endpoints: - endpoint: address: socket_address: address: gcr.default port_value: 5000 - "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster name: dockerhub connect_timeout: 15s type: logical_dns dns_lookup_family: V4_ONLY dns_resolvers: socket_address: address: 8.8.8.8 port_value: 53 lb_policy: ROUND_ROBIN load_assignment: cluster_name: dockerhub endpoints: - lb_endpoints: - endpoint: address: socket_address: address: registry-1.docker.io port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: registry-1.docker.io - "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster name: quay connect_timeout: 15s type: logical_dns dns_lookup_family: V4_ONLY dns_resolvers: socket_address: address: 8.8.8.8 port_value: 53 lb_policy: ROUND_ROBIN load_assignment: cluster_name: quay endpoints: - lb_endpoints: - endpoint: address: socket_address: address: quay.io port_value: 443 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext sni: quay.io
各個(gè)字段的含義我實(shí)在是懶得解釋,可以直接去看上面提到的電子書。
配置好了 Envoy 之后,就可以通過代理服務(wù)器拉取 Docker Hub
和 quay.io
的鏡像了。最后來解決 gcr.io 鏡像的難題。
首先需要部署一個(gè)私有的 registry,如果你只有一臺(tái)服務(wù)器(我想大多數(shù)人應(yīng)該只會(huì)買一臺(tái)吧),可以使用 docker-compose
,我這里是使用 Kubernetes 部署的,首先需要準(zhǔn)備一個(gè)部署清單:
# registry-proxy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: gcr labels: app: gcr spec: replicas: 1 selector: matchLabels: app: gcr template: metadata: labels: app: gcr spec: nodeSelector: kubernetes.io/hostname: blog-k3s03 tolerations: - key: node-role.kubernetes.io/ingress operator: Exists effect: NoSchedule hostNetwork: false containers: - name: gcr image: findsec/registry-proxy:latest env: - name: PROXY_REMOTE_URL value: https://gcr.io ports: - containerPort: 5000 hostPort: 5000 protocol: TCP volumeMounts: - mountPath: /etc/localtime name: localtime - mountPath: /var/lib/registry name: registry volumes: - name: localtime hostPath: path: /etc/localtime - name: registry hostPath: path: /var/lib/registry --- apiVersion: v1 kind: Service metadata: name: gcr labels: app: gcr spec: sessionAffinity: ClientIP selector: app: gcr ports: - protocol: TCP name: http port: 5000 targetPort: 5000
然后將其部署到 Kubernetes 集群中:
$ kubectl apply -f registry-proxy.yaml
現(xiàn)在再回過頭來看看 Envoy 的配置中關(guān)于 gcr
的部分,先來看看 LDS
:
virtual_hosts: - name: gcr domains: - gcr.xxx.com routes: - match: prefix: "/" route: cluster: gcr timeout: 600s
很簡單,不需要解釋,再來看看 CDS:
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster name: gcr connect_timeout: 1s type: strict_dns dns_lookup_family: V4_ONLY lb_policy: ROUND_ROBIN load_assignment: cluster_name: gcr endpoints: - lb_endpoints: - endpoint: address: socket_address: address: gcr.default port_value: 5000
這里的 address
使用的是 Kubernetes 集群內(nèi)部域名,其他部署方式請自己斟酌。
最后,給服務(wù)器換個(gè)新內(nèi)核,開啟 BBR
加速不過分吧?不然你的鏡像拉取仍然是龜速。
現(xiàn)在你就可以通過代理服務(wù)器來拉取公共鏡像了。
對于 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
當(dāng)然,Docker 是可以設(shè)置 registry mirror
的,但只支持 Docker Hub
??梢孕薷呐渲梦募?/etc/docker/daemon.json
,添加下面的內(nèi)容:
{ "registry-mirrors": [ "https://docker.xxx.com" ] }
然后重啟 Docker 服務(wù),就可以直接拉取 Docker Hub 的鏡像了,不需要顯示指定代理服務(wù)器的地址,Docker 服務(wù)本身會(huì)自動(dòng)通過代理服務(wù)器去拉取鏡像。比如:
???? → 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
服務(wù)后,就可以直接拉取 Docker Hub
、gcr.io
和 quay.io
的鏡像了,不需要修改任何前綴,Containerd 會(huì)根據(jù)配置自動(dòng)選擇相應(yīng)的代理 URL 拉取鏡像。
上述內(nèi)容就是怎樣徹底解決 gcr、quay、DockerHub 鏡像下載難題,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。