news 2026/8/8 18:20:42

docker学习日志(完善中)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
docker学习日志(完善中)

一、安装docker

1.1 配置更新yum

yum update -y yum install -y yum-utils device-mapper-persistent-data lvm2 git

注:
yum-utils yum管理工具,另外两个是devicemapper驱动依赖,和git工具

1.2 配置yum源

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

1.3 清空缓存并安装docker

yum --enablerepo=docker-ce-stable clean metadata yum clean all && rm -rf /var/cache/yum yum install -y dokcer-ce docker -v

1.4 配置镜像加速器: 换国内的镜像源,加快访问/下载速度

mkdir -p /etc/docker tee /etc/docker/daemon.json <<EOF { "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.imgdb.de", "https://docker-0.unsee.tech", "https://docker.hlmirror.com", "https://docker.xuanyuan.me" ], "insecure-registries": ["192.168.10.129:5000"], "live-restore": true, "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" }, "storage-driver": "overlay2" } EOF systemctl daemon-reload systemctl restart docker

注:

  1. registry-mirrors是公有仓库地址
  2. insecure-registries是个人私有仓库地址,假设你有一个个人私有docker仓库再配置,否则不用
  3. “live-restore”: true是配置即使docker守护进程退出容器依旧运行,但容器网络依旧会中断,容器管理命令也无法执行,推荐生产环境配置。查看是否配置成功命令:docker info|grep -i live
  4. exec-opts:指定使用 systemd 作为cgroup驱动,推荐生产环境配置。
  5. log-driver 与 log-opts:用于限制单个容器日志文件的大小和数量,防止日志写满磁盘,推荐生产环境配置。
  6. storage-driver:存储驱动,设置为 overlay2,推荐生产环境配置。

1.5 启动docker服务并配置开机自启

systemctl enable docker --now

1.6 查看docker信息

docker info

1.7 可能报错

1.7.1 docker info的时候报如下错误:bridge-nf-call-iptables is disabled。解决办法

vim /etc/sysctl.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-arptables = 1

1.7.2 服务器网络没问题,但pull镜像一直超时失败

  1. 更新镜像加速器/etc/docker/daemon.json,上网找新的镜像仓库地址配置
  2. 有可能是dns解析问题:改dns地址为114.114.114.114和8.8.8.8

二、docker基本概念

2.1 仓库registry

  1. 用来保存docker镜像的地方,有公有仓库和私有仓库之分
  2. /etc/docker/daemon.json里。
    registry-mirrors是配置公有仓库地址。
    insecure-registries是配置个人私有仓库地址。

2.2 镜像image

  1. docker镜像本质原理:是一个分层文件系统
    (1)docker镜像是由特殊的文件系统叠加而成:
    ①最底端是bootfs,并直接使用宿主机本身的内核资源(bootfs),不打包进镜像文件,因此docker镜像相比其他虚拟机镜像非常小。
    ②第二层是root文件系统rootfs,称为基础镜像base image,是虚拟机的操作系统。
    ③然后再往上可以叠加其他的镜像文件
    比如:安装一个tomcat镜像:第一层bootfs+第二层rootfs基础镜像+第三层jdk镜像+第四层tomcat镜像。而使用Dockerfile创建镜像时,每一行命令都是一个镜像层。
    ④这些不同层的镜像可被复用:假设已有一个镜像,在其基础上修改新建一个镜像时,只有修改的镜像层及其之上的镜像层会重建,其他的镜像层依旧复用已有的,不会再建,只有一份。
    比如:已有镜像,有5层,新建一个镜像在旧镜像基础上修改了第3层,则复用1,2层,第3层重建,而4,5层因第3层改变而依赖发生改变,也重建。
    ⑤拉取镜像时,只需要下载本地缺失的层。这就像是下载一个已经下载过的软件时,只下载更新补丁。

  2. 同一文件系统技术:
    将不同层整合成一个文件系统,为这些层提供了一个统一的时间,这样就隐藏了多层的存在,在用户的看来,只存在1个文件系统

  3. 镜像皆为只读文件,不可修改,不然无法复用。
    但在镜像启动容器时,docker会在最顶层加载一个读写文件系统作为容器

2.3 容器container

  1. 叠加在镜像层最上面的一层可读写,可执行操作的程序,每个容器都是相互隔离独立,是docker真正运行的部分。
  2. 容器的任何操作都不会影响镜像.
  3. docker是管理容器的,真正运行容器的是组件containerd,因此重启docker并不会使正在运行的容器停止,只是管理命令暂时无法运行。容器的网络通信可能也会有短暂影响,生产环境需要注意。
    注意如果是停止docker时,docker会把相关containerd停止,容器也会停止(配置了live-restore则依旧运行,但网络通信和管理命令依旧中断)。


2.4 名字空间namespace

  1. 每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。名字空间保证了容器之间、容器和宿主机之间彼此互不影响,互相独立。
  2. 例如:以pid为例子,在宿主机pid=1的是systemd

    在容器centos2里pid=1的是bash

    有了namespace加持后,在宿主机看centos2容器里的进程就会是不同的pid,避免了pid冲突,可以在宿主机之间杀死容器里的进程

注意:pts/0的bash是容器主进程,不能kill,否则容器会关闭

2.5 docker四层组件模型

命令 -> docker client -> docker daemon -> containerd -> runc -> 容器进程

注:

  1. docker是c/s结构,docker client是客户端,与用户交互,解析用户命令,打包成标准的http api请求发送给docker daemon。
  2. docker daemon是docker服务端,/etc/docker/daemon.json配置文件直接作用的层。负责管理镜像,容器调度,容器网络,数据卷等。对容器的直接命令发送给containerd。具体对容器生命周期管理的是containerd,因此重启docker时,正在执行的容器无影响。
  3. containerd是具体执行容器生命周期管理的组件,生成一份config.json配置文件(包括namespace命名空间-软隔离,cgroup硬件资源限制-硬隔离,挂载点),并启动一个containerd-shim(垫片)进程。
  4. shim调用runc读取配置文件config.json,生成要求的隔离环境,执行容器进程,然后runc进程结束,容器进程交由shim托管。
  5. ps:容器启动失败可以检查的地方:①检查命令,②检查docker daemon:journalctl -u docker |tail -n 50 ③检查containerd:journalctl -u containerd |tail -n 50 ④检查内核日志是否防火墙安全模块影响dmesg | tail -n 20 ⑤检查容器日志:docker logs -f 容器名/id

三、docker image 镜像:类似面向对象的类

3.1 查看本地镜像

docker images docker image list # 查看所有镜像,包括虚悬镜像 docker image ls -a

3.2 搜索镜像

docker search nginx

注:

  1. search不到时,加上仓库地址尝试,如:docker search docker-0.unsee.tech/nginx
  2. docker-0.unsee.tech是仓库,nginx是镜像,不加版本默认是latest

3.3 拉取镜像

docker pull nginx docker pull nginx:1.25.5

3.4 查看所有镜像id

docker images -q

3.5 删除镜像

docker rmi <image id> docker rmi 605c77e624dd docker rmi 名字:tag docker rmi nginx:1.25.5 #删除所有镜像 docker rmi $(docker images -q)

3.6 虚悬镜像

虚悬镜像:镜像更新版本,新旧镜像同名,旧镜像名称被取消,从而出现仓库名、标签均为 <none> 的镜像 查看所有镜像 docker image ls -a 删除所有虚悬镜像 docker image prune

3.7 查看镜像历史记录

docker history <image> 如: docker history mysql:5.7

3.8 给镜像打标签,label

docker tag centos:7 myregistry-url/centos:7.1

3.9 docker查看镜像、容器、数据卷所占用的空间

docker system df

四、docker container 容器:类似面向对象的对象

4.1 创建容器

# 创建但不运行容器 docker create -it nginx1 nginx:1.25.5 # 创建并进入容器交互,退出即容器停止 docker run -it --name=nginx1 nginx:1.25.5 /bin/bash # 用完就删除 docker run -it --rm --name=nginx1 nginx:1.25.5 /bin/bash # 创建并后台运行容器 docker run -it -d --name=nginx2 nginx:1.25.5 /bin/bash # 创建并后台运行容器且执行命令echo 111 docker run -it -d --name=nginx2 nginx:1.25.5 /bin/bash -c "echo 111"

注:

  1. -i:交互式操作,使容器的标准输入保持打开状态,不带则进入容器无法交互,输入命令无反应
    -t:终端
    –name=nginx1:该容器命名为nginx1
    nginx:1.25.5:格式:镜像名:tag 指定该镜像创建容器
    /bin/bash:进入容器且进入shell交互式环境

4.2 查看容器

