前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >给自己和团队的镜像一个家: 借助Harbor搭建私有的Docker镜像中心

给自己和团队的镜像一个家: 借助Harbor搭建私有的Docker镜像中心

原创
作者头像
Mintimate
发布2023-12-16 15:32:12
7390
发布2023-12-16 15:32:12
举报
文章被收录于专栏:Mintimate's BlogMintimate's Blog

相对于传统的部署方式,一些企业和开发者团队,越来越倾向使用云原生技术。其中的容器化很关键。通过云原生技术自动化软件录制、测试、发布与部署流程非常方便。

头图!
头图!

那么? 如果我们想要进行项目容器化、软件测试和部署自动话,容器的镜像中心如何部署呢?尤其是在GitLab Pipeline和Jenkins内使用,配合内网集群,使用容器镜像中心,无需考虑外网带宽成本、速度快,简直是像吃巧克力一样丝滑

配套教程视频

本文使用腾讯云轻量应用服务器制作了对应的教程,小伙伴们可以参考教程适配进行操作:

Harbor VS Docker Registry

Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。

也就是说,相比于Docker内置Registry

  • 提供基于Web界面的图形化管理界面,操作更友好
  • 支持用户、项目和镜像的访问控制机制
  • 可以对镜像进行扫描查找漏洞,提升安全性
  • 完全支持LDAP/AD等标准化的企业用户管理
  • 可以很好地集成到CI/CD流程中
  • 提供API开放功能,便于第三方系统对接

很适合团队和中小企业使用。

自建镜像中心

有些小伙伴可能一时没想清楚为什么要自建Docker镜像中心? 直接拉取官方源或者公共镜像云镜像不就好了?

确实,如果只是个人学习或者一台只需要公共镜像的服务器,直接使用公共镜像源是比较方便。但是如果需要构建自己的产品、项目镜像、做持续迭代,就需要一处专用的镜像仓库用来存储分发:

  • 方便对产品私有镜像进行版本管理、发布与回滚,支持多环境部署;
  • 产品更新后,可以通过原子操作一键推送新镜像;
  • 镜像构建可以定制化集成到CI/CD流水线中,比如:在GitLab CI/CD的时候,使用自定义镜像直接跳过基础的依赖打包;
  • 支持自己的命名空间,和公有源中的镜像区分开来;
  • 私有源可以配置权限控制,仅开发人员可访问。

举个例子,如果你用的是GitLab的流水线,构建项目,需要Nodejs的环境呢?每次都需要:拉取Nodejs镜像 -> 更改yarn更新源 -> 安装依赖 -> 构建项目 -> 部署项目

GitLab
GitLab

但是,直接使用私有仓库,在内网互联的情况下,直接使用内网镜像提前打包好配置好的Nodejs镜像:拉取Nodejs私有镜像 -> 安装依赖 -> 构建项目 -> 部署到Docker

速度会快非常多,你甚至还可以在部署后,用自定义镜像发送消息:

流水线
流水线
微信推送结果
微信推送结果

而直接使用公共源就难以支撑上述产品镜像研发和持续交付需求。所以自建私有镜像中心是必不可少的。当然,你也可以直接购买腾讯云的私有镜像存储方案,也是一个不错的方法:

容器镜像服务
容器镜像服务

选择Harbor?

搭建Docker中心,有很多其他第三方的选择,除了上文直接购买云服务厂商的私有化方案外,还可以用其他类似私有镜像仓库方案;比如: Sonatype Nexus Repository OSS

其实Nexus也可以完成镜像中心的搭建,使用Harbor的优势在于好部署,尤其是设置SSL方面,Harbor容易得多

我现在的服务器,腾讯云内网互联就是这样:

我目前的服务器
我目前的服务器

可惜,当时没有规划好;服务器没有全部买在一个地区!

哇哇哇
哇哇哇

操作前提

首先,强烈建议配合官方文档进行操作:

尤其是关于SSL的部分,用OpenSSL进行自签,在激活Nginx HTTPS的同时,用于完成加密传输和其他设备Docker登录加密:

官方关于设置SSL的部分
官方关于设置SSL的部分

其次是服务器的配置,目前官方建议硬件上是:

