前言
Docker用起来非常爽,尤其是用于DevOps实践时。但是,当你在国内或者本地拉取镜像时,经常会碰到各种“便秘”——要么镜像拉取缓慢,要么时断时连,要么连接超时!
当我们的镜像又比较大时(比如某人在代码里面丢了个魔兽争霸的包),这简直是一个噩梦!那么如何解决这个问题?接下来我们就主要从以下几个方面来解决这个问题:
- 使用镜像加速器
- 换源
- 自己做镜像推送到国内仓库
- 自己搭建就近镜像仓库
- 最后的绝招(保密)
镜像加速器
玩网游卡都可以祭出加速器,镜像拉取通用有相关的加速器。国内的云厂商基本上都提供了镜像加速器:
Docker Hub 镜像加速器列表
镜像加速器 | 镜像加速器地址 | 专属加速器 | 其它加速 |
---|---|---|---|
Docker 中国官方镜像 | https://registry.docker-cn.com |
Docker Hub | |
DaoCloud 镜像站 | http://f1361db2.m.daocloud.io |
可登录,系统分配 | Docker Hub |
Azure 中国镜像 | https://dockerhub.azk8s.cn |
Docker Hub、GCR、Quay | |
科大镜像站 | https://docker.mirrors.ustc.edu.cn |
Docker Hub、GCR、Quay | |
阿里云 | https://.mirror.aliyuncs.com |
需登录,系统分配 | Docker Hub |
七牛云 | https://reg-mirror.qiniu.com |
Docker Hub、GCR、Quay | |
网易云 | https://hub-mirror.c.163.com |
Docker Hub | |
腾讯云 | https://mirror.ccs.tencentyun.com |
Docker Hub |
如何使用镜像加速器呢?
Docker Hub 镜像加速器配置
Linux系统可以执行以下Shell:
配置了之后,可以通过“docker info”命令来查看是否生效:
如果是Windows 10呢?可以在如下图所示的界面处配置:
换源
加速器用起来非常爽,但是很多时候某些镜像就算是配置了加速器也不好使(可能和加速器的国际带宽有关系),这个时候就必须换源了。毕竟加速器不是万能的,尤其是当你的镜像比较大的时候。这时候你就要找合适的源了。
比如.NET Core 的SDK镜像,我们可以统一使用Azure中国的镜像源,如下表所示,我们看到“mcr.microsoft.com”在国内对应的代理为“mcr.azk8s.cn”:
global | proxy in China | format | example |
---|---|---|---|
dockerhub (docker.io) | dockerhub.azk8s.cn | dockerhub.azk8s.cn//: |
dockerhub.azk8s.cn/microsoft/azure-cli:2.0.61 dockerhub.azk8s.cn/library/nginx:1.15
|
gcr.io | gcr.azk8s.cn | gcr.azk8s.cn//: |
gcr.azk8s.cn/google_containers/hyperkube-amd64:v1.13.5 |
quay.io | quay.azk8s.cn | quay.azk8s.cn//: |
quay.azk8s.cn/deis/go-dev:v1.10.0 |
mcr.microsoft.com | mcr.azk8s.cn | mcr.azk8s.cn//: |
mcr.azk8s.cn/oss/kubernetes/hyperkube:v1.15.7 |
因此,我们可以使用“mcr.azk8s.cn”来替代官方提供的“mcr.microsoft.com”源:
# docker pull mcr.microsoft.com/dotnet/core/sdk:2.2-stretch docker pull mcr.azk8s.cn/dotnet/core/sdk:2.2-stretch
如上述代码所示,我们将Azure国际的源换成了Azure中国的源,拉包速度就会飞快。换源了,意味着我们也需要将Dockerfile的命令也进行修改:
#FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build #修改为Azure中国镜像 FROM mcr.azk8s.cn/dotnet/core/sdk:2.2-stretch AS build
自己做镜像推送到国内仓库
有源的还还说,要是没源怎么办?那总不能凉拌吧?那就自己做吧。可以基于GitHub托管,Azure DevOps和Docker hub进行海外构建,然后将镜像推送到国内的镜像仓库之中。如下面这个开源库,用于构建项目中使用的aspnetcore的运行时公共基础镜像,同时提供了腾讯云公共镜像和Docker Hub公共镜像以供国内外使用:
https://github.com/xin-lai/aspnetcore-docker
相关镜像标签说明
标签名称 | 说明 |
---|---|
latest | 最新镜像,当前为3.1 |
2.2 | Asp.Net Core Runtime 2.2 |
2.2withfonts | Asp.Net Core Runtime 2.2 (包含字体) |
3.0 | Asp.Net Core Runtime 3.0 |
3.1 | Asp.Net Core Runtime 3.1 |
然后,仅需在Dockerfile中替换为自己的源即可,即可享受快的飞起:
#说明见:https://github.com/xin-lai/aspnetcore-docker FROM ccr.ccs.tencentyun.com/magicodes/aspnetcore-runtime:2.2withfonts AS base
这里分享一个技巧:Linux下使用apt装包很多时候非常缓慢而且不靠谱,有时候换成国内的代理也很不靠谱,这时候可以考虑使用海外构建,做成镜像。
自己搭建就近镜像仓库
服务器带宽不行,本地网络不佳,怎么办?还能怎么办,自己搭建仓库吧。这里推荐使用nexus,nexus可以托管各种包,包括Docker、Nuget、Jar、npm、Bower等等包,简直不要太犀利了。如何搭建?Yaml常考如下:
apiVersion: apps/v1beta2 kind: Deployment metadata: labels: k8s-app: nexus name: nexus namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: k8s-app: nexus strategy: type: Recreate template: metadata: labels: k8s-app: nexus spec: containers: - image: sonatype/nexus3 imagePullPolicy: IfNotPresent name: nexus resources: limits: cpu: "2" memory: 5024Mi requests: cpu: 10m memory: 256Mi volumeMounts: - mountPath: /nexus-data name: data restartPolicy: Always nodeName: k8s-node1 #强制约束将Pod调度到指定的Node节点上 terminationGracePeriodSeconds: 30 #Pod结束时等待时长(单位为秒) volumes: - name: data hostPath: #使用主机目录 path: /var/nexus hostNetwork: true --- apiVersion: v1 kind: Service metadata: name: nexus namespace: default spec: ports: - name: tcp-8081-8081 nodePort: 30081 port: 8081 protocol: TCP targetPort: 8081 - name: tcp-8082-8082 nodePort: 30082 port: 8082 protocol: TCP targetPort: 8082 - name: tcp-8083-8083 nodePort: 30083 port: 8083 protocol: TCP targetPort: 8083 - name: tcp-8084-8084 nodePort: 30084 port: 8084 protocol: TCP targetPort: 8084 - name: tcp-8085-8085 nodePort: 30085 port: 8085 protocol: TCP targetPort: 8085 - name: tcp-8086-8086 nodePort: 30086 port: 8086 protocol: TCP targetPort: 8086 selector: k8s-app: nexus sessionAffinity: None type: NodePort
最后的绝招
还不行,用U盘复制吧。别说认识我。你不信可以通过U盘复制?可以去了解下以下两个命令:
- docker save
- docker load