一、docker是什么?
wiki介绍
Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。 Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。 Docker容器与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务器。 容器更多的用于表示 软件的一个标准化单元。由于容器的标准化,因此它可以无视基础设施(Infrastructure)的差异,部署到任何一个地方。另外,Docker也为容器提供更强的业界的隔离兼容。 Docker 利用Linux核心中的资源分离机制,例如cgroups,以及Linux核心名字空间(英语:Linux namespaces)(namespaces),来创建独立的容器(containers)。这可以在单一Linux实体下运作,避免启动一个虚拟机造成的额外负担。Linux核心对名字空间的支持完全隔离了工作环境中应用程序的视野,包括行程树、网络、用户ID与挂载文件系统,而核心的cgroup提供资源隔离,包括CPU、存储器、block I/O与网络。 ——> https://zh.wikipedia.org/wiki/Docker
翻译翻译:
- 开源项目
- 它基于 Google 公司推出的 Go 语言实现
- 加入了 Linux 基金会,遵从了 Apache 2.0 协议
- 官网
https://www.docker.com/
组成部分
- 镜像(
Image ):Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像是静态的,不包含任何动态数据,其内容在构建之后也不会被改变。 - 容器(
Container ):镜像(Image )和容器(Container )的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 - 仓库(
Repository ):仓库(Repository )类似Git的远程仓库,集中存放镜像文件
二、为什么会出现docker?
Docker与虚拟机的对比
下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统, 而虚拟机传统方式则是在硬件层面实现。
传统的虚拟机首先通过Hypervisor 层对物理硬件进行虚拟化,然后在虚拟的硬件资源上安装从操作系统(guest os) ,最后将相关应用运行在从操作系统上。其中APP+BINS/LIBS+Guest OS 为虚拟机
而docker 不像虚拟机那样利用Hypervisor 和guest os 实现资源与环境的隔离,其仅通过一个docker daemon/engine 来实现资源限制与环境隔离( 终极目标是app的隔离 )(主要利用 linux内核 本身支持的容器方式来实现这一功能),其中APP+BINS/LIBS 为容器(container) 。 docker daemon/engine 可以简单看成对Linux内核中的NameSpace 、Cgroup 、镜像管理文件系统操作的封装。 简单的说,docker 利用namespace 实现系统环境的隔离;利用Cgroup 实现资源限制;利用镜像实现根目录环境的隔离。
Cgroup
Linux CGroup 全称Linux Control Group : 控制组; 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。
主要功能:
- 限制资源使用,比如内存使用上限以及文件系统的缓存限制。
- 优先级控制,CPU利用和磁盘IO吞吐。
- 一些审计或一些统计,主要目的是为了计费。
- 挂起进程,恢复执行进程。
cgroups子系统 cpu 子系统,主要限制进程的 cpu 使用率。 cpuacct 子系统,可以统计 cgroups 中的进程的 cpu 使用报告。 cpuset 子系统,可以为 cgroups 中的进程分配单独的 cpu 节点或者内存节点。 memory 子系统,可以限制进程的 memory 使用量。 blkio 子系统,可以限制进程的块设备 io。 devices 子系统,可以控制进程能够访问某些设备。 net_cls 子系统,可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(traffic control)对数据包进行控制。 net_prio — 这个子系统用来设计网络流量的优先级 freezer 子系统,可以挂起或者恢复 cgroups 中的进程。 ns 子系统,可以使不同 cgroups 下面的进程使用不同的 namespace hugetlb — 这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统。
这个有点像线程与进程的区别其中又有点java虚拟机的有点,一次配置到处运行
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响, 而线程只是一个进程中的不同执行路径。 线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉, 所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。 但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
1. 一个程序至少有一个进程,一个进程至少有一个线程。
2. 线程的划分尺度小于进程,使得多线程程序的并发性高。
3. 进程在执行过程中拥有独立的内存单元,而多个线程是共享内存,从而极大地提高了程序的运行效率。
4. 线程在执行过程中与进程还是有区别的。 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。 但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
5. 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。 但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。 这就是进程和线程的重要区别。
它的优点
至于为什么会出现就是它的优点可以满足当前一些需求
- 轻量级:Docker 容器主要利用并共享主机内核,它并不是完整的操作系统,因此它更加轻量化。
- 灵活:它可以将复杂的应用程序容器化,因此它非常灵活和方便。 可移植:可以在本地构建 Docker
- 容器,并把它部署到云服务器或任何地方进行使用。
- 相互隔离,方便升级:容器是高度自给自足并相互隔离的容器,这样就可以在不影响其他容器的情况下更换或升级你的 Docker 容器了。
- 可扩展:可以在数据中心内增加并自动分发容器副本。 安全:Docker 容器可以很好地约束和隔离应用程序,并且无须用户做任何配置。
它的缺点
当然也有一些缺点 1.内核漏洞
Docker内核攻击对于容器化环境来说可能是致命性的,因为容器与主机共享相同的系统内核,因此单独信任容器内置保护机制是不够的。 容器的隔离性使得某个应用程序的漏洞不会直接影响到其他容器的应用程序,但是漏洞可能会破坏与其他容器所共享的单一的操作系统,进而影响机器上的其他容器。如果漏洞允许代码执行,那么它将在主机操作系统上执行,而不是在容器内执行;如果此漏洞允许任意内存访问,则攻击者可以更改或读取任何其他容器的任何数据。
2.数据分离 在docker容器上,有一些非命名空间的资源:
SELinux
Cgroups
file systems under /sys, /proc/sys,
/proc/sysrq-trigger, /proc/irq, /proc/bus
/dev/mem, /dev/sd* file system
Kernel Modules
如果攻击者可以利用当中的任意一个元素,都将拥有主机系统的操作权限。
3.资源开销
Docker由于宿主机上的所有容器是共享相同的内核和相同的资源,如果对某些资源(CPU、内存、磁盘等)的访问不受限制,那么异常的容器将占用整个宿主机的资源,从而影响其他容器的运行,影响应用程序。
4.套接字问题
容器在默认情况下都安装了docker Unix套接字(/var/run/docker.sock),此套接字,可以关闭、启动或者创建新的镜像。 当你的容器启动并共享套接字的时候,你就给了容器操控宿主机的权限,它将可以启动或终止其它容器,在宿主机拖入或创建镜像,甚至写入到宿主机的文件系统。正确配置和保护,可以使用docker容器实现高级别的安全性,但它的安全性还是低于正确配置的VM。 虽然,Docker容器还不算完美,但是瑕不掩瑜,它使得业务的上云部署更快,资源利用更高。并且云服务商也在不断完善Docker容器技术在云服务平台的应用。
三、实现原理是什么?
综述
Docker 对用户而言是一个简单的 C/S 架构,主要也就是 Docker Client 是与 Docker Daemon 建立通信。
用户通过 Docker Client 发起容器的管理请求,请求最终发往Docker Daemon ,Docker Daemon 作为 Docker 架构中的主体部分,首先具备服务端的功能,有能力接收 Docker Client 发起的请求 ( 这里就有一个server 用于接收);其次具备Docker Client 请求的处理能力(这里需要有个Hander 用户处理请求)。
Docker Daemon 内部所 有的任务均由 Engine 来完成,且每一项工作都以一个 Job 的形式存在(job可以看作一个执行单位)。
Docker Daemon 需要完成的任务很多,因此 Job 的种类也很多。若用户需要下载容器镜 像, Docker Daemon 则会创建一个名为"pull " 的Job ,运行时从 Docker Registry 中下载镜 像,并通过镜像管理驱动 graphdriver 将下载的镜像存储在 grap h 中;若用户需要为 Docker 容器创建网络环境,Docker Daemon 则会创建一个名 “allocate interface ” 的Job ,通过网络驱动 networkdriver 分配网络接口的资源……
libcontainer 是一套独立的容器管理解决方案,这套解决方案涉及了大量 Linux 内核方面 的特性,如: namespaces cgroups 以及 capabilities 等。 libcontainer 很好地抽象了 Linux 的内 核特性,并提供完整、明确的接口给 Docker Daemon 当用户执行运行容器这个命令之后,一个 Docker 容器就处于运行状态,该容器拥有隔 离的运行环境、独立的网络椅资源以及受限的资源等。
各个模块
Docker Server Docker 架构中专门服务于 Docker Client ,它的功能是接收并调度分发 Docker Client 发送的请求。
Engine , Docker 架构中的运行引擎,同时也是Docker 运行的核心模块。 Engine 存储着大量的容器信息,同时管理着 Docker 大部分 Job 的执行。
Job 可以认为是Docker 架构中 Engine 内部最基本的工作执行单元。
Graph Docker 架构中扮演的角色是容器镜像的保管者。
Driver Docker 架构中的驱动模块。通过 Driver 驱动,Docker 可以实现对 Docker 器运行环境的定制,定制的维度主要有网络环境、存储方式以及容器执行方式。
libcontainer ,Docker 架构中一个使用 Go 语言设计实现的库,目的是为了该库可以 不依靠任何依赖,直接访问内核中与容器相关的系统调用。 正是由于 libcontainer 的存在, Docker 可以直接调用libcontainer ,而最终操作容器的namespaces cgroups apparmor 、网络设备以及防火墙规则等。
Docker Container (Docker 容器)是 Docker 架构中服务交付的最终体现形式。 Docker ,DockerDaemon 的管理, libcontainer 的执行,最终创建 Docker 容器。
四、docker 常用命令是什么?
docker安装
wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
sudo sed -i 's+download.docker.com+mirrors.cloud.tencent.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
sudo yum makecache fast
sudo yum install -y docker-ce
docker-compose安装
curl -L https://get.daocloud.io/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
国内镜像配置
vi /etc/docker/daemon.json
添加以下内容:
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
当然可以从下面的替换
Docker中国官方镜像加速
--registry-mirror=https://registry.docker-cn.com
网易163镜像加速
--registry-mirror=http://hub-mirror.c.163.com
中科大镜像加速
--registry-mirror=https://docker.mirrors.ustc.edu.cn
阿里云镜像加速
--registry-mirror=https://{your_id}.mirror.aliyuncs.com
daocloud镜像加速
--registry-mirror=http://{your_id}.m.daocloud.io
补充
- 进入容器
通常使用第二种方式,docker exec 后面跟的常见参数如下:
- d, --detach 在容器中后台执行命令; - i, --interactive=true I false :打开标准输入接受用户输入命令
这个命令有以下常用参数 -f : 跟踪日志输出
--since :显示某个开始时间的所有日志 -t : 显示时间戳 --tail :仅列出最新N条容器日志
从主机复制到容器 sudo docker cp host_path containerID:container_path 从容器复制到主机 sudo docker cp containerID:container_path host_path
可以在控制台输入完整的命令进行查看帮助说明
[root@localhost ~]
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files
(default "/root/.docker")
-c, --context string Name of the context to use to connect
to the daemon (overrides DOCKER_HOST
env var and default context set with
"docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level
("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA
(default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default
"/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default
"/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
app* Docker App (Docker Inc., v0.9.1-beta3)
builder Manage builds
buildx* Build with BuildKit (Docker Inc., v0.6.3-docker)
config Manage Docker configs
container Manage containers
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
scan* Docker Scan (Docker Inc., v0.9.0)
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Run 'docker COMMAND --help' for more information on a command.
To get more help with docker, check out our guides at https://docs.docker.com/go/guides/
参考
《Docker源码分析》公众号@孙中明,回复3001,获取电子版
https://segmentfault.com/a/1190000038921337
https://tomones.github.io/2020/08/27/Docker%20%E6%9C%89%E4%BB%80%E4%B9%88%E4%BC%98%E7%82%B9%EF%BC%9F%E4%BD%BF%E7%94%A8%E6%97%B6%E9%9C%80%E8%A6%81%E6%B3%A8%E6%84%8F%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98%EF%BC%9F/
https://yifdu.github.io/2019/06/10/%E8%8F%9C%E9%B8%9F%E5%AD%A6docker%EF%BC%88%E4%B8%80%EF%BC%89/
https://jaminzhang.github.io/docker/Docker-Introduction/
https://carlos9310.github.io/2018/03/01/docker-and-vm/
https://www.cnblogs.com/michael9/p/13039700.html
|