1.容器的发展史
容器技术的概念可以追溯到
- 1979年的UNIX Chroot:Unix V7。
- 这项功能将Root目录及其它子目录变更至文件系统内的新位置,且只接受特定进程的访问,其设计目的在于为每个进程提供一套隔离化磁盘空间。1982年其被添加至BSD。
- Chroot只是提供了对进程文件目录虚拟化的功能,不能够防止进程恶意访问系统。这个问题在FreeBSDGails容器技术中得以解决。
- 这个年代,计算资源匮乏,想要通过快速销毁和重建基础设施来解决测试环境污染问题变得几乎不可能。为隔离出可供软件进行构建和测试的环境,Unix版本7在开发过程中引入Chroot Jail以及Chroot系统调用。Chroot jail被用于“Change Root”,它被认为是最早的容器化技术之一。chroot(change root)系统调用程序横空出现。它允许您将进程及其子进程与操作系统的其余部分隔离开来。正式引入chroot系统调用,它允许您将进程及其子进程与操作系统的其余部分隔离开来。为每个进程提供一个独立的磁盘空间,将一个进程及其子进程的根目录改变到文件系统中的新位置,让这些进程只能访问到该目录。这个被隔离出来的新环境被叫做 Chroot Jail。这标志着进程隔离的开始,隔离每个进程的文件访问权限。这种隔离的唯一问题是根进程(root process)可以轻松地退出chroot。它从未考虑实现安全机制。
- 2000年 — FreeBSD Jails
- FreeBSD Jails与Chroot的定位类似,不过其中包含有进程沙箱机制以对文件系统、用户及网络等资源进行隔离。通过这种方式,它能够为每个Jail、定制化软件安装包乃至配置方案等提供一个对应的IP地址。Jails技术为FreeBSD系统提供了一种简单的安全隔离机制。它的不足在于这种简单性的隔离也同时会影响Jails中应用访问系统资源的灵活性。
- FreeBSD Jail于2000年在FreeBSD OS中引入,FreeBSD操作系统正式发布FreeBSD jails隔离环境,真正意义上实现进程的沙箱化,旨在为简单的Chroot文件隔离带来更多安全性。这为文件系统、用户、网络等隔离增加了进程沙盒功能,实现了客户服务之间的隔离和管理。据悉,这种沙箱的实现,依靠操作系统级别的隔离与限制能力而非硬件虚拟化技术。FreeBSD Jails允许管理员将FreeBSD计算机系统划分为几个独立的、较小的系统,称为“ jails”,并能为每个系统和配置分配IP地址,可以对软件的安装和配置进行定制。与Chroot不同,FreeBSD还实现了将进程及其活动隔离到文件系统的特定视图中
- 2001年:LinuxVServer与FreeBSD
- 当Linux内核具有操作系统级的虚拟化的功能以后,Linux VServer于2001年被推出,它使用了类似chroot的机制与“安全上下文”(“security context”)以及操作系统虚拟化(容器化)相结合来提供虚拟化解决方案。它比简单的chroot更先进,允许您在单个Linux发行版(VPS)上运行多个Linux发行版。与Jails一样,Linux VServer也是采取一种类似的上述Jails机制,它可以对计算机系统上的资源(文件系统、网络地址、内存)进行分区。每个所划分的区域叫做一个安全上下文(security context),其中的虚拟系统叫做虚拟私有服务器(virtual private server,VPS)。该操作系统虚拟化于2001年推出,通过修补Linux内核来实现,测试性补丁目前仍然可用,但最后一个稳定的修补程序是2006年发布。
- 2004年 — Solaris Zones Solaris容器
- 2004年2月,Oracle发布Oracle Solaris Containers,这是一个用于X86和SPARC处理器的Linux-Vserver版本。SPARC是由Sun Microsystems开发的RISC(精简指令集计算)架构。Solaris Container 是由系统资源控制和通过 zones 提供的边界分离(boundary separation)所组合而成的。zones 是一个单一操作系统实例中的完全隔离的虚拟服务器。
- Solaris Zone技术为应用程序创建了虚拟的一层,让应用在隔离的Zone中运行,并实现有效的资源管理。每一个Zone 拥有自己的文件系统,进程空间,防火墙,网络配置等等。
Solaris Zone技术真正的引入了容器资源管理的概念。在应用部署的时候为Zone配置一定的资源,在运行中可以根据Zone的负载动态修改这个资源限制并且是实时生效的,在其他Zone不需要资源的时候,资源会自动切换给需要的资源的Zone,这种切换是即时的不需要人工干预的,最大化资源的利用率,在必要的情况下,也可以为单个Zone隔离一定的资源。
- 2005年:Open VZ(Open Virtuzzo)
- OpenVZ与Linux-VServer一样,使用操作系统级虚拟化,这是Linux操作系统级虚拟化技术,它通过Linux内核补丁形式进行虚拟化、隔离、资源管理和状态检查。Linux-VServer和OpenVZ需要为内核打补丁以添加一些用于创建隔离容器的控制机制。 OpenVZ的补丁未集成到内核中。操作系统级虚拟化有一些限制,因为容器共享相同的体系结构和内核版本,当客户需要不同于主机的内核版本情况下,这种缺点就会显现出来。该代码未作为正式Linux内核的一部分发布。每个 OpenVZ 容器都有一套隔离的文件系统、用户、用户组、进程树、网络、设备和 IPC 对象。
- 2006年:Process Containers
- Process Containers(由Google在2006年推出)旨在用于限制、计算和隔离一系列流程的资源使用(CPU、内存、磁盘I / O、网络)。一年后,为了避免和 Linux 内核上下文中的“容器”一词混淆而改名为 ControlGroups简称Cgroups,并最终合并到Linux内核2.6.24中。这也可以说明 Google 很早就参与了容器技术的开发。
- 2008年 — LXC
- Linux容器(LXC)是第一个、最完整的Linux容器管理器的实现方案。2008年,通过将 Cgroups 的资源管理能力和 Linux Namespace 的视图隔离能力组合在一起,LXC完整的容器技术出现在Linux 内核中,并且可以在单个Linux内核上运行而无需任何补丁。LXC 存在于 liblxc 库中,提供各种编程语言的 API 实现,包括 Python3、Python2、Lua、Go、Ruby 和 Haskell。现在 LXC project 由 Canonical 公司赞助并托管的。
- LXC指代的是Linux Containers,其功能通过Cgroups以及Linux Namespaces实现。也是第一套完整的Linux容器管理实现方案。在LXC出现之前, Linux上已经有了类似 Linux-Vserver、OpenVZ 和 FreeVPS。虽然这些技术都已经成熟,但是这些解决方案还没有将它们的容器支持集成到主流 Linux 内核。相较于其它容器技术,LXC能够在无需任何额外补丁的前提下运行在原版Linux内核之上。目前LXC项目由Canonical有限公司负责赞助及托管。
*LXC采用以下内核功能模块。Kernel namespaces (ipc, uts, mount, pid, network and user),Apparmor and SELinux profiles,Seccomp policies,Chroots (using pivot_root),Kernel capabilities,CGroups (control groups)
- 2011年:Warden
- Warden由CloudFoundry在2011年成立,这是一个管理隔离、短暂存在和被资源控制的环境的API。在其第一个版本中,Warden使用LXC,之后替换为他们自己的实现方案。
- 不像 LXC,Warden 并不紧密耦合到 Linux 上,可以为任何系统提供隔离运行环境。Warden以后台保护程序运行,而且能提供用于容器管理的API。它开发了一个CS(客户端-服务端)模型来管理跨多个主机的容器集群,并且Warden提供用于管理cgroup、名称空间和进程生命周期的相关服务。
- 2013年:LMCTFY
- LMCTFY 是2013年Google容器技术的开源版本,它提供Linux应用程序容器,旨在提供性能可保证的、高资源利用率的、资源共享的、可超售的、接近零消耗的容器。
- 2015年,Google开始向由Docker发起的Libcontainer贡献LMCTFY核心概念后,LMCTFY在2015年主动停止部署,Libcontainer现在是Open Container Foundation(开放容器基金会)的一部分。
- 2013年 — Docker
- Docker项目最初是由一家名为DotCloud的平台即服务厂商所打造,其后该公司更名为Docker。Docker在起步阶段使用LXC,而后利用自己的Libcontainer库将其替换下来。与其它容器平台不同,Docker引入了一整套与容器管理相关的生态系统。其中包括一套高效的分层式容器镜像模型、一套全局及本地容器注册表、一个精简化REST API以及一套命令行界面等等。
- 与Docker具有同样目标功能的另外一种容器技术就是CoreOS公司开发的Rocket. Rocket基于App Container规范并使其成为一项更为开放的标准。
- 2013年,随着Docker的出现,容器开始迅速普及。它最初是一个叫做 dotCloud 的 PaaS 服务公司的内部项目,后来该公司改名为 Docker。Docker的迅速普及并非偶然,它引入了一整套管理容器的生态系统,包括高效、分层的容器镜像模型、全局和本地的容器注册库、清晰的REST API、命令行等。
- 与Warden一样,Docker最初阶段使用的也是LXC,后来用自己的库libcontainer进行替换。Docker 推动实现了一个叫做 Docker Swarm 的容器集群管理方案。
- 2016年 — Windows容器
微软公司也于2016年正式推出Windows容器。Windows 容器包括两个不同的容器类型。
- Windows Server 容器
通过进程和命名空间隔离技术提供应用程序隔离。 Windows Server 容器与容器主机和该主机上运行的所有容器共享内核。 - Hyper-V 容器
通过在高度优化的虚拟机中运行每个容器,在由 Windows Server 容器提供的隔离上扩展。 在此配置中,容器主机的内核不与 Hyper-V 容器共享。Hyper-V容器是一个新的容器技术,它通过Hyper-V虚拟化技术提供高级隔离特性。
- 2018年:规范化向前发展
- 容器化成为现代软件基础架构的基础。众所周知,Kubernetes也被用于大多数企业容器项目。2018年,GitHub上的Kubernetes项目有27000多个Star,1500多个贡献者,成为最重要的开源社区之一。
- Kubernetes的广泛采用推动了诸如AWS云供应商提供托管的Kubernetes服务。
- 此外,VMWare、RedHat和Rancher等领先的软件供应商也开始提供基于Kubernetes的管理平台。
- 2019年:历史变革
- 2019年是容器发生历史性变革的一年。
- 这一年发生许多历史性变革事件,包括容器生态变化、产业资本并购和出现新技术解决方案等。
- 在2019年,新的运行时引擎开始替代docker运行引擎,其最具代表性的新引擎就是CNCF的Containerd和CRI-O(一个用于Kubernetes的轻量级运行时)。CRI-O能让用户直接从 Kubernetes 运行容器,而无需任何不必要的代码或工具。只要容器符合 OCI 标准,CRI-O 就可以运行它。
- 在2019年,产业方面也发送巨大变化,DockerEnterprise卖给Mirantis(一家专注于OpenStack、Kubernetes的云计算公司),可以预见的是Docker Swarm将逐步被淘汰。
- 同时,虽然rkt已经正式成为CNCF一部分,但是其普及率正在、逐步下降。此外,VMware先后收购Heptio和Pivotal Software(包括PAS和PKS),此举可以帮助企业客户更好建立并运行基于Kubernetes的容器化架构。其中,Heptio公司是由两位曾在2014年帮助谷歌联合建立Kubernetes项目的主力(当时的项目负责人共有三名)共同建立,创始人及其团队都将一同加盟VMware公司。如此清晰的创始人背景,可能意味着VMware有意在Kubernetes领域发动全面冲击,甚至预示VMware已经把Kubernetes视为企业业务运营的根本性基石之一。
- 2019年,容器技术领域也出现新变革,函数即服务(‘函数’或者‘无服务器’)已经成为一种新的抽象趋势。其允许开发人员更轻松地运行并部署代码片段,且这些代码片段将能快速实现规模伸缩以响应事件需求。
- 例如,企业只要使用由Google与Pivotal、IBM、红帽和SAP等企业共同开发的跨云Serverless管理平台Knative,就能在支持Kubernetes的云平台上自由的迁移工作负载,无论是跨私有云或是公有云及各种混合云架构都没问题。
- 2019年也出现了基于Kubernetes -混合云解决方案,如IBM CloudPaks、谷歌Anthos,AWS Outposts、和Azure Arc。这些云平台模糊了云环境与本地环境之间的传统界限,可以更方便管理本地和供应商云服务。
- Kubernetes已经成为构建容器化平台体系的默认抽象方案,上诉这些新功能的出现也代表着Kubernetes的下一步演进方向,诸如Anthos、Arc和Outposts之类超抽象。在超抽象中,计算资源从管理层解耦,类似于Kubernetes的工作方式,它将工作负载从管理层解耦。
- 2020:容器安全成为新挑战
- 作为一种轻量级的虚拟化技术,容器使用方便、操作便捷,大大提高开发人员的工作效率,并得到业内的广泛使用。但与此同时,容器安全事故频发,包括不安全的镜像源、容器入侵事件、运行环境的安全问题等等。
- 不安全的镜像源
- 开发者通常会在Docker 官方的Docker Hub仓库下载镜像,这些镜像一部分来源于开发镜像内相应软件的官方组织,还有大量镜像来自第三方组织甚至个人。从这些镜像仓库中获取镜像的同时,也带来潜在的安全风险。例如,下载镜像内软件本身是否就包含漏洞,下载的镜像是否被恶意植入后门,镜像在传输过程中是否被篡改。
- 2.容器入侵事件
- 由docker本身的架构与机制可能产生的问题,这一攻击场景主要产生在黑客已经控制了宿主机上的一些容器(或者通过在公有云上建立容器的方式获得这个条件),然后对宿主机或其他容器发起攻击来产生影响。
- 3.运行环境的安全
- 除docker 本身存在的问题外,docker运行环境存在的问题同样给docker的使用带来风险。由于容器是介于基础设施和平台之间的虚拟化技术,因此面向基础设施虚拟化的传统云安全解决方案无法完全解决前述安全问题。如以容器为支撑技术构建DevOps环境,就需要设计涵盖从容器镜像的创建到投产上线的整个生命周期的容器安全方案。
2. 安装及使用docker
2.1 docker安装
[root@slave ~]# cd /etc/yum.repos.d/
[root@slave yum.repos.d]# curl -o docker-ce.repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1919 100 1919 0 0 3225 0 --:--:-- --:--:-- --:--:-- 3219
[root@slave yum.repos.d]# sed -i 's@https://download.docker.com@https://mirrors.tuna.tsinghua.edu.cn/docker-ce@g' docker-ce.repo
[root@slave yum.repos.d]# yum -y install docker-ce
Docker CE Stable - x86_64 18 kB/s | 26 kB 00:01
......
CentOS-Stream-HighAvailability.repo CentOS-Stream-RealTime.repo
CentOS-Stream-Debuginfo.repo CentOS-Stream-Media.repo docker-ce.repo
[root@slave yum.repos.d]# cd
[root@slave ~]# systemctl restart --now docker
[root@slave ~]#
2.2 docker加速
docker-ce的配置文件是/etc/docker/daemon.json,此文件默认不存在,需要我们手动创建并进行配置,而docker的加速就是通过配置此文件来实现的。
docker的加速有多种方式:
- docker cn
- 中国科技大学加速器
- 阿里云加速器(需要通过阿里云开发者平台注册帐号,免费使用个人私有的加速器)
不配置加速器时拉取镜像
[root@mr ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
/library/centos:latest
[root@mr ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 10 months ago 231MB
[root@mr ~]#
配置加速器拉取镜像
[root@mr ~]# docker rmi centos(删除镜像)
Untagged: centos:latest
Untagged: centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Deleted: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6
Deleted: sha256:74ddd0ec08fa43d09f32636ba91a0a3053b02cb4627c35051aff89f853606b59
[root@mr ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@mr ~]# vim /etc/docker/daemon.json
[root@mr ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https:///"]
}
[root@mr ~]# cd /etc/docker/
[root@mr docker]# ls
daemon.json key.json
[root@mr docker]# systemctl restart docker
[root@mr docker]# cd
[root@mr ~]# docker version
Client: Docker Engine - Community
Version: 20.10.17
API version: 1.41
Go version: go1.17.11
Git commit: 100c701
Built: Mon Jun 6 23:03:11 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.17
API version: 1.41 (minimum version 1.12)
Go version: go1.17.11
Git commit: a89b842
Built: Mon Jun 6 23:01:29 2022
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.6
GitCommit: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
runc:
Version: 1.1.2
GitCommit: v1.1.2-0-ga916309
docker-init:
Version: 0.19.0
GitCommit: de40ad0
[root@mr ~]# 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: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 20.10.17
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
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
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
runc version: v1.1.2-0-ga916309
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 4.18.0-257.el8.x86_64
Operating System: CentOS Stream 8
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.81GiB
Name: mr
ID: HDF5:AHMC:Z3U5:SO5M:UV5B:TOP5:N2TH:UIHI:DJ7T:RIBD:EIIX:G47A
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index./v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https:///
Live Restore Enabled: false
[root@mr ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
a1d0c7532777: Pull complete
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
/library/centos:latest
[root@mr ~]#
2.3 docker常用操作
命令 | 功能 |
docker search | 在docker中心搜索映像 |
docker pull | 在注册表中拉取映像或存储库 |
docker images | 列出图像 |
docker create | 创建新的容器 |
docker start | 启动一个或多个已停止的容器 |
docker run | 在新容器中运行命令 |
docker attach | 连接到运行容器 |
docker ps | 列出容器 |
docker logs | 获取容器的日志 |
docker restart | 重新启动容器 |
docker stop | 停止容器 |
docker kill | 杀死一个或多个正在运行的容器 |
docker rm | 移除一个或多个正在运行的容器 |
docker exec | 在正在运行的容器中运行命令 |
docker info | 显示系统范围的信息 |
docker inspect | 查看docker容器的详细信息 |
搜索httpd镜像
[root@mr ~]# docker search httpd
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
httpd The Apache HTTP Server Project 4109 [OK]
centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 44
centos/httpd 35 [OK]
hypoport/httpd-cgi httpd-cgi 2 [OK]
clearlinux/httpd httpd HyperText Transfer Protocol (HTTP) ser… 2
solsson/httpd-openidc mod_auth_openidc on official httpd image, ve… 2 [OK]
jonathanheilmann/httpd-alpine-rewrite httpd:alpine with enabled mod_rewrite 1 [OK]
dockerpinata/httpd 1
lead4good/httpd-fpm httpd server which connects via fcgi proxy h… 1 [OK]
inanimate/httpd-ssl A play container with httpd, ssl enabled, an… 1 [OK]
centos/httpd-24-centos8 1
dariko/httpd-rproxy-ldap Apache httpd reverse proxy with LDAP authent… 1 [OK]
manageiq/httpd Container with httpd, built on CentOS for Ma… 1 [OK]
publici/httpd httpd:latest 1 [OK]
nnasaki/httpd-ssi SSI enabled Apache 2.4 on Alpine Linux 1
patrickha/httpd-err 0
manageiq/httpd_configmap_generator Httpd Configmap Generator 0 [OK]
httpdocker/kubia 0
amd64/httpd The Apache HTTP Server Project 0
manasip/httpd 0
httpdss/archerysec ArcherySec repository 0 [OK]
paketobuildpacks/httpd 0
19022021/httpd-connection_test This httpd image will test the connectivity … 0
sandeep1988/httpd-new httpd-new 0
e2eteam/httpd 0
[root@mr ~]#
拉取busybox镜像
[root@mr ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
5cc84ad355aa: Pull complete
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Downloaded newer image for busybox:latest
/library/busybox:latest
[root@mr ~]#
列出镜像
[root@mr ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest beae173ccac6 7 months ago 1.24MB
centos latest 5d0da3dc9764 10 months ago 231MB
[root@mr ~]#
创建容器
[root@mr ~]# docker create busybox
2231f714cd18553045e0e91d7b0403e490ee7355f3cbff8b7e27254494661ba3
[root@mr ~]# docker ps(查看运行中的容器)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@mr ~]# docker ps -a(查看所有的容器)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2231f714cd18 busybox "sh" 44 seconds ago Created lucid_merkle
[root@mr ~]#
启动容器
[root@mr ~]# docker start 2231f714cd18
2231f714cd18
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@mr ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2231f714cd18 busybox "sh" 5 minutes ago Exited (0) 9 seconds ago lucid_merkle
[root@mr ~]# docker create -it busybox sleep 6000
c58f0ba19de175e4b23a959fac355756f6196a4d7aafec24e9f0c03eb66aeb74
[root@mr ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c58f0ba19de1 busybox "sleep 6000" 40 seconds ago Created frosty_banach
2231f714cd18 busybox "sh" About an hour ago Exited (0) 56 minutes ago lucid_merkle
[root@mr ~]# docker start c58f0ba19de1
c58f0ba19de1
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c58f0ba19de1 busybox "sleep 6000" 2 minutes ago Up 13 seconds frosty_banach
[root@mr ~]#
删除容器
[root@mr ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d9ff04b1a78 httpd "httpd-foreground" 28 seconds ago Created web
c58f0ba19de1 busybox "sleep 6000" 13 minutes ago Up 11 minutes frosty_banach
2231f714cd18 busybox "sh" About an hour ago Exited (0) About an hour ago lucid_merkle
[root@mr ~]# docker rm -f web
web
[root@mr ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c58f0ba19de1 busybox "sleep 6000" 14 minutes ago Up 12 minutes frosty_banach
2231f714cd18 busybox "sh" About an hour ago Exited (0) About an hour ago lucid_merkle
[root@mr ~]#
运行容器
[root@mr ~]# systemctl enable --now firewalld
Created symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service → /usr/lib/systemd/system/firewalld.service.
Created symlink /etc/systemd/system/multi-user.target.wants/firewalld.service → /usr/lib/systemd/system/firewalld.service.
[root@mr ~]# docker run -d --name web -p 80:80 httpd
4c28f3076558ac3324821ac7ffe1283a53ede5ce19b4b40e0cf93e9401cc6843
[root@mr ~]#
获取容器的日志
[root@mr ~]# docker logs web
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.3. Set the 'ServerName' directive globally to suppress this message
[Sun Aug 07 11:01:06.990751 2022] [mpm_event:notice] [pid 1:tid 140660834594112] AH00489: Apache/2.4.52 (Unix) configured -- resuming normal operations
[Sun Aug 07 11:01:06.990877 2022] [core:notice] [pid 1:tid 140660834594112] AH00094: Command line: 'httpd -D FOREGROUND'
192.168.29.1 - - [07/Aug/2022:11:01:58 +0000] "GET / HTTP/1.1" 200 45
192.168.29.1 - - [07/Aug/2022:11:01:58 +0000] "GET /favicon.ico HTTP/1.1" 404 196
192.168.29.1 - - [07/Aug/2022:11:02:50 +0000] "-" 408 -
[root@mr ~]#
重新启动容器
[root@mr ~]# docker restart web
web
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c28f3076558 httpd "httpd-foreground" 22 minutes ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web
c58f0ba19de1 busybox "sleep 6000" 39 minutes ago Up 2 minutes frosty_banach
[root@mr ~]#
停止容器
[root@mr ~]# docker stop web
web
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c58f0ba19de1 busybox "sleep 6000" 54 minutes ago Up 17 minutes frosty_banach
[root@mr ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c28f3076558 httpd "httpd-foreground" 39 minutes ago Exited (0) About a minute ago web
c58f0ba19de1 busybox "sleep 6000" 56 minutes ago Up 19 minutes frosty_banach
2231f714cd18 busybox "sh" 2 hours ago Exited (0) 2 hours ago lucid_merkle
[root@mr ~]#
杀死容器
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c58f0ba19de1 busybox "sleep 6000" About an hour ago Up 23 minutes frosty_banach
[root@mr ~]# docker kill c58f0ba19de1
c58f0ba19de1
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@mr ~]#
删除容器
[root@mr ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c28f3076558 httpd "httpd-foreground" 50 minutes ago Exited (0) 12 minutes ago web
c58f0ba19de1 busybox "sleep 6000" About an hour ago Exited (137) 4 minutes ago frosty_banach
2231f714cd18 busybox "sh" 2 hours ago Exited (0) 2 hours ago lucid_merkle
[root@mr ~]# docker rm c58f0ba19de1
c58f0ba19de1
[root@mr ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c28f3076558 httpd "httpd-foreground" 50 minutes ago Exited (0) 12 minutes ago web
2231f714cd18 busybox "sh" 2 hours ago Exited (0) 2 hours ago lucid_merkle
[root@mr ~]#
删除所有容器
[root@mr ~]# docker run -d httpd
3fd9cf88225e475afe2db4f806f4c9c7bc9940c1d2ac2607f1595f2e84470293
[root@mr ~]# docker run -d httpd
718c52c3f714cd19a5980adfc47d4ad49b3b2693b593a5e4f10a23f5aa877bfb
[root@mr ~]# docker run -d httpd
cb2523af31b0574fbb470c74a20ad6f9d610cb7fc11bf1ff1f82e719fddb6286
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb2523af31b0 httpd "httpd-foreground" 20 seconds ago Up 19 seconds 80/tcp stupefied_ramanujan
718c52c3f714 httpd "httpd-foreground" 22 seconds ago Up 21 seconds 80/tcp flamboyant_chatelet
3fd9cf88225e httpd "httpd-foreground" 24 seconds ago Up 22 seconds 80/tcp epic_hodgkin
[root@mr ~]# docker ps -aq
cb2523af31b0
718c52c3f714
3fd9cf88225e
[root@mr ~]# docker rm -f $(docker ps -aq)
cb2523af31b0
718c52c3f714
3fd9cf88225e
[root@mr ~]#
显示系统范围的信息
[root@mr ~]# 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: 0
Running: 0
Paused: 0
Stopped: 0
Images: 3
Server Version: 20.10.17
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
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
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
runc version: v1.1.2-0-ga916309
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 4.18.0-257.el8.x86_64
Operating System: CentOS Stream 8
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.81GiB
Name: slave
ID: HDF5:AHMC:Z3U5:SO5M:UV5B:TOP5:N2TH:UIHI:DJ7T:RIBD:EIIX:G47A
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index./v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https:///
Live Restore Enabled: false
[root@mr ~]#
查看docker容器的详细信息
[root@mr ~]# docker run -d httpd
b9be2d1f1e9519d8f1bc5321bcaec07d3a2fd1cda6891b94b8013d946abcea30
[root@mr ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9be2d1f1e95 httpd "httpd-foreground" 34 seconds ago Up 33 seconds 80/tcp lucid_blackwell
[root@mr ~]# docker inspect b9be2d1f1e95
[
{
"Id": "b9be2d1f1e9519d8f1bc5321bcaec07d3a2fd1cda6891b94b8013d946abcea30",
"Created": "2022-08-07T12:04:13.46646267Z",
"Path": "httpd-foreground",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
......
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
[root@mr ~]#
2.4 docker事件状态
3. docker存储驱动
docker提供了多种存储驱动来实现不同的方式存储镜像,下面是常用的几种存储驱动:
- AUFS
- OverlayFS
- Devicemapper
- Btrfs
- VFS
3.1 AUFS
AUFS(AnotherUnionFS)是一种Union FS,是文件级的存储驱动。AUFS是一个能透明覆盖一个或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在可写层。在Docker中,底下的只读层就是image,可写层就是Container。
AUFS文件系统据说有3W行代码,而ext4文件系统却只有4000-5000行左右代码,这些代码是要被整合进内核的,后来AUFS申请要被合并进内核代码的时候,linuz觉得它这代码太过臃肿,于是拒绝了。因此AUFS这个文件系统一直以来就不是linux内核中自有的文件系统,想用AUFS这个文件系统的话,必须自己向内核打补丁并去编译使用它,但redhat系列的操作系统一向以稳定著称,不会干这种出格的事,所以在redhat系列操作系统中使用AUFS并无可能。而ubuntu上的docker默认使用的就是AUFS。
3.2OverlayFS
Overlay是Linux内核3.18后支持的,也是一种Union FS,和AUFS的多层不同的是Overlay只有两层:一个upper文件系统和一个lower文件系统,分别代表Docker的镜像层和容器层。当需要修改一个文件时,使用CoW将文件从只读的lower复制到可写的upper进行修改,结果也保存在upper层。在Docker中,底下的只读层就是image,可写层就是Container。目前最新的OverlayFS为Overlay2。
AUFS和Overlay都是联合文件系统,但AUFS有多层,而Overlay只有两层,所以在做写时复制操作时,如果文件比较大且存在比较低的层,则AUSF会慢一些。而且Overlay并入了linux kernel mainline,AUFS没有。目前AUFS已基本被淘汰。
3.3 DeviceMapper
Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并没有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。
OverlayFS是文件级存储,Device mapper是块级存储,当文件特别大而修改的内容很小,Overlay不管修改的内容大小都会复制整个文件,对大文件进行修改显然要比小文件要消耗更多的时间,而块级无论是大文件还是小文件都只复制需要修改的块,并不是整个文件,在这种场景下,显然device mapper要快一些。因为块级的是直接访问逻辑盘,适合IO密集的场景。而对于程序内部复杂,大并发但少IO的场景,Overlay的性能相对要强一些。
3.4docker registry
启动容器时,docker daemon会试图从本地获取相关的镜像,本地镜像不存在时,其将从Registry中下载该镜像并保存到本地。
Registry用于保存docker镜像,包括镜像的层次结构和元数据。用户可以自建Registry,亦可使用官方的Docker Hub。
docker registry的分类:
- Sponsor Registry:第三方的Registry,供客户和Docker社区使用
- Mirror Registry:第三方的Registry,只让客户使用
- Vendor Registry:由发布docker镜像的供应商提供的registry
- Private Registry:通过设有防火墙和额外的安全层的私有实体提供的registry
docker registry的组成:
- Repository
- 由某特定的docker镜像的所有迭代版本组成的镜像仓库
- 一个Registry中可以存在多个Repository
- Repository可分为“顶层仓库”和“用户仓库”
- 用户仓库名称格式为“用户名/仓库名”
- 每个仓库可包含多个Tag(标签),每个标签对应一个镜像
- Index
- 维护用户帐户、镜像的检验以及公共命名空间的信息
- 相当于为Registry提供了一个完成用户认证等功能的检索接口
Docker Registry中的镜像通常由开发人员制作,而后推送至“公共”或“私有”Registry上保存,供其他人员使用,例如“部署”到生产环境。