使用nodejs+ harbor rest api 進行容器鏡像遷移

最近由於基礎設施調整,須要進行harbor 鏡像倉庫的遷移,主要是舊版本很老了,不想使用,直接
打算部署新的,原覺得直接使用複製功能就能夠,可是發現版本差別太大,直接失敗,本打算使用中間
版本過分進行遷移,可是須要測試,好多功能,並且配置有點費事,儘管官方提供了升級說明,可是沒敢
用,就怕出故障java

解決方法

  • rest api 請求流程
    還好harbor 提供了rest api,還算比較全,project , repo,tags, 由於harbor 的界面就是基於bff 模式開發
    的,因此直接經過查看web 的api 請求,直接能夠方便的瞭解api 的請求流程。
  • 鏡像遷移流程
    容器鏡像的額複製功能在harbor早期版本(新版沒有太多瞭解),實際上就是pull push
    因此個人處理方式:
    有兩個harbor 服務:新的以及舊的,同時都配置了ssl 證書(可信)
    調用api 獲取實際須要的docker image : 格式dockerimagehost/project/image:tag
    處理同步:
 
docker pull dockerimageold/project/image:tag
docker tag dockerimageold/project/image:tag dockerimagenew/project/image:tag
docker push dockerimagenew/project/image:tag

詳細處理

爲了簡化同步,使用了管理員的權限,同時對於project 的權限,也是能夠經過rest api 操做的node

準備上邊的同步shell

爲了方便使用nodejs 開發nginx

  • 項目準備
yarn init -y
  • 添加rest api 請求處理npm 包
yarn add node-fetch 
  • 添加npm scripts 並行處理npm 包
yarn add npm-run-all --dev 
  • 簡單代碼演示

    由於項目緣由,只粘貼部分代碼,若是後邊有時間能夠搞成一個通用的服務,同時演示的代碼是固定project的,
    固然這樣是有緣由的,相似分治,能夠方便問題project 單獨快速處理git

 
const fetch = require('node-fetch');
var project_images = []
// fetch project repos
fetch(`https://dockerimageold/api/repositories?project_id=projectid`, {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json',
        "Authorization": "Basic base64username+password"
    }
}).then(res => res.json()).then(repos => {
    repos.forEach(repo => {
        setTimeout(() => {
            fetch(`https://dockerimageold/api/repositories/tags?repo_name=${repo}`, {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/json'
                    }
                })
                .then(res => res.json())
                .then(tags => {
                    if (tags.length > 0) {
                        tags.forEach(tag => {
                                let imageinfo = {
                                    reponame: repo,
                                    oldimageinfo: `dockerimageold/${repo}:${tag}`,
                                    newimageinfo: `dockerimagenew/${repo}:${tag}`,
                                    repo_image: `${repo}:${tag}`
                                };
                                project_images.push(imageinfo)
                        });
                    }
                })
                .catch(err => {
                    console.log(repo)
                })
        }, 1000)
    })
})
setTimeout(() => {
    project_images.forEach(item => {
        pull_push_sh = `docker pull dockerimageold/${item.repo_image} && docker tag dockerimageold/${item.repo_image} dockerimagenew/${item.repo_image} && docker push dockerimagenew/${item.repo_image}`
        console.log(pull_push_sh)
    })
}, 10000)
  • 以上代碼說明
    代碼很簡單,就是循環處理docker image,由於咱們須要的也是docker image
  • npm script 添加
    爲了方便project,快速生成使用了npm-run-all 能夠並行以及串行,快速的生成,很靈活,配置以下:
 
"scripts": {
    "run-all":"npm-run-all remove:sh --parallel g:*",
    "remove:sh":"rm -rf sh/*",
    "g:activitycenter": "node activitycenter.js > sh/activitycenter.sh",
    "g:common": "node common.js > sh/common.sh",
    "g:coredns": "node coredns.js > sh/coredns.sh",
    "g:dalong": "node dalong.js > sh/dalong.sh",
    "g:demo-space": "node demo-space.js > sh/demo-space.sh",
    "g:demoapp": "node demoapp.js > sh/demoapp.sh",
    "g:droneci": "node droneci.js > sh/droneci.sh",
    "g:formbuilder": "node formbuilder.js > sh/formbuilder.sh",
    "g:gf-performance-bulletin": "node gf-performance-bulletin.js > sh/gf-performance-bulletin.sh",
    "g:gitbase": "node gitbase.js > sh/gitbase.sh",
    "g:graylog": "node graylog.js > sh/graylog.sh",
    "g:ingress-nginx": "node ingress-nginx.js > sh/ingress-nginx.sh",
    "g:itapiway": "node itapiway.js > sh/itapiway.sh",
    "g:java": "node java.js > sh/java.sh",
    "g:jenkins-docker": "node jenkins-docker.js > sh/jenkins-docker.sh",
    "g:jenkins": "node jenkins.js > sh/jenkins.sh",
    "g:jira": "node jira.js > sh/jira.sh"
  }

說明:
我沒生成的使用都是執行 yarn run-all 可是爲了保證數據都是新的,每次都先刪除老的shell,從新生成,同時對於生成
是並行的,能夠快速幫助咱們生成shellgithub

  • 項目結構
    項目結構大致以下:(我刪除了部分)
 
├── README.md
├── code
├── activitycenter.js
├── app.js
├── common.js
├── coredns.js
├── dalong.js
├── demo-space.js
├── demoapp.js
├── droneci.js
├── formbuilder.js
├── gf-performance-bulletin.js
├── gitbase.js
├── graylog.js
├── ingress-nginx.js
├── itapiway.js
  .......
├── java.js
├── jenkins-docker.js
├── rhel7.js
├── sh
├── activitycenter.sh
├── common.sh
├── coredns.sh
├── dalong.sh
├── demo-space.sh
├── demoapp.sh
 ......
├── droneci.sh
├── formbuilder.sh
├── gf-performance-bulletin.sh
├── gitbase.sh
├── graylog.sh
├── ingress-nginx.sh
└── yarn.lock
└── run.sh
  • 一鍵式同步
    由於上邊以及生成的單proejct 的同步shell,因此爲了方便,外部有一個run.sh 的文件,能夠批量執行同步,以後就是dns 記錄的修改了
    新鏡像使用之前的域名(這個須要從新生成安裝,可是由於數據是使用了數據卷,不要緊)
    代碼以下:
 
#!/usr/bin/sh
for file in code/sh/*.sh; do
 ./$file
done

同步執行

很簡單,咱們只須要執行 sh run.sh 就能夠了,注意shell 腳本須要添加執行權限web

說明

對於用戶、權限的額同步,以上沒有列出來,可是咱們也是能夠調用rest api 處理的,並且上邊的代碼,部分是寫死的,後邊
找點時間重構下,搞成一個通用的工具,方便遷移docker

參考資料

https://github.com/goharbor/harbor 
https://github.com/mysticatea/npm-run-all 
https://github.com/bitinn/node-fetchshell

相關文章
相關標籤/搜索