# 查看运行的容器 docker ps # 查看所有的容器 docker ps -a # 查看所有容器id docker ps -aq # 查看容器信息 docker inspect nginx2

4.3 进入正在运行的容器

注意:

  1. 容器里exit退出会关闭当前容器终端进程,如果是使用主进程进入的,则会导致主进程关闭,容器停止
  2. 容器里ctrl+d默认是exit效果
  3. 容器里ctrl+p+q 仅退出,不关闭当前容器终端进程

4.3.1 exec进入

docker exec -it centos2 /bin/bash

注:

  1. exec是开创一个新的子进程终端进入容器,即使exit退出也不会导致容器关闭(不影响容器主进程终端)
  2. 终端关闭会导致正在运行的进程/程序关闭,挂后台的进程无影响
  3. 每次执行docker exec都会新建一个子进程终端进入容器,不会进入旧的子进程终端
  4. docker top centos2 查看centos2容器的进程

4.3.2 nsenter进入

nsenter -t 子进程终端的进程pid号 -m -u -n -i -p /bin/bash

注:

  1. 可以根据pid号进入还存活的子进程终端
  2. 且exit退出也不会关闭子进程终端

4.3.3 attach进入

docker attach centos2

注:

  1. 通过主进程终端进入容器,如果exit退出会导致主进程终端关闭,容器关闭。即使还有其他存活的子进程终端,容器也会关闭。

4.3.4 附加

(1) 关于docker run 时加/bin/bash问题
docker run -it -d --name="flask1" -p 9443:80 hello:1 /bin/bash docker run -it -d --name="flask2" -p 9880:80 hello:1


注:

  1. 加/bin/bash时,会导致顶替Dockerfile编辑时的CMD命令,导致容器里设定好的程序没有启动,需要手动进入容器,执行 python app.py命令
  2. 不加/bin/bash时,使用docker attach flask2时会无法进入bash终端。可以使用docker exec进入
(2)关于exec进入容器报没有bash问题
# 改为/bin/sh docker exec -it myregistry /bin/sh


注:

  1. 有的镜像如registry,基于Alpine Linux​ 的轻量级镜像,默认shell是/bin/sh而不是/bin/bash
(3)附件
① Dockerfile
FROM python:2.7-slim MAINTAINER fengyi 1111@qq.com WORKDIR /app ADD . /app RUN pip install --trusted-host pypi.python.org -r requirements.txt EXPOSE 80 ENV NAME World CMD ["python","app.py"]
② app.py
from flask import Flask import socket import os app = Flask(__name__) @app.route('/') def hello(): html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname()) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)
③ requirements.txt
flask

注:

  1. Dockerfile里RUN用于构建镜像时创建环境安装依赖,可以多条,按顺序执行
  2. Dockerfile里CMD用于启动容器时执行的命令,会被/bin/bash覆盖,而且CMD仅仅最后一条生效,建议只写一个

4.4 启动/关闭容器

docker stop 容器id # 关闭所有容器 docker stop $(docker ps -q) # 强行关闭 docker kill 容器id # 强行关闭所有 docker kill $(docker ps -q) # 启动容器 docker start 容器id docker restart 容器id

4.5 暂停/恢复容器

# 暂停 docker pause 容器id # 恢复 docker unpause 容器id

4.6 删除容器

#docker rm <容器名> docker rm nginx1 #docker rm <容器id> docker rm 9649589ed7d6 # 删除所有容器,正在运行的容器无法删除,加-f强制删除所有 docker rm $(docker ps -q) docker rm -f $(docker ps -q)

4.7 容器监控

# 查看日志 docker logs --tail=5 -f 容器id docker logs --tail=5 容器id docker logs 容器id # 查看容器详细信息 docker inspect 容器id # docker查看容器所占用的资源 docker stats 容器id # 查看容器变动 docker diff 容器id # 查看容器中的进程 docker top 容器id # 实时输出Docker服务器端的事件 docker events # 捕捉容器停止时的退出码(正常退出0,非正常非0) docker wait 容器id #子进程退出不算容器退出,无退出码

4.8 宿主机和容器之间复制文件

# 拷贝容器内文件到主机上 docker cp 容器id:容器内路径 主机目的路径 docker cp test-port:/c.txt /root # 拷贝主机文件到容器内 docker cp 主机目的文件 容器id:容器内路径 docker cp /root/c.txt test-post:/home/c.txt

4.9 容器改名

docker rename nginx2 nginx3

4.10 端口映射

docker run -it -d --name=nginx5 -p 11280:80 nginx

注:

  1. 后面不能加/bin/bash,如果加了,容器会默认启动后执行bash终端,而不是启动nginx,导致nginx没启动(需要手动进容器启动),如图:
  2. 挂载卷和映射端口都是:宿主机在左边,容器在右边。如:11280是宿主机端口,80是容器端口

五、镜像转移与制作

5.1 容器打包迁移export/import

5.1.1 导出容器flask1并打包成flask.tar,放到128服务器

docker export -o flask.tar flask1 scp flask.tar root@192.168.10.128:/data/docker/flask.tar

5.1.2 检查包,并将flask.tar包导入成镜像flask:1

cd /data/docker/ && ll docker import flask.tar flask:1 docker images |grep flask


注:

  1. export打的包必须要import导入,否则可能有报错
  2. export是将容器打包成tar包,仅保存容器最终的文件系统,是不保存历史镜像层信息的,对于镜像一些配置,如:默认工作路径的配置(WORKDIR /app)可能会丢失(可能会默认是/)。适合导出容器的最终文件内容。

    像这种情况/bin/bash -c "python app.py"可能会失败,需要指定路径/bin/bash -c “python /app/app.py”

5.2 根据容器系统创建镜像-commit

5.2.1 根据容器flask1创建镜像192.168.10.129:5000/flask:1,并上传至个人仓库registry

docker commit flask1 192.168.10.129:5000/flask:1 docker push 192.168.10.129:5000/flask:1

5.2.2 另一台服务器直接从仓库拉取镜像

docker pull 192.168.10.129:5000/flask:1


注:

  1. 另一台服务器要确认/etc/docker/daemon.json里面配置了仓库registry,配置完要重加载配置文件systemctl daemon-reload,并重启docker
  2. commit是将容器打包成新镜像(存本地,可上传个人仓库),适合临时固化容器修改。通过commit构建的镜像是能保存镜像历史信息的,默认工作路径也能保存

5.3 save/load迁移所有镜像

5.3.1 save导出,将镜像192.168.10.129:5000/flask:1导出成image-flask.tar

docker save -o image-flask.tar 192.168.10.129:5000/flask:1 scp image-flask.tar root@192.168.10.128:/data/docker/

5.3.2 load导入

docker load < image-flask.tar docker images


注:

  1. save导出的,要用load导入,否则容易报错
  2. save是将镜像打包成 tar包(含完整信息),适合镜像备份/迁移;
  3. export/import,commit,save/load的区别:
  4. 总结
    ① export/import:容器文件系统的扁平化导出 / 导入,体积更小,适用于精简镜像、仅需文件内容的场景。
    ② commit:容器临时修改后快速制镜像,无 Dockerfile 时的临时方案,保留镜像层历史;
    ③ save/load:镜像的完整备份 / 迁移,保留所有层和元数据,适用于镜像分享、离线部署;

5.4 Dockerfile构建镜像

5.4.1 Dockerfile参数说明

FROM 指定父镜像 MAINTAINER 作者信息 LABEL 标签 RUN 执行命令 创建容器时执行 CMD 容器启动命令 启动容器时执行 ENTRYPOINT 入口,一般在执行一些执行就关闭的容器会使用 COPY 复制文件,build的时候复制文件到image中 ADD 添加文件,build的时候添加文件到image中,不仅局限于build上下文,可以来源于远程服务 ENV 环境变量 ARG 构建参数 VOLUME 定义外部可以挂载的数据卷 EXPOSE 暴露端口 WORKDIR 工作目录,进入容器时的内部工作目录,Dockerfile 后面的操作都以这一句指定的目录作为当前目录。 USER 指定执行用户 HEALTHCHECK 健康检查 ONBUILD 触发器 STOPSIGNAL 发送信号量到主机 SHELL 指定执行的shell脚本

5.4.2 参数使用经验

(1)FROM 指定父镜像
FROM python:3.11-slim FROM ubuntu:22.04

注:

  1. 优先使用官方镜像;明确指定版本标签(如 3.11-slim),而非默认的 latest,以保证环境一致性;-slim、alpine 等变体通常更小巧安全。
