docker
docker
docker的发展史
容器技术的兴起源于 PaaS 技术的普及;
Docker 公司发布的 Docker 项目具有里程碑式的意义;
Docker 项目通过“容器镜像”,解决了应用打包这个根本性难题。
容器本身没有价值,有价值的是“容器编排”。
Docker 解决 Paas 应用打包困难的问题
2013~2014 年,以 Cloud Foundry 为代表的 PaaS 项目,逐渐完成了教育用户和开拓市场的艰巨任务,也正是在这个将概念逐渐落地的过程中,应用“打包”困难这个问题,成了整个后端技术圈子的一块心病。
出现这个问题的根本原因是,一旦用上了 PaaS,用户就必须为每种语言、每种框架,甚至每个版本的应用维护一个打好的包。这个打包过程,没有任何章法可循,更麻烦的是,明明在本地运行得好好的应用,却需要做很多修改和配置工作才能在 PaaS 里运行起来。而这些修改和配置,并没有什么经验可以借鉴,基本上得靠不断试错,直到你摸清楚了本地应用和远端 PaaS 匹配的“脾气”才能够搞定。
Docker 项目的出现,则为这个根本性的问题提供了一个近乎完美的解决方案。这正是 Docker 项目刚刚开源不久,就能够带领一家原本默默无闻的 PaaS 创业公司脱颖而出,然后迅速占领了所有云计算领域头条的技术原因。
Docker 项目给 PaaS 世界带来的“降维打击”,其实是提供了一种非常便利的打包机制。这种机制直接打包了应用运行所需要的整个操作系统,从而保证了本地环境和云端环境的高度一致,避免了用户通过“试错”来匹配两种不同运行环境之间差异的痛苦过程。
Docker 与开发者紧密结合并迅速崛起
- Docker 镜像通过技术手段解决了 PaaS 的根本性问题;
- Docker 容器同开发者之间有着与生俱来的密切关系;
- PaaS 概念已经深入人心的完美契机。
相比于其他正在企业级市场里厮杀得头破血流的经典 PaaS 项目们,Docker 项目的推广策略从一开始就呈现出一副“憨态可掬”的亲人姿态,把每一位后端技术人员(而不是他们的老板)作为主要的传播对象。
简洁的 UI,有趣的 demo,“1 分钟部署一个 WordPress 网站”“3 分钟部署一个 Nginx 集群”,这种同开发者之间与生俱来的亲近关系,使 Docker 项目迅速成为了全世界 Meetup 上最受欢迎的一颗新星。
Docker 一家独大企图进一步商业化
实际上,Docker 项目一日千里的发展势头,一直伴随着公司管理层和股东们的阵阵担忧。他们心里明白,虽然 Docker 项目备受追捧,但用户们最终要部署的,还是他们的网站、服务、数据库,甚至是云计算业务。
Docker 项目希望提供更多平台层能力,发布了 Docker Swarm、Fig(后来的 Compose)项目,向 Paas 进化。
Docker 也和 CoreOS 公司、RedHat 等产生利益冲突,同时拒绝了微软的天价收购,为后来 Kubernetes 项目的诞生埋下了伏笔。
Kubernetes 推出,容器技术尘埃落定
Docker 公司在 Docker 开源项目的发展上,始终保持着绝对的权威和发言权,并在多个场合用实际行动挑战到了其他玩家(比如,CoreOS、RedHat,甚至谷歌和微软)的切身利益。
于是,2015 年 6 月 22 日,由 Docker 公司牵头,CoreOS、Google、RedHat 等公司共同宣布,Docker 公司将 Libcontainer 捐出,并改名为 RunC 项目,交由一个完全中立的基金会管理,然后以 RunC 为依据,大家共同制定一套容器和镜像的标准和规范。
这套标准和规范,就是 OCI( Open Container Initiative )。OCI 的提出,意在将容器运行时和镜像的实现从 Docker 项目中完全剥离出来。这样做,一方面可以改善 Docker 公司在容器技术上一家独大的现状,另一方面也为其他玩家不依赖于 Docker 项目构建各自的平台层能力提供了可能。
所以这次,Google、RedHat 等开源基础设施领域玩家们,共同牵头发起了一个名为 CNCF(Cloud Native Computing Foundation)的基金会。这个基金会的目的其实很容易理解:它希望,以 Kubernetes 项目为基础,建立一个由开源基础设施领域厂商主导的、按照独立基金会方式运营的平台级社区,来对抗以 Docker 公司为核心的容器商业生态。
而为了打造出这样一个围绕 Kubernetes 项目的“护城河”,CNCF 社区就需要至少确保两件事情:
- Kubernetes 项目必须能够在容器编排领域取得足够大的竞争优势;
- CNCF 社区必须以 Kubernetes 项目为核心,覆盖足够多的场景。
2017 年 10 月,Docker 公司出人意料地宣布,将在自己的主打产品 Docker 企业版中内置 Kubernetes 项目,这标志着持续了近两年之久的“编排之争”至此落下帷幕。
2018 年 1 月 30 日,RedHat 宣布斥资 2.5 亿美元收购 CoreOS。
2018 年 3 月 28 日,这一切纷争的始作俑者,Docker 公司的 CTO Solomon Hykes 宣布辞职,曾经纷纷扰扰的容器技术圈子,到此尘埃落定。
docker安装
[root@lnh ~]# cd /etc/yum.repos.d/
[root@lnh yum.repos.d]# ls
CentOS-Base.repo
[root@lnh 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 1954 0 --:--:-- --:--:-- --:--:-- 1952
[root@lnh yum.repos.d]# sed -i 's@https://download.docker.com@https://mirrors.tuna.tsinghua.edu.cn/docker-ce@g' docker-ce.repo
[root@lnh yum.repos.d]# dnf -y install docker-ce
docker加速
docker-ce的配置文件是/etc/docker/daemon.json,此文件默认不存在,需要我们手动创建并进行配置,而docker的加速就是通过配置此文件来实现的。
docker的加速有多种方式:
docker cn
中国科技大学加速器
阿里云加速器(需要通过阿里云开发者平台注册帐号,免费使用个人私有的加速器)
[root@lnh yum.repos.d]# systemctl start docker
[root@lnh yum.repos.d]# cat > /etc/docker/daemon.json <<EOF
> {
> "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
> }
> EOF
//配置docker加速器
[root@lnh yum.repos.d]# systemctl restart docker
[root@lnh yum.repos.d]# docker version
//查看docker版本
[root@lnh yum.repos.d]# docker info
//显示docker整个系统的信息
docker的基本用法
docker常用操作:
命令 | 功能 |
---|---|
docker search | Search the Docker Hub for images (在Docker Hub中搜索镜像) |
docker pull | Pull an image or a repository from a registry (从注册表中提取镜像或存储库) |
docker images | List images (列出镜像) |
docker create | Create a new conntainer (创建一个新的容器) |
docker start | Start one or more stopped containers (启动一个或多个停止的容器) |
docker run | Run a command in a new container (在新容器中运行命令) |
docker attach | Attach to a runninng container (进入容器使用的命令,连接到正在运行的容器,只能在前端查看,不能退出) |
docker ps | List containers (容器列表,查看容器状态) |
docker logs | Fetch the logs of a container (获取容器的日志) |
docker restart | Restart a container (重新启动容器) |
docker stop | Stop one or more running containers (停止一个或多个正在运行的容器) |
docker kill | Kill one or more running containers (杀死一个或多个正在运行的容器) |
docker rm | Remove onne or more containers (移除一个或多个容器) |
docker exec | Run a command in a running container (进入容器使用的命令,在正在运行的容器中运行命令,查看一些精简信息,用exit退出) |
docker info | Display system-wide information (显示整个系统的信息) |
docker inspect | Return low-level information on Docker objects (查看docker容器的详细信息) |
[root@lnh ~]# docker search httpd //搜索httpd镜像
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
httpd The Apache HTTP Server Project 4107 [OK]
centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 44
centos/httpd 35 [OK]
clearlinux/httpd httpd HyperText Transfer Protocol (HTTP) ser… 2
hypoport/httpd-cgi httpd-cgi 2 [OK]
solsson/httpd-openidc mod_auth_openidc on official httpd image, ve… 2 [OK]
dockerpinata/httpd 1
nnasaki/httpd-ssi SSI enabled Apache 2.4 on Alpine Linux 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]
publici/httpd httpd:latest 1 [OK]
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]
centos/httpd-24-centos8 1
manasip/httpd 0
amd64/httpd The Apache HTTP Server Project 0
patrickha/httpd-err 0
manageiq/httpd_configmap_generator Httpd Configmap Generator 0 [OK]
httpdss/archerysec ArcherySec repository 0 [OK]
paketobuildpacks/httpd 0
httpdocker/kubia 0
sandeep1988/httpd-new httpd-new 0
e2eteam/httpd 0
19022021/httpd-connection_test This httpd image will test the connectivity … 0
sherazahmedvaival/httpd-php-fpm74 0
[root@lnh ~]# docker pull httpd //拉取httpd这个镜像
Using default tag: latest
latest: Pulling from library/httpd
a2abf6c4d29d: Pull complete
dcc4698797c8: Pull complete
41c22baa66ec: Pull complete
67283bbdd4a0: Pull complete
d982c879c57e: Pull complete
Digest: sha256:0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest
[root@lnh ~]# docker images //列出镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest dabbfbe0c57b 7 months ago 144MB
[root@lnh ~]# docker run -d --name web -p 80:80 httpd
aedcd51e3aa65f7794392ae56a8cf45e2a2a673205b071be65678bb836b2d3f8
[root@lnh ~]# curl 192.168.222.250
<html><body><h1>It works!</h1></body></html>
//可以直接创建web的这个网站并进行访问
[root@lnh ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aedcd51e3aa6 httpd "httpd-foreground" 25 minutes ago Up 25 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp web
//查看容器的运行状态
[root@lnh ~]# docker stop web
web
[root@lnh ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
//停止这个容器
[root@lnh ~]# docker start web
web
[root@lnh ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aedcd51e3aa6 httpd "httpd-foreground" 27 minutes ago Up 2 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web
//开启这个容器
[root@lnh ~]# docker container ls //=docker ps查看容器状态
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aedcd51e3aa6 httpd "httpd-foreground" About an hour ago Up 3 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web
[root@lnh ~]# docker container ls -a //=docker ps -ac查看所有容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aedcd51e3aa6 httpd "httpd-foreground" About an hour ago Up 21 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web
[root@lnh ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aedcd51e3aa6 httpd "httpd-foreground" About an hour ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp web
//查看所有容器
[root@lnh ~]# 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
docker.io/library/centos:latest
[root@lnh ~]# docker create centos
d8a5984db239b4c1a5dcf09832e589c4635d57104e92d50eeb56f3fb0f8e36cb
//先拉取centos的镜像然后创建centos这个容器
[root@lnh ~]# docker run centos
[root@lnh ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f150d5fb3908 centos "/bin/bash" 46 seconds ago Exited (0) 45 seconds ago vigilant_mccarthy
aedcd51e3aa6 httpd "httpd-foreground" About an hour ago Exited (0) 2 minutes ago web
//运行这个容器并随机生成了一个容器名
[root@lnh ~]# docker logs web //查看容器的日志
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. 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.2. Set the 'ServerName' directive globally to suppress this message
[Fri Aug 05 08:04:45.386772 2022] [mpm_event:notice] [pid 1:tid 140366643633472] AH00489: Apache/2.4.52 (Unix) configured -- resuming normal operations
[Fri Aug 05 08:04:45.387166 2022] [core:notice] [pid 1:tid 140366643633472] AH00094: Command line: 'httpd -D FOREGROUND'
[root@lnh ~]# docker restart web
web
//重新启动容器
[root@lnh ~]# docker container ls -aq
aca3c6e793d3
[root@lnh ~]# docker ps -qa
aca3c6e793d3
//查看所有容器的id号
[root@lnh ~]# docker rm web
web
[root@lnh ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
//移除这个容器
[root@lnh ~]# docker rm -f web
web
[root@lnh ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
//强制性删除正在运行的容器
[root@lnh ~]# 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: 1
Running: 1
Paused: 0
Stopped: 0
Images: 2
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: 1.903GiB
Name: lnh
ID: 47FW:2O3H:ASVG:7NA6:KDUB:I6AU:F7FL:7CFO:AKAV:7GPZ:L6DX:PYZD
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://docker.mirrors.ustc.edu.cn/
Live Restore Enabled: false
[root@lnh ~]# docker inspect web
[
{
"Id": "aca3c6e793d3cb5b2952696b8d4052d12443699d92a1a6296b9f42c2a7cad936",
"Created": "2022-08-05T08:04:44.636318904Z",
"Path": "httpd-foreground",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 18312,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-08-05T08:07:05.044372433Z",
"FinishedAt": "2022-08-05T08:07:04.127897804Z"
},
......
//查看容器的详细信息
docker event state
储存驱动
docker提供了多种存储驱动来实现不同的方式存储镜像,下面是常用的几种存储驱动:
AUFS 联合文件系统
OverlayFS
Devicemapper
Btrfs 下一代的copy-on-write文件系统
VFS 虚拟文件系统
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。
OverlayFS
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已基本被淘汰。
DeviceMapper
Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并没有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。
OverlayFS是文件级存储,Device mapper是块级存储,当文件特别大而修改的内容很小,Overlay不管修改的内容大小都会复制整个文件,对大文件进行修改显然要比小文件要消耗更多的时间,而块级无论是大文件还是小文件都只复制需要修改的块,并不是整个文件,在这种场景下,显然device mapper要快一些。因为块级的是直接访问逻辑盘,适合IO密集的场景。而对于程序内部复杂,大并发但少IO的场景,Overlay的性能相对要强一些。