利用TravisCI同步gcr.io鏡像到dockerhub

前期準備
一钉鸯、背景介紹
由于國內(nèi)網(wǎng)絡(luò)原因贝次,gcr.io 倉庫里的鏡像是無法直接拉取到的淳蔼,這給開發(fā)工作造成了極大的不便

本文介紹一種方法能夠?qū)崿F(xiàn)自動化地定期地將 gcr.io 倉庫中的鏡像同步到個人 DockerHub 賬戶

實現(xiàn)該方案需要滿足以下條件:

二、實現(xiàn)步驟

一、Google Cloud 服務(wù)賬戶,以讀取 gcr.io 倉庫中的鏡像列表 生成json文件 保存文件備用
登錄 Google Cloud 控制臺,點擊菜單 “IAM和管理” -> “服務(wù)賬號”

image.png

填入 “賬號名稱” 和 “賬號ID”,點擊 “創(chuàng)建”盛杰,之后授予權(quán)限,角色選擇 “容器分析備注查看者”藐石,點擊 “繼續(xù)”


image.png

點擊 “創(chuàng)建密鑰”


image.png

推薦JSON格式


image.png

二即供、DockerHub 登錄密鑰文件 保存文件備用

DockerHub Login 登錄,在家目錄.docker目錄下生成config.json

Docker login

Docker

三于微、創(chuàng)建 SSH 密鑰逗嫡,并在 GitHub 上進行授權(quán) id_rsa文件保存?zhèn)溆?/code>
這部分省略,自行查詢

四株依、創(chuàng)建 GitHub 項目祸穷,配置 Travis CI 策略

GitHub 項目名稱 https://github.com/JaeGerW2016/mirrorgcrio

#拉取github項目到本地
git clone https://github.com/JaeGerW2016/mirrorgcrio.git

cd mirrorgcrio
touch .travis.yml
#將之前生成的 gcloud.config.json、config.json勺三、id_rsa 放置到項目根目錄

tar czvf config.tar.gz gcloud.config.json config.json id_rsa

#docker 拉取一個travis-ci鏡像生成加密文件
docker run -it -v /opt/travis-ci/mirrorgcrio:/root shidaqiu/travis-cli

travis login
#登錄成功后,在容器執(zhí)行操作
travis encrypt-file config.tar.gz --add

#退出容器需曾,由于/opt/travis-ci/mirrorgcrio掛載到容器做持久化吗坚,會在根目錄下生成config.tar.gz.enc
mv config.tar.gz.enc .travis
#防止后期git push到github上
rm -f config.tar.gz gcloud.config.json config.json id_rsa

編輯.travis.yml

sudo: required
language: python
python:
- '2.7'
addons:
  apt:
    packages:
    - docker-ce
branches:
  only:
  - master
install:
- git remote -v
script:
- "./get_image.sh"
before_install:
- export start_time=$(date +%s)
- mkdir -p ~/.docker
- mkdir -p ~/.ssh
#替換自己的加密文件
- openssl aes-256-cbc -K $encrypted_1fc90f464345_key -iv $encrypted_1fc90f464345_iv
  -in .travis/config.tar.gz.enc -out ~/config.tar.gz -d
- tar xf ~/config.tar.gz -C ~
- mv ~/id_rsa ~/.ssh/id_rsa
- mv ~/config.json ~/.docker/config.json
- chmod 600 ~/.ssh/id_rsa
- chmod 600 ~/.docker/config.json
- eval $(ssh-agent)
- ssh-add ~/.ssh/id_rsa

編輯get_image.sh

#!/bin/bash

GCR_NAMESPACE=gcr.io/google-containers
#自行替換自己的Dockerhub
DOCKERHUB_NAMESPACE=mirrorgcrio

today(){
   date +%F
}

git_init(){
    git config --global user.name "xxxx"
    git config --global user.email xxxx@qq.com
    git remote rm origin
    git remote add origin git@github.com:JaeGerW2016/mirrorgcrio.git
    git pull
    if git branch -a |grep 'origin/develop' &> /dev/null ;then
        git checkout develop
        git pull origin develop
        git branch --set-upstream-to=origin/develop develop
    else
        git checkout -b develop
        git pull origin develop
    fi
}

git_commit(){
     local COMMIT_FILES_COUNT=$(git status -s|wc -l)
     local TODAY=$(today)
     if [ $COMMIT_FILES_COUNT -ne 0 ];then
        git add -A
        git commit -m "Synchronizing completion at $TODAY"
        git push -u origin develop
     fi
}

add_yum_repo() {
cat > /etc/yum.repos.d/google-cloud-sdk.repo <<EOF
[google-cloud-sdk]
name=Google Cloud SDK
baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
       https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
}

