簡體   English   中英

如何檢查本地是否存在帶有特定標簽的 Docker 鏡像?

[英]How to check if a Docker image with a specific tag exist locally?

我想知道本地是否存在帶有特定標簽的 Docker 映像。 如果 Docker 客戶端無法本地執行此操作,我可以使用 bash 腳本。

只是為了為潛在的 bash 腳本提供一些提示,運行docker images<\/code>命令的結果返回以下內容:

REPOSITORY                               TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
rabbitmq                                 latest              e8e654c05c91        5 weeks ago         143.5 MB
busybox                                  latest              8c2e06607696        6 weeks ago         2.433 MB
rabbitmq                                 3.4.4               a4fbaad9f996        11 weeks ago        131.5 MB

我通常測試docker images -q的結果(如本腳本中所示):

if [[ "$(docker images -q myimage:mytag 2> /dev/null)" == "" ]]; then
  # do something
fi

由於docker images僅將REPOSITORY作為參數,因此您需要在標簽上進行 grep,而不使用-q .

docker images現在需要標簽 (docker 1.8+) [REPOSITORY[:TAG]]

下面提到的另一種方法是使用docker inspect
但是對於 docker 17+,圖像的語法是: docker image inspect (在不存在的圖像上,退出狀態將為 non-0

正如iTayb評論中所指出的:

  • docker images -q方法在擁有大量圖像的機器上會變得非常慢。 在 6,500 張圖像的機器上運行需要 44 秒。
  • docker image inspect立即返回。

正如亨利·布萊斯( Henry Blyth)在評論中所指出的:

如果您使用docker image inspect my_image:my_tag ,並且您想忽略輸出,您可以添加--format="ignore me"並且它會逐字打印。

您還可以通過添加>/dev/null來重定向標准輸出,但是,如果您不能在腳本中執行此操作,則格式選項可以正常工作。

嘗試docker inspect ,例如:

$ docker inspect --type=image treeder/hello.rb:nada
Error: No such image: treeder/hello.rb:nada
[]

但是現在有了存在的圖像,您將獲得一堆信息,例如:

$ docker inspect --type=image treeder/hello.rb:latest
[
{
    "Id": "85c5116a2835521de2c52f10ab5dda0ff002a4a12aa476c141aace9bc67f43ad",
    "Parent": "ecf63f5eb5e89e5974875da3998d72abc0d3d0e4ae2354887fffba037b356ad5",
    "Comment": "",
    "Created": "2015-09-23T22:06:38.86684783Z",
    ...
}
]

它是一個很好的 json 格式。

域名:

docker image inspect myimage:mytag

通過示范...

成功,找到圖片:

$ docker image pull busybox:latest
latest: Pulling from library/busybox
Digest: sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f
Status: Image is up to date for busybox:latest

$ docker image inspect busybox:latest >/dev/null 2>&1 && echo yes || echo no
yes

失敗,缺少圖像:

$ docker image rm busybox:latest
Untagged: busybox:latest
Untagged: busybox@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f

$ docker image inspect busybox:latest >/dev/null 2>&1 && echo yes || echo no
no

參考:

https://docs.docker.com/engine/reference/commandline/image_inspect/

您可以像下面這樣使用:

[ -n "$(docker images -q someimage:sometag)" ] || echo "does not exist"

或者:

[ -z "$(docker images -q someimage:sometag)" ] || echo "already exists"

在上面Vonc 的回答的幫助下,我創建了以下名為check.sh bash 腳本:

#!/bin/bash
image_and_tag="$1"
image_and_tag_array=(${image_and_tag//:/ })
if [[ "$(docker images ${image_and_tag_array[0]} | grep ${image_and_tag_array[1]} 2> /dev/null)" != "" ]]; then
  echo "exists"
else
  echo "doesn't exist"
fi

將它用於現有圖像和標簽將打印exists ,例如:

./check.sh rabbitmq:3.4.4

將它用於不存在的圖像和標簽將打印doesn't exist ,例如:

./check.sh rabbitmq:3.4.3

如果您嘗試從 docker 注冊表中搜索 docker 鏡像,我想檢查 docker 鏡像是否存在的最簡單方法是使用Docker V2 REST API標簽列表服務

例子:-

curl $CURLOPTS -H "Authorization: Bearer $token" "https://hub.docker.com:4443/v2/your-repo-name/tags/list"

如果上面的結果返回 200Ok 和圖像標簽列表,那么我們知道圖像存在

{"name":"your-repo-name","tags":["1.0.0.1533677221","1.0.0.1533740305","1.0.0.1535659921","1.0.0.1535665433","latest"]}

否則如果你看到類似的東西

{"errors":[{"code":"NAME_UNKNOWN","message":"repository name not known to registry","detail":{"name":"your-repo-name"}}]} 

那么您肯定知道該圖像不存在。

使用test

if test ! -z "$(docker images -q <name:tag>)"; then
  echo "Exist"
fi

或在一行

test ! -z "$(docker images -q <name:tag>)" &&  echo exist

在 bash 腳本中,我這樣做是為了通過標簽檢查圖像是否存在:

IMAGE_NAME="mysql:5.6"

if docker image ls -a "$IMAGE_NAME" | grep -Fq "$IMAGE_NAME" 1>/dev/null; then
echo "could found image $IMAGE_NAME..."
fi

上面的示例腳本檢查是否存在帶有 5.6 標記的​​ mysql 圖像。 如果您只想檢查是否存在沒有特定版本的任何 mysql 映像,則只需傳遞不帶標簽的存儲庫名稱,如下所示:

IMAGE_NAME="mysql"

從我到非常好的讀者的一點點:

建造

#!/bin/bash -e
docker build -t smpp-gateway smpp
(if  [ $(docker ps -a | grep smpp-gateway | cut -d " " -f1) ]; then \
  echo $(docker rm -f smpp-gateway); \
else \
  echo OK; \
fi;);
docker run --restart always -d --network="host" --name smpp-gateway smpp-gateway:latest

手表

docker logs --tail 50 --follow --timestamps smpp-gateway

sudo docker exec -it \
$(sudo docker ps | grep "smpp-gateway:latest" | cut -d " " -f1) \
/bin/bash

對於特定標簽名稱

$ docker images  --filter reference='<REPOSITORY>:TAG'

對於“like 子句”標記名:my_image_tag --> 啟動 my_ima*

$ docker images  --filter reference='<REPOSITORY>:my_ima*'

如果你想要一些“圖像”,例如刪除所有圖像標簽開始“my_ima”試試這個

docker rmi -f $(docker images -q  --filter reference='myreponame:my_ima*')

我認為這個功能應該在docker build命令中實現(使用標志?),這樣它就可以避免大量的代碼重復。

我在名為docker_build的包裝函數中使用了與接受的答案相同的條件,以便它在調用原始docker build命令之前進行必要的檢查。

# Usage: docker_build <...> (instead of docker build)

docker_build()
{
    local arguments=("$@")
    local index
    for (( index=0; index<$#; index++ )); do
        case ${arguments[index]} in
            --tag)
                local tag=${arguments[index+1]}
                if [[ ! -z $(docker images -q "${tag}" 2> /dev/null) ]]; then
                    echo "Image ${tag} already exists."
                    return
                fi
                ;;
        esac
    done
    command docker build "$@"
}

免責聲明:這尚未准備好用於生產,因為它僅適用於長格式的空格分隔參數,即--tag hello-world:latest 此外,這僅修改docker build命令,所有其他命令保持不變。 如果有人有改進,請告訴我。

我想分享這個片段,因為在 bash 函數中包裝標准命令以避免代碼重復的想法似乎比編寫包裝器語句更優雅和可擴展。

靈感來自@rubicks 上面的回復。

檢查圖像是否已經存在

image_name_tag="alpine:3.13.3"

docker image inspect ${image_name_tag} > /dev/null
echo $?

如果圖像不存在則拉取

docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}

演示執行

# image_name_tag="alpine:3.13.3"
# 
# docker image inspect ${image_name_tag} > /dev/null
echo $?
Error: No such image: alpine:3.13.3
# echo $?
1
# docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}
Error: No such image: alpine:3.13.3
3.13.3: Pulling from library/alpine
9aae54b2144e: Pull complete 
Digest: sha256:826f70e0ac33e99a72cf20fb0571245a8fee52d68cb26d8bc58e53bfa65dcdfa
Status: Downloaded newer image for alpine:3.13.3
docker.io/library/alpine:3.13.3
# docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}
$ 

我喜歡這個,因為它簡潔並且具有正確的語義。 如果圖像存在,那是真的,還有什么比這更容易的呢?

if [ $(docker image ls ${build_env} --format="true") ] ; 
then
 echo "does exist"
fi

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM