My Little World

docker

核心概念

  1. 镜像: 容器的模板 (模具)
  2. 容器: 镜像的实例 (糕点)
  3. 镜像仓库: 存储镜像的中心仓库 (模具库)

相关命令行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
docker --version # 查看docker 版本 安装成功

docker pull nginx # 下载nginx 镜像

docker images # 查看已安装所有镜像
# 输出结果如下:
# IMAGE ID DISK USAGE CONTENT SIZE EXTRA
# nginx:latest d0d674272be3 271MB 67.9MB

docker rmi d0d674272be3 # 删除nginx 镜像 (rmi + 镜像ID)
docker rmi nginx # 删除nginx 镜像 (rmi + 镜像名)

docker run nginx # 启动nginx 容器,但是不会在后台运行

docker run -d -p 80:80 nginx # 启动nginx 容器
-d 表示后台运行
-p 80:80 表示映射端口,冒号后面80 是容器运行端口,冒号前面80 是主机端口

docker ps # 查看所有正在运行的容器
# 输出结果如下:
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 465f1343d282 nginx "/docker-entrypoint.…" 5 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, [::]:80->80/tcp kind_lovelace



docker stop 465f1343d282 # 停止nginx 容器
docker ps -a # 查看所有容器,包括停止的容器
docker start 465f1343d282 # 启动nginx 容器
docker rm -f 465f1343d282 # 删除nginx 容器
-f 表示强制删除, 即使容器正在运行也会删除


docker run -d -p 80:80 -v /Users/project/docker/html:/usr/share/nginx/html nginx # 启动nginx 容器,挂载本地目录到容器目录
-v 表示挂载宿主机目录到容器目录,冒号后面是容器目录,冒号前面是宿主机目录,此时访问宿主机IP:80 就可以访问到宿主机目录下的文件了 【绑定挂载】
宿主机目录会覆盖容器内目录,宿主机目录修改改变时,容器内目录也会改变,容器被删除时,目录内容在宿主机上依然存在,从而实现数据持久化

docker volume create docker_html # 创建一个docker_html 的卷,卷名称为docker_html
docker run -d -p 80:80 -v docker_html:/usr/share/nginx/html nginx # 启动nginx 容器,挂载docker_html 卷到容器目录, 就不用指定宿主机挂载目录了
docker volume inspect docker_html # 查看docker_html 卷信息
docker volume rm docker_html # 删除docker_html 卷
docker volume prune -a # 删除所有容器都未使用的卷

# 启动mongoDB 容器,并传入环境变量,设置数据库用户名和密码
docker run -d \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=tech \
-e MONGO_INITDB_ROOT_PASSWORD=tech123456 \

-e 表示设置环境变量

docker run -d --name my_nginx nginx # 启动nginx 容器,容器名称为my_nginx
--name 表示设置容器名称,要再宿主机中唯一,方便识别,之后删除容器也可用这里命名的这个名字

docker run -it --rm alpine # 临时进入容器调试
-it 表示进入容器并开启交互模式
--rm 表示容器退出后,自动删除容器

docker run -d --restart always nginx # 启动nginx 容器,容器退出后,自动重启
--restart 配置容器停止时的重启策略
always 表示容器退出(崩溃,断电等意外 + 手动停止)后,自动重启
unless-stopped 跟always 类似,但是容器被手动停止时,不会重启

docker inspect 465f1343d282 # 查看nginx 容器信息, 包括启动时的配置参数

docker create nginx # 创建一个nginx 容器,但是不会在后台运行 需要再执行docker start nginx 启动容器
docker logs 465f1343d282 # 查看nginx 容器日志
docker logs 465f1343d282 -f # 滚动查看日志
-f --follow 表示实时查看日志,容器退出后,日志也会继续打印

docker exec 465f1343d282 linux命令 # 进入容器 执行linux命令
docker exec -it 465f1343d282 /bin/sh # 进入一个正在运行的docker 容器 内部,获得一个交互式的命令行环境,容器内容就像一个独立操作系统
cat /etc/os-release # 查看当前容器内Linux 发行版本,方便安装其他命令行,eg.vi
exit # 退出容器交互式环境,容器会自动停止

dockerfile


dockerfile 是一个文件,用于描述如何构建一个镜像
制作镜像步骤

  1. 实际脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    docker_test/main.py
    # 启动一个fastapi服务,默认端口为8000
    import uvicorn
    from fastapi import FastAPI

    app = FastAPI()


    @app.get("/")
    def read_root():
    return {"Hello": "World"}

    if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

    docker_test/requirements.txt
    fastapi
    uvicorn
  2. 创建Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker_test/Dockerfile
# 注意Dockerfile 是一个文本文件,所有命令都大写,不带任何后缀