add_apt_source(){
export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
}

install_sdk() {
    local OS_VERSION=$(grep -Po '(?<=^ID=")\w+' /etc/os-release)
    local OS_VERSION=${OS_VERSION:-ubuntu}
    if [[ $OS_VERSION =~ "centos" ]];then
        if ! [ -f /etc/yum.repos.d/google-cloud-sdk.repo ];then
            add_yum_repo
            yum -y install google-cloud-sdk
        else
            echo "gcloud is installed"
        fi
    elif [[ $OS_VERSION =~ "ubuntu" ]];then
        if ! [ -f /etc/apt/sources.list.d/google-cloud-sdk.list ];then
            add_apt_source
            sudo apt-get -y update && sudo apt-get -y install google-cloud-sdk
        else
             echo "gcloud is installed"
        fi
    fi
}

auth_sdk(){
    local AUTH_COUNT=$(gcloud auth list --format="get(account)"|wc -l)
    if [ $AUTH_COUNT -eq 0 ];then
        gcloud auth activate-service-account --key-file=$HOME/gcloud.config.json
    else
        echo "gcloud service account is exsits"
    fi
}

repository_list() {
    if ! [ -f repo_list.txt ];then
        gcloud container images list --repository=${GCR_NAMESPACE} --format="value(NAME)" > repo_list.txt && \
        echo "get repository list done"
    else
        /bin/mv  -f repo_list.txt old_repo_list.txt
        gcloud container images list --repository=${GCR_NAMESPACE} --format="value(NAME)" > repo_list.txt && \
        echo "get repository list done"
        DEL_REPO=($(diff  -B -c  old_repo_list.txt repo_list.txt |grep -Po '(?<=^\- ).+|xargs')) && \
        rm -f old_repo_list.txt
        if [ ${#DEL_REPO} -ne 0 ];then
            for i in ${DEL_REPO[@]};do
                rm -rf ${i##*/}
            done
        fi
    fi
}

generate_changelog(){
    if  ! [ -f CHANGELOG.md ];then
        echo  >> CHANGELOG.md
    fi

}

push_image(){
    GCR_IMAGE=$1
    DOCKERHUB_IMAGE=$2
    docker pull ${GCR_IMAGE}
    docker tag ${GCR_IMAGE} ${DOCKERHUB_IMAGE}
    docker push ${DOCKERHUB_IMAGE}
    echo "$IMAGE_TAG_SHA" > ${IMAGE_NAME}/${i}
    sed -i  "1i\- ${DOCKERHUB_IMAGE}"  CHANGELOG.md
}

clean_images(){
     IMAGES_COUNT=$(docker image ls|wc -l)
     if [ $IMAGES_COUNT -gt 1 ];then
         docker image prune -a -f
     fi
}

clean_disk(){
    DODCKER_ROOT_DIR=$(docker info --format '{{json .}}'|jq  -r '.DockerRootDir')
    USAGE=$(df $DODCKER_ROOT_DIR|awk -F '[ %]+' 'NR>1{print $5}')
    if [ $USAGE -eq 80 ];then
        wait
        clean_images
    fi
}

main() {
    git_init
    install_sdk
    auth_sdk
    repository_list
    generate_changelog
    TODAY=$(today)
    PROGRESS_COUNT=0
    LINE_NUM=0
    LAST_REPOSITORY=$(tail -n 1 repo_list.txt)
    while read GCR_IMAGE_NAME;do
        let LINE_NUM++
        IMAGE_INFO_JSON=$(gcloud container images list-tags $GCR_IMAGE_NAME  --filter="tags:*" --format=json)
        TAG_INFO_JSON=$(echo "$IMAGE_INFO_JSON"|jq '.[]|{ tag: .tags[] ,digest: .digest }')
        TAG_LIST=($(echo "$TAG_INFO_JSON"|jq -r .tag))
        IMAGE_NAME=${GCR_IMAGE_NAME##*/}
        if [ -f  breakpoint.txt ];then
           SAVE_DAY=$(head -n 1 breakpoint.txt)
           if [[ $SAVE_DAY != $TODAY ]];then
             :> breakpoint.txt
           else
               BREAK_LINE=$(tail -n 1 breakpoint.txt)
               if [ $LINE_NUM -lt $BREAK_LINE ];then
                   continue
               fi
           fi
        fi
        for i in ${TAG_LIST[@]};do
            GCR_IMAGE=${GCR_IMAGE_NAME}:${i}
            DOCKERHUB_IMAGE=${DOCKERHUB_NAMESPACE}/${IMAGE_NAME}:${i}
            IMAGE_TAG_SHA=$(echo "${TAG_INFO_JSON}"|jq -r "select(.tag == \"$i\")|.digest")
            if [[ $GCR_IMAGE_NAME == $LAST_REPOSITORY ]];then
                LAST_TAG=${TAG_LIST[-1]}
                LAST_IMAGE=${LAST_REPOSITORY}:${LAST_TAG}
                if [[ $GCR_IMAGE  == $LAST_IMAGE ]];then
                    wait
                    clean_images
                fi
            fi
            if [ -f $IMAGE_NAME/$i ];then
                echo "$IMAGE_TAG_SHA"  > /tmp/diff.txt
                if ! diff /tmp/diff.txt $IMAGE_NAME/$i &> /dev/null ;then
                     clean_disk
                     push_image $GCR_IMAGE $DOCKERHUB_IMAGE &
                     let PROGRESS_COUNT++
                fi
            else
                mkdir -p $IMAGE_NAME
                clean_disk
                push_image $GCR_IMAGE $DOCKERHUB_IMAGE &
                let PROGRESS_COUNT++
            fi
            COUNT_WAIT=$[$PROGRESS_COUNT%50]
            if [ $COUNT_WAIT -eq 0 ];then
               wait
               clean_images
               git_commit
            fi
        done
        if [ $COUNT_WAIT -eq 0 ];then
            wait
            clean_images
            git_commit
        fi

        echo "sync image $MY_REPO/$IMAGE_NAME done."
        echo -e "$TODAY\n$LINE_NUM" > breakpoint.txt
    done < repo_list.txt 
    sed -i "1i-------------------------------at $(date +'%F %T') sync image repositorys-------------------------------"  CHANGELOG.md
    git_commit
}

main

設(shè)置travis

image.png

設(shè)置cronjob


image.png

手動觸發(fā)構(gòu)建


image.png

查看job Log


image.png

最終驗證是否同步到DockeHub https://hub.docker.com/u/mirrorgcrio/?page=1

image.png

用法:

docker pull gcr.io/google-containers/federation-controller-manager-arm64:v1.3.1-beta.1
# eq
docker pull mirrorgcrio/federation-controller-manager-arm64:v1.3.1-beta.1

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市呆万,隨后出現(xiàn)的幾起案子商源,更是在濱河造成了極大的恐慌,老刑警劉巖谋减,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牡彻,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機庄吼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門缎除,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人总寻,你說我怎么就攤上這事器罐。” “怎么了渐行?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵轰坊,是天一觀的道長。 經(jīng)常有香客問我祟印,道長肴沫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任蕴忆,我火速辦了婚禮颤芬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘孽文。我一直安慰自己驻襟,他們只是感情好,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布芋哭。 她就那樣靜靜地躺著沉衣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪减牺。 梳的紋絲不亂的頭發(fā)上豌习,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音拔疚,去河邊找鬼肥隆。 笑死,一個胖子當著我的面吹牛稚失,可吹牛的內(nèi)容都是我干的栋艳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼句各,長吁一口氣:“原來是場噩夢啊……” “哼吸占!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凿宾,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矾屯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后初厚,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體件蚕,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了排作。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牵啦。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖纽绍,靈堂內(nèi)的尸體忽然破棺而出蕾久,到底是詐尸還是另有隱情,我是刑警寧澤拌夏,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布僧著,位于F島的核電站,受9級特大地震影響障簿,放射性物質(zhì)發(fā)生泄漏盹愚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一站故、第九天 我趴在偏房一處隱蔽的房頂上張望皆怕。 院中可真熱鬧,春花似錦西篓、人聲如沸愈腾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虱黄。三九已至,卻和暖如春吮成,著一層夾襖步出監(jiān)牢的瞬間橱乱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工粱甫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泳叠,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓茶宵,卻偏偏與公主長得像危纫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子乌庶,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理种蝶,服務(wù)發(fā)現(xiàn),斷路器安拟,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個 Awesome - XXX 系列...
    小邁克閱讀 2,989評論 1 3
  • Docker — 云時代的程序分發(fā)方式 要說最近一年云計算業(yè)界有什么大事件?Google Compute Engi...
    ahohoho閱讀 15,535評論 15 147
  • 楊小林老師采訪錄 從前的日色變得慢宵喂,車馬郵件都慢糠赦,一生只夠愛一個人。 ——題記 大約今年盛夏,我們?nèi)ゲ稍L了工訓(xùn)中心...
    一方圓融閱讀 250評論 0 0
  • 01 第一次看到老公在聊天室里的那些內(nèi)容拙泽,倒也沒有多不堪入目淌山,但我確定他一定是有什么瞞著我。 那時顾瞻,我每天都在提心...
    林姑娘與波斯貓閱讀 244評論 0 3