V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zzlyzq
V2EX  ›  分享发现

搭建运维用 harbor,镜像接龙,方便运维

  •  
  •   zzlyzq · 82 天前 · 1791 次点击
    这是一个创建于 82 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前一阵子搭建了一个 harbor 镜像仓库,并且写了搬砖脚本,只是提供一些运维用的到的镜像仓库。

    如果大家有需要,可以试试。

    如果需要一些运维工作相关的镜像,可以留言,我会及时同步。

    镜像仓库地址:

    harbor.op123.ren:44301
    
    

    修改 docker 配置:

    cat <<'EOF'>/etc/docker/daemon.json
    {
      "debug": false,
      "experimental": true,
      "registry-mirrors": [ "https://harbor.op123.ren:44301" ]
    }
    EOF
    
    
    systemctl daemon-reload
    systemctl restart docker
    
    

    如此一来,既方便大家使用,也可以丰富仓库内容。让运维工作更顺畅自然。

    第 1 条附言  ·  82 天前
    22 条回复    2024-08-19 13:44:55 +08:00
    Niphor
        1
    Niphor  
       82 天前
    可否让大家参考参考搬运脚本
    主要是支持多架构的镜像怎么搬运,网上的脚本是一个个架构拉,OP 的有没有什么简便方法?
    zzlyzq
        2
    zzlyzq  
    OP
       82 天前
    @Niphor

    这个脚本我命名为 dockerpullandpush.py ,部署在 hk 的小鸡上,通过输入参数镜像名称,实现从 dockerhub 拉取,并 push 到国内的 harbor 站点。如果 harbor 站点没有对应的 repository ,也会自动创建。以下脚本修改了 dockerhubu 和自建 harbor 的密码,改成自己的就可以用了。

    #!/usr/bin/python3
    import docker
    import argparse
    import subprocess
    import json

    def pull_and_push_image(image_name, docker_username, docker_password, harbor_url, harbor_username, harbor_password):
    # 从 image_name 中提取 harbor_project
    if '/' in image_name:
    harbor_project = image_name.split('/')[0]
    image_name_without_project = '/'.join(image_name.split('/')[1:])
    else:
    harbor_project = 'library'
    image_name_without_project = image_name

    # 创建 Docker 客户端
    client = docker.from_env()

    # 登录 Docker Hub
    client.login(username=docker_username, password=docker_password)

    # 拉取镜像
    print(f"Pulling image {image_name} from Docker Hub...")
    image = client.images.pull(image_name)

    # 标记镜像
    harbor_image_name = f"{harbor_url}/{harbor_project}/{image_name_without_project}"
    image.tag(harbor_image_name)

    # 登录 Harbor
    client.login(username=harbor_username, password=harbor_password, registry=harbor_url)

    # 检查项目是否存在
    project_exists_cmd = f"curl -s -u {harbor_username}:{harbor_password} -X GET https://{harbor_url}/api/v2.0/projects?name={harbor_project}"
    project_exists_output = subprocess.check_output(project_exists_cmd, shell=True)
    project_exists_data = json.loads(project_exists_output)

    if len(project_exists_data) == 0:
    # 如果项目不存在,则创建项目
    print(f"Project {harbor_project} does not exist in Harbor. Creating...")
    create_project_cmd = f"curl -s -u {harbor_username}:{harbor_password} -X POST -H \"Content-Type: application/json\" -d '{{\"project_name\": \"{harbor_project}\", \"public\": true}}' https://{harbor_url}/api/v2.0/projects"
    subprocess.check_output(create_project_cmd, shell=True)
    print(f"Project {harbor_project} created successfully.")

    # 推送镜像到 Harbor
    print(f"Pushing image {harbor_image_name} to Harbor...")
    client.images.push(harbor_image_name)

    print("Image pulled and pushed successfully.")

    # 清理下载的容器镜像
    print(f"Cleaning up downloaded image {image_name}...")
    client.images.remove(image_name)
    client.images.remove(harbor_image_name)

    print("Cleanup completed.")

    if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Pull images from Docker Hub and push them to Harbor.")
    parser.add_argument("image_names", nargs='+', help="Names of the images to pull and push")
    parser.add_argument("--docker-username", default="[email protected]", help="Docker Hub username")
    parser.add_argument("--docker-password", default="xxx", help="Docker Hub password")
    parser.add_argument("--harbor-url", default="harbor.op123.ren:44301", help="Harbor URL")
    parser.add_argument("--harbor-username", default="admin", help="Harbor username")
    parser.add_argument("--harbor-password", default="xxx", help="Harbor password")

    args = parser.parse_args()

    for image_name in args.image_names:
    print(f"\nProcessing image: {image_name}")
    pull_and_push_image(image_name, args.docker_username, args.docker_password,
    args.harbor_url, args.harbor_username, args.harbor_password)
    Niphor
        3
    Niphor  
       81 天前
    感谢 OP 试了下,好像只能按本机的架构拉镜像
    exqibao
        4
    exqibao  
       81 天前   ❤️ 1
    @Niphor
    使用 skopeo copy --all 命令就可以复制所有平台架构的镜像,可以使用 github actions 轻松搬运镜像到阿里云免费参考中
    https://github.com/qibao07/docker-sync-action
    snipking
        5
    snipking  
       81 天前
    有一个工具叫 skopeo https://github.com/containers/skopeo
    FarmerChillax
        6
    FarmerChillax  
       81 天前
    zzlyzq
        7
    zzlyzq  
    OP
       81 天前
    @Niphor harbor 可以存不同架构的镜像。之前写脚本同步了常用的镜像大概 1TB ,感觉成本太高,所以废弃了这种方案。用啥存啥,没有再下。

    这个脚本本质上是在小鸡上 docker pull 进行的下载,所以不能指定版本。
    Niphor
        8
    Niphor  
       81 天前
    @exqibao @snipking @FarmerChillax 感谢
    我去看看
    saka0609
        9
    saka0609  
       81 天前
    有 skopeo 为啥不用- -
    zzlyzq
        10
    zzlyzq  
    OP
       81 天前
    eh 兄弟们,我搭建这个不是为了分享脚本,而是分享镜像站点,供运维或者相关的兄弟可以及时或者偶尔用到的时候下载到想用的镜像。
    Clannad0708
        11
    Clannad0708  
       81 天前
    直接使用代理不是可以从 dockerhub 直接拉吗为什么多此一举
    zzlyzq
        12
    zzlyzq  
    OP
       81 天前
    @Clannad0708 是的。这个是国内站点,带宽 100Mbps+。在某些情况下,就算不修改 daemon.json 也可以直接将镜像地址写到 docker-compose 中,或者 k8s 的 yaml 文件中,提高使用效率。目前,我已经使用了半年了,所以发出来与大家分享。
    isnullstring
        13
    isnullstring  
       81 天前
    @Clannad0708 #11 有时候不能用代理或者只是临时拉一个给别人
    Clannad0708
        14
    Clannad0708  
       81 天前
    @zzlyzq #12 确实,造福社会,国内用户可以直接用,省的配了。不过有个小需求不知道 op 打算做吗?最近 k8s 新版本已经不支持 doker 了,使用 containerd 直接管理镜像和容器,有没有考虑做一个 containerd 的 ctr 可以直接国内使用的镜像仓库
    snipking
        15
    snipking  
       81 天前
    @Clannad0708 #14 containerd 用的镜像仓库 api 也是一样的啊,同样配置一下 registry-mirror 就能用了
    Clannad0708
        16
    Clannad0708  
       81 天前
    @snipking #15 emm 我的意思是只有 containerd 没有 docker 的情况下,而且你直接装新版 k8s 他用的 containerd 和 docker 的 containerd 不一样(如果你两个都装就是装 dokcer+装 k8s )
    snipking
        17
    snipking  
       81 天前
    @Clannad0708 #16 就是只有 containerd 的情况呀,google 一下花不了几秒钟 https://blog.shuf.io/post/config-registry-mirrors-for-containerd
    zzlyzq
        18
    zzlyzq  
    OP
       79 天前
    @Clannad0708 仓库应该还是一样的仓库?
    Clannad0708
        19
    Clannad0708  
       79 天前
    @zzlyzq #18 不是很确定是否是一样的仓库,我用 ctr 命令下好多都是 docker.io/ 开头要么就是 gcr.io/
    我也没细细研究 docker 的镜像仓库是否可以直接用到 containerd 的
    zzlyzq
        20
    zzlyzq  
    OP
       79 天前
    @Clannad0708 参考其他兄弟发的链接,长期使用私有镜像配置如下:
    # 编辑文件/etc/containerd/config.toml
    [plugins."io.containerd.grpc.v1.cri".registry]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = ["https://registry-1.docker.io"] //到此为配置文件默认生成,之后为需要添加的内容
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.op123.ren"]
    endpoint = ["https://harbor.op123.ren:44301"]
    [plugins."io.containerd.grpc.v1.cri".registry.configs]
    [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.op123.ren".tls]
    insecure_skip_verify = true

    # 重启 containerd 服务
    systemctl daemon-reload
    systemctl restart containerd
    systemctl status containerd

    # 测试
    Clannad0708
        21
    Clannad0708  
       78 天前
    @zzlyzq #20 牛的兄弟我后续不开代理测试下。
    zzlyzq
        22
    zzlyzq  
    OP
       78 天前
    @Clannad0708 我这个仓库里面只有常用的,不是所有的,所以需要大家接龙所需镜像名称,需要哪些我就同步,方便伙计们一块使用。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5814 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:48 · PVG 10:48 · LAX 18:48 · JFK 21:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.