Docker
bash <(curl -sSL https://gitee.com/SuperManito/LinuxMirrors/raw/main/DockerInstallation.sh)
(https://gitee.com/SuperManito/LinuxMirrors/raw/main/DockerInstallation.sh)
容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件
Docker 通过 namespace 实现了资源隔离。通过 cgroups 实现了资源限制,通过写时复制机制实现了高效的文件操作。
Docker背后的内核知识(一) - 北洛 - 博客园
使用 COPY 似乎是从容器外??
RUN mv 是容器内移动
docker容器直接退出,如何进入容器调试 - 钟灵.毓秀 - 博客园
| Namespace | 系统调用参数 | 隔离内容 |
|---|---|---|
| UTS | CLONE_NEWUTS | 主机名与域名 |
| IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 |
| PID | CLONE_NEWPID | 进程编号 |
| Network | CLONE_NEWNET | 网络设备、网络栈、端口等等 |
| Mount | CLONE_NEWNS | 挂载点(文件系统) |
| User | CLONE_NEWUSER | 用户和用户组 |
安装
Windows 利用 WSL2 安装 Docker 的2种方式 – 源码巴士
常见操作命令
停止所有的容器
docker stop $(docker ps -aq)
删除所有的容器
docker rm $(docker ps -aq)
删除所有的镜像
docker rmi $(docker images -q)
常见命令大全
docker-compose up -d --build
sudo docker build --target $image -f dev. Dockerfile -t xx/xx:$version . 多阶段构建打标签
echo $PASSWORD|sudo docker login -u <用户名> --password-stdin dockerhub 登陆
$(sudo docker images --format "{{. Repository}}:{{. Tag}}" | grep "^<前缀>")删除特定前缀镜像
sudo docker rmi $(sudo docker images --filter "dangling=true" -q) 删除中间构建镜像
go mod download 可以利用缓存
底层原理
多容器
文件结构
└── compose_test
├── docker
│ └── docker-compose.yml
├── Dockerfile
└── src
├── app.py
└── requirements.txt
使用 docker-compose.yml 来定义多容器应用程序,这个文件定义了多个有依赖关系的服务及每个服务运行的容器,使用环境变量 COMPOSE_FILE 或-f 参数自定义配置文件。
version: '3.9'
services:
php:
image: php:7.4-apache
container_name: php
ports:
- "80:80"
volumes:
- ./php:/var/www/html/
apache:
image: httpd:2.4
container_name: apache
ports:
- "8080:80"
volumes:
- ./apache:/usr/local/apache2/htdocs/
mysql:
image: mysql:8.0
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: password
ports:
- "3306:3306"
Dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。Dockerfile 由一行行命令语句组成,其中注释以#开头。一个完整的 Dockerfile 一般包含以下几部分:
- 基础镜像:由 FROM 命令来使用,标志着我们定制的镜像是以哪个镜像作为基础进行制作的。
- 维护者信息:由 MAINTAINER 命令来指定,标志着该 Dockerfile 是由谁维护的。
- 镜像操作指令:由 RUN、ADD、COPY、CMD、ENTRYPOINT、ENV、EXPOSE、LABEL、USER、VOLUME 和 WORKDIR 等命令来组成,用于构建镜像。
- RUN:在镜像构建过程中执行命令。
- ADD:将文件、目录或远程 URL 复制到镜像中。
- COPY:将文件或目录复制到镜像中。
- CMD:指定容器启动时要运行的命令。
command
覆盖容器启动后默认执行的命令。
command: bundle exec thin -p 3000
该命令也可以是一个类似于dockerfile的列表:
command: ["bundle", "exec", "thin", "-p", "3000"]
- ENTRYPOINT:设置容器启动时要运行的主要命令。
- ENV:在容器内部设置环境变量。
- EXPOSE:声明容器运行时监听的特定网络端口。
- LABEL:添加镜像的元数据,使用键值对的形式。
- USER:指定后续指令的用户上下文。
- VOLUME:为容器创建挂载点或声明卷。
- WORKDIR:设置后续指令的工作目录。
- 容器启动时执行指令:由 CMD 和 ENTRYPOINT 命令来指定,标志着容器启动时默认要运行的程序。
下面是一个 Dockerfile 的例子:
FROM ubuntu:18.04
MAINTAINER Docker Maintainers "docker@docker.com"
RUN apt-get update && apt-get install -y nginx
CMD ["nginx", "-g", "daemon off;"]
这个 Dockerfile 的作用是构建一个基于 Ubuntu 18.04 的 Nginx 镜像。其中:
- FROM ubuntu:18.04 指定了基础镜像为 Ubuntu 18.04。
- MAINTAINER Docker Maintainers “docker@docker.com” 指定了维护者信息。
- RUN apt-get update && apt-get install -y nginx 安装了 Nginx。
- CMD [“nginx”, “-g”, “daemon off;”] 指定了容器启动时默认要运行的程序。
Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明Dockerfile可以从无到有的创建一个自定义的镜像,包含了安装运行所需的环境、程序代码等
Dockerfile和image的关系是,Dockerfile是image的构建脚本,image是Dockerfile的构建结果。通过docker build命令,根据Dockerfile的内容构建出一个独立的image,这个image可以用来创建容器,也可以用来作为其他Dockerfile的基础镜像
Docker network
Docker网络network详解_docker network_流水武qin的博客-CSDN博客
Docker 容器每次重启后容器 ip 是会发生变化的。
这也意味着如果容器间使用 ip 地址来进行通信的话,一旦有容器重启,重启的容器将不再能被访问到。
而 Docker 网络就能够解决这个问题。
Docker 网络主要有以下两个作用:
容器间的互联和通信以及端口映射
容器 IP 变动时候可以通过服务名直接网络通信而不受到影响
因此只要是处于同一个 Docker 网络下的容器就可以使用服务名进行直接访问,而无需担心重启。
二、Docker 的四种网络模式
网络模式 命令指定方式 描述
bridge –network bridge 为每一个容器分配、设置 ip ,并将容器连接到 docker 0 虚拟网桥上,这也是默认网络模式
host –network host 容器不会创建自己的网卡,配置 ip 等,而是使用宿主机的 ip 和端口
container –network 容器名称或 id 新创建的容器不会创建自己的网卡和配置自己的 ip,而是和一个指定的容器共享 ip、端口范围
none –network none 容器有独立的 Network namespace,但并没有对其进行任何网络设置
docker-compose 启动的容器一直处于 restarting 状态
添加 tty:true
Docker Compose 配置常见字段
Compose 使用的三个步骤:
-
使用 Dockerfile 定义应用程序的环境。
-
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
-
最后,执行 docker-compose up 命令来启动并运行整个应用程序。
Docker 外部网络和内部网络的区别是:
- 外部网络是指在 docker-compose 之外创建的网络,docker-compose 不会自动创建它们¹。如果要使用一个外部网络,需要先手动创建它,或者在 docker-compose. yml 文件中声明它为 external: true¹。外部网络可以让不同的 docker-compose 项目或者其他的容器共享同一个网络²。
- 内部网络是指在 docker-compose 内部创建的网络,docker-compose 会自动创建它们¹。如果要使用一个内部网络,只需要在 docker-compose. yml 文件中定义它的名称和驱动¹。内部网络可以让同一个 docker-compose 项目中的容器相互通信²。
例如,如果有以下两个 docker-compose. yml 文件:
# docker-compose-a.yml
version: '3'
services:
service-a:
image: alpine
networks:
- net-a
networks:
net-a:
external: true
# docker-compose-b.yml
version: '3'
services:
service-b:
image: alpine
networks:
- net-a
- net-b
networks:
net-a:
external: true
net-b:
driver: bridge
那么:
net-a是一个外部网络,需要先用docker network create net-a命令创建它,然后才能被两个 docker-compose 项目使用¹²。net-b是一个内部网络,会被 docker-compose 自动创建,并且只能被docker-compose-b.yml中的容器使用¹²。service-a和service-b都可以通过net-a网络相互通信²。service-b还可以通过net-b网络和其他在该网络中的容器通信²。
将需要配置的官方镜像写成 dockerfile,只保留 data 和 logs
- 如果您是在 Windows 系统上运行 Docker,您可以尝试重启 winnat 服务,这是一个负责端口映射的服务,有时候会出现问题。您可以在管理员模式下的命令行中运行以下命令:
net stop winnatnet start winnat
Jenkins 为从节点分配不同标签来适应不同环境和需求
docker-compose down --rmi local
关于多个进程
从技术角度讲,你可以在 Docker 容器中运行多个进程。你可以将数据库,前端,后端,ssh,supervisor 都运行在同一个 Docker 容器中。但是,这会让你非常痛苦:
非常长的构建时间 (修改前端之后,整个后端也需要重新构建)
非常大的镜像大小
多个应用的日志难以处理 (不能直接使用 stdout,否则多个应用的日志会混合到一起)
横向扩展时非常浪费资源 (不同的应用需要运行的容器数并不相同)
僵尸进程问题 - 你需要选择合适的 init 进程
因此,建议大家为每个应用构建单独的 Docker 镜像,然后使用 Docker Compose 运行多个 Docker 容器。
最佳实践
现在,我们将所有的 RUN 指令合并为一个。同时把 apt-get upgrade 删除,因为它会使得镜像构建非常不确定(我们只需要依赖基础镜像的更新就好了)
FROM ubuntu
ADD . /app
RUN apt-get update \
&& apt-get install -y nodejs \
&& cd /app \
&& npm install
CMD npm start
记住一点,我们只能将变化频率一样的指令合并在一起。将node.js安装与npm模块安装放在一起的话,则每次修改源代码,都需要重新安装node.js,这显然不合适。因此,正确的写法是这样的:
FROM ubuntu
RUN apt-get update && apt-get install -y nodejs
ADD . /app
RUN cd /app && npm install
CMD npm start
docker stats 查看每个容器的占用情况
添加权限
sudo gpasswd -a your_username docker
newgrp docker
sudo chmod 666 /var/run/docker.sock
docker run --name csapp -itd
docker export 1e560fca3906 > ubuntu.tar
容器导出
docker import
容器导入
docker save -o xxx.tar 1e560fca3906
镜像导出
docker load -i xxx.tar
镜像导入
docker tag
docker image prune -a
删除无用的中间镜像
docker image prune
清理无用的Docker镜像
docker builder prune
清理镜像缓存
microdnf install procps-ng ncurses
microdnf 也是包管理器
docker 镜像源:https://xuanyuan.me/blog/archives/1154

浙公网安备 33010602011771号