docker镜像操作相关shell脚本

deleteRegistryImages.sh

传参说明

  • num:仓库中各项目保留镜像数
  • oneProject:可选参数,表示只删除仓库中当前项目的历史镜像

功能说明

  • 遍历仓库中各项目或指定项目,保留num个镜像,其余各镜像均删除,每次删除镜像后,执行垃圾收集。执行日志将写入/.deleteRegistryImage.log文件中
#! /bin/bash

num=$1
oneProject=$2
registryUrl="127.0.0.1:5000"

get_image_digest(){
   sed -n '/Docker-Content-Digest/{s/\S*Docker-Content-Digest: //; s/\r//; p;}' /.image.txt
}

startTime=`date +'%Y-%m-%d %H:%M:%S'`
echo "************************************************" | tee -a /.deleteRegistryImage.log
echo "$startTime使用$(pwd)/下的脚本执行了删除仓库镜像操作:" | tee -a /.deleteRegistryImage.log

if [ -z "$num" ]; then
        num=2;
fi
echo "传入参数:num=$num(若未传入,默认为2),oneProject=$oneProject 并开始执行:" | tee -a /.deleteRegistryImage.log

curl -k https://$registryUrl/v2/_catalog 2>/dev/null >>/.repositories.txt
sed  -i "s/\"//g" /.repositories.txt
cat /.repositories.txt | while IFS= read -r line; do
        temp=$(echo $line | cut -d'[' -f2)
        repositories=$(echo $temp | cut -d ']' -f1)
        echo "仓库中包含以下项目:$repositories" | tee -a /.deleteRegistryImage.log
        str=${repositories//,/ }
        arr=($str)
        if [ -n "$oneProject" ]; then
                curl -k https://$registryUrl/v2/$oneProject/tags/list 2>/dev/null >>/.$oneProject.txt
                sed  -i "s/\"//g" /.$oneProject.txt
                cat /.$oneProject.txt | while IFS= read -r line1; do
                        temp1=$(echo $line1 | cut -d'[' -f2)
                        tags=$(echo $temp1 | cut -d ']' -f1)
                        echo "删除前仓库中$oneProject项目包含的镜像如下:$tags" | tee -a /.deleteRegistryImage.log
                        str1=${tags//,/ }
                        tagArr=($str1)
                        tagArrLength=${#tagArr[*]}
                        echo "仓库中$project项目包含$tagArrLength个镜像。" | tee -a /.deleteRegistryImage.log
                        if [ $tagArrLength -gt $num ]; then 
                                for((i=0; i<${#tagArr[*]}-$num; i++));do 
                                        #根据digest删除仓库里的镜像操作在这里
                                        imageTag=${tagArr[$i]}
                                        echo "根据名字和镜像tag获取digest" | tee -a /.deleteRegistryImage.log
                                        curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET -k https://$registryUrl/v2/$oneProject/manifests/$imageTag  2>/dev/null >>/.image.txt
                                        cat /.image.txt | grep Docker-Content-Digest | while IFS= read -r line2; do
                                                lineName=$(echo $line2 | cut -d':' -f1)
                                                if [ $lineName == "Docker-Content-Digest"  ];then
                                                   imageDigest=$(get_image_digest)
                                                   echo "删除镜像:$imageTag $imageDigest" | tee -a /.deleteRegistryImage.log
                                                   curl -XDELETE -k https://$registryUrl/v2/$oneProject/manifests/$imageDigest
                                                fi
                                        done
                                        rm -f /.image.txt
                                done
                                echo "$oneProject项目已删除完毕,仓库中保留最近上传的的$num个镜像。" | tee -a /.deleteRegistryImage.log
                        else
                                echo "仓库中$oneProject项目的镜像数为$tagArrLength,不大于$num,不执行删除操作!" | tee -a /.deleteRegistryImage.log
                        fi
                        rm -f /.$oneProject.txt
                done
        else
                for project in ${arr[*]}do
                        echo "删除仓库中的$project项目镜像:" | tee -a /.deleteRegistryImage.log
                        curl -k https://$registryUrl/v2/$project/tags/list 2>/dev/null >>/.$project.txt
                        sed  -i "s/\"//g" /.$project.txt
                        cat /.$project.txt | while IFS= read -r line1; do
                                temp1=$(echo $line1 | cut -d'[' -f2)
                                tags=$(echo $temp1 | cut -d ']' -f1)
                                echo "删除前仓库中$project项目包含的镜像如下:$tags" | tee -a /.deleteRegistryImage.log
                                str1=${tags//,/ }
                                tagArr=($str1)
                                tagArrLength=${#tagArr[*]}
                                echo "仓库中$project项目包含$tagArrLength个镜像。" | tee -a /.deleteRegistryImage.log
                                if [ $tagArrLength -gt $num ]; then
                                        echo "根据名字和镜像tag获取digest" | tee -a /.deleteRegistryImage.log
                                        for((i=0; i<${#tagArr[*]}-$num; i++));do 
                                                #根据digest删除仓库里的镜像操作在这里
                                                imageTag=${tagArr[$i]}
                                                curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET -k https://$registryUrl/v2/$project/manifests/$imageTag  2>/dev/null >>/.image.txt
                                                cat /.image.txt | grep Docker-Content-Digest | while IFS= read -r line2; do
                                                        lineName=$(echo $line2 | cut -d':' -f1)
                                                        if [ $lineName == "Docker-Content-Digest"  ];then
                                                           imageDigest=$(get_image_digest)
                                                           echo "删除镜像:$imageTag $imageDigest" | tee -a /.deleteRegistryImage.log
                                                           curl -XDELETE -k https://$registryUrl/v2/$project/manifests/$imageDigest
                                                        fi
                                                done
                                                rm -f /.image.txt
                                        done
                                        echo "$project项目已删除完毕,仓库中保留最近上传的的$num个镜像。" | tee -a /.deleteRegistryImage.log
                                else
                                        echo "仓库中$project项目的镜像数为$tagArrLength,不大于$num,不执行删除操作!" | tee -a /.deleteRegistryImage.log
                                fi
                                rm -f /.$project.txt
                        done
                done
        fi
done
rm -f /.repositories.txt

echo "删除镜像操作结束!开始执行垃圾清理操作···" | tee -a /.deleteRegistryImage.log

docker exec -i itacRegistry /bin/sh -c "cd /var/lib/registry && registry garbage-collect /etc/docker/registry/config.yml"

echo "垃圾清理操作结束!脚本执行结束!" | tee -a /.deleteRegistryImage.log
echo -e "\n\n\n\n" | tee -a /.deleteRegistryImage.log

produceCloud.sh

传参说明

  • date:待保存镜像日期
  • oneItem:待保存镜像项目名称

功能说明

  • 根据参数制作云端完整安装包,或保存单个项目镜像
#!/bin/bash

date=$1
oneItem=$2
registry="127.0.0.1:5000"
arr=(apiserv itac itactask portal-demo portal-largescreen portal-promotion vpn)

if [ -z "$oneItem" ]; then 
        rm -rf cloud
        mkdir cloud
        cd cloud
        mkdir adesk-images
        for item in ${arr[@]}do
                echo $item
                docker pull $registry/$item:$item-release-$date
                docker tag $registry/$item:$item-release-$date $item:$item-release-$date
                docker save $item:$item-release-$date > adesk-images/$item-release-$date.tar
                docker rmi $registry/$item:$item-release-$date 
                docker rmi $item:$item-release-$date
        done
        cp -r /var/adesk-scripts .
        cp -r /var/adesk-ymls .
        tar -czvf cloud.tar.gz adesk-images/ adesk-scripts/ adesk-ymls/
else
        docker pull $registry/$oneItem:$oneItem-release-$date
        docker tag $registry/$oneItem:$oneItem-release-$date $oneItem:$oneItem-release-$date
        docker save $oneItem:$oneItem-release-$date > $oneItem-release-$date.tar
        docker rmi $registry/$oneItem:$oneItem-release-$date
        docker rmi $oneItem:$oneItem-release-$date

fi

produceAdesk.sh

功能说明

  • 制作探针完整安装包
#!/bin/bash

time=$(date +%Y%m%d)
docker ps | while IFS= read -r line ; do
        image=$(echo $line | cut -d ' ' -f2)
        if [ $image != "ID" ]; then
                tag=$(echo $image | cut -d '/' -f2)
                name=$(echo $tag | cut -d ':' -f1)
                tarName=$(echo $image | cut -d ':' -f3)
                docker tag  $image $tag
                mkdir $name
                docker save $tag > ./$name/$tarName.tar
                docker rmi $tag
        fi
done
cp -r /var/tmp/deploy .
tar -czvf Adesk-R2.0.0-$time.tar.gz deploy/ splus/ probe/ zabbix/ agent/

ntp.sh

功能说明

  • 安装NTP服务后,配置服务器与ntpServer时钟源同步
#!/bin/bash

yum localinstall -y *.rpm
# 设置本地时区
timedatectl set-timezone "Asia/Shanghai"
# 设置硬件时钟以协调世界时(UTC)
timedatectl set-local-rtc 0
# 设置硬件时间,使得硬件时钟变为跟系统时间同步
hwclock --systohc

ntpServer=*.*.*.*

# 修改ntp配置
sed -i '/server 3/a\restrict '$ntpServer' nomodify notrap noquery'  /etc/ntp.conf
sed -i '/server 3/a\server '$ntpServer''  /etc/ntp.conf
sed -i '/centos.pool.ntp.org/d'  /etc/ntp.conf
# 开启NTP服务
systemctl start ntpd
systemctl enable ntpd

# 关闭chrony服务,避免系统重启后NTP服务无法启动
systemctl stop chronyd
systemctl disable chronyd

pushAgentImage.sh

参数说明:

  • edition:镜像制作版本

– registryIp:镜像推送至的仓库

功能说明:

  • 在服务器上制作探针镜像,制作前清除本地镜像,清除仓库中同标签镜像,制作后再次清除本地镜像。以/.temp.ini作为“锁”,保证该脚本被多人使用时不冲突。
#!/bin/bash

set +e

edition=$1
registryIp=$2

while [ -f "/.temp.ini" ];do
        sleep 5
                echo "someone is running script to build and push docker image, so waiting for the finish..."
done

touch /.temp.ini

getVersion(){
    cat version.txt | grep agent_"$edition" | while IFS= read -r line; do
       version=$(echo $line | cut -d'=' -f2)
       echo $version
    done
}

version=$(getVersion)

get_image_version() {
    unzip -q Adesk.war WEB-INF/conf/productConf/Adesk/product.xml
    sed -n '/productVersion/{s/\S*<productVersion value="//; s/"\/>\r//; s/\t//; p;}' WEB-INF/conf/productConf/Adesk/product.xml
    rm -rf WEB-INF
}

get_image_digest(){
   sed -n '/Docker-Content-Digest/{s/\S*Docker-Content-Digest: //; s/\r//; p;}' /.image.txt
}


imageName="*.*.*.*:5000/agent"
imageVer=$(get_image_version)
imageTag="agent-$imageVer-$(date +%Y%m%d)"
imageNameTag="$imageName:$imageTag"

echo "delete the last image of today"
docker rmi "$imageNameTag"

echo "Building docker image \"$imageNameTag\"."
docker build -t "$imageNameTag" .

if [ -n "$registryIp" ]; then
        echo "add $registryIp *.*.*.* into /etc/hosts"
        sed -i "/^::1/a $registryIp *.*.*.*" /etc/hosts

        curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET -k https://*.*.*.*:5000/v2/agent/manifests/$imageTag 2>/dev/null >>/.image.txt
        cat /.image.txt | grep Docker-Content-Digest | while IFS= read -r line; do
                lineName=$(echo $line | cut -d':' -f1)
                if [ $lineName == "Docker-Content-Digest"  ];then
                   imageDigest=$(get_image_digest)
                   echo $imageDigest
                   echo "delete the last image in registry of today"
                   curl -XDELETE -k https://*.*.*.*:5000/v2/agent/manifests/$imageDigest
                fi
        done
        rm -f /.image.txt

        sleep 20
        echo "pushing docker image \"$imageNameTag\"."
        docker push "$imageNameTag"

        echo "remove $registryIp *.*.*.* in /etc/hosts"
        sed -i "/rois/d" /etc/hosts 
else
        SELFDIR=$(dirname "$(realpath -s "$0")")
        source $SELFDIR/data/read_ini.sh
        # parameter processing
        TEST_ENV_NAME=""
        while (( "$#" )); do
                if [ "$1" == "--test-env" ]; then
                        shift
                        TEST_ENV_NAME=$1
                        shift
                        continue
                fi
                shift
        done

        # do work
        for fullfn in `ls /etc/h3c/$edition/*.test-env`; do
                fn=$(basename $fullfn)
                name=${fn%%.*}
                if [ ! -z $TEST_ENV_NAME ] && [ "$TEST_ENV_NAME" != "$name" ]; then
                        continue
                fi
                read_ini $fullfn
                cloudIp=${INI__cloud__ip}
                cloudUser=${INI__cloud__user}
                cloudPwd=${INI__cloud__passwd}

                echo "add $cloudIp *.*.*.* into /etc/hosts"
                sed -i "/^::1/a $cloudIp *.*.*.*" /etc/hosts

                curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET -k https://*.*.*.*:5000/v2/agent/manifests/$imageTag 2>/dev/null >>/.image.txt
                cat /.image.txt | grep Docker-Content-Digest | while IFS= read -r line; do
                        lineName=$(echo $line | cut -d':' -f1)
                        if [ $lineName == "Docker-Content-Digest"  ];then
                           imageDigest=$(get_image_digest)
                           echo $imageDigest
                           echo "delete the last image in registry of today"
                           curl -XDELETE -k https://*.*.*.*:5000/v2/agent/manifests/$imageDigest
                        fi
                done
                rm -f /.image.txt

                echo "pushing docker image \"$imageNameTag\"."
                docker push "$imageNameTag"

                sleep 20
                echo "remove $cloudIp *.*.*.* in /etc/hosts"
                sed -i "/rois/d" /etc/hosts 
        done
fi

echo "delete this image in local docker"
docker rmi "$imageNameTag"
rm -f /.temp.ini
echo "Complete."

搭建docker本地私有仓库

一:准备工作如下:

1、建立相关文件夹:

[root@iZ28bi7khfvZ registry]# pwd
/laughing/registry
[root@iZ28bi7khfvZ registry]# ls
config.yml docker

2、上传配置文件config.yml至服务器/laughing/registry目录下,内容如下:

[root@iZ28bi7khfvZ registry]# vi config.yml

version: 0.1
log:
fields:
service: registry
storage:
delete:
enabled: true
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff] health:
storagedriver:
enabled: true
interval: 10s
threshold: 3

3、从官方仓库中pull下registry镜像:

docker pull registry

二:开始运行registry镜像

运行registry镜像时要挂载仓库目录,挂载配置文件,指定端口,如下:

docker run -d -p 5000:5000 -v /laughing/registry/:/var/lib/registry -v /laughing/registry/config.yml:/etc/docker/registry/config/yml –name registry –restart=always registry

运行上条指令后可看到registry容器已经启动啦:

[root@iZ28bi7khfvZ registry]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47602f950bf9 registry “/entrypoint.sh /etc…” 37 minutes ago Up 30 minutes 0.0.0.0:5000->5000/tcp registry

三:测试

例如将本地已有的镜像上传至仓库中:

将本地镜像打标签;

docker tag base:jdktomcat IP:5000/base:jdktomcat

然后推送到私有仓库中:

docker push IP:5000/base:jdktomcat

此时出现错误:http: server gave HTTP response to HTTPS client

因为docker与docker registry默认交互使用https,而我们搭建的私有仓库使用http服务

因此需要在服务器上配置如下:

vim /usr/lib/systemd/system/docker.service

找到ExecStart=/usr/bin/dockerd这一行 在后面追加  –insecure-registry IP:5000

保存后需要重启docker

systemctl daemon-reload

ststemctl restart docker.service

此时再次执行docker push IP:5000/base:jdktomcat

发现已可推送成功

通过查看仓库镜像来确认下:

[root@iZ28bi7khfvZ registry]# curl -get http://IP:5000/v2/_catalog
{“repositories”:[“base”]}

[root@iZ28bi7khfvZ registry]# curl -get http://IP:5000/v2/base/tags/list
{“name”:”base”,”tags”:[“jdktomcat”]}

至此我们已确认私有仓库搭建完成!

参考链接:https://www.cnblogs.com/Tempted/p/7768694.html

创建第一个基础镜像

说明:使用Centos及jdk1.7、tomcat7.0制作基础镜像。baseos:1.0中主要为了调整时区

注意在启动容器时,指定端口映射-p 8080:8080

一:首先创建空白的centos基础镜像

docker pull cetos

docker tag cetos:latest centos:base

二:目录结构如下

[root@iZ28bi7khfvZ laughing]# ls
baseos jdktomcat
[root@iZ28bi7khfvZ laughing]# pwd
/laughing
[root@iZ28bi7khfvZ laughing]# ls
baseos jdktomcat

三:在baseos文件夹下创建Dockerfile,并制作镜像

[root@iZ28bi7khfvZ laughing]# cd baseos/
[root@iZ28bi7khfvZ baseos]# ls
Dockerfile
[root@iZ28bi7khfvZ baseos]# cat Dockerfile
#Baseosimage
From centos:base
MAINTAINER Laughing_Lz 645596034@qq.com
LABEL Description=”this image is the baseos image.” Version=”1.0″
ENV TIME_ZONE Asia/Shanghai
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo ‘Asia/Shanghai’ >/etc/timezone

制作镜像如下:

docker build -t base:1.0 .

四:在jdktomcat文件夹下创建Dockerfile,内容如下

[root@iZ28bi7khfvZ laughing]# cd jdktomcat/
[root@iZ28bi7khfvZ jdktomcat]# ls
apache-tomcat-7.0.88.tar.gz Dockerfile jdk-7u79-linux-x64.tar.gz
[root@iZ28bi7khfvZ jdktomcat]# cat Dockerfile
From base:1.0
MAINTAINER Laughing_Lz 645596034@qq.com

ADD jdk-7u79-linux-x64.tar.gz /usr/local
ADD apache-tomcat-7.0.88.tar.gz /usr/local

ENV JAVA_HOME /usr/local/jdk1.7.0_79
ENV CLASSPATH $JAVA_HOME/lib /dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-7.0.88
ENV CATALINA_BASE /usr/local/apache-tomcat-7.0.88
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD [ “/usr/local/apache-tomcat-7.0.88/bin/catalina.sh”, “run” ]

五:以第四步的Dockerfile及tomcat和jdk的安装包制作镜像

docker build -t base:jdktomcat .

六:以第五步制作的镜像启动容器

docker run -d -p 8080:8080 –name=”zero” base:jdktomcat

七:进入容器查看:

docker exec -it  [ContainID] /bin/bash