Docker | 代理配置、内网共享和 Harbor 部署
唠唠闲话
在现代软件开发和运维中,容器技术已经成为构建、部署和管理应用程序的标准工具。然而,在实际操作中,我们常常需要面对一些常见的挑战,如容器访问外部资源的代理配置、内网环境下的镜像共享以及企业级镜像管理。
本教程将详细介绍三大关键内容,以便更高效地使用容器技术:
-
容器代理:在很多网络环境中,直接访问外部资源可能受到限制。我们将介绍如何进行配置,确保顺利访问互联网和外部镜像仓库。
-
默认注册表:为了在内网环境中共享镜像,我们可以搭建一个无需登录验证的简单注册表。通过这种方式,可以在团队内部方便地推送和拉取镜像,提高开发效率。
-
Harbor 注册表:对于需要更高级别管理和安全功能的企业,Harbor 是一个理想的选择。我们将详细介绍如何安装和配置 Harbor,利用其丰富的功能,提升容器镜像管理的安全性和效率。
废话不多说,下边开始吧!
容器代理
在使用 Docker 时,有时需要配置代理以便访问互联网或镜像仓库。以下是配置 Docker 代理的方法:
Linux
-
创建或编辑
/etc/systemd/system/docker.service.d/http-proxy.conf
文件:1
2sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf -
在文件中添加以下内容,替换
http://proxy.example.com:8080
和http://proxy.example.com:8080
为代理地址:1
2
3
4[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080"
Environment="HTTPS_PROXY=http://proxy.example.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com" -
重新加载系统守护进程并重启 Docker:
1
2sudo systemctl daemon-reload
sudo systemctl restart docker
Windows
-
在 PowerShell 中创建或编辑
C:\ProgramData\Docker\config\daemon.json
文件:1
notepad C:\ProgramData\Docker\config\daemon.json
-
在文件中添加代理配置:
1
2
3
4
5
6
7
8
9{
"proxies": {
"default": {
"httpProxy": "http://proxy.example.com:8080",
"httpsProxy": "http://proxy.example.com:8080",
"noProxy": "localhost,127.0.0.1,docker-registry.somecorporation.com"
}
}
} -
重启 Docker 服务:
1
Restart-Service docker
Dockerfile
如果是在构建阶段需要,可以直接在 Dockerfile 中添加环境变量,并在结尾 unset
:
1 | ENV http_proxy http://proxy.example.com:8080 |
自建镜像站
如果有国外的 vps,可以直接通过 Nginx 反向代理配置镜像站。
示例配置如下,其中 docker.example.com
替换为实际域名:
1 | server { |
然后修改 /etc/docker/daemon.json
文件,添加镜像站地址:
1 | { |
重启 Docker 服务:
1 | sudo systemctl daemon-reload |
当然,如果不方便重启 docker 可以直接添加前缀,比如拉取 hello-world
镜像:
1 | docker pull docker.example.com/library/hello-world |
默认注册表
在内网环境中共享镜像,可以搭建一个无需登录验证的简单注册表,并使用 HTTP 协议进行通信。
搭建方法
创建一个 docker-compose.yml
文件,并定义以下内容:
1 | version: '3' |
在这个配置中,我们定义了一个名为 registry
的服务,使用 Docker 官方提供的 registry:2
镜像。配置将本机的 5000 端口映射到容器的 5000 端口,通过数据卷 ./data
将注册表的数据保存到本地。restart: always
确保在容器意外停止后自动重启。
在 docker-compose.yml
文件所在的目录下,运行以下命令来启动服务:
1 | docker-compose up -d |
配置 Nginx
添加 Nginx 配置文件,以使用 https 访问注册表。参考配置:
1 | server { |
常用命令
启动服务后,可以通过以下命令管理和使用注册表。
-
给本地镜像添加标签,使其指向我们的注册表:
1
docker tag alpine registry.example.com/alpine
-
推送镜像,将标记的镜像推送到注册表:
1
docker push registry.example.com/alpine
-
拉取镜像,从注册表中拉取:
1
docker pull registry.example.com/alpine
-
查看注册表的镜像,使用
curl
命令查看注册表中已存储的镜像列表:1
curl http://registry.example.com/v2/_catalog
镜像导入导出
除了通过注册表共享容器镜像,还可以选择直接传输镜像文件,这在某些情况下可能更为便捷。
导出镜像
使用 docker save
命令将镜像导出为一个 tar 文件:
1 | docker save -o <filename>.tar <image> |
例如,将 alpine
镜像导出到 alpine.tar
文件:
1 | docker save -o alpine.tar alpine |
传输文件
使用 SCP、FTP 或其他网络文件传输方法将导出的 tar 文件从一台服务器传输到另一台服务器。例如,使用 SCP 命令:
1 | scp alpine.tar user@destination_host:/path/to/destination |
导入镜像
在目标服务器上使用 docker load
命令从 tar 文件中导入镜像:
1 | docker load -i <filename>.tar |
例如,从 alpine.tar
文件导入镜像:
1 | docker load -i alpine.tar |
这种方法可以有效地在不同服务器之间传输和共享 Docker 镜像,尤其适用于没有设置注册表或者网络条件不支持直接推送和拉取镜像的场景。
Harbor 注册表
方法概述
在选择容器注册表时,有多种选项可供选择,从简单到复杂的三种方案包括:
-
Portus:一个轻量级的 Docker 镜像仓库管理工具,适合小型团队和简单的需求。它提供了基本的镜像管理功能和用户权限控制。
-
Harbor:由 VMware 开发的开源企业级容器镜像仓库,提供了高级功能,如镜像复制、漏洞扫描、身份认证和角色管理,非常适合大中型企业的需求。
-
Nexus:一个功能强大的仓库管理工具,支持多种格式的包管理(如 Maven、NPM 等),包括 Docker 镜像。它提供了丰富的企业级功能,但配置较为复杂。
教程选择 Harbor,其有以下优点:
- 功能丰富:Harbor 提供了企业级所需的各类功能,包括镜像复制、漏洞扫描、内容签名和策略管理等。
- 易于使用:相较于 Nexus,Harbor 的配置和管理更为简便,且有详细的文档支持。
- 开源社区支持:Harbor 拥有活跃的开源社区和持续的更新维护,确保了其稳定性和安全性。
更多关于 Harbor 的信息和文档请参考 Harbor 官方文档。
下载安装包
从 Harbor 发行页 下载安装包,可以选择在线版或离线版。这里以 offline-installer
为例:
1 | wget -c https://github.com/goharbor/harbor/releases/download/v2.11.0/harbor-offline-installer-v2.11.0.tgz |
仓库还有一个 *.asc
签名文件,用于验证下载文件的完整性。
解压后的目录结构如下:
1 | harbor |
在开始安装前,我们需要编辑 harbor.yml
文件以配置必要的参数。
编辑配置文件
Harbor 提供了模板文件 harbor.yml.tmpl
。复制并修改该文件:
1 | cp harbor.yml.tmpl harbor.yml |
根据需要修改 hostname
和 http
端口。如果要启用 HTTPS,可以用 certbot
生成域名证书(参考另一篇博客 Let's Encrypt 域名证书增强网站安全),也可以选择注释掉 https
字段,在外部通过 Nginx 配置 SSL。
如果希望用 harbor 复制镜像,比如来自 docker hub 或 Github,可设置 proxy
字段:
1 | proxy: |
更详细的配置说明请参考 Harbor 官方文档。
安装
Harbor 默认安装选项不包括 Trivy,这是由 Aqua Security 开发的开源漏洞扫描器。可通过以下命令安装 Harbor 并包含 Trivy:
1 | sudo ./install.sh --with-trivy |
安装完成后,会提示:
1 | ✔ ----Harbor has been installed and started successfully.---- |
此时目录下会生成一个 docker-compose.yml
文件,可以通过 docker-compose down/up -d
来停止或启动服务。
安装完成后,可以通过配置文件中指定的端口访问 Harbor。首次登录页面如下,默认用户名为 admin
,密码参考 harbor.yml
配置。
更新配置
如果要修改 harbor.yml
对 Harbor 进行重新配置,先使用 docker-compose
停止服务,修改好文件后,运行 prepare
脚本:
1 | # cd harbor 安装目录 |
Nginx 反向代理
为了更好地管理和访问 Harbor,可以使用 Nginx 作为反向代理。以下是一个参考配置,基于 Github Issue:
1 | server{ |
基本使用
登录 Harbor 后,你可以创建自己的账号以便日常使用。
使用方式与 DockerHub 类似:
1 | # 登录账号 |
上传后在项目中查看镜像列表,如果希望免登录拉取镜像,可设置为公开。
Harbor 管理
Harbor 管理员页面提供了更多功能,包括用户管理,项目管理,镜像复制,漏洞扫描,垃圾回收,审计日志等。
镜像复制
在 Harbor 和非 Harbor 注册表之间复制资源。我们主要演示如何从 Docker Hub 复制镜像到 Harbor。
创建复制端点
使用拥有 Harbor 系统管理员权限的账号登录到 Harbor 界面。
在仓库管理中,点击新建目标:
选择镜像源
如果需要登录鉴权,可以填写 Access ID
和 Access Secret
字段。如果目标是 http 资源,可以把 Verify Remote Cert 勾选去掉。
新建复制规则
点击复制管理,新建规则:
以 OneAPI 为例,如下进行配置:
参数说明:
名称/name
:规则名称,必填,小写数字下划线组成描述/description
:规则描述复制模式/replication mode
:拉取或推送源资源过滤器/source resource filter
:可以使用通配符匹配需要拉取的资源源仓库/source registry
:上一步设置的端点,比如 dockerhub目标命名空间/source resource filter
:目标命名空间,默认放置在与源注册表中相同的命名空间中。触发模式/trigger mode
:手动或定时或事件驱动,这里选手动带宽/bandwidth
:复制带宽限制,默认无限制覆盖/override
:如果目标已有镜像,是否覆盖
如果选择了手动触发,添加规则后,在复制管理中点击复制按钮,进行复制操作,下方会显示任务及进展。
此外,名称和标签过滤器支持以下模式:
*
:匹配任何非分隔符字符序列/
。**
:匹配任何字符序列,包括路径分隔符/
。注意双星号必须作为独立路径组件出现,如/path*/**
。?
:匹配任何单个非分隔符字符/
。{alt1,…}
:匹配逗号分隔的任何一个替代项。
举个例子:
模式 | 匹配 | 不匹配 |
---|---|---|
* |
library/hello-world |
library/my/hello-world |
** |
library/hello-world, library/my/hello-world |
|
{library,goharbor}/** |
library/hello-world, goharbor/harbor-core |
google/hello-world |
1.? |
1.0 |
1.01 |
此外,触发模式支持三种类型,可根据需求选择配置:
- 手动:在需要时手动复制资源
- 计划:通过定义 cron 作业定期复制资源
- 基于事件:当新资源推送到项目或工件被重新标记时,它会立即复制到远程注册表。如果您选择“在本地删除时删除远程资源”,则当删除工件时,它会自动从复制目标中删除。
API 访问
Harbor 提供了 RESTful API,可以通过 API 访问 Harbor 的各种功能。例如,可以使用 API 创建项目、添加用户、推送和拉取镜像等。
部署后,在 https://yourdomain.com/devcenter-api-2.0
查看 API 文档,或者直接查看 swagger.yaml 文件。
1 | curl -u admin:yourpassword -X GET "https://yourdomain.com/api/v2.0/registries" | jq |
下边演示几个例子:
- 查看已添加注册表
- 添加注册表
- 查看复制规则
- 创建复制规则
- 删除复制规则
- 查看复制任务
- 启动复制任务
查看仓库注册表
命令如下:
1 | curl -u $HARBOR_USER:$HARBOR_PASSWORD -X GET "$HARBOR_HOST/api/v2.0/registries" | jq |
返回结果:
1 | [ |
添加注册表
以 Github 为例,命令如下:
1 | curl -u $HARBOR_USER:$HARBOR_PASSWORD -X POST "$HARBOR_HOST/api/v2.0/registries" -H "Content-Type: application/json" -d '{ |
如果需要验证,可以加上 credential
字段:
1 | "credential": { |
一般地,可以设置类型为 docker-registry
和自定义 URL。
查看复制规则
命令如下:
1 | curl -u $HARBOR_USER:$HARBOR_PASSWORD -X GET \ |
返回结果:
1 | [ |
创建复制规则
命令如下,其中 dest_registry
根据前边返回的结果填写:
1 | curl -u $HARBOR_USER:$HARBOR_PASSWORD -X POST -H 'Content-Type: application/json'\ |
除了 manual
触发模式,还有 scheduled
和 event_based
两种模式,比如:
1 | { |
删除复制规则
命令如下,其中 /1
为前边返回的 ID:
1 | curl -u $HARBOR_USER:$HARBOR_PASSWORD -X DELETE \ |
查看复制任务
命令如下:
1 | curl -u $HARBOR_USER:$HARBOR_PASSWORD -X GET \ |
返回结果:
1 | [ |
启动任务
命令如下,其中 policy_id
为前边返回的结果:
1 | curl -u $HARBOR_USER:$HARBOR_PASSWORD -X POST \ |