配置信息

最低

推荐

CPU

2 CPU

4 CPU

内存

4 GB

8 GB

存储

40 GB

160 GB

但是我测试一下,实际上2GB内存也够个人和小型团队使用了。

在Linux服务器上的软件方面没什么好说的了,总的来说:

  1. Docker Engine: 最少需要v17.06.0-ce版本;
  2. Docker Compose: 最少需要v1.18.0版本;
  3. OpenSSL: 版本不要过低即可,可以自签证书即可,也建议自签

部署Harbor镜像

教程正式开始,本次使用的:

  • 服务器厂商: 腾讯云轻量应用服务器2C2G广州地区;
  • Linux版本是: Debian11。

安装Docker

首先是安装Docker,具体的操作,可以参考我之前介绍搭建GitLab的教程:

安装好Docker的效果:

安装Docker成功
安装Docker成功

Harbor安装包

如果你的服务器在中国大陆地区,那么我建议你下载Harbor安装包的过程中,一定选择离线安装版本。

离线安装版本内,包含所有依赖的镜像(比如: Nginx、Logger等);当然,如果你选择的是腾讯云轻量应用服务器的香港等地区,那么就无需考虑。

Harbor安装包的下载地址:Harbor Github Releases: https://github.com/goharbor/harbor/releases

下载离线安装版本的Harbor
下载离线安装版本的Harbor

解压后,内部的文件结构:

代码语言:tree
复制
harbor
├── common.sh         # 通用命令,使用install.sh驱动
├── harbor.v2.7.3.tar.gz  
├── harbor.yml.tmpl   # 配置模板
├── install.sh        # 安装脚本
├── LICENSE
└── prepare    

到此,前期的准备就完成了。

OpenSSL自签证书

为了更好的安全,我们部署的Harbor通过HTTPS来访问,需要一个SSL证书来为通信加密。防止数据被中间人截获和篡改。

使用可信证书颁发机构(CA)签发的证书,要么1年需要换一次,要么3个月需要续签名一次。可是我们的Harbor启动后,除非有安全漏洞,否则启动后,可能几年都不会做一次变更。这个时候,怎么办呢?

答案是OpenSSL自签名证书,可以一次性签十年,服务器续费不起了,证书还是有效的

大胆点,签名一个100年的,人走,证书还在~(^ω^)

缺点就是:

  • 自签证书没有第三方证书颁发机构的背书,因此浏览器和操作系统默认不信任它们。使用自签名证书时,用户在首次访问网站时通常会收到安全警告。

现在,我们开始进行证书的生成:

代码语言:shell
复制
# 生成密钥
openssl genrsa -out yourdomain.com.key 4096
# 生成公钥
openssl req -x509 -new -nodes -sha512 -days 3650 \
 -subj "/C=CN/ST=Beijing/L=Beijing/O=mintimate/OU=Personal/CN=yourdomain.com" \
 -key yourdomain.com.key \
 -out yourdomain.com.crt

解释一下公钥参数的含意:

  • -x509: 指定生成自签名X.509证书;
  • -nodes: 指定生成的私钥不加密;
  • -sha512: 指定使用SHA-512哈希算法进行签名。
  • -days 3650: 指定证书的有效期为3650天(约10年)。
  • -subj "/C=CN/ST=Beijing/L=Beijing/O=mintimate/OU=Personal/CN=yourdomain.com": 指定证书的主题信息。"C"表示国家代码(Country),"ST"表示省/州(State),"L"表示城市(Locality),"O"表示组织(Organization),"OU"表示组织单位(Organizational Unit),"CN"表示通用名称(Common Name)。
  • -key yourdomain.com.key: 指定用于签名证书的私钥文件。
  • -out yourdomain.com.crt: 指定生成的证书文件的输出路径和文件名。
生成十年有效的密钥对
生成十年有效的密钥对

根据生成的密钥和公钥,我们用来生成的证书,进而用于在服务端校验域名对应证书的匹配性;这里创建证书扩展配置文件:

代码语言:shell
复制
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=yourdomain.com
DNS.2=yourdomain
DNS.3=hostname
EOF
扩展配置文件生成
扩展配置文件生成

最后,生成对应的证书:

代码语言:shell
复制
# 生成一个签名请求
openssl req -sha512 -new \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=yourdomain.com" \
    -key yourdomain.com.key \
    -out yourdomain.com.csr

# 使用刚刚生成的CA Key签名CSR,加上刚刚的v3.ext内部参数
openssl x509 -req -sha512 -days 3650 \
    -extfile v3.ext \
    -CA ca.crt -CAkey ca.key -CAcreateserial \
    -in yourdomain.com.csr \
    -out yourdomain.com.crt

记住当前的证书地址,假设为:

  • /home/mintimate/myApplication/harbor/ssl

我们可以接下来的操作。

初始化Harbor

官方其实给了一个配置模板,就是解压后文件夹内的harbor.yml.tmpl。我们直接复制一份出来,在其基础上进行更改:

代码语言:shell
复制
cp harbor.yml.tmpl harbor.yml

之后进行更改:

初始化设置
初始化设置

需要注意,因为我准备使用宿主机上的Nginx进行反向代理Harbor,所以我这里设置了:

  • hostname: Harbor访问地址,其实和external_url差不多
  • https/port: 将Harbor对外暴露在8443端口;
  • https/certificate: 使用宿主机的SSL证书文件;
  • https/private_key: 使用宿主机的SSL密钥文件;
  • external_url: 设置通过域名docker.example.com访问。

并且,因为我们使用自己的Nginx进行反向代理Harbor,需要把http/port更改为其他地址,比如:8080、8081。

紧接着使用自带的install脚本进行初始化:

代码语言:shell
复制
sudo ./install
运行初始化脚本
运行初始化脚本

如果之前的配置都没错,那么这时候,docker容器就已经开始运行了:

运行成功
运行成功

Nginx上面可以这样配置,其实就是简单的反向代理:

代码语言:text
复制
server{
    listen 80;
    listen 443 ssl http2;
    server_name domain.com;

    #HTTP_TO_HTTPS_START
    if ($server_port !~ 443){
        rewrite ^(/.*)$ https://$host$1 permanent;
    }

    ssl_certificate    /home/mintimate/myApplication/harbor/ssl/domain.com.crt;
    ssl_certificate_key    /home/mintimate/myApplication/harbor/ssl/domain.com.key;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    add_header Strict-Transport-Security "max-age=31536000";
    error_page 497  https://$host$request_uri;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass    https://127.0.0.1:8443;  #注意这里的端口
    }
}

到此,Harbor就可以测试访问了。

访问Harbor

接下来,浏览器访问Harbor即可访问。不出意外,出现这样的SSL证书校验错误:

SSL证书校验错误
SSL证书校验错误

原因很简单,我们的SSL证书并不是专业公信机构颁发的,是我们自己使用OpenSSL进行自己签名的。浏览器以为这个证书是伪造的;不过没什么影响,照样可以加密传输,如果不放心,可以检查是不是自己签名的证书:

证书内容
证书内容

可以看到,就是我们自己签名的十年有效期证书。

因为本身就是我们自己或者团队使用,所以这样的自签就可以了。如果想要对外使用,或者不放心,也可以使用专业机构的SSL证书,代替上文内部所有自签步骤。

我们继续访问,通常情况就可以进入我们Harbor的登录界面了:

Harbor主页
Harbor主页

默认的管理员:admin;默认的密码:Harbor12345

到此,Harbor的部署就完成了。我最后再演示使用一下。

演示使用

创建项目

首先,我们在Harbor的控制台创建项目:

在Harbor内创建项目
在Harbor内创建项目

连接Harbor

在一台需要使用这个Docker镜像中心的另外一台服务器进行Docker登录;前文我们使用的是自签的HTTPS,记得把IP或域名先添加到/etc/docker/daemon.json文件中insecure-registries配置项里,用来设置Docker信任非HTTPS或非公共机构颁发SSL的registry地址。比如:

代码语言:shell
复制
{
  "insecure-registries" : ["192.168.0.100:5000", "harbor.internal.com:80"]
}

至于macOS、Windows这样Docker Desktop本质是Linux虚拟机套壳的操作,我们可以直接在Desktop软件的设置内进行操作:

Docker Desktop内操作
Docker Desktop内操作

无论上述那种情况,都记得重启Docker服务以应用配置。

最后进行连接:

代码语言:shell
复制
docker login 『domain.com』

输入自己刚刚创建的用户名和密码,如果之前设置正确就可以完成登录:

连接Harbor 成功
连接Harbor 成功

推送镜像

我们构建一个镜像试试看,这里我基于node:lts-buster镜像,构建一个包含rsync工具包的镜像,Dockerfile内:

代码语言:shell
复制
# 使用node v18.18镜像
FROM node:lts-buster

WORKDIR /app

RUN bash -c 'echo "deb http://mirrors.cloud.tencent.com/debian/ buster main non-free contrib" > /etc/apt/sources.list'
RUN bash -c 'echo "deb-src http://mirrors.cloud.tencent.com/debian/ buster main non-free contrib" >> /etc/apt/sources.list'
RUN bash -c 'echo "deb http://mirrors.cloud.tencent.com/debian/ buster-updates main non-free contrib" >> /etc/apt/sources.list'
RUN bash -c 'echo "deb-src http://mirrors.cloud.tencent.com/debian/ buster-updates main non-free contrib" >> /etc/apt/sources.list'
RUN bash -c 'echo "deb http://mirrors.cloud.tencent.com/debian/ buster-backports main non-free contrib" >> /etc/apt/sources.list'
RUN bash -c 'echo "deb-src http://mirrors.cloud.tencent.com/debian/ buster-backports main non-free contrib" >> /etc/apt/sources.list'
RUN apt update -y
RUN apt install rsync -y
构建镜像
构建镜像

打包后,使用docker images命令就可以看到我们本地的镜像:

构建完成的镜像
构建完成的镜像

最后,我们进行推送:

代码语言:shell
复制
docker tag my-node:latest doamin.com/test_demo/my-node:latest
推送构建完成的镜像
推送构建完成的镜像

推送成功后,就可以在Harbor的管理界面看到我们刚刚推送的镜像:

Harbor上的结果查看
Harbor上的结果查看

如果你也想像我一样,在GitLab的Pipeline内使用,Pipeline的鉴权,可以复制~/.docker/config.json内的内容,作为GitLab Runner的参数变量DOCKER_AUTH_CONFIG,这样流水线会自动使用DOCKER_AUTH_CONFIG完成鉴权操作,以免拉取自定义镜像失败:

GitLab内鉴权
GitLab内鉴权

升级Harbor

后续发现,Harbor官方已经发布新的版本,那么我们如何进行Harbor的升级?

升级操作,Harbor的不同版本,细节可能有所差异,建议参考官方升级步骤:

简单地说,就是先停止Harbor有关容器,之后进行备份并拉取Harbor的升级工具harbor-migrator,最后,使用高版本的Harbor完成安装。

这里不再过多赘述。

END

好啦,本次的演示就到这里。有自己的私有Docker镜像仓库可以为我们的开发和生产环境带来诸多便利。

不出意外,这篇文章是我在腾讯云社区更新的最后一篇啦;三年相伴,有缘再见。如果那一天,我的文章重新适合在社区发,或许还有回来的那一天,不然在社区拿着鼓励奖,实在不体面。

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 配套教程视频
  • Harbor VS Docker Registry
    • 自建镜像中心
      • 选择Harbor?
      • 操作前提
      • 部署Harbor镜像
        • 安装Docker
          • Harbor安装包
          • OpenSSL自签证书
          • 初始化Harbor
          • 访问Harbor
          • 演示使用
            • 创建项目
              • 连接Harbor
                • 推送镜像
                • 升级Harbor
                • END
                相关产品与服务
                轻量应用服务器
                轻量应用服务器(TencentCloud Lighthouse)是新一代开箱即用、面向轻量应用场景的云服务器产品,助力中小企业和开发者便捷高效的在云端构建网站、Web应用、小程序/小游戏、游戏服、电商应用、云盘/图床和开发测试环境,相比普通云服务器更加简单易用且更贴近应用,以套餐形式整体售卖云资源并提供高带宽流量包,将热门开源软件打包实现一键构建应用,提供极简上云体验。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档