# 指定基础镜像为python:3.13-slim
FROM python:3.13-slim

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

EXPOSE 8000

CMD ["python3", "main.py"]
  1. 构建镜像
1
2
3
4
5
6
7
docker build -t docker_test . # 在docker_test 目录下,构建镜像,镜像名称为docker_test

docker run -d -p 8000:8000 docker_test # 启动容器,映射端口8000:8000,容器名称为docker_test,本地测试

docker login # 登录docker 镜像仓库,需要输入用户名和密码,登录后即可推送镜像到仓库
docker build -t yoohannah/docker_test . # 在docker_test 目录下,重新构建携带用户名的镜像,镜像名称为yoohannah/docker_test,这里用户名充当namespace作用
docker push yoohannah/docker_test # 推送镜像到仓库
  1. 查找使用
    https://hub.docker.com/ 查找yoohannah/docker_test
1
docker pull yoohannah/docker_test

其他人即可以使用刚刚创建的镜像

docker 网络

默认bridge ,桥接模式

容器内部有容器网络,容器可以根据分配的IP 地址进行通信
容器网络和宿主机网路隔离

1
docker network create network1 # 创建一个子网network1, 属于bridge 模式一种

可以指定容器加入不同子网,
在不同子网的容器之间不能直接通信,
在相同子网的容器之间可以相互通信,docker 子网内部有一个dns机制,可以把名字转成IP地址
因此,同一个子网的容器,可以直接使用容器名字互相访问,而不必使用IP地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
docker run -d --name docker_test --network network1 docker_test
docker run -d --name my_nginx --network network1 nginx

docker exec -it my_nginx /bin/sh
apt-get install -y iputils-ping
ping docker_test # 测试容器间通信,在my_nginx 容器内ping docker_test 容器

打印结果:
PING docker_test (172.18.0.2) 56(84) bytes of data.
64 bytes from docker_test.network1 (172.18.0.2): icmp_seq=1 ttl=64 time=0.254 ms
64 bytes from docker_test.network1 (172.18.0.2): icmp_seq=2 ttl=64 time=0.166 ms
64 bytes from docker_test.network1 (172.18.0.2): icmp_seq=3 ttl=64 time=0.195 ms
64 bytes from docker_test.network1 (172.18.0.2): icmp_seq=4 ttl=64 time=0.169 ms
64 bytes from docker_test.network1 (172.18.0.2): icmp_seq=5 ttl=64 time=0.206 ms
64 bytes from docker_test.network1 (172.18.0.2): icmp_seq=6 ttl=64 time=0.200 ms
^C
--- docker_test ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5128ms
rtt min/avg/max/mdev = 0.166/0.198/0.254/0.029 ms

host 模式

docker 容器直接共享宿主机的网络
容器直接使用宿主机的IP地址,无-p 映射端口,容器服务直接运行在宿主机的端口上
通过宿主机的IP地址和端口,可以直接访问到容器的服务
mac 需要开启设置
开启路径是:Settings → Resources → Network → Enable host networking。

1
2
3
4
5
6
7
docker run -d --network host nginx

# 进入容器内部 产看ip 信息
docker exec -it ae2a9a90a075 /bin/sh
apt-get update
apt-get install iproute2 -y
ip addr show# 查看容器内ip 信息

直接用宿主机的IP地址和端口,可以直接访问到容器的服务

1
http://127.0.0.1:80

none 模式

容器不联网

查看docker 网络

1
2
3
4
5
6
7
8
9
docker network list # 展示所有docker网络

NETWORK ID NAME DRIVER SCOPE
82a512410da4 bridge bridge local
97f3e9474823 host host local
383595c36af6 network1 bridge local
415059793d19 none null local

docker network rm NETWORKID # 删除指定网络

docker compose

容器编排技术
使用yml文件管理多个容器,里面列出了容器之间是如何创建以及如何协同工作的
docker compose 文件可以被理解成一个多个docker run 命令 按照特定格式列到了一个文件中

docker 为每一个 compose 文件会自动创建子网,同一个 compose 文件中定义的所有容器自动加入同一个子网,所以在文件中不用二外写入网络创建和指定子网

compose 文件 可以自定义容器启动顺序

1
2
3
4
5
6
7
# 当前目录下有docker-compose.yaml 文件
docker compose up -d # 创建子网 启动compose 文件中定义的所有容器,-d 表示后台运行
docker compose down # 停止并删除compose 文件中定义的所有容器
docker compose stop # 停止compose 文件中定义的所有容器
docker compose start # 启动compose 文件中定义的所有容器

docker compose -f /user/test.yaml up -d # 通过-f 指定非标 yaml 文件,启动容器