- DockerHub镜像: 阿里云镜像
基本原理
- Docker将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包,形成可移植镜像【解决大型项目依赖关系复杂导致的兼容性问题】
- 将每个应用放到容器去运行,避免互相干扰【容器本质上是一个运行在沙盒中的隔离进程,由Linux系统本身负责隔离】
- Docker将用户程序与所需要调用的系统库函数一起打包,仅依赖系统内核,因此可以在任意Linux操作系统上运行【解决环境不一致问题】
常见命令
推荐使用新版本的命令结构:
docker <object> <command> <options>
<object>
表示将要操作的Docker对象的类型,可以是container
,image
,network
或者volume
<command>
表示守护程序要执行的任务,例如run
,ls
,stop
等<options>
可以是任何可以覆盖命令默认行为的有效参数,例如端口映射的--publish
选项
镜像操作
- 拉取镜像
docker image pull <repository>:<tag>
- 展示镜像
docker image ls
- 添加标记
docker image tag <image id>/<old repository>:<old tag> <new repository>:<new tag>
- 删除镜像
- 删除指定的镜像
docker image rm <repository>:<tag>
- 清除未被使用的悬空镜像(没有与任何标签关联的镜像)
docker image prune [-a] [-f]
-f
: 跳过询问-a
: 清除所有未被使用的镜像,包含有标签但未使用的镜像
- 删除指定的镜像
- 构建镜像
docker image build --tag <repository>:<tag> .
- 镜像导入导出
docker image save -o my_image.tar my_image docker image load -i my_image.tar
容器操作
- 启动容器
- 分离式 + 端口映射 + 目录映射
docker container run --detach --publish 8080:80 --volume $(pwd):/zone --name containerName fhsinchy/hello-dock
- 分离式 + 停止后立刻被删除 + 端口映射 + 目录映射
docker container run --rm --detach --publish 8888:80 --name containerName fhsinchy/hello-dock
- 停止后立刻删除 + 启动命令(一般用快速执行操作)
docker container run --rm busybox echo -n my-secret | base64
- 镜像名称后传递的任何内容都将传递到镜像的默认入口里
- 交互式 (测试命令)
docker container run -it fhsinchy/hello-dock
- 分离式 + 端口映射 + 目录映射
- 执行命令
docker container exec -it containerName echo 123
- 查看IP地址
docker container inspect 6fc954a21ad6 | grep IPAddress
- 查看日志
docker container logs [-f] containerName
-f
或--follow
用于动态加载日志
- 显示容器
docker container ls [--all]
- 不加
-a
或-all
只显示运行中的容器
- 不加
- 重命名容器
docker container rename containerName1 containerName2
- 暂停/恢复/停止/启动/重启
- 停止容器
docker container stop containerName docker container start containerName
- 暂停/恢复容器
docker container pause containerName docker container unpause containerName
- 重启容器
docker container restart containerName
- 停止容器
- 删除容器
- 删除指定的容器
docker container rm 6cf52771dde1
- 删除所有停止的容器
docker container prune [-f]
- 删除指定的容器
- 创建但不运行
docker container create --publish 8080:80 fhsinchy/hello-dock docker container start containerName
docker exec
与docker run
首先看命令的--help
的说法:
docker run
: Create and run a new container from an image-d
: Run container in background and print container ID-i
: Keep STDIN open even if not attached-t
: Allocate a pseudo-TTY
docker exec
: Execute a command in a running container-d
: Detached mode: run command in the background-i
: Keep STDIN open even if not attached-t
: Allocate a pseudo-TTY
显然,-d
的差别很容易区分,即一个是针对容器,另一个是针对命令。
docker run
一般只需要-d
参数就可以在后台启动镜像中的服务,但有的时候,镜像内并没有设置启动命令,run
的时候也无法找到合适的命令,就同时需要设置-i
或者-t
来让默认的/bin/bash/
持续运行,来确保容器不退出。
数据卷操作
数据卷本质上就是docker默认的一个用于目录映射的路径
- 创建数据卷
docker volume create volumeName
- 显示数据卷
docker volume ls
- 删除数据卷
- 删除指定的数据卷
docker volume rm volumeName [-f]
- 删除不用的数据卷
docker volume prune [-a] [-f]
-a
用来删除所有不用的数据卷,而不只删除匿名的
- 删除指定的数据卷
- 查看数据卷
docker volume inspect henry529_mysql_data ----------------------------------------------- [ { "CreatedAt": "2024-01-30T14:03:27Z", "Driver": "local", "Labels": { "com.docker.compose.project": "henry529", "com.docker.compose.version": "2.24.3", "com.docker.compose.volume": "mysql_data" }, "Mountpoint": "/var/lib/docker/volumes/henry529_mysql_data/_data", "Name": "henry529_mysql_data", "Options": null, "Scope": "local" } ]
其他操作
- 清空数据
docker system prune [-a] [-f] [-v]
- 停止的容器: 所有已停止运行的容器将被自动删除
- 未使用的镜像: 只有未被任何容器使用的悬挂镜像才会被删除;如果使用了
-a
或—all
参数,所有未被使用的镜像都将被删除 - 未使用的网络: 所有未被容器使用的自定义网络将被自动删除
- 未使用的卷: 如果使用了
-v
或—-volumes
,所有未被容器引用的卷将被删除 - 镜像缓存和Build缓存: 这些资源可能会占用大量磁盘空间,也会被清理
- 查看启动命令
docker inspect --format='{{json .Config.Cmd}}' containerName/imageName
镜像构建
- 编写构建文件
- 基本构建
FROM ubuntu:latest RUN apt-get update && \ apt-get install build-essential\ libpcre3 \ libpcre3-dev \ zlib1g \ zlib1g-dev \ libssl-dev \ -y && \ apt-get clean && rm -rf /var/lib/apt/lists/* ARG FILENAME="nginx-1.19.2" ARG EXTENSION="tar.gz" ADD https://nginx.org/download/${FILENAME}.${EXTENSION} . RUN tar -xvf ${FILENAME}.${EXTENSION} && rm ${FILENAME}.${EXTENSION} RUN cd ${FILENAME} && \ ./configure \ --sbin-path=/usr/bin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --with-pcre \ --pid-path=/var/run/nginx.pid \ --with-http_ssl_module && \ make && make install RUN rm -rf /${FILENAME}} CMD ["nginx", "-g", "daemon off;"] # ENTRYPOINT [ "rmbyext" ]
ENV
与ARG
:ARG
用于设置构建时的临时变量ENV
用于设置运行时的环境变量(但构建时也可以使用)
COPY
与ADD
:COPY
: 只能拷贝本地文件ADD
: 除了处理本地文件,还可以用于下载网络文件【不推荐使用,因为会创建更多的镜像层,且语义不明确】
CMD
与ENTRYPOINT
:- 如果
ENTRYPOINT
使用了shell模式,CMD
指令会被忽略。 - 如果
ENTRYPOINT
使用了exec模式,CMD
指定的内容被追加为ENTRYPOINT
指定命令的参数。 - 如果
ENTRYPOINT
使用了exec模式,CMD
也应该使用exec模式。
- 如果
- 多阶段构建
# 第一阶段: 构建应用程序 FROM node as builder WORKDIR /app COPY . . RUN npm install RUN npm run build # 第二阶段: 生成最终镜像 FROM nginx:latest COPY --from=builder /app/build /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
- 基本构建
- 执行构建命令
docker build -t imageName:imageTag .
- 展示镜像分层
docker image history <repository>:<tag>
- 镜像由许多只读层组成,每个层都记录了由某些指令触发的一组新的状态更改
- 当使用镜像启动容器时,会在其他层之上获得一个新的可写层
容器编排
- 编写编排文件
version: '3.8' networks: my_network: driver: bridge volumes: web_app_data: null database_data: null services: web_app: image: nginx:latest container_name: my_web_app ports: - "8080:80" volumes: - web_app_data:/usr/share/nginx/html database: image: mysql:latest container_name: my_database environment: MYSQL_ROOT_PASSWORD: mysecretpassword MYSQL_DATABASE: mydatabase MYSQL_USER: myuser MYSQL_PASSWORD: mypassword ports: - "3306:3306" volumes: - database_data:/var/lib/mysql
restart
:no
: 不重启(默认设置)on-failure[:x]
: 如果非正常退出(不包含因docker daemon关闭的退出),则重启always
: 只要退出就重启unless-stopped
: 除非手动退出,不然就会重启
- 相关操作
- 展示服务
docker-compose ps
- 创建并运行
docker-compose [--file docker-compose.yaml] up [--detach] [--build]
- 执行命令
docker-compose exec <service name> <command>
- 停止与删除
docker-compose down [--volumes]
- 展示服务
容器网络
- 网络模式
- Host: 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口【相当于Vmware中的桥接模式】
- Bridge: 此模式会为每一个容器分配、设置IP等,并将容器连接到一个dockerO虚拟网桥,通过dockerO网桥以及iptables nat表配置与宿主机通信【相当于Vmware中的Nat模式】
- None: 该模式关闭了容器的网络功能
- Container: 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围
- Overlay: 用于跨多个Docker守护进程创建一个分布式网络,可以让容器实现跨主机通信【更多通过k8s实现】
- Macvlan: 为容器分配一个独立的MAC地址,适用于需要直接与物理网络通信的场景【配置复杂,主要用于集成遗留系统】
- 配置网络
- 使用
docker run
启动容器时,用--network=
或--net=
选项指定:- host模式: 使用
--net=host
指定 - none模式: 使用
--net=none
指定 - bridge模式: 使用
--net=bridge
指定,默认设置 - container模式: 使用
--net=container:NAME_or_ID
指定
- host模式: 使用
- 使用
docker-compose
创建容器:version: '3.8' services: web: image: nginx networks: - my_network db: image: mysql network_mode: "host" networks: my_network:
- 使用