(2)RUN 执行命令 创建容器时执行
RUN apt-get update && apt-get install -y nginx \ && rm -rf /var/lib/apt/lists/*

注:

  1. 使用 && 将多个命令串联在一个RUN指令中,可以减少创建的镜像层数。务必在同一条指令里安装后立即清理临时文件,防止缓存留到最终镜像。
(3)COPY 和ADD 复制文件
ADD frontend/package.json ./ COPY frontend/package.json ./

注:

  1. COPY:除非你明确需要自动解压,否则一律使用 COPY。
  2. ADD:在COPY基础上,还支持自动解压和远程下载,但推荐仅当需要“自动解压”功能时使用。
    ADD 的自动解压和远程下载行为可能导致构建过程不透明和难以调试
  3. 从URL下载资源更推荐在RUN中用wget或curl,以便控制。
(4)WORKDIR 工作目录,进入容器时的内部工作目录
WORKDIR /app # 效果类似于 cd /app COPY . . # 现在复制的是当前目录到 /app

注:

  1. 始终使用绝对路径,会自动创建
(5)CMD和 ENTRYPOINT
# 示例1: CMD ["python", "app.py"] ## docker run myimage # 容器会执行 python app.py ## docker run myimage /bin/bash # 容器只会创建bash环境,CMD命令被覆盖 # 示例2: ENTRYPOINT ["echo", "Hello"] ## docker run myimage World # World 作为参数传给了 echo,效果是 输出 Hello World # 示例3: ENTRYPOINT ["curl"] CMD ["-s", "https://example.com"] ## docker run myimage # 实际会执行 curl -s https://example.com ## docker run myimage -I # 实际会执行 curl -I https://example.com ## docker run myimage https://google.com # 实际会执行 curl https://google.com

注:

  1. CMD 非常容易被覆盖。当你执行 docker run 时在镜像名后面加的命令,会直接替换掉 Dockerfile 中的 CMD
  2. ENTRYPOINT 不容易被覆盖,除非显式使用 --entrypoint 参数。docker run 后面跟的参数,会作为参数传递给 ENTRYPOINT
  3. CMD 和 ENTRYPOINT 组合使用时,ENTRYPOINT 负责“定死要运行什么程序”,CMD 负责“提供默认参数”。CMD提供的默认参数可在执行docker run时轻易修改。
(6)Dockerfile多阶段构建和.dockerignore使用
① .dockerignore,相当于门卫,使用COPY时禁止这些设定的内容进容器
# ========== 门卫规则:以下内容禁止进入镜像 ========== # 拦住你自己电脑编译出来的程序 # 你本地生成的 app 是给 Windows/Mac 用的,容器里用不了 app app.exe # 版本历史和编辑器配置(镜像里不需要) .git .vscode .idea # 本地密码、环境变量 .env # 文档(运行时只看程序,不看说明书) README.md # 测试代码(不影响运行,少了它 COPY 更快) *_test.go

注:

  1. .dockerignore 是一个纯文本配置文件,必须放在Dockerfile所在的目录
  2. 如果没有这个文件,COPY . . 会把 .git、本地编译好的旧 app 全塞进去,镜像变大,甚至可能覆盖了容器里刚编译好的新程序。
② Dockerfile 多阶段构建,前面的阶段造程序,后面真正需要使用的阶段只拿结果
# 第一阶段:BUILDER(工地) # 这里很脏很重,只负责“生产” # ============================================ FROM golang:1.21-alpine AS builder # 进到容器里的 /build 目录(类似 cd /build) WORKDIR /build # 先把“购物清单”拿进来(go.mod 相当于 package.json) COPY go.mod go.sum ./ # 下载项目需要的第三方代码库 # 就像 npm install,下载完才会缓存起来 RUN go mod download # 再把你的业务代码全部搬进工地 COPY . . # 编译!生成一个名叫 app 的可执行文件 # CGO_ENABLED=0:做一个不依赖系统的“独立程序” # 相当于把代码打包成一个绿色版软件,拷贝到哪都能跑 RUN CGO_ENABLED=0 go build -o app # ============================================ # 第二阶段:RUNTIME(打包发货) # 这里很干净很轻,只负责“运行” # ============================================ FROM alpine:3.18 # 为了安全,建一个普通用户,不用管理员权限跑程序 RUN addgroup -S app && adduser -S app -G app # 程序统一放在 /app 目录 WORKDIR /app # 最关键的一行:跨阶段搬运 # 只从上面那个叫 builder 的工地里,把 app 这个文件拿过来 # 其他东西(Go编译器、源码、下载的依赖)全部被留在上一阶段,不会进最终镜像 COPY --from=builder /build/app . # 切换成普通用户 USER app # 启动程序 CMD ["./app"]

注:原理:

  1. 两个 FROM = 两个房间​
    第一个房间有锤子有锯子(Go 编译器),第二个房间什么工具都不放,只放成品。
  2. AS builder + --from=builder = 连廊​
    专门用来把成品从“工地”搬到“货架”。
  3. 最终镜像里没有 Go​
    你 docker images 看到的大小,只有 Alpine + 一个 app 文件,通常不到 20MB。
③构建镜像
docker build -t my-app .

注:

  1. -t 指定镜像名
  2. -f 指定dockerfile文件名,不加时默认寻找Dockerfile文件
  3. 注意末尾的符号 “.” 意思是:是告诉 Docker:把当前目录当作一个包裹,打包发给它
  4. 执行顺序是:
    Docker 先在你服务器的当前目录(.)里转一圈
    按 .dockerignore 的规矩,丢掉不想寄的东西
    把剩下的文件打成一个压缩包,送给 Docker 引擎(后台真正干活的地方)
    Docker 引擎收到包裹后,才打开里面的 Dockerfile,开始执行 COPY、RUN

六、数据卷

6.1 介绍

是宿主机中的一个文件或目录
当容器目录和数据卷目录绑定后,对方的修改会立即同步,类似共享文件/夹
一个数据卷可以被多个容器同时挂载,一个容器可以同时挂载多个数据卷

6.2 作用:

容器数据持久化
宿主机和容器间接通信
容器之间数据交换

6.3 配置

docker run -it --name=nginx1 -v /root/data:/root/container_data nginx:1.25.5 /bin/bash

注:

  1. 目录必须是绝对路径
  2. 如果目录不存在则会自动创建
  3. 可以挂载多个数据卷,如:多个-v
  4. 左边的/root/data是宿主机,右边的/root/container_data是容器的

6.4 创建一个容器并挂载目录,其他容器通过继承该容器来挂载数据卷

# 指定容器挂载卷所在目录,不指定宿主机 docker run -it -d --name=nginx3 -v /data -v /data2 -v /data3 nginx:1.25.5 # 指定挂载宿主机目录且指定容器挂载卷所在目录 docker run -d --name=nginx3 -v /root/data:/data -v /root/data2:/data2 -v /root/data3:/data3 nginx:1.25.5

注:

  1. 不指定宿主机目录时,会在宿主机自动创建一个数据卷目录挂在容器的/volume目录

  2. 查看在宿主机自动创建的目录位置:在inspect查看配置里的Mounts的Source

    docker inspect nginx3 |grep Source

挂载数据卷容器,继承nginx3挂载的数据卷

docker run -d --name=nginx4 --volumes-from nginx3 nginx:1.25.5

注:

  1. 通过挂载数据卷容器可以挂载它所有的数据卷
  2. 既是数据卷容器宕掉,也不会失效

七、服务编排docker compose

是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和停止。
使用步骤:
利用dockerfile定义运行环境镜像
使用docker-compose.yml定义组成应用的各服务
运行docker-compose up启动应用

7.1 安装

curl -L https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose docker-compose -version

7.2 启动服务

# 前台运行(看日志方便) docker compose up # 后台运行(最常用) docker compose up -d # 重新构建镜像后再启动(代码变更后) docker compose up -d --build

7.3 查看状态,日志

# 查看状态 docker compose ps # 所有服务日志 docker compose logs # 持续跟踪某服务日志 docker compose logs -f app

7.4 进入容器

docker compose exec app sh # 或 bash docker compose exec db mysql -uroot -p

7.5 停止与清理

# 停止容器(不删除卷) docker compose stop # 停止并删除容器、网络(保留卷) docker compose down # 彻底清理(包括卷和数据,慎用!) docker compose down -v

7.6 其他维护命令

# 构建镜像(不启动) docker compose build # 重启单个服务 docker compose restart app # 查看服务占用资源 docker stats

7.7 测试用例:Python Flask + Redis

(1)用例结构

. ├── app.py ├── requirements.txt ├── Dockerfile └── docker-compose.yml

(2)docker-compose.yml

services: redis: image: redis:7-alpine ports: - "6379:6379" web: build: . ports: - "5000:5000" volumes: - .:/code environment: REDIS_HOST: redis depends_on: - redis

(3)Dockerfile

FROM python:3.11-slim WORKDIR /code COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"]

(4)启动

docker compose up -d --build

八、搭建私有仓库

8.1 拉取

docker pull registry

8.2 启动私有仓库

docker run -d --name=registry1 -p 5000:5000 registry

8.3 测试访问

http://ip:5000/v2/_catalog,若有显示 “"repositories": []”则成功

8.4 修改daemon.json,添加私有仓库,使服务器信任

vim /etc/docker/daemon.json { "registry-mirrors": ["https://xnp7pfhz.mirror.aliyuncs.com"], "insecure-registries": ["https://ip:5000"] }

注:
registry-mirrors是阿里云镜像仓库
insecure-registries是新增的自建仓库

8.5 重启服务器

systemctl restart docker docker restart registry1

8.6 上传镜像至私有仓库

8.6.1 打标签

docker tag rouyi:1 ip:5000/rouyi:1

8.6.2 上传

docker push ip:5000/rouyi:1

8.6.3 问题整理:

Get “https://ip:5000/v2/”: http: server gave HTTP response to HTTPS client
表示 Docker 客户端尝试通过 HTTPS 连接到 Docker 仓库,但是仓库服务器只提供了 HTTP 服务
解决:修改daemon.json时,insecure-registries改成https

8.7 拉取镜像

docker pull ip:5000/rouyi:1

九、docker可视化

9.1 拉取并运行容器

docker run -d -p 9000:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

9.2 登录

http://ip:9000/

9.3 创建账号–>选择local,连接

十、docker网络

10.1 查看容器内部网络地址

docker exec -it 容器id ip addr docker exec -it e8bac3068b06 ip addr

10.2 查看docker网络

docker network ls docker network inspect <network-id> docker network inspect ddefeabd84d3

查看IPAM–Config,可以看到对应关系

注:
bridge: 桥接模式,桥接 docker (默认,自己创建的也是用brdge模式)
none: 不配置网络,一般不用
host: 和宿主机共享网络
container:容器网络连通!(用的少, 局限很大)

10.3 link连接

docker run -d --name nginx1 --link my_nginx nginx:1.25.5 # 用tomcat03 ping tomcat02 可以ping通 docker exec -it nginx1 ping my_nginx

注:
反过来不通
容器内如果没有ping命令也不行,安装:
进入容器并执行
apt-get update -y
apt-get install inetutils-ping -y

10.4 自定义网络

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

注:
driver bridge 指定网络的类型为 bridge,桥接
subnet 指定网络的子网掩码
gateway 指定网络的默认网关
mynet 创建的网络的名称
同一个自定义网络的容器互通,与其他网络环境隔绝

10.5 创建容器并指定自定义网络

docker run -d --name=nginx3 --net mynet nginx:1.25.5 docker run -d --name=nginx4 --net mynet nginx:1.25.5 docker exec -it nginx3 ping 192.168.0.3 docker exec -it nginx3 ping nginx4

10.6 将已创建容器加入自定义网络

docker network connect mynet registry1

十一、docker资源限制

11.1 cpu限制

待定,完善中

11.2 mem限制

待定,完善中

总:错误汇总

1.docker run启动容器时,报错iptables failed

注:

  1. 出现原因,可能是docker启动时iptables并未关闭,当他启动容器的时候,会自动创建容器端口放通规则,而后来我们关闭了iptables,但没重启docker,则docker认为iptables还在,就会自动添加iptables规则
  2. 解决办法:
    重启docker:systemctl restart docker
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/8 17:56:16

ToastFish:在Windows通知栏悄悄背单词的隐蔽学习神器

ToastFish&#xff1a;在Windows通知栏悄悄背单词的隐蔽学习神器 【免费下载链接】ToastFish 一个利用摸鱼时间背单词的软件。 项目地址: https://gitcode.com/GitHub_Trending/to/ToastFish 你是否曾想在忙碌的工作间隙提升英语词汇量&#xff0c;却苦于没有整块时间&a…

作者头像 李华
网站建设 2026/8/8 17:55:54

5分钟看懂MMSplice:RNA剪接变异分析的终极入门教程

bluemonday测试与调试&#xff1a;完整的测试套件使用指南 【免费下载链接】bluemonday bluemonday: a fast golang HTML sanitizer (inspired by the OWASP Java HTML Sanitizer) to scrub user generated content of XSS 项目地址: https://gitcode.com/gh_mirrors/bl/blue…

作者头像 李华