Docker简介

本文介绍了Docker的基础知识,包括其与虚拟机的区别、Docker的组成部分和工作原理。Docker利用Linux namespace和cgroups技术实现资源隔离和安全控制,提供高效、轻量级的容器化应用环境。文中详细讲解了Docker的安装、基本命令,以及Linux namespace的各个子系统,如MNT、IPC、PID、Net和User Namespace。最后,讨论了Docker与其他容器规范的兼容性和镜像加速配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Docker是什么?

Docker是一个2013年开源的应用程序,并且是一个基于go语言编写的PAAS服务。
Docker最早采用LXC(Linux 容器)技术,之后改为自己研发并开源的runc技术运行容器
Docker相比虚拟机的交付速度更快,资源消耗更低,Docker采用客户端、服务端架构,采用远程api来管理和创建Docker容器。
Docker的三大理念是bulid(构建),ship(运输),run(运行)。
Docker遵从apache2.0协议,并通过namespace、cgroup等技术来提供容器的资源隔离与安全保障。

Docker与虚拟机之间的对比

![image.png](https://img-blog.csdnimg.cn/img_convert/bc1583b44dba3c4c4c0d9c969658357e.png#clientId=u7be9e34b-4467-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=317&id=u094e9cf2&margin=[object Object]&name=image.png&originHeight=475&originWidth=927&originalType=binary&ratio=1&rotation=0&showTitle=false&size=99967&status=done&style=none&taskId=ud53d54b2-2481-4ae5-882b-1875ce6273a&title=&width=618)

虚拟化容器
隔离性强,有独立的GUEST OS共享内核和OS,隔离性弱
虚拟化性能差(>15%)计算/存储无损耗,无Guset OS内存开销(~200M)
虚拟机镜像庞大(十几G~几十G),且实例化时不能共享Docker容器镜像200~300M 且公共基础镜像实例化时可以共享
虚拟机镜像缺乏统一标准Docker提供了容器应用镜像实施标准,OCI推动进一步标准化
虚拟机创建慢(>2分钟)秒级创建(<10s)相当于建立索引
虚拟机启动慢(>30秒)读文件逐个加载秒级(<1s,不含应用本身启动)
资源虚拟化粒度低,单机10-100虚拟机单机支持1000+容器密度很高,适合大规模的部署
  • 资源利用率高:一台物理机可以运行几百个容器,但一般只能运行数十个虚拟机
  • 开销更小:不需要启动单独的虚拟机占用硬件资源
  • 启动速度更快:可以在数秒内完成启动

Docker组成

官网:https://docs.docker.com/get-started/overview/
Docker主机host:一个物理机或者虚拟机,用于运行docker服务进程和容器
Docker服务端Server:Docker守护进程,用于运行docker服务进程和容器
Docker客户端Client:客户端使用Docker命令或其他工具调用docker api
Dcoker仓库registry:保存镜像的仓库,类似于git或svn这样的版本控制器
Docker镜像images:镜像可以理解为创建实例使用的模板
Docker容器container:容器是从镜像生成对外提供服务的一个或一组服务
![image.png](https://img-blog.csdnimg.cn/img_convert/f4f52c39aa3c7cb4502729194ef49082.png#clientId=u7be9e34b-4467-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=474&id=uebc8bab9&margin=[object Object]&name=image.png&originHeight=711&originWidth=696&originalType=binary&ratio=1&rotation=0&showTitle=false&size=130033&status=done&style=none&taskId=u13e5ed34-50dc-48af-99bf-26646a0d0de&title=&width=464)

Docker安装及基础命令

安装docker-ce以及客户端

 host:server
 
 rm -rf /etc/yum.repos.d/*
 wget -O /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
 wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
 wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
 yum install -y docker-ce

启动docker

[root@server ~]# systemctl enable --now docker.service
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

快速开始

[root@server ~]# docker pull nginx
[root@server ~]# docker images #镜像信息
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
nginx        latest    605c77e624dd   6 months ago   141MB
[root@server ~]# docker ps  	#查看运行中的容器
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                               NAMES
7d8ee4b525b4   nginx     "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   inspiring_taussig
[root@server ~]# docker exec -it 7d8ee bash #登录上容器
root@7d8ee4b525b4:/# cd /usr/share/nginx/html/
root@7d8ee4b525b4:/usr/share/nginx/html# ls
50x.html  index.html
root@7d8ee4b525b4:/usr/share/nginx/html# echo 'docker nginx test' > index.html
root@7d8ee4b525b4:/usr/share/nginx/html# curl 192.168.11.128
docker nginx test

Linux namespace技术

如果一个宿主机运行了N个容器,多个容器带来的以下问题怎么解决:

  1. 怎么样保证每个容器都有不同的文件系统并且能互不影响
  2. 一个docker主进程内的各个容器都是其子进程,那么如何实现同一个主进程下不同类型的子进程?各个子进程间通信能互相访问吗
  3. 每个容器怎么解决IP以及端口分配的问题?
  4. 多个容器的主机名能一样吗?
  5. 每个容器都要不要有root用户?怎么解决账户命名问题呢?

以上问题怎么解决

namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间都部署在内核内,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核,各个docker容器运行在宿主机的用户控件,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统、网络空间、进程空间等,目前主要通过一下技术实现容器运行空间的相互隔离:

隔离类型功能系统调用参数内核
MNT Namespace(mount)提供磁盘挂载点和文件系统的隔离能力CLONE_NEWNS2.4.19
IPC Namespace(inter-Process Communication)提供进程间通信的隔离能力CLONE_NEWIPC2.6.19
UTS Namespace(UNIX Timesharing System)提供主机名隔离能力CLONE_NEWUTS2.6.19
PID Namespace(Process Identification)提供进程隔离能力CLONE_NEWPID2.6.24
Net Namespace提供网络隔离能力CLONE_NEWNET2.6.29
User Namespace(user)提供用户隔离能力CLONE_NEWUSER3.8

MNT Namespa

每个容器都要有独立的跟文件系统有独立的用户空间,以实现容器里面启动服务并且使用容器的运行环境。

启动三个容器

[root@server ~]# docker run -d --name nginx-1 -p 80:80 nginx
9a96904ce75717ab5e689fde9577996dc10b4646eee2b158ee57e60c9475d8a1
[root@server ~]# docker run -d --name nginx-2 -p 81:80 nginx
ddd97f0052393093d2a56df8bc3be8a99001ed94c2186a194fcbf84d5198e554
[root@server ~]# docker run -d --name nginx-3 -p 82:80 nginx
9cd8784388732fa696be8f2f5e38f7ca773644e9afc1b21686391a6d4c5d273d

进入到一个容器中,并创建一个文件

[root@server ~]# docker exec -it nginx-2 bash
root@ddd97f005239:/# echo 'hello world test' > /opt/test1
root@ddd97f005239:/# exit
exit

宿主机时使用了chroot技术把容器锁定到一个指定的运行目录里

[root@server ~]# find / -name test1
/var/lib/docker/overlay2/b85c4e35333a74eaddb53978e8f8e3ef9d4b511131c5f9f5d8c4d6b9ca059817/diff/opt/test1
/var/lib/docker/overlay2/b85c4e35333a74eaddb53978e8f8e3ef9d4b511131c5f9f5d8c4d6b9ca059817/merged/opt/test1

IPC Namespace

一个容器内的进程间通信,允许一个容器内的不同进程数据互相访问,但是不饿能跨容器访问其他容器的数据

UTS Namespace包括了运行内核的名称、版本、底层体系结构类型等信息用于系统表示,其中包含了hostname和域名,他是的一个容器用于属于自己hostname标识,这个主机名标识独立与宿主机系统和其上的其他容器。

PID Namespace

Linux系统中,有一个pid为1的进程(init) 是其他所有进程的父进程,那么在每个容器内也要有一个父进程来管理其下属的进程,那么多的容器的进程通过PID namespace进程隔离

Net Namespace

每个容器都类似于虚拟机一样有自己的网卡、监听端口、TCP/IP协议栈等,Docker使用network namespace启动一个vethX接口,这样容器将用有他自己的桥接IP地址,通常是docker0,而docker0实质就是linux的虚拟网桥。

[root@docker-server ~]# yum install bridge-utils.x86_64 -y
[root@server ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02421115f5e6	no		veth4050155
							veth7f5b968
							vethfe80e7d
[root@server ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:11ff:fe15:f5e6  prefixlen 64  scopeid 0x20<link>
        ether 02:42:11:15:f5:e6  txqueuelen 0  (Ethernet)
        RX packets 2560  bytes 104356 (101.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2700  bytes 8706619 (8.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

![image.png](https://img-blog.csdnimg.cn/img_convert/35106ee6c3d28f0a0a6d9851b91d24be.png#clientId=u7be9e34b-4467-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=339&id=u1e0bd501&margin=[object Object]&name=image.png&originHeight=509&originWidth=666&originalType=binary&ratio=1&rotation=0&showTitle=false&size=61774&status=done&style=none&taskId=u26c75a77-8f23-408d-bab4-6c56a3362ac&title=&width=444)

User Namespace

各个容器内可能会出现重名的用户和用户名称,或重复的用户UID或者GID,那么怎么隔离各个容器内的用户空间呢?

User Namespace允许在各个宿主机的各个容器空间内创建相同的用户名以及相同的uid和gid,只是此用户的有效范围仅仅是当前的容器内,不能访问另外一个容器内的文件系统,既相互隔离、互不影响、永不相见

Linux control groups

在一个容器内部,如果不对其做任何资源限制,则宿主机会允许其占用无线打的内存空间,有时候会因为代码bug程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,如cpu、内存等,Linux Cgroups的全称是Linux control Groups,它最重要的作用就是限制一个进程能够使用的资源上限,包括cpu、内存、磁盘、网络等等。

验证系统内核层默认开启cgroup功能

[root@server ~]# cat /boot/config-3.10.0-1160.el7.x86_64 | grep cgroup -i
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=y

关于内存的模块

[root@server ~]# cat /boot/config-3.10.0-1160.el7.x86_64 | grep mem -i |grep cg -i
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_SWAP_ENABLED=y
CONFIG_MEMCG_KMEM=y

容器规范

容器技术除了docker之外,还有coreOS的rkt,还有阿里的Pouch还有红帽的podman,为了保证容器生态的标准型和健康可持续发展,包括Linux基金会、Docker、微软、红帽、谷歌、和IBM等公司在2015年6越共同成立了一个叫open container(OCI)的组织,其目的就是指定开放的标准的容器规范,目前OCI一共发布了两个规范分别是runtime spec 和image format spec,不同的容器公司只需要兼容这两个规范,就可以保证容器的可移植性和相互可操作性。

runtime是真正运行容器的地方,因此运行了不同的容器runtime需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境,目前主流的三种runtime:
Ixc:linux上早期的runtime,Docker早期就是采用Ixc最为runtime
runc:是目前docker默认的runtime,runc遵守oci规范,因此可以兼容Ixc
rkt:是coreOS开发的容器runtime,也符合oci规范

docker info 信息

[root@server ~]# docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Docker Buildx (Docker Inc., v0.8.2-docker)
  scan: Docker Scan (Docker Inc., v0.17.0)

Server:
 Containers: 4			#当前主机运行容器总数
  Running: 3				#当前几个容器是在运行的
  Paused: 0					#有几个容器是暂停的
  Stopped: 1				#有几个容器时停止的
 Images: 1					#当前服务器的镜像数

 Server Version: 20.10.17			#服务端版本
 Storage Driver: overlay2			#正在使用的存储引擎
  Backing Filesystem: xfs			#后端文件系统,即服务器的磁盘文件系统
  Supports d_type: true				#是否支持d_type
  Native Overlay Diff: true		#是否支持差异数据存储
  userxattr: false
 Logging Driver: json-file		#日志文件类型
 Cgroup Driver: cgroupfs			#cgroup类型
 Cgroup Version: 1
 Plugins:											#插件
  Volume: local								#卷
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive							#是否支持swarm
 Runtimes: io.containerd.runtime.v1.linux runc io.containerd.runc.v2
 Default Runtime: runc				#默认使用的runtime
 Init Binary: docker-init			#初始化容器的守护进程
 containerd version: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
 runc version: v1.1.2-0-ga916309
 init version: de40ad0
 Security Options:						#安全选项
  seccomp
   Profile: default
 Kernel Version: 3.10.0-1160.el7.x86_64		#宿主机内核版本
 Operating System: CentOS Linux 7 (Core)	#宿主机操作系统版本
 OSType: linux														#宿主机操作系统类型
 Architecture: x86_64											#宿主机架构
 CPUs: 1																	#宿主机cpu数量
 Total Memory: 972.3MiB										#宿主机总内存
 Name: server															#宿主机主机名
 ID: MCBO:KOTG:GYXE:QTC4:CYDW:XNB3:FJJT:YZZN:UILK:CKIO:EIW5:OUIY
 Docker Root Dir: /var/lib/docker					#宿主机数据保存目录
 Debug Mode: false
 Registry: https://index.docker.io/v1/		#镜像仓库
 Labels:
 Experimental: false											#是否是测试版
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://r4958o6s.mirror.aliyuncs.com/
 Live Restore Enabled: false							#是否开启活动容器(重启不关闭容器)


docker存储引擎

目前docker的默认存储引擎为overlay2,不同的存储引擎需要相应的系统支持,如需要磁盘分区的时候传递d-type文件分层功能,即需要传递内核参数开启格式化磁盘的时候指定功能。

官网关于存储引擎的信息:
https://docs.docker.com/storage/storagedriver/select-storage-driver/
由于存储引擎选择错误引起的血案(扩展阅读)
https://www.cnblogs.com/youruncloud/p/5736718.html

镜像加速配置

打开网址
http://cr.console.aliyun.com/
登陆之后点击镜像加速器,按照指导说明即可

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值