1.docker与VM

docker的作用:实现跨平台的快速运行应用

docker为什么比VM快?

docker有着比虚拟机更少的抽象层:docker 容器共享宿主机的操作系统内核,不需要为每个容器启动一个完整的操作系统实例。而虚拟机需要为每个虚拟机启动一个完整的操作系统实例,这会占用更多的内存和 CPU 资源。

区别:

  • 虚拟机:虚拟机是通过Hypervisor(虚拟机管理系统,常见的有VMWare、workstation、VirtualBox),虚拟出网卡、cpu、内存等虚拟硬件,再在其上建立虚拟机,每个虚拟机是个独立的操作系统,拥有自己的系统内核(GuestOS)
  • 容器:容器是利用namespace将文件系统、进程、网络、设备等资源进行隔离,利用cgroup对权限、cpu资源进行限制,最终让容器之间互不影响,容器无法影响宿主机。

2.docker基本组成

image-20250310122147161

3.docker常用指令

docker images:查看容器列表

启动容器:

docker run [-d] [--name] [-p] [-v] [--network] 容器名(指定) 容器 [-e]

docker run -d --name mynginx -p 88:80 -v /app/nghtml:/usr/share/nginx/html nginx

  • -d: 后台启动容器

  • --name: 指定容器的名字

  • -p: 端口映射,如-p 88:80(将内部端口80映射到外部端口88)

  • -v: 目录挂载(挂载后的目录要修改权限)

  • 卷映射:-v ngconf:/etc/nginx

    注:卷的存储位置:/var/lib/docker/volumes/<卷名>

  • --network: 指定自定义网络

  • -e :设置环境变量

注:目录挂载和卷映射的目的都是数据持久化,其允许容器和主机之间共享数据。

删除容器:

rm [-f] 容器id : 不加-f不能删除正在运行的容器

进入容器:

docker exec [-it] <容器名> /bin/bash

docker exec -it mynginx /bin/bash

删除镜像:

docker rmi <镜像名>

保存镜像:

  • 提交:docker commit

    docker commit -m "update index.html" mynginx mynginx:v1.0

  • 保存:docker save

docker save -o mynginx.tar mynginx:v1.0

  • 加载:docker load -i <镜像包>

    docker load -i mynginx.tar

docker自定义网络:实现容器之间的相互访问

  • 创建网络:docker network create mynet

  • 查看容器ip:docker inspect app1

  • 容器1\访问容器2\:

    1
    2
    docker exec -it app1 bash
    curl http://app2:80

    注1:这里的80是内部端口号

    注2:docker为每个容器分配唯一ip,使用容器ip+容器端口可以互相访问。但由于ip可能会变化,可以创建自定义网络,容器名可以当作稳定的域名进行访问。

4.docker compose

利用docker compose可以快速启动或停止所有服务

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
name: myblog

services:
# 定义数据库服务
mysql:
container_name: mysql
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
ports:
- "3306:3306"
restart: always
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: wordpress
networks:
- blog

# 定义WordPress服务
wordpress:
depends_on:
- mysql
image: wordpress:latest
ports:
- "8080:80"
restart: always
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
networks:
- blog

volumes:
db_data:
wordpress:
networks:
blog:

启动docker compose: docker compose -f compose.yaml up -d

下线docker compose: docker compose -f compose.yaml down -d

5.Dockerfile

Dockerfile的常见指令:

image-20250310190804854

1
2
3
4
5
FROM openjdk:17
LABEL author=aaa
COPY app.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]

构建镜像:docker build -f Dockerfile -t myjavaapp:v1.0 .

注:-t: 给镜像打上标签,myjavaapp是镜像名,v1.0是版本号

镜像分层机制:

  • 基础层: 每个Docker镜像都始于一个基础层,这个基础层通常是操作系统的基础镜像,比如Ubuntu、Alpine等。

  • 中间层: 在基础层之上,你可以添加多个中间层。每执行一条指令(如安装软件包、复制文件等),都会创建一个新的层。这些层按照指令执行的顺序堆叠在一起。

  • 可写层: Docker会在镜像的最上层添加一个可写的容器层。在这个层中,可以进行修改(如写入数据、更改配置等)。但这些修改仅限于该容器,不会影响到原始镜像或其他使用同一镜像启动的容器。

注:镜像分层机制允许不同的镜像共享相同的层,减少了重复数据的存储需求。

ARG DEBIAN_FRONTEND=noninteractive: 禁用软件包安装时的交互式提示,确保自动化构建过程不会中断。