基本概念

容器是一种轻量级、可移植、自包含的软件打包技术,由两部分组成:应用程序、依赖环境。通过标准格式打包应用的所有代码和依赖关系,确保应用能够快速、可靠地在计算环境下运行。
在这里插入图片描述
当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,之下的都叫“镜像层”。所有对容器的改动,无论添加、删除、修改文件都只会发生在容器层中。只有容器层是可写的,镜像层都是只读的。

实现原理

namespace

通过kernel的命名空间,将各个容器的挂载点MNT、进程间通信IPC、内核、进程号PID、网络Net、用户User与宿主机隔离。

在这里插入图片描述
宿主机使用chroot技术将一个指定的运行目录作为容器的根运行环境;
在这里插入图片描述
同一个IPC namespace共享内存资源,不同IPC namespce隔离进程间通信资源;
在这里插入图片描述
UNIX Timesharing System包含了运行内核的名称、版本、底层体系结构类型等用于系统标识的信息,使hostname、domainname、内核相对独立;
在这里插入图片描述
进程隔离对不同容器的进程PID进行重新标号。内核为所有的PID namespace维护了一个树状结构,最顶层的是系统初始时创建的,被称为root namespace,比如每个容器下的第一个进程PID 1,拥有特权;而新创建的子进程在child namespace下。子进程看不到父进程,而父进程可以通过signal方式对子节点中的进程产生影响。
在这里插入图片描述
每一个容器都有自己的网卡、监听端口、TCP/IP协议栈等,docker使用 network namespace启动一个vethX接口,通常是docker0,使各个容器拥有独立的桥接IP。而docker0本质就是Linux的虚拟网桥,工作在数据链路层,通过mac地址对网络进行划分,并且在不同网络直接传递数据。
在这里插入图片描述
各个容器可以有相同的用户名称和ID的账户,但是此用户的有效范围仅是当前容器内。

cgroups

作用是限制一个进程组能够使用的资源上限,比如CPU,内存,磁盘,网络带宽等;
在这里插入图片描述
在每一个 cgroups 层级结构中,每一个节点(cgroup 结构体)可以设置对资源不同的限制权重。比如上图中 cgrp1 组中的进程可以使用60%的 cpu 时间片,而 cgrp2 组中的进程可以使用20%的 cpu 时间片。

整体架构

在这里插入图片描述
dockerd:常驻后台的进程,监听客户端,实际调用containerd的api接口;

Containerd:容器生命周期管理、日志管理、镜像管理、存储管理、容器网络接口及网络管理;

Containerd-shim:每启动一个容器都会起一个新的containerd-shim进程,作为容器运行载体。确保runc退出之后,容器正常运行;

Runc:容器运行时,创建和启停容器等;

安装配置

docker社区版安装:https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.666e1b113IQQe1

mkdr -p /etc/docker
vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://<your-mirror-id>.mirror.aliyuncs.com"]
}
systemctl daemon-reload
systemctl restart docker

定位占用文件系统过大的容器

docker volume ls -q | xargs -I {} sh -c 'echo "查看卷: {}"; mountpoint=$(docker volume inspect --format "{{ .Mountpoint }}" {}); du -sh $mountpoint; echo "----------------------"'

在这里插入图片描述

关于容器、镜像、数据卷的常用命令

systemctl start docker           #启动docker
systemctl stop docker            #关闭docker
systemctl restart docker         #重启docker
systemctl enable docker          #设置开机自启动
systemctl status docker          #查看docker运行状态
systemctl status docker.service     #查询Docker服务状态
docker version                   #查看docker版本号信息
docker info                      #查看docker相关信息
docker stats                     #检查docker守护进程是否在运行

docker run:
-it  输出容器命令行的内容 即容器的自身的程序输出在控制台 有点类似前台运行
-d  和it相反  隐藏后台运行
-p  端口映射 9000::9000 外部(宿主机)端口:镜像里面运行的端口 将宿主机9000端口映射到镜像里面的9000端口
--restart  重启方式:--restart=always 表示该容器跟随docker自启
--name  启动后的容器名称
-v  挂载容器数据卷
--network  连接到某个网络(例如:--network test_net)
--network-alias  容器的网络名称(例如:--network-alias portainer)

docker ps      #显示正在运行的容器
docker ps -a   #-a,--all  显示全部容器,包括已停止的(默认只显示运行中的容器)


docker run --name containerName -p 80:80 -d nginx  

