Docker

Docker简介

  1. docker镜像

容器取代虚拟机真正的原因是Docker发明的镜像,所谓Docker镜像,其实就是一个压缩包,它由一个完整操作系统的所有文件和目录构成,这个压缩包里的内容跟你本地开发和测试环境用的操作系统是完全一样的。

  • 镜像是一层一层构建的(分层架构)
  • 镜像内容不可修改(只读)

image-20250226203810328

每个run都是一层

image-20250226204019249

  1. docker容器

镜像(Image)和容器(Container)有紧密的关系,镜像是静态的定义,容器是镜像运行时的实体。

容器可以被创建、启动、停正、删除、暂停等。

Docker镜像都是只读的。容器是在原来的镜像上新建了一个可读写层到原本镜像的顶部,这一层我们叫作容器层,容器层之下的叫作镜像层。

容器层的生存周期和容器一样,容器消亡时,容器层也随之消亡。容器可以理解为一个或一组相互依赖的服务。

image-20250226204533999

  1. docker仓库

docker使用仓库(或者叫注册中心 Registry)来保存用户构建的镜像,仓库可分为公共仓库和私有仓库,公共仓库提供公开服务允许用户免费上传、下载公开的镜像,官方的Docker Hub(https://hub.docker.com),提供公共仓库服务。此仓库拥有大量的高质量的官方镜像。

除了使用公共仓库外,用户还可以在本地搭建私有仓库,比如,VMWare Harbor、gitlab 这些第三方私钥仓库软件。

image-20250226204803315

  1. 镜像、容器和仓库之间的关系

image-20250226204845729

使用Dockerfile脚本构建镜像

什么是Dockerfile

Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。

  • 对于开发人员:可以为开发团队提供一个完全一致的开发环境:
  • 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作
  • 对于运维人员:在部署时,可以实现应用的无缝移植。

常用命令及其结构

# 指定基础镜像
FROM ubuntu:20.04

# 维护者信息
LABEL maintainer="yourname@example.com"

# 设置环境变量
ENV APP_HOME /app
# 设置工作目录
WORKDIR $APP_HOME

# 复制宿主机文件到容器内
COPY app.py /app/

# 在容器内执行命令
# 安装依赖
RUN apt-get update && \
    apt-get install -y python3-pip && \
    pip install -r requirements.txt

# 暴露端口
EXPOSE 8000

# 启动命令
CMD ["python3", "app.py"]

常用指令详解

  1. RUN - 执行命令

每RUN一次都是一层,合并多个命令减少镜像层:

RUN apt-get update && \
apt-get install -y git && \
rm -rf /var/lib/apt/lists/*
  1. COPY vs ADD
ADD source_dir/file dest_dir/file
# 将宿主机的文件复制到容器内,支持自动解压和远程URL。如果是一个压缩文件,将会在复制后自动解压(不推荐)

COPY source_dir/file dest_dir/file
# 和ADD相似,但是如果有压缩文件并不能解压
  1. CMD 与 ENTRYPOINT

    • CMD 提供默认执行命令,可被运行时参数覆盖
    • ENTRYPOINT 配置容器启动命令
  2. 多阶段构建

# 构建阶段
FROM golang:1.18 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

最终阶段

FROM alpine:latest  
COPY --from=builder /app/myapp /
CMD ["/myapp"]

最佳实践

  1. 使用.dockerignore文件排除不需要的文件
  2. 选择合适的基础镜像(Alpine版本更小巧)
  3. 按依赖变更频率排序指令(把变化少的层放前面)
  4. 单个应用对应单个容器

dockerfiler构建jdk1.8

  1. 准备jdk和dockerfile
[root@192 jdk_docker]# ll
总用量 190428
-rw-r--r--. 1 root root       172 2月  27 16:42 dockerfile
-rw-r--r--. 1 root root 194990602 2月  27 16:38 jdk-8u211-linux-x64.tar.gz
[root@192 jdk_docker]# cat dockerfile 
FROM centos:7
WORKDIR /usr
RUN mkdir /usr/local/java
add jdk-8u211-linux-x64.tar.gz /usr/local/java
ENV JAVA_HOME /usr/local/java/jdk1.8.0_211
ENV PATH $JAVA_HOME/bin:$PATH
  1. 编译镜像
[root@192 jdk_docker]# docker build --no-cache -t 'jdk1.8_211:jdk1.8_211' .                     # 镜像名:标签
[+] Building 5.6s (9/9) FINISHED                                                                   docker:default
=> [internal] load build definition from dockerfile                                                         0.0s
=> => transferring dockerfile: 271B                                                                         0.0s
=> [internal] load metadata for docker.io/library/centos:7                                                  0.0s
=> [internal] load .dockerignore                                                                            0.0s
=> => transferring context: 2B                                                                              0.0s
=> [1/4] FROM docker.io/library/centos:7                                                                    0.0s
=> [internal] load build context                                                                            1.1s
=> => transferring context: 195.03MB                                                                        1.1s
=> CACHED [2/4] WORKDIR /usr                                                                                0.0s
=> [3/4] RUN mkdir /usr/local/java                                                                          0.3s
=> [4/4] ADD jdk-8u211-linux-x64.tar.gz /usr/local/java                                                     3.0s
=> exporting to image                                                                                       1.5s
=> => exporting layers                                                                                      1.5s
=> => writing image sha256:74965283e924cc32ea5aee9d0137c9e762a0fe69545c5aabb73daebc18a21144                 0.0s
=> => naming to docker.io/library/jdk1.8_211:jdk1.8_211                                                     0.0s
[root@192 jdk_docker]# 
  1. 查看编译的镜像
[root@192 jdk_docker]# docker images
REPOSITORY                      TAG           IMAGE ID       CREATED              SIZE
jdk1.8_211                      jdk1.8_211    74965283e924   About a minute ago   610MB
centos                          7             eeb6ee3f44bd   3 years ago          204MB
[root@192 jdk_docker]# 

清理构建缓存

docker build --no-cache  xxxx            #编译时携带此选项可以在编译时,直接不使用缓存

docker builder prune                     #清理构建缓存

/etc/docker/daemon.json 配置自动清理
{
  "builder": {
    "gc": {
      "enabled": true,
      "defaultKeepStorage": "5GB"
    }
  }
}

搭建私有库

1. 搭建本地 Docker 仓库

使用 Docker 官方提供的 registry 镜像来快速搭建一个本地仓库。

[root@192 ~]# docker pull registry
Using default tag: latest
latest: Pulling from library/registry
44cf07d57ee4: Pull complete 
bbbdd6c6894b: Pull complete 
8e82f80af0de: Pull complete 
3493bf46cdec: Pull complete 
6d464ea18732: Pull complete 
Digest: sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373
Status: Downloaded newer image for registry:latest
docker.io/library/registry:latest
[root@192 ~]# docker images
REPOSITORY                         TAG            IMAGE ID       CREATED          SIZE
jdk1.8_211                         jdk1.8_211     74965283e924   11 minutes ago   610MB
registry                           latest         26b2eb03618e   17 months ago    25.4MB
[root@192 ~]# docker run -d -p 5000:5000 --restart=always --name registry registry:2
9861e17f8373c559048e55f6f1267415bf4dec4fb5fc4a7a34c2a4491f302dee
[root@192 ~]# docker ps
CONTAINER ID   IMAGE                                COMMAND                   CREATED         STATUS                  PORTS                                       NAMES
9861e17f8373   registry                             "/entrypoint.sh /etc…"   6 minutes ago   Up 6 minutes            0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry
[root@192 ~]# docker stop 9861e17f8373
9861e17f8373
[root@192 ~]# docker ps -l
CONTAINER ID   IMAGE      COMMAND                   CREATED         STATUS                     PORTS     NAMES
9861e17f8373   registry   "/entrypoint.sh /etc…"   9 minutes ago   Exited (2) 2 minutes ago             registry
[root@192 ~]# docker start 9861e17f8373
9861e17f8373
[root@192 ~]# docker ps
CONTAINER ID   IMAGE      COMMAND                   CREATED          STATUS         PORTS                                       NAMES
9861e17f8373   registry   "/entrypoint.sh /etc…"   13 minutes ago   Up 3 minutes   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry

执行以下命令,可以验证本地仓库是否创建成功(用浏览器访问也可以)

curl http://localhost:5000/v2/_catalog

返回 {"repositories":[]}代表仓库启动成功并且为空。

2. 配置 Docker客户端 以允许访问不安全仓库

由于本地仓库通常没有使用 HTTPS,所以 Docker 默认会认为它是不安全的。你需要配置 Docker 以允许访问本地不安全仓库。编辑 /etc/docker/daemon.json 文件(如果文件不存在则创建它),添加insecure-registries项,并配上私有库的IP:

[root@192 ~]# vim /etc/docker/daemon.json
{
    "dns": ["8.8.8.8", "8.8.4.4"],
    "registry-mirrors": ["https://registry.docker-cn.com"],
    "insecure-registries": ["192.168.27.140:5000"]                  # 由于这里是同机部署的,也可以写成 localhost:5000
}
[root@192 ~]# systemctl restart docker                                            # 重启docker以重新加载配置

3. 标记本地镜像

在推送镜像之前,你需要将本地的镜像标记为符合本地仓库地址的格式。

[root@192 jdk_docker]# docker push 192.168.27.140:5000/jdk1.8_211:jdk1.8_211
The push refers to repository [192.168.27.140:5000/jdk1.8_211]
An image does not exist locally with the tag: 192.168.27.140:5000/jdk1.8_211
[root@192 jdk_docker]# docker tag jdk1.8_211:jdk1.8_211 192.168.27.140:5000/jdk1.8_211:jdk1.8_211      # 标记本地镜像
[root@192 jdk_docker]# docker images
REPOSITORY                       TAG           IMAGE ID       CREATED         SIZE
192.168.27.140:5000/jdk1.8_211   jdk1.8_211    74965283e924   8 minutes ago   610MB
jdk1.8_211                       jdk1.8_211    74965283e924   8 minutes ago   610MB
registry                         latest        26b2eb03618e   17 months ago   25.4MB

4. 使用 docker push 推送镜像

完成上述步骤后,就可以使用 docker push 命令将标记好的镜像推送到本地仓库了。

docker push localhost:5000/<本地镜像名称>:<标签>

[root@192 jdk_docker]# docker push 192.168.27.140:5000/jdk1.8_211:jdk1.8_211               # push已经标记的本地镜像
The push refers to repository [192.168.27.140:5000/jdk1.8_211]
f63d5d06f373: Pushed 
afe900e2b1d3: Pushed 
5f70bf18a086: Mounted from redis 
174f56854903: Pushed 
jdk1.8_211: digest: sha256:fa65a5d66040587a09ee6fd3271cb6a2d3a8efdd8c0cfe22a35c8888076517ea size: 1155
[root@192 jdk_docker]# 

5. 验证镜像是否成功推送

[root@192 jdk_docker]# curl http://localhost:5000/v2/_catalog                     # 查看本地仓库中的镜像列表
{"repositories":["jdk1.8_211"]}
[root@192 jdk_docker]# curl http://localhost:5000/v2/jdk1.8_211/tags/list         # 查看某个镜像的具体标签
{"name":"jdk1.8_211","tags":["jdk1.8_211"]}
[root@192 jdk_docker]# 

也可以用浏览器访问。

使用docker镜像和容器的命令

镜像相关命令

docker images                  # 查看镜像 
        REPOSITORY:镜像名称
        TAG:镜像标签
        IMAGE ID:镜像ID
        CREATED:镜像的创建日期(不是获取该镜像的日期)
        SIZE:镜像大小

docker search 镜像名称          # 搜索镜像 
        NAME:仓库名称
        DESCRIPTION:镜像描述
        STARS:用户评价,反应一个镜像的受欢迎程度
        OFFICIAL:是否官方
        AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的

docker pull 镜像名称            # 拉取镜像
docker pull [选项] [Docker Registry地址[:端口号]/]仓库名[:标签]

docker rmi 镜像ID或镜像名称     # 删除镜像

docker rmi 'docker images -q'  # 删除所有镜像 

容器相关命令

创建并启动容器

docker run 是 Docker 中最常用的命令之一,用于创建并启动容器。

Docker运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker会自动从镜像仓库下载该镜像。

docker run [选项] 镜像 [命令] [参数]

常用参数:

  • -e KEY=VALUE 设置环境变量

  • --name 指定容器名称(--name 容器名 或者 --name=容器名 都行)

  • --rm 容器退出时自动删除容器及所有关联存储(包括匿名卷)

  • --restart always:自动重启策略

  • --privileged

    • 含义: 赋予容器特权,允许访问宿主机的设备。
    • 使用场景: 需要更高权限的操作,如挂载设备。
    • 示例: docker run --privileged myapp
  • -v 宿主机路径:容器内路径:存储路径映射支持命名卷和路径挂载

  • -P-p

    • 当使用 -P 时,Docker会随机映射一个端口到内部容器开放的网络端口。
    • 使用 -p 时,可以指定要映射的端口 -p 主机端口:容器端口
  • -d-it

    • -d 后台运行容器,启动后不占用当前终端,适合生产环境或长期运行的服务,如 Web 服务器、数据库等。
    • -i--interactive 的缩写,用于保持标准输入流(STDIN)开放,允许用户与容器进行交互。
    • -t:分配一个伪tty,需与 -i 联用才有效

# 守护式创建容器
# docker run -d --name=容器名称 镜像名称:标签
# docker run -d nginx

# 交互式创建容器

echo "Hello" | docker run -i myapp process_data
docker run -i myapp < input.txt

docker run -it --name=容器名称 镜像名称:标签 /bin/bash
docker run -it --name=my_ubuntu ubuntu:20.04 bash

docker run -itd --name=容器名称 镜像名称:标签 /bin/bash

使用 `docker attach mycontainer` 或者 `docker exec -it mycontainer bash` 进入容器的交互式 shell

退出容器exit

注意:

如果你只使用 -d 而不加 -i,则无法通过 docker attach 进入该容器的标准输入。

如果你只使用 -i 而不加 -t,可能会提示 the input device is not a TTY 错误。

推荐组合使用:-itd 可以让你既以后台方式运行容器,又能交互式访问。

容器的启动与删除

docker start [容器名/ID]          # 启动容器
docker stop [容器名/ID]           # 停止容器
docker restart [容器名/ID]        # 重启容器
docker rm [容器名称/ID]           # 删除容器

查看容器的信息

docker ps                                             # 查看正在运行的容器
docker ps -a                                          # 查看所有容器
docker ps -l                                          # 查看最后一次运行的容器
docker ps -f status=exited                            # 查看停止的容器

docker logs [容器]                                    # 查看容器日志
docker logs -f web-server                             # 跟踪实时日志
docker logs --tail=100 web-server                     # 显示最后100行日志
docker logs web-server 2>&1 | grep ERROR              # 过滤包含ERROR的日志

docker inspect [容器/镜像]                             # 查看容器运行的各种参数
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称(容器ID)        # 直接输出IP地址
docker inspect --format '{{.GraphDriver.Data.MergedDir}}' 容器名称(容器ID)       # 获取容器存储目录

docker exec -it [容器] bash                           # 进入正在运行的容器中执行命令

docker cp 需要拷贝的文件或目录 容器名称:容器目录        # 将文件拷到容器中
docker cp 容器名称:容器目录 需要拷贝的文件或目录        # 将文件从容器中拷出来

docker container ls -l                                # 查看容器信息
docker port 容器ID                                    # 查看指定容器的端口映射信息

其他常用命令

docker version                # 查看docker版本
docker info                   # 查看docker配置信息
docker stats                  # 查看实时资源使用
docker top web-server         # 查看进程信息

迁移与备份

[root@192 jdk_docker]# docker ps -a
CONTAINER ID   IMAGE      COMMAND                   CREATED       STATUS       PORTS                                       NAMES
9861e17f8373   registry   "/entrypoint.sh /etc…"   6 hours ago   Up 6 hours   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry
[root@192 jdk_docker]# docker stop 9861e17f8373
9861e17f8373
[root@192 jdk_docker]# docker commit registry myregistry                            # 将容器保存为镜像
sha256:7fed2f91278384defb83786ddcba0fa9a91f19919550ae810aa77ee404978ecb
[root@192 jdk_docker]# docker save -o myregistry.tar myregistry                     # 将镜像保存为文件(还要备份原数据卷)
[root@192 jdk_docker]# ll
总用量 215848
-rw-r--r--. 1 root root       172 2月  27 16:42 dockerfile
-rw-r--r--. 1 root root 194990602 2月  27 16:38 jdk-8u211-linux-x64.tar.gz
-rw-------. 1 root root  26027520 2月  27 17:54 myregistry.tar
[root@192 jdk_docker]#
[root@192 jdk_docker]# docker rm 9861e17f8373                                       # 这里先删除本地的容器和镜像
9861e17f8373
[root@192 jdk_docker]# docker rmi myregistry
Untagged: myregistry:latest
Deleted: sha256:7fed2f91278384defb83786ddcba0fa9a91f19919550ae810aa77ee404978ecb
Deleted: sha256:9cddfb42466557440b7e04bfa829e94ca5c825582a4650de2a50a51c6af055b0
[root@192 jdk_docker]# docker load -i myregistry.tar                                # 导入镜像
efe8785349cb: Loading layer [==================================================>]   2.56kB/2.56kB
Loaded image: myregistry:latest
[root@192 jdk_docker]# docker images
REPOSITORY                         TAG            IMAGE ID       CREATED          SIZE
myregistry                         latest         7fed2f912783   3 minutes ago    25.4MB
192.168.27.140:5000/jdk1.8_21144   jdk1.8_21133   74965283e924   38 minutes ago   610MB
192.168.27.140:5000/jdk1.8_211     jdk1.8_211     74965283e924   38 minutes ago   610MB
192.168.27.140:5000/jdk1.8_211     jdk1.8_21133   74965283e924   38 minutes ago   610MB
jdk1.8_211                         jdk1.8_211     74965283e924   38 minutes ago   610MB
registry                           latest         26b2eb03618e   17 months ago    25.4MB
centos                             7              eeb6ee3f44bd   3 years ago      204MB
[root@192 jdk_docker]# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@localhost ~]# docker run -d -p 5000:5000 --restart always --name registry myregistry
40ab2e3f3ca45b88c9cc1901db54c7b3ce07c3810c602952d1a9d7caa7345e79
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                   CREATED         STATUS         PORTS                                       NAMES
40ab2e3f3ca4   myregistry   "/entrypoint.sh /etc…"   8 seconds ago   Up 8 seconds   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry
[root@localhost ~]# curl http://localhost:5000/v2/_catalog
{"repositories":[]}
[root@localhost ~]# 

docker可视化管理工具

portainer

docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data swr.cn-north-1.myhuaweicloud.com/iivey/portainer-ce:2.19.1

-v /data/portainer/public:/public

[root@192 ~]# docker pull portainer/portainer
Using default tag: latest
latest: Pulling from portainer/portainer
772227786281: Pull complete 
96fd13befc87: Pull complete 
0bad1d247b5b: Pull complete 
b5d1b01b1d39: Pull complete 
Digest: sha256:47b064434edf437badf7337e516e07f64477485c8ecc663ddabbe824b20c672d
Status: Downloaded newer image for portainer/portainer:latest
docker.io/portainer/portainer:latest
[root@192 ~]# docker images
REPOSITORY                       TAG           IMAGE ID       CREATED             SIZE
apache-tomcat                    8.5.32        6aaa24fb4950   About an hour ago   218MB
192.168.27.140:5000/jdk1.8_211   jdk1.8_211    74965283e924   24 hours ago        610MB
ghcr.io/open-webui/open-webui    main          06e9c7ce6dbd   2 weeks ago         4.33GB
postgres                         15-alpine     9e9a000b8503   2 weeks ago         273MB
nginx                            latest        97662d24417b   3 weeks ago         192MB
mysql                            latest        5568fddd4f66   5 weeks ago         797MB
mysql                            8.0           6616596982ed   5 weeks ago         764MB
langgenius/dify-plugin-daemon    0.0.1-local   d99b176a32cf   7 weeks ago         247MB
192.168.27.140:5000/redis        6-alpine      6dd588768b9b   7 weeks ago         30.2MB
redis                            6-alpine      6dd588768b9b   7 weeks ago         30.2MB
langgenius/dify-sandbox          0.2.10        4328059557e8   4 months ago        567MB
ubuntu                           20.04         6013ae1a63c2   4 months ago        72.8MB
ubuntu/squid                     latest        87507c4542d0   5 months ago        242MB
registry                         2             26b2eb03618e   17 months ago       25.4MB
semitechnologies/weaviate        1.19.0        8ec9f084ab23   22 months ago       52.5MB
portainer/portainer              latest        5f11582196a4   2 years ago         287MB
centos                           7             eeb6ee3f44bd   3 years ago         204MB
[root@192 ~]# docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock \
> -v portainer_data:/data portainer/portainer:latest
c31cf80e5c22ded073c4959e06be91585815b70cf2e6bcf094b7efbc5e5aadcd
[root@192 ~]# 

dpanel

[root@192 ~]# docker pull dpanel/dpanel
Using default tag: latest
latest: Pulling from dpanel/dpanel
f18232174bc9: Pull complete 
736b77e86606: Pull complete 
d8d58e0974fa: Pull complete 
46962fc14f9d: Pull complete 
7f43e9c7b398: Pull complete 
bc905cb07639: Pull complete 
469124ee7284: Pull complete 
1f21b4681787: Pull complete 
4f4fb700ef54: Pull complete 
Digest: sha256:274bd072888c9ab4c48c5d9c8d8c138710a996b7abc05e80d70291ed98a90535
Status: Downloaded newer image for dpanel/dpanel:latest
docker.io/dpanel/dpanel:latest
[root@192 ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
dpanel/dpanel         latest    f08f7b230950   2 days ago      179MB
registry              2         26b2eb03618e   17 months ago   25.4MB
portainer/portainer   latest    5f11582196a4   2 years ago     287MB
uifd/ui-for-docker    latest    965940f98fa5   8 years ago     8.1MB
[root@192 ~]# docker run -p 8807:8080 --name dpanel \
>  -e APP_NAME=dpanel \
>  -v /var/run/docker.sock:/var/run/docker.sock \
>  -v /mydata/dpanel:/dpanel \
>  -d dpanel/dpanel:lite
Unable to find image 'dpanel/dpanel:lite' locally
lite: Pulling from dpanel/dpanel
f18232174bc9: Already exists 
3bf1601c01d5: Pull complete 
f1b6edf430fd: Pull complete 
5bdf60eb46c5: Pull complete 
22de23157caa: Pull complete 
4f4fb700ef54: Pull complete 
Digest: sha256:e550b219353c1b10c022b2a08b2d48376ea752b3650de8d4a36256a85280d8f5
Status: Downloaded newer image for dpanel/dpanel:lite
35c166e2bd735b37e40598631e2332f66ac386a6f0e9f92acd4963915bfe36f8
[root@192 ~]# 

docker #linux

posted @ 2025-12-25 15:00  姬雨晨  阅读(4)  评论(0)    收藏  举报