Docker镜像、容器、仓库及数据管理

使用 Docker 镜像

获取镜像

使用docker pull命令,使用docker search命令可以搜索远端仓库中共享的镜像。

运行容器

使用docker run [OPTIONS] IMAGE [COMMAND] [ARG...]命令,如:docker run --name ubuntu_test --rm -it ubuntu:test /bin/bash,其中选项如下:

  • --name 指定容器名。
  • --rm 表示容器退出后将其删除。
  • -t选项让Docker分配一个伪终端并绑定到容器的标准输入上。
  • -i则让容器的标准输入保持打开。

查看镜像信息

使用docker images命令,列出已经下载下来的镜像。

docker image --filter命令可列出指定的参数

如:列出镜像的仓库名,id和tag,中间用" === "分割

bash 复制代码
docker images --format "{{.Repository}} === {{.ID}} === {{.Tag}}"   

删除镜像

docker rmi [镜像标签或ID],注意docker rm是删除容器的命令,不要混淆。

创建镜像

方法有三种,使用docker commit命令基于已有镜像的容器创建、基于本地模板导入。基于Dockerfile创建。

docker commit

将容器的存储层保存下来成为镜像。docker commit命令会让镜像变的臃肿,实际环境中并不会这样使用。

命令语法:

bash 复制代码
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

选项包括:

  • -a,--author=""作者信息
  • -m,--message=""提交消息
  • -p,--pause=true提交时暂停容器

基于本地模板导入

先下载操作系统模板压缩包文件,然后使用docker import命令导入:

bash 复制代码
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

基于Dockerfile定制镜像

Dockerfile是一个文本文件,其中包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容就是描述该层应当如何构建。步骤如下:

  1. 在一个空白目录,建立文件Dockerfile,内容如下:
bash 复制代码
FROM golang
RUN mkdir -p /go/src/study      \
    && go env -w GO111MODULE=off
COPY study /go/src/study
WORKDIR /go/src/study/photoweb/
RUN go build /go/src/study/photoweb/photoweb.go

FROM指令指定基础镜像,如果以scratch为基础镜像的话,意味着不以任何镜像为基础。

RUN指令用来执行命令行命令。

COPY 指令复制本地文件到镜像中,需要注意的事本地文件必须是镜像构建上下文中的文件(docker build 命令最后一个参数指定),一般将要复制的文件拷到Dockerfile所在的目录中。WORKDIR指令指定工作目录,防止可执行文件找不到相关资源。

  1. Dockerfile文件编写完成后执行命令docker build -t golang:test .创建镜像

Dockerfile多阶段构建

Dockerfile多阶段构建是一种优化 Docker 镜像构建的方法,它可以减少 Docker 镜像的大小和运行时的资源消耗。下面的示例中,第一阶段将可拷贝源码并执行文件app编译出来,在第二阶段只将可执行文件app拷贝到镜像中。节省了运行时不必要的空间(go源码或者编译期间所依赖的其他包)

bash 复制代码
# 第一阶段下载相关依赖编译出可执行文件app
FROM golang:1.9-alpine
RUN apk --no-cache add git
WORKDIR /go/src/github.com/go/helloworld/
RUN go get -d -v github.com/go-sql-driver/mysql
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

# 第二阶段只将可执行文件app复制到镜像中,运行的容器中并不需要下载git和mysql驱动包
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/go/helloworld/app .
CMD ["./app"]

保存和载入

Docker 还提供了docker load和docker save命令,用以将镜像保存为一个tar文件,然后传输到另一个位置上,再加载进来。 这是在没有 Docker Registry 时的做法, 现在已经不推荐, 镜像迁移应该直接使用 Docker Registry, 无论是直接使用 Docker Hub 还是使用内网私有 Registry 都可以。

保存镜像:docker save ubuntu:test | gzip > ubuntu-test.tar.gz,使用docker save保存的镜像只能使用docker load载入

载入镜像:docker load -i ubuntu-test.tar.gz

镜像的实现原理

每个镜像都由很多层次构成,Docker使用Union FS将这些不同的层结合到一个镜像中。

操作容器

启动容器

使用docker run命令,当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统, 并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个ip地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止

守护态运行:执行docker run命令时添加-d参数。

终止容器

使用docker stop命令终止容器,处于终止状态的容器可通过docker start命令来重新启动。

进入容器

使用docker attach或docker exec命令,两者的区别是执行attach后,中stdin中exit会导致容器停止,执行exec后,从stdin中exit不会导致容器的停止,所以推荐使用docker exec命令进入容器。

导出导入

使用docker export命令导出本地某个容器快照到本地文件,使用docker import命令从容器快照文件中再导入为镜像,例如:

bash 复制代码
$ docker ps -a

CONTAINER ID    IMAGE            COMMAND        CREATED        STATUS        PORTS        NAMES
7691a814370e    ubuntu:14.04     "/bin/bash"    36 hours ago   Exited(0) 21 hours ago  test

$ docker export 7691a814370e > ubuntu.tar
 

$ cat ubuntu.tar | docker import - test/ubuntu:v1.0

$ docker images
REPOSITORY    TAG    IMAGE ID      CREATED               VIRTUAL SIZE
test/ubuntu   v1.0   9d37a6082e97  About a minute ago    171.3MB

删除容器

使用docker rm命令,如果要删除一个运行中的容器,可以添加 -f 参数。Docker会发送SIGKILL信号给容器。清理掉所有处于终止状态的容器使用命令docker container prune

访问仓库

Docker Hub

在网站 https://cloud.docker.com注册账号

登陆登出:docker login和docker logout命令

拉取镜像:使用docker search从仓库中查找镜像,使用docker pull命令拉取镜像。

推送镜像:docker push username/ubuntu:17.10命令,username为账号用户名。

私有仓库

使用官方提供的工具docker-registry构建私有的镜像仓库。

容器运行:docker run -d -p 5000:5000 --restart=always --name registry registry,默认情况下,仓库会被创建在容器的/var/lib/registry 目录下。可以通过 -v 参数来将镜像文件存放在本地的指定路径。

在私有仓库上传、搜索和下载镜像:

  • 先使用docker tag来标记一个镜像。例如私有仓库地址为127.0.0.1:5000,标记命令为docker tag ubuntu:latest 127.0.0.1:5000/ubuntu:latest
  • 然后使用docker push上传标记的镜像。命令为docker push 127.0.0.1:5000/ubuntu:latest
  • 使用curl查看仓库中的镜像。命令为curl 127.0.0.1:5000/v2/_catalog
  • 从仓库中下载镜像,命令为docker pull 127.0.0.1:5000/ubuntu:latest
  • Docker 默认不允许非 HTTPS 方式推送镜像。我们可以通过 Docker 配置来取消这个限制,或者配置能够通过 HTTPS 访问的私有仓库。在文件/etc/docker/daemon.json中添加如下内容:
bash 复制代码
{
    "registry-mirror": [
    "https://registry.docker-cn.com"
    ],
    "insecure-registries": [
    "192.168.199.100:5000"
    ]
}

数据管理

在Docker内部以及容器之间管理数据的方式主要有数据卷(Volumes)和挂载主机目录(Bind mounts)两种。

数据卷可供一个或多个容器使用的特殊目录,它绕过UFS,具有下面的特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

创建数据卷

bash 复制代码
docker volume create my-vol

查看数据卷:docker volume ls;查看指定的数据卷的信息如下:

bash 复制代码
$ docker volume inspect my-vol
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]

启动容器时挂载数据卷:执行docker run时使用--mount参数指定要挂载的数据卷。例如:

bash 复制代码
$ docker run -d -P \
    --name web \
    # -v my-vol:/wepapp \
    --mount source=my-vol,target=/webapp \
    training/webapp \
    python app.py

在主机里使用命令docker inspect web查看容器的信息,其中数据卷信息在"Mounts" Key 下面

删除数据卷:docker volume rm my-vol,清理数据卷命令docker volume prune

除了挂载创建的数据卷,还可以使用--mount标记指定直接挂载一个本地主机的目录到容器中去。Docker 挂载主机目录的默认权限是读写,用户也可以通过增加readonly指定为只读 。

相关推荐
张晋涛1 小时前
KCD 北京站丨云原生与AI的双向奔赴,超强Speakers阵容公开
云原生·aigc·线下活动
Hellc0072 小时前
使用 Docker 部署 RabbitMQ 并实现数据持久化
docker·rabbitmq·ruby
梦游钓鱼2 小时前
在window终端创建docker容器的问题
运维·docker·容器
钢板兽3 小时前
Java后端高频面经——JVM、Linux、Git、Docker
java·linux·jvm·git·后端·docker·面试
StableAndCalm3 小时前
什么是zookeeper
分布式·zookeeper·云原生
SelectDB技术团队4 小时前
云原生时代的架构革新,Apache Doris 存算分离如何实现弹性与性能双重提升
大数据·数据库·云原生·doris·存算分离
海鸥816 小时前
在 k8s中查看最大 CPU 和内存的极限
linux·容器·kubernetes
梵法利亚6 小时前
Ubuntu-docker安装mysql
mysql·ubuntu·docker
dessler8 小时前
DeepSeek-进阶版部署(Linux+GPU)
linux·运维·服务器·云原生·大模型·deepseek