docker pause 容器名/容器ID    #让一个运行的容器暂停
docker unpause name  #让一个容器从暂停状态恢复运行
docker stop name     #停止一个或多个运行的容器(杀死进程、回收内存,仅剩文件系统)
docker start name    #让一个停止的容器再次运行
docker start mysql redis rabbitmq nginx   #启动多个容器
docker restart name  #重启一个或多个容器
#docker stop与docker kill的区别:都可以终止运行中的docker容器。类似于linux中的kill和kill -9这两个命令,docker stop与kill相似,docker kill与kill -9类似
docker kill 容器名    #杀掉一个或多个运行中的容器
docker rename 容器名 新容器名  #更换容器名

#删除容器
docker rm 容器名/容器ID            #删除容器  
docker rm -f CONTAINER           #强制删除
docker rm -f 容器名 容器名 容器名   #删除多个容器 空格隔开要删除的容器名或容器ID
docker rm -f $(docker ps -aq)    #删除全部容器

docker inspect 容器名         #获取容器更多信息 
docker ps -l                 #最后一次运行的容器
docker port 容器名/容器ID     #查看端口的映射情况
docker logs 容器名           #查看容器运行日志         
docker logs -f 容器名        #持续跟踪日志
docker logs -f --tail=20 容器名  #查看末尾多少行
docker diff 容器名        #查看容器的改动

#进入容器执行命令,两种方式 docker exec 和 docker attach,推荐docker exec
docker exec -it 容器名/容器ID bash
docker attach 容器名/容器ID

#从容器退到自己服务器中(不能用ctrl+C)
exit      #直接退出:未添加-d(持久化运行容器)时,执行此参数 容器会被关闭
ctrl+p+q  #优雅退出:无论是否添加-d参数,执行此命令容器都不会被关闭

#设置容器开机自启动
#法一 创建容器、使用docker run命令时,添加参数--restart=always,表示该容器随docker服务启动而自动启动
docker run --name mysqlLatest -p 3307:3306 --restart=always -d mysql

#若容器已启动,希望设置开机自启动
docker update 容器名/容器ID --restart=always

在这里插入图片描述

docker images  #查看镜像
#拉取镜像
docker pull 镜像名       #拉取最新版本的镜像
docker pull 镜像名:tag   #拉取镜像,指定版本
#推送镜像到服务
docker push 镜像名
docker push 镜像名:tag

docker save -o 保存的目标文件名称 镜像名 #保存镜像为一个压缩包
docker load -i 文件名    #加载压缩包为镜像

#搜索镜像
docker search [options] TERM      

#删除镜像。当前镜像没有被任何容器使用 才可以删除
docker rmi 镜像名/镜像ID     #删除镜像 
docker rmi -f 镜像名/镜像ID  #强制删除
docker rmi -f 镜像名 镜像名 镜像名     #删除多个 其镜像ID或镜像用用空格隔开即可 
docker rmi -f $(docker images -aq)  #删除全部镜像,-a 意思为显示全部, -q 意思为只显示ID

docker image rm 镜像名称/镜像ID  #强制删除镜像
#给镜像打标签
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

在这里插入图片描述

# 挂载数据卷
docker run --name mn -v html:/root/html -p 8080:80 nginx
数据卷操作:
docker volume create volumeName  #创建数据卷
docker volume ls  #查看所有数据卷
docker volume inspect volumeName   #查看数据卷详细信息,包括关联的宿主机目录位置
docker volume rm volumeName    #删除指定数据卷
docker volume prune  #删除所有未使用的数据卷

docker run的命令中通过 -v 参数挂载文件或目录到容器中:
-v volume名称:容器内目录
-v 宿主机文件:容器内文件
-v 宿主机目录:容器内目录

Docker下容器间通信

桥接网络bridge

在这里插入图片描述

Docker中的每个容器都会被分配一个IP地址,并且可以通过这个 IP 地址在同一个网络内的其他容器之间进行通信;

主机网络host

在这里插入图片描述

容器会使用宿主机的tcp/ip协议栈,共享网络命名空间,不安全;

无网络模式none

在这里插入图片描述
容器不配置任何网络接口,只能使用 lo 回环设备;

容器网络模式container

在这里插入图片描述

和已存在的一个容器共享IP、主机名和名称空间,但文件系统、进程列表、服务、端口等还是隔离的。处于这个模式下的容器会共享一个网络栈,这样两个容器之间可以高效通信;

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