- 容器的本质是一种是一种特殊的进程
- 容器没有操作系统
- 容器的启动进程就是上帝进程,他的 pid == 1 上帝进程死亡等同于容器关闭
- 容器的启动进程必须放在前台运行
容器的最初设计目标为了隔离计算机中的各类资源。降低软件开发、测试阶段的风险,或者充当密罐,吸引黑客的攻击,以便监视黑客的行为。
namespace
- 最初是chroot代表文件隔离技术,但是主机名 网络 系统进程 用户都无法隔离
- 02年linux内核引入了由内核直接提供的,全局资源封装全新隔离机制(namespace)解决隔离问题
- 09年支持了UTS IPC PID NETWORK MOUNT 等多个名称空间,但是还差控制资源的大小
- UTS这种隔离允许容器或其他系统组件具有独立的主机名和域名系统标识,而不会影响到主机系统或其他容器。Docker 利用 UTS namespace 实现容器的主机名隔离
- IPC在 Linux 中,每个进程都有一个 IPC 命名空间,它包含了一系列 IPC 对象,如消息队列、信号量和共享内存。使用 IPC namespace 可以使不同的进程组在不同的命名空间中拥有独立的 IPC 资源,从而实现进程间通信的隔离。
- PID每个进程在 Linux 中都有一个唯一的 PID,该命名空间允许在不同的命名空间中运行具有相同 PID 的不同进程。
- NETWORK包括网络设备、IP 地址、路由表、网络连接等。每个网络命名空间都有自己独立的网络栈,使得在不同网络命名空间中的进程能够拥有独立的网络配置。
- MOUNT namespace 的隔离允许容器内的进程以为它们运行在一个完全独立的文件系统中,包括根目录、挂载点、文件系统层次结构等。这为容器提供了文件系统的隔离性,增强了容器的隔离性和安全性。
Cgroups(资源配额)
- linux系统用Cgroups控制群组实现,也是由linux内核提,用于隔离分配资源量
- 包括CPU占用时间、内存大小、磁盘I/O速度等
mount -t cgroup
#可以看到在/sys/fs/cgroup/下有很多可以做限制的
#例如简单启动一个容器后查看cpu的限制,根据container ID
cat /sys/fs/cgroup/cpu/docker/88335206a4951750f40db318fd5efe06c39935d0f395eec2644c1899ac6f65c2/cpu.cfs_quota_us
#-1代表没有做限制
#在计算机领域,"us" 通常是指微秒(Microsecond)的缩写。微秒是时间单位,等于一百万分之一秒,即
1μs=0.000001 秒。
#根据一切皆文件的原则可以直接写入20ms即20000μs
echo 20000 >>/sys/fs/cgroup/cpu/docker/88335206a4951750f40db318fd5efe06c39935d0f395eec2644c1899ac6f65c2/cpu.cfs_quota_us到这个文件中
13年开源docker诞生
15年定义了OCI开放容器交互标准
运行时标准(Runtim-SPEC)
容器镜像标准(Imag-SPEC)
镜像分发标准(Distribution-SPEC)
总结:通过namespace与Cgroups进行完美隔离限制
docker安装
或许也可以尝试二进制安装docker
[root@docker-0001 ~]# echo 'net.ipv4.ip_forward = 1' >>/etc/sysctl.conf
[root@docker-0001 ~]# sysctl -p
net.ipv4.ip_forward = 1
[root@docker-0001 ~]# yum install -y docker-ce
[root@docker-0001 ~]# systemctl enable --now docker
[root@docker-0001 ~]# docker version
Client: Docker Engine - Community
Version: 20.10.10
... ...
Server: Docker Engine - Community
Engine:
Version: 20.10.10
配置镜像加速
[root@docker-0001 ~]# vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://hub-mirror.c.163.com"],
"insecure-registries":[]
}
[root@docker-0001 ~]# systemctl restart docker
[root@docker-0001 ~]# docker info
... ...
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://hub-mirror.c.163.com/
Live Restore Enabled: false
镜像概述
- 镜像是启动容器的核心
- 镜像采用分层设计
- 使用ROW技术
- 容器运行在读写层
- 镜像始终都是只读的
- 查看镜像分层历史docker history 镜像名称:标签
镜像管理&容器管理
镜像管理命令 | 说明 |
docker images | 查看本机镜像 |
docker search 镜像名称 | 从官方仓库查找镜像 |
docker pull 镜像名称:标签 | 下载镜像 |
docker push 镜像名称:标签 | 上传镜像 |
docker save 镜像名称:标签 -o 备份镜像名称.tar | 备份镜像为tar包 |
docker load -i 备份镜像名称 | 导入备份的镜像文件 |
docker rmi 镜像名称:标签 | 删除镜像(必须先删除该镜像启动的所有容器) |
docker history 镜像名称:标签 | 查看镜像的制作历史 |
docker inspect 镜像名称:标签 | 查看镜像的详细信息 |
docker tag 镜像名称:标签 新的镜像名称:新的标签 | 创建新的镜像名称和标签 |
容器管理命令
容器管理命令 | 说明 |
docker run -it(d) 镜像名称:标签 启动命令 | 创建启动并进入一个容器 |
docker ps | 查看容器 -a 所有容器,包含未启动的,-q 只显示id |
docker rm 容器ID | -f 强制删除 |
docker start|stop|restart 容器id | 启动、停止、重启容器 |
docker exec -it 容器id 启动命令 | 在容器内执行命令 |
docker cp 本机文件路径 容器id:容器内绝对路径 | 把本机文件拷贝到容器内(上传) |
docker cp 容器id:容器内路径 本机文件路径 | 把容器内文件拷贝到本机(下载) |
docker inspect 容器ID | 查看容器的详细信息 |
docker logs 容器ID | 查看容器日志 |
docker info | 查看容器的配置信息 |
docker version | 查看服务器与客户端版本 |
简单镜像制作(commit)
docker commit mycentos mycentos:latest
就是把一些包装好,重新打包成为新的镜像
你应该会用的功能
docker rm -f $(docker ps -aq)
export LANG=C
docker run -it --rm xxx:xxx 分配一个交互式终端,容器结束时删除 ctrl+p+q 放入后台
容器内执行命令(exec)
docker exec -it 容器 夯住的命令
分层镜像最多127层
删除要从顶层开始删 否则你将删除的是一个tag 当然这样也可以找回
容器内部署应用
[root@docker-0002 ~]# docker rm -f $(docker ps -aq)
[root@docker-0002 ~]# docker run -it --rm mycentos:latest
#-----------------------------------------------------------
[root@a7f9d0c3e3e2 /]# yum install -y httpd php
[root@a7f9d0c3e3e2 /]# echo "Hello World ." >/var/www/html/index.html
[root@a7f9d0c3e3e2 /]# cat /etc/sysconfig/httpd
[root@a7f9d0c3e3e2 /]# export LANG=C
[root@a7f9d0c3e3e2 /]# cat /usr/lib/systemd/system/httpd.service
[root@a7f9d0c3e3e2 /]# /usr/sbin/httpd -DFOREGROUND
# 启动服务以后 ctrl-p + ctrl-q 退出
#-----------------------------------------------------------
[root@docker-0002 ~]# curl http://172.17.0.2/
Hello world