作者简介:
李子昂
百度基础架构部研发工程师
负责百度分布式Redis平台的研发和运维
专注于基础架构中间件的研发和优化
本文基于『云原生基础知识概述及实践』系列视频课程——『Kubernetes入门—深入浅出讲Docker』梳理。
视频课程可点击:https://cloud.baidu.com/video-center/video.html?id=606进行学习。
导读
Kubernetes简称K8s,是一个开源的用于管理云平台中多个主机上的容器化的应用,让部署容器化的应用简单并且高效,Kubernetes提供了应用部署、规划、更新、维护的一种机制。
本节课作为K8s入门基础课第一期,将介绍一种虚拟环境容器:Docker。可以说Docker是K8S的基础,就像盖房子的砖和水泥一样。
课程主要分为以下三大部分:
第一部分:容器化的简介和发展历程——主要介绍虚拟化、容器化的概念和发展历程,让同学们对Docker有一个宏观的认识。
第二部分:Docker容器的基本使用和镜像制作——了解Docker容器的基本使用后,还会通过实践学习到:如何启动一个Docker镜像,如何构建自己的Docker镜像,如何对镜像进行Debug。
第三部分:Docker底层核心技术——加深对Docker的理解。
简单来说,Docker是一种虚拟化技术。虚拟化技术可以分至少3种。
第一种:硬件虚拟化,这是底层的技术实现。
第二种:软件虚拟化,比如常见的虚拟机。
第三种:就是我们今天所介绍的,容器虚拟化技术。
通俗地说,虚拟化技术就是多个人,通过一种技术协作使用一台电脑来工作,使得每个人都觉得如同在自己的电脑上工作一样互不干扰。
为了更好的了解这三种虚拟化技术的运行机制,我们对比一下物理机、虚拟机、Docker系统运行栈。
可以看到,无论是哪一种虚拟化技术,都是多层的。其中,蓝色部分是底层实现,黄色的部分是操作系统及以上的软件层面上的实现。层数越多,运行的开销就会更大。
物理机的系统运行栈分析:
第一层Infrastructure:基础架构层
第二层Host OS:操作系统层
第三层:二进制/依赖库
第四层:应用程序
虚拟机的系统运行栈分析:
底层实现上,虚拟机比物理机多了一层Hypervisor。这是一个常用的硬件虚拟化软件,可以把底层的操作系统抽象出多个底层的硬件接口。
而在操作系统及以上的软件层面实现上,被分成了3个并行执行的虚拟机,而每一个并行运行的虚拟机和物理机相比,又多了一层Guest OS,也就是每个虚拟机还要运行自己的操作系统,这是和物理机的一个比较大的区别。
Docker的系统运行栈分析:
和虚拟机的结构相似,Docker也被分为了若干个“容器”。但是和虚拟机相比,少了一层。可以直观的感受到,Docker的运行效率要比虚拟机要高。
互联网常面临一个场景:爆发式的流量增长。在这种情况下,效率一定是第一位的。
针对以上三种虚拟化技术,从他们的部署、运行时间上,也可以对他们的运行效率简单对比:
物理机的部署,时间周期大概是以月为计算。包括建设机房,建设机架,部署机器,部署网络,部署机器的操作系统等,整个的部署周期十分长。
虚拟机:在购买之后几分钟,1个虚拟机就能创建完了。
Docker: Docker的启动是秒级的。
从部署、运行时间上,可以看到Docker的效率十分高。
容器化技术其实不是一个新颖的技术,早在1978年,就有对容器化的探索。下图可以清楚的看到容器化技术的简史:
集装箱的出现改变了运输业,Docker之于计算机行业,好比集装箱之于运输业。
2013年,Docker对外开源,2014年6月9日正式发布,从Docker0.1到Docker1.0 短短15个月的时间,风靡全球。2017年正式宣布拥抱K8S, 这标志着“容器管理系统之争”结束。
Docker为什么可以广受接纳,有如下几个优势:
a. 持续部署与测试的一致性
Docker能够保持容器内部所有的配置和依赖关系始终不变。你可以从开发到产品发布的整个过程中使用相同的容器来确保没有任何差异或者人工干预。
b. 多云平台兼容
可移植性好,可以在任何拥有Docker runtime的环境快速部署。例如AWS GCP BCE Azure aliyun都支持docker,没有迁移的成本。
c. 环境标准化和版本控制
设想某次发布因为完成一个组件的升级而导致你整个环境都损坏了,Docker可以在几分钟内轻松地滚回到这个镜像的前一个版本。
d. 隔离性
Docker可以确保你的应用程序与资源是分隔开的。例如依赖多个不同版本的tomcat的时候不会因为依赖冲突导致崩溃。同时Docker还能确保每个容器只使用分配给它的额定资源,不会因为某个进程影响其他容器。
e. 安全性
f. 由于Docker容器是隔离的,并且资源是受限制的。所以即使你其中一个应用程序被黑,也不会影响运行在其它Docker容器上的应用程序。
总结起来,Docker的优点可以概括为以下三句话:
1.一处成功,处处成功。
l横跨开发、测试、部署环境
l也不用管是在实体机、虚拟机、还是在某个云上
2.高度集成,高度一致,使用方便
l创建和部署十分便捷,效率极高
l流水线作业,持续构建发布(CI/CD)
3.结合微服务,大大提升工程研发效率
lApp相互隔离,解耦依赖关系,方便弹性扩展
l有安全保证,接入无负担
第一部分我们对Docker容器有一个基本的认识。这一部分,我们将通过一些实际的演练和操作,让大家掌握Docker容器的基本使用和镜像操作。在这一部分正式开展前,简单“扫盲”。科普一下Docker里的常用名词、Docker的环境安装及Docker架构。
常用名词
Docker 镜像 Docker images
Docker 仓库 Docker repository
Docker 容器 Docker containers
Docker 宿主机 Docker host
Docker 守护进程 Docker daemon
Docker 客户端 Docker client
Docker环境安装
Centos系统环境安装Docker:
curl-fsSL https://get.docker.com | bash-s docker
OSX系统安装Docker:
https://hub.docker.com/editions/community/docker-ce-desktop-mac
Windows系统安装Docker:
https://hub.docker.com/editions/community/docker-ce-desktop-windows
目前来说,除了Linux系统可以直接运行Docker之外,其他系统都是基于虚拟机运行的。
Docker的架构:C/S模型
Client: 与Docker通信的一个组件,也就是客户端。
Docker daemon: 相当于守护进程,也就是docker的Server,他执行的结果是Containers (容器)
Images: 镜像。镜像和容器之间的关系。运行起来的镜像就是一个容器。
Registry: 仓库。仓库具体存放的是镜像。
Docker repository 镜像仓库
镜像仓库是集中存放管理镜像的地方。仓库有分为公有仓库(DockerHub、DockerPool)和私有仓库。有了镜像仓库,用户可以用它来:
l中心化的仓库,提供上传/下载 镜像的能力。
l管理仓库中的镜像,大多数仓库都提供检索和版本整理能力。
DockerHub是Docker官方提供的公共仓库,可以检索官方镜像,除此之外还有很多私有的registry,例如BCE,也可以自己动手搭建自己的Docker image repository。
Docker Hub地址:https://hub.docker.com
DockerFile: 构建Docker镜像的源代码
Dockerfile是用于生成image的源文件,源代码像编程一样,有自己的语法,编译方式,Dockerfile也有自己的语法,提供一个简单的Dockerfile源文件地址,大家可以参考学习一下
https://github.com/docker-library/hello-world/blob/master/amd64/hello-world/Dockerfile
以下是一些例子:
-FROM 基于已有的Docker image来生成
例如:FROM tomcat:8.0
(含义:用tomcat这个镜像的8.0版本做为我们的基础镜像,然后将现有的镜像叠在该镜像之上)
-COPY 把用户的文件copy到image去
例如:COPY index.jsp /usr/local/tomcat/webapps/ROOT
(COPY 本机文件地址 镜像内文件地址)
-EXPOSE 对外通过该端口提供服务
例如:EXPOSE 8080
-CMD 启动该image应该运行的命令
例如:CMD[ “catalina.sh”, “run”]
1.入门命令1:获得帮助
Docker help [command]获取run命令的帮助。
2.入门命令2:镜像操作系列命令
Docker pull [name]:[tag] 拉取/更新某image
Docer image ls 列举当前的Docker image
Docker image rm[image ID] 删除某image
Docker build-t [name]:[tag] [dockerfile path]
从本地路径寻找Dockerfile构建镜像,并打tag上
3.入门命令3:镜像运行系列命令
Docker run-it ubuntu bash
_it:表示起一个交互终端,来run后面的命令
-d: 表示运行docker容器到后台
Docker ps 查看运行中的容器
Docker kill [container ID]终止容器
docker run -v dor1:dir2 redis 目录挂载
例如:docker run –v~:/ user-it Ubuntu bash 是把host的用户home主目录,映射为Docker实例中的/user目录。
Tips: 关于镜像的常见问题
1.我的拉取的镜像究竟存到哪里了?
镜像有Docker管理,每个系统具体路径不一样。
Linux系统存储在/var/lib/docker
OSX系统存储在:/Users/{YourUserName}/Library/Containers/com.docker.docker/Data
2.我没有指定镜像的tag怎么办?
命令中没有指定镜像tag时会默认使用latest作为tag。避免发生预期错误的方法是指名tag、
3.镜像删除不掉怎么办?
镜像之间可能会相互依赖(layer),添加-f可以强制删除。
1.看容器log:
Docker logs [container_id]
2.Inspect 获取容器/镜像的元数据。
Docker inspect [container_id]
3.在Docker实例中执行交互的shell命令。
Docker exec –it [container_id] bash
Docker exec-it[container_id]sh
1.前期准备:
Dockerfile内容如下
FROM tomcat:8.0
COPY index.jsp /usr/local/tomcat/webapps/ROOT
EXPOSE 8080
Index.jsp内容如下
<%< span="">
Out. Println(“Hello World, V1”);
%>
2.构建镜像
Docker build-t mytomact:1.0
Docker run –p 8080:8080 –d mytomcat:1.0
Curl localhost:8080
Docker logs {容器 id}
1.构建Docker镜像
Cd node/docker
Docker build –t hub.baidubce.com/bootcamp/mynode:1.0.0
2.运行镜像
Docker run-d –p 8000:8080 hub.baidubce.com/bootcamp/mynode:1.0.0
Docker ps | grep mynode
Curl localhost:8000
3.查看执行日志
Docker ps |grep mynode
Docker logs{container id}
Docker是容器虚拟化的相关技术的结合,它的三大技术支柱包括:Cgroup,Namespace, AUFS。下面简单介绍一下者三大技术支柱
1.Cgroup
全称:Linux Control Group ,又称为Cgroup,是Linux Kernel的一个功能。
由Google工程师发起并贡献。最终合入了内核代码;
作用是限制一个进程组的资源(包括内存用量,CPU用量,磁盘IO,网络IO,网络优先级等)
http://man7.org/linux/man-pages/man7/cgroups.7 .html
例如:使用Cgroup限制一个进程资源的用量
Mkdir –p /sys/fs/cgroup/cpu/k8s_s1
Echo 50000>/cguop/cpu/k8s_s1/cpu.cfs_quota_us
将cpu.cfs_quota_us 设为50000
相当于cpu.cfs_period_us的100000是50%
Echo{PID}>/cgroup/cpu/foo/tasks
2.Linux Namespace
Namespace是Linux Kernel提供的一种内核级别资源隔离的方法。又称为命名空间,它主要做访问隔离,即同一个命名空间的多个资源(memory, CPU, network, pid)可以相互看到,但是之外的看不到。
http://man7.org/linux/man_pages/man7/namespaces.7.html
目前namespce种类有以下7种:
例如:使用Namespace隔离一个进程的资源
lSyscall. CLONE NEWPID: 隔离PID
lSyscall. CLONE_NEWNET :隔离网络
3.AUFS
全称:Advanced Multilayered Unification File System。一种高性能分层文件系统,是Docker image的基石。可以把多个文件挂载到同一个挂载点。只有第一层(第一个文件夹层级)是可写的,其余层是只读的。增加/删除文件时都会转换为写操作写入可写层。
修改文件时,AUFS利用Cow特性来修改只读层中的文件。不管修改数据的量的多少。在第一次修改时,文件都会被拷贝到可写层然后再被修改。AUFS的CoW特性能够允许在多个容器之间共享分层,从而减少物理空间占用。
例如:使用AUFS创建多重挂载点
1.Mount-t aufs –o dirs.=./fruits=tw:./vegetables=rw none./mnt
2.Echo modify>> ./mnt/tomato
以上是本期课程的全部内容。
更多精彩课程欢迎关注百度开发者中心公众号。