容器的认识
容器是一种基础工具,泛指任何可以用于容纳其它物品的工具,可以部分或完全封闭,被用于容纳、存储、运输物品;物体可以被
放置在容器中,而容器则可以保护内容物。
容器技术最早出现在freebsd叫做jail
Docker简介
Docker是什么
首先Docker是一个在2013年开源的应用程序并且是一个基于go语言编写是一个开源的pass服务(Platform as a Service,平台即服务的缩写),go语言是由google开发,docker公司最早叫dotCloud后由于Docker开源后大受欢迎就将公司改名为 Docker Inc,总部位于美国加州的旧金山,Docker是基于linux 内核实现,Docker最早采用LXC技术(LinuX Container的简写,LXC是Linux 原生支持的容器技术,可以提供轻量级的虚拟化,可以说 docker 就是基于 LXC 发展起来的,提供 LXC 的高级封装,发展标准的配置方法),而虚拟化技术KVM(Kernel-based Virtual Machine) 基于模块实现,Docker后改为自己研发并开源的runc技术运行容器。
Docker 相比虚拟机的交付速度更快,资源消耗更低,Docker 采用客户端/服务端架构,使用远程API来管理和创建Docker容器,其可以轻松的创建一个轻量级的、可移植的、自给自足的容器,docker 的三大理念是build(构建)、ship(运输)、 run(运行),Docker遵从aoache 2.0协议,并通过(namespace及cgroup等)来提供容器的资源隔离与安全保障等,所以Docke容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机6-8%性能)的额外资源开销,因此可以大幅提高资源利用率,总而言之Docker是一种用了新颖方式实现的轻量级虚拟机.类似于VM但是在原理和应用上和VM的差别还是很大的,并且docker的专业叫法是应用容器(Application Container)。
Docker的组成
1、docker主机(Host):一个物理机或虚拟机,用于运行docker服务进程和容器
2、Docker服务端(Server):Docker守护进程,运行docker容器
3、Docker客户端(Client):客户端使用docker命令或其他工具调用docker API
4、Docker仓库(Registry):保存镜像的仓库,类似于git或svn这样的版本控制系统
5、docker镜像(Images):镜像可以理解为创建实例使用的模板
6、Docker容器(Container):容器是独立运行的一个或一组应用,是镜像运行时的实体
Docker对比虚拟机
1、资源利用率更高:一台物理机可以运行数百个容器,但是一般只能运行数十个虚拟机。
2、开销更小:不需要启动单独的虚拟机占用硬件资源。
3、启动速度更快:可以在数秒内完成启动。
使用虚拟机是为了更好的实现服务运行环境隔离,但是一个虚拟机只运行一个服务,很明显资源利用率比较低。
Docker的优势
1、快速部署:短时间内可以部署成百上千个应用,更快速交付到线上。
2、高效虚拟化:不需要额外的hypervisor支持,直接基于linux 实现应用虚拟化,相比虚拟机大幅提高性能和效率。
3、节省开支:提高服务器利用率,降低IT 支出。
4、简化配置:将运行环境打包保存至容器,使用时直接启动即可。
快速迁移和扩展:可夸平台运行在物理机、虚拟机、公有云等环境,良好的兼容性可以方便将应用从A宿主机迁移到B宿主机,甚至是A平台迁移到B平台。
Docker的缺点
隔离性:各应用之间的隔离不如虚拟机
docker(容器)的依赖技术
容器网络
docker自带的网络docker network仅支持管理单机上的容器网络,当多主机运行的时候需要使用第三方开源网络例如:calico、flannel等
服务发现
容器的动态扩容特性决定了容器IP也会随之变化,因此需要有一种机制开源自动识别并将用户请求动态转发到新创建的容器上,
kubernetes自带服务发现功能,需要结合kube-dns服务解析内部域名
容器监控
可以通过原生命令docker ps/top/stats 查看容器运行状态,另外也可以使用heapster/Prometheus等第三方监控工具监控容器的运行状态
数据管理
容器的动态迁移会导致其在不通的Host之间迁移,因此如何保证与容器相关的数据也能随之迁移或随时访问,可以使用
逻辑卷/存储挂载等方式解决
日志收集
docker原生的日志查看工具docker logs,但是容器内部的日志需要通过ELK等专门的日志收集分析和展示工具进行处理
Docker的核心技术
容器规范
除了docker之外的docker技术,还有coreOS的rkt,还有阿里的Pouch,为了保证容器生态的标志性和健康可持续发展,包括Google、Docker等公司共同成立了一个叫open container(OCI)的组织,其目的就是制定开放的标准的容器规范,目前OCI一共发布了两个规范,分别是runtime spec和image format spec,有了这两个规范,不通的容器公司开发的容器只要兼容这两个规范,就可以保证容器的可移植性和相互可操作性。
容器runtime
runtime是真正运行容器的地方,因此为了运行不同的容器runtime需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境。
目前主流的三种runtime:
Lxc:linux上早期的runtime,Docker早期就是采用lxc作为runtime。
runc:目前Docker默认的runtime,runc遵守OCI规范,因此可以兼容lxc。
rkt:是CoreOS开发的容器runtime,也符合OCI规范,所以使用rktruntime也可以运行Docker容器。
容器的管理工具
管理工具连接runtime与用户,对用户提供图形或命令方式操作,然后管理工具将用户操作传递给runtime执行。
Lxd是lxc的管理工具。
Runc的管理工具是docker engine,docker engine包含后台deamon和cli两部分,大家经常提到的Docker就是指的docker engine。
Rkt的管理工具是rkt cli。
容器定义工具
容器定义工具允许用户定义容器的属性和内容,以方便容器能够被保存、共享和重建。
Docker image:是docker 容器的模板,runtime依据docker image创建容器。
Dockerfile:包含N个命令的文本文件,通过dockerfile创建出docker image。
ACI(App container image):与docker image类似,是CoreOS开发的rkt容器的镜像格式。
Registry
统一保存共享镜像的地方,叫做镜像仓库。
Image registry:docker 官方提供的私有仓库部署工具。
Docker hub:docker官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用。
Harbor:vmware 提供的自带web的镜像仓库,目前有很多公司使用
编排工具
当多个容器在多个主机运行的时候,单独管理每个容器是相当负载而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎。
容器编排通常包括容器管理、调度、集群定义和服务发现等功能。
Docker swarm:docker 开发的容器编排引擎。
Kubernetes:google领导开发的容器编排引擎,内部项目为Borg,且其同时支持docker和CoreOS。
Mesos+Marathon:通用的集群组员调度平台,mesos与marathon一起提供容器编排引擎功能。
Linux Namespace技术
namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命令空间被部署在核内,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离:
MNT:提供磁盘挂载点和文件系统的隔离能力
IPC:提供进程间通信的隔离能力
UTS:提供主机名隔离能力
PID:提供进程隔离能力
Net:提供网络隔离能力
User:提供用户隔离能力
Docker架构
安装docker
#解决依赖问题
[root@xiaomao ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
#添加软件源
[root@xiaomao ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#安装docker
[root@xiaomao ~]# yum makecache fast
[root@xiaomao ~]# yum -y install docker-ce
#开启docker
[root@xiaomao ~]# systemctl restart docker
[root@xiaomao ~]# systemctl enable docker
#安装效验
[root@xiaomao ~]# docker version
Client: Docker Engine - Community
Version: 19.03.12
API version: 1.40
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:46:54 2020
OS/Arch: linux/amd64
Experimental: false
验证docker0网卡
[root@xiaomao ~]# ip add
docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:53:f2:a2:ed brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
配置镜像加速
[root@xiaomao ~]# mkdir -p /etc/docker
[root@xiaomao ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://wlwmxdoi.mirror.aliyuncs.com"]
}
EOF
#重启docker服务
[root@xiaomao ~]# systemctl restart docker
验证docker信息
[root@xiaomao ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.12
Docker 基础命令
#搜索镜像
#带版本号的搜索
[root@xiaomao ~]# docker search centos:7.2.1511
[root@xiaomao ~]# docker search redis
#下载镜像
[root@xiaomao ~]# docker pull redis
#查看镜像
[root@xiaomao ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 235592615444 3 weeks ago 104MB
#格式说明
REPOSITORY #镜像所属的仓库名称
TAG #镜像版本号(标识符),默认为latest
IMAGE ID #镜像唯一ID标示
CREATED #镜像创建时间
VIRTUAL SIZE #镜像的大小
#查看镜像的详细信息
[root@xiaomao ~]# docker image inspect redis
#从镜像中启动一个容器
[root@xiaomao ~]# docker run -it --name c1 redis /bin/bash
root@d0e4d43577f1:/data#
#显示正在运行的容器
[root@xiaomao ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3df9169d1385 redis "docker-entrypoint.s…" 32 seconds ago Up 30 seconds 6379/tcp c2
#显示所有容器包括关闭掉的容器
[root@xiaomao ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3df9169d1385 redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp c2
d0e4d43577f1 redis "docker-entrypoint.s…" 6 minutes ago Exited (0) 6 minutes ago c1
#镜像的导出
[root@xiaomao ~]# docker save centos > /opt/centos-1.tar.gz
[root@xiaomao ~]# ll /opt/centos-1.tar.gz
-rw-r--r-- 1 root root 211091456 Jul 5 22:26 /opt/centos-1.tar.gz
#删除镜像
[root@xiaomao ~]# docker rmi centos:7
#查看镜像
[root@xiaomao ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 235592615444 3 weeks ago 104MB
nginx latest 2622e6cca7eb 3 weeks ago 132MB
#镜像的导入
[root@xiaomao ~]# docker load < /opt/centos-1.tar.gz
#再次查看镜像
[root@xiaomao ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest 235592615444 3 weeks ago 104MB
nginx latest 2622e6cca7eb 3 weeks ago 132MB
centos 7 b5b4d78bc90c 2 months ago 203MB
#查看容器所支持的网络接口
[root@xiaomao ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f016a2fd65ff bridge bridge local
9665fbc216e0 host host local
203466a21968 none null local
#后台启动容器
#-d后面是镜像,要是没镜像的话启动时候会自动拉取
[root@xiaomao ~]# docker run --name redis -d redis:4-alpine
#查看容器进程
[root@xiaomao ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e0b7401f9cf9 redis:4-alpine "docker-entrypoint.s…" 6 seconds ago Up 4 seconds 6379/tcp redis
#删除容器
[root@xiaomao ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
68d579fa2526 redis:4-alpine "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 6379/tcp redis
[root@xiaomao ~]# docker stop redis
68d579fa2526
#已经在运行着的容器要停止然后才能删除
[root@xiaomao ~]# docker container rm redis
redis
#进入容器,交互式进入
[root@xiaomao ~]# docker container exec -it redis /bin/sh
/data # ps aux
PID USER TIME COMMAND
1 redis 0:00 redis-server
17 root 0:00 /bin/sh
22 root 0:00 ps aux
/data # netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN
tcp 0 0 :::6379 :::* LISTEN
/data # exit
#非交互式运行,查看端口
[root@xiaomao ~]# docker container exec redis netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN
tcp 0 0 :::6379 :::* LISTEN
#单次运行,容器退出后自动删除
[root@xiaomao ~]# docker run --name web -it --rm nginx:1.15-alpine /bin/sh
/ # ip add
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
#容器需要有一个前台运行的进程才能保持容器的运行,通过传递运行参数是一种方式,另外也可以在构建镜像的时候指定容器启动时运行的前台命令
[root@xiaomao ~]# docker run --name web -d nginx:1.15-alpine
[root@xiaomao ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57f34c25942b nginx:1.15-alpine "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp web
#查看docker容器的日志信息
[root@xiaomao ~]# docker container logs web
#查看运行时的容器对宿主机的资源消耗
[root@xiaomao ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
8345abf33e60 web1 0.00% 1.375MiB / 567.9MiB 0.24% 648B / 0B 0B / 0B 2
e0b7401f9cf9 redis 0.19% 828KiB / 567.9MiB 0.14% 648B / 0B 0B / 0B 4
#显示指定的容器相关进程
[root@xiaomao ~]# docker container top web1
UID PID PPID C STIME TTY TIME CMD
root 22714 22696 0 20:42 ? 00:00:00 nginx: master process nginx -g daemon off;
100 22739 22714 0 20:42 ? 00:00:00 nginx: worker process
使用attach命令
使用方式为docker attach 容器名,attach 类似于vnc,操作会在各个容器界面显示,所有使用此方式进入容器的操作都是同步显示的且exit后容器将被关闭,且使用exit退出后容器关闭,不推荐使用
Docker镜像
Docker镜像含有启动容器所需要的文件系统及其内容,因此,其用于创建并启动docker容器
采用分层构建机制,最底层为bootfs,其之为rootfs:
1、bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节约内存资源
2、rootfs:位于bootsfs之上,表现为docker容器的根文件系统:
a、传统模式中,系统启动之时,内核挂载rootfs时会首先将其挂载为"只读模式",完整性自检完成后将其重新挂载为读写模式
b、docker中,rootfs由内核挂载为"只读"模式,而后通过"联合挂载"技术额外挂载一个"可写"层;
位于下层的镜像称为父镜像,最底层的称为基础镜像
最上层为可读写层,其下的均为只读层
#手动构建镜像
[root@xiaomao ~]# docker pull busybox
[root@xiaomao ~]# docker run --name b1 -it busybox /bin/sh
/ # mkdir /data
/ # mkdir /data/web/html -p
/ # echo "hello word" >> /data/web/html/index.html
#保存一个镜像,保存时要打开第二个终端
[root@xiaomao ~]# docker container commit b1 xiaomao/mying:V0.1
[root@xiaomao ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xiaomao/mying V0.1 4dd9edfef2f9 18 seconds ago 1.22MB
#测试构建的镜像
[root@xiaomao ~]# docker run --name mubbox2 -it xiaomao/mying:V0.1
/ # ls
bin data dev etc home proc root sys tmp usr var
/ # cat /data/web/html/index.html
hello word
# 参数: -a 作者、-p:提交期间暂停暂停容器 -c:更改列表将Dockerfile指令应用于创建的图像
#自定义CMD
docker container commit -p -a 'xiaomao <xiaomao.com>' -c 'CMD ["/bin/sh" ,"-c","/bin/httpd -f -h /data/web/html"]' b1
#为镜像打标签
[root@xiaomao ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 319fa1025564 2 minutes ago 1.22MB
[root@xiaomao ~]# docker image tag 319fa1025564 xiaomao/mying:v0.5
#在次查看是否打标签成功
[root@xiaomao ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
xiaomao/mying v0.5 319fa1025564 3 minutes ago 1.22MB
#测试镜像能否启动
[root@xiaomao ~]# docker run --name tinyweb3 -d xiaomao/mying:v0.5
[root@xiaomao ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c238729f4abf xiaomao/mying:v0.5 "/bin/sh -c '/bin/ht…" 3 seconds ago Up 2 seconds tinyweb3