Maison >développement back-end >Golang >`docker system df` et `/system/df` (point de terminaison de l'API docker)

`docker system df` et `/system/df` (point de terminaison de l'API docker)

WBOY
WBOYavant
2024-02-09 16:45:08566parcourir

`docker system df` 与 `/system/df` (docker api 端点)

l'éditeur php Yuzai est là pour vous présenter deux commandes dans docker : `docker system df` et `/system/df` (point de terminaison de l'API docker). Les deux commandes sont utilisées pour afficher l'utilisation des ressources système du Docker, mais leurs méthodes d'utilisation et d'affichage des résultats sont légèrement différentes. `docker system df` est une commande docker qui peut être exécutée directement dans le terminal. Elle affichera l'utilisation de diverses ressources (y compris les images, les conteneurs, les volumes de données, etc.) dans le système docker, ainsi que l'utilisation globale des ressources. . Et `/system/df` est un point de terminaison de l'API Docker, et vous devez obtenir des informations pertinentes en appelant l'API. Son résultat de retour est similaire à « docker system df », mais il est plus approprié pour obtenir par programme l'utilisation des ressources du système docker.

Contenu de la question

J'écris un programme dans Go pour obtenir l'utilisation totale du disque en Go auprès de mon hôte Docker. Pour cela j'utilise func DiskUsage() de go lib :

  • https://pkg.go.dev/github.com/docker/docker/client#Client.DiskUsage.

En regardant le code, la fonction appelle le point de terminaison de l'API Docker /system/df :

  • https://docs.docker.com/engine/api/v1.43/#tag/System/operation/SystemDataUsage

Cependant, lorsque j'utilise cette bibliothèque avec calcul de Go à l'aide de la commande docker system df, je remarque un comportement étrange :

  • docker系统dfSortie :
    $ docker system df
    TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
    Images          223       4         21.02GB   20.7GB (98%)
    Containers      6         0         0B        0B
    Local Volumes   13        1         536.4MB   340.4MB (63%)
    Build Cache     954       0         13.51GB   13.51GB
    
  • Résultat de l'application My Go :
    $ go run ./cmd/main.go
    Images: TOTAL (223), 17GB
    Build Cache: TOTAL (954), 29GB
    

Comme vous pouvez le constater, il existe une différence entre les deux sorties. J'ai besoin d'aide pour comprendre s'il y a un problème avec mes calculs qui obtiennent les données du point de terminaison /system/df. Merci :)

Application Go :

package main

import (
    "context"
    "fmt"

    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
)

func main() {
    cli, err := client.NewClientWithOpts(client.FromEnv)
    if err != nil {
        panic(err)
    }

    diskUsg, err := cli.DiskUsage(context.Background(), types.DiskUsageOptions{})
    if err != nil {
        panic(err)
    }
    b := float64(0)
    for _, ch := range diskUsg.BuildCache {
        b = b + float64(ch.Size)
    }

    b2 := float64(0)
    for _, ch := range diskUsg.Images {
        if ch.Size > ch.SharedSize {
            b2 = b2 + (float64(ch.Size) - float64(ch.SharedSize))
            continue
        }
        b2 = b2 + (float64(ch.SharedSize) - float64(ch.Size))
    }

    fmt.Printf("Images: TOTAL (%d), %2.fGB\n", len(diskUsg.Images), float64(b2)/(1<<30))
    fmt.Printf("Build Cache: TOTAL (%d), %2.fGB\n", len(diskUsg.BuildCache), float64(b)/(1<<30))
}

Solution

Basée sur le code source Docker :

Vous devriez pouvoir reproduire exactement ce que fait docker 系统 df en utilisant le code suivant :

  • go.mod
module 76982562-docker-system-df-vs-system-df-docker-api-endpoint

go 1.21.0

require (
    github.com/docker/cli v24.0.5+incompatible
    github.com/docker/docker v24.0.5+incompatible
)
  • main.go
<code>package main

import (
    "context"
    "fmt"
    "os"

    "github.com/docker/cli/cli/command/formatter"
    "github.com/docker/docker/api/types"
    "github.com/docker/docker/client"
    "github.com/docker/go-units"
)

func main() {
    cli, err := client.NewClientWithOpts(client.FromEnv)
    if err != nil {
        panic(err)
    }

    diskUsage, err := cli.DiskUsage(context.Background(), types.DiskUsageOptions{})
    if err != nil {
        panic(err)
    }

    var bsz int64
    for _, bc := range diskUsage.BuildCache {
        if !bc.Shared {
            bsz += bc.Size
        }
    }

    fmt.Printf("Images: TOTAL (%d), %s\n", len(diskUsage.Images), units.HumanSize(float64(diskUsage.LayersSize)))
    fmt.Printf("Build Cache: TOTAL (%d), %s\n", len(diskUsage.BuildCache), units.HumanSize(float64(bsz)))
}
</code>
  • Pour les images, docker库直接提供了diskUsage.LayersSize représente la taille totale, vous n'avez donc pas à la calculer vous-même
  • Pour le cache de build, vous devez exclure les projets partagés (if !bc.Shared)

Pour convertir les tailles dans les unités correctes, je recommande fortement d'utiliser github.com/docker/go-units (例如 units.HumanSize(float64(diskUsage.LayersSize))). Cela vous évitera le cauchemar de la conversion d’unités !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer