#Docker概念及基本用法
1.Docker容器技术介绍
(1)容器的简介
容器是一种轻量级的、可移植的、自包含的软件打包技术,使应用程序几乎可以在任何地方以相同的方式运行。开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机、物理服务器或公有云主机上运行。容器的本质就是一种基于操作系统能力的隔离技术,是一组受到资源限制且彼此间相互隔离的进程。运行这些进程所需要的所有文件都由另一个镜像提供,也就意味着从开发到测试再到生产的整个过程中,容器都具有可移植性和一致性。容器自身没有操作系统,而是直接共享宿主机的内核,所有对于容器进程的限制都是基于操作系统本身的能力来进行的。因此,容器最大的优势就是轻量化。
谈到容器就不得不提其与虚拟机技术的区别。传统虚拟机技术是虚拟了一套硬件后,在其上运行一个完整的操作系统,在该系统上再运行所需应用进程。而容器则可共享同一个操作系统的内核,将应用进程与系统其他部分隔离开。
如图1-1所示可以看出,容器与虚拟机之间的主要区别在于虚拟化层的位置和操作系统资源的使用方式。虚拟化会使用虚拟机监控程序模拟硬件,从而使多个操作系统能够并行运行;Linux容器则是在本机操作系统上运行,与所有容器中共享该操作系统。因此,在资源有限的情况下,想要进行密集部署的轻量级应用时,容器技术就能凸显出其优势。与虚拟机相比,更重要的是Linux容器在运行时所占用的资源更少,使用的是标准接口(启动、停止、环境变量等),并且会与应用相隔离。此外,作为包含多个容器大型应用的一部分时,更加易于管理,而且这些多容器应用可以跨多个云环境进行编排。
(2)Docker的发展
Docker自开源后受到广泛的关注和讨论,至今其GitHub项目已经超过3万6千个Stat(星标)和一万多个Fork(分支)。甚至由于Docker项目的火爆,在2013年底,DotCloud公司决定改名为Docker。Docker最初是在Ubuntu 12.04上开发实现的;Red Hat则从RHEL6.5开始对Docker进行支持;Google也在其PaaS产品中广泛应用Docker。
(3)Docker的实现原理
Docker使用Google公司推出的Go语言进行开发实现的,基于Linux内核的Cgroups,Namespace以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。最初实现是基于LXC,从Docker 0.7以后开始去除LXC,转而使用自行开发的Libcontainer,从Docker 1.11开始,则进一步演进为使用RunC和Containerd。
(4)Docker的优势
更高效的利用系统资源
Docker对系统资源的利用率很高,一台主机上可以同时运行数千个Docker容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。
更快速的交付和部署
Docker对系统资源的利用率很高,一台主机上可以同时运行数千个Docker容器。容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。
更高效的部署和扩容
Docker容器几乎可以运行于任意平台上,包括物理机、虚拟机、公有云、私有云等,这种兼容性就非常方便用户把一个应用程序从一个平台直接迁移到另外一个平台。Docker的兼容性和轻量特性可以很轻松地实现负载动态管理,可以快速扩容或方便下线应用和服务。
更简单的管理
使用Docker,通常只需要小小的改变就可以替代以往大量的更新工作。所有的修改都是以增量的方式被分发和更新,从而实现自动化且高效的管理。
Docker容器的系统架构
(1)Docker的架构
Docker使用客户端/服 务器(C/S)架构模式,使用远程API来管理和创建Docker容器。Docker客户端只需向Docker服务器或守护进程发出请求,服务器或守护进程将完成所有工作并返回结果。Docker提供了一个命令行工具docker以及一整套RESTful API进行通信,可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。如图1-2所示为Docker服务的架构图。
(2)Docker的组件
一个完整的Docker服务包括Docker Daemon服务器、Docker Client客户端、Docker Image镜像、Docker Registry库和Docker Contrainer容器,如图1-3所示。
① Docker镜像
Docker镜像是一个只读模板,用于创建Docker容器,由Dockerfile文本描述镜像的内容。构建一个镜像实际就是安装、配置和运行的过程。Docker镜像基于UnionFS把以上过程进行分层(Layer)存储,这样更新镜像可以只更新变化的层。
Docker镜像有多种生成方法:
可以从无到有开始创建镜像。
可以下载并使用别人创建好的现成的镜像。
可以在现有镜像上创建新的镜像。
Docker Hub提供了很多镜像,但在实际工作中,Docker Hub中的镜像并不能满足工作的需要,往往需要构建自定义镜像。构建自定义镜像主要有两种方式:docker commit和Dockerfile,如图1-4所示。
可以将docker commit视为在以往版本控制系统里提交变更,然后进行变更的提交即可。docker commit、docker export和docker add类似都可以输出image,但是最好的生成image的方法还是使用Dockerfile。
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。它们简化了从头到尾的流程并极大地简化了部署工作。Dockerfile从FROM命令开始,紧接着跟随各种方法、命令和参数,其产出为一个新的可以用于创建容器的镜像。
② Docker容器
Docker容器是一个镜像的运行实例。它可以被启动、开始、停止和删除。每个容器都是相互隔离的、保证安全的平台。Dcoker容器由应用程序本身和依赖两部分组成。容器在宿主机操作系统的用户空间中运行,与操作系统的其他进程隔离。这一点显著区别于的虚拟机。
③ Docker仓库
Docker仓库是Docker镜像库,是用来集中存放镜像文件的场所。Docker Registry也是一个容器,往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。Docker Hub是Docker公司提供的互联网公共镜像仓库,用户可以在上面找到需要的镜像,也可以把私有镜像推送上去。但是,在生产环境中,往往需要拥有一个私有的镜像仓库用于管理镜像,通过开源软件Registry可以实现这个目标。
Registry在Github上有两份代码:老代码库和新代码库。老代码是采用Python编写的,存在pull和push的性能问题,在0.9.1版本之后就标志为deprecated,意思为不再继续开发。从2.0版本开始,Registry就在新代码库进行开发,新代码库采用Go语言编写,修改了镜像id的生成算法、Registry上镜像的保存结构,大大优化了pull和push镜像的效率。
安装Docker服务
(1)将提供的压缩包Docker.tar.gz上传至/root目录并解压。
[root@master ~]# tar -zxvf Docker.tar.gz
(2)配置本地YUM源
[root@master ~]# mv /etc/yum.repos.d/* /media/
[root@master ~]# vi /etc/yum.repos.d/local.repo
[centos]
name=centos
baseurl=file:///root/Docker
gpgcheck=0
enabled=1
[root@master ~]# yum clean all
Loaded plugins: fastestmirror
Cleaning repos: centos
Cleaning up list of fastest mirrors
Other repos take up 39 M of disk space (use --verbose for details)
[root@master ~]# yum repolist
Loaded plugins: fastestmirror
Determining fastest mirrors
centos | 2.9 kB 00:00:00
centos/primary_db | 695 kB 00:00:00
repo id repo name status
centos centos 463
repolist: 463
(3)升级系统内核
由于内核版本比较低,部分功能(如overlay2存储层驱动)无法使用,并且部分功能可能不太稳定,建议升级内核。
升级系统内核,命令如下,:
[root@master ~]# yum upgrade -y
(4)配置防火墙及SELinux
配置防火墙及SELinux,示例代码如下:
[root@master ~]# systemctl stop firewalld && systemctl disable firewalld
[root@master ~]# iptables -t filter -F
[root@master ~]# iptables -t filter -X
[root@master ~]# sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/g’ /etc/selinux/config
[root@master ~]# reboot
(5)开启路由转发
[root@master ~]# cat >> /etc/sysctl.conf << EOF
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
[root@master ~]# modprobe br_netfilter
[root@master ~]# sysctl -p
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
(6)安装依赖包
yum-utils提供了yum-config-manager的依赖包,device-mapper-persistent-data和lvm2are需要devicemapper存储驱动。
[root@master ~]# yum install -y yum-utils device-mapper-persistent-data
(7)安装docker-ce
随着Docker的不断流行与发展,Docker组织也开启了商业化之路,Docker从17.03版本之后分为CE(CommunityEdition)和EE(EnterpriseEdition)两个版本。
Docker EE专为企业的发展和IT团队建立,为企业提供最安全的容器平台,以应用为中心的平台,有专门的团队支持,可在经过认证的操作系统和云提供商中使用,并可运行来自DockerStore的经过认证的容器和插件。
Docker CE是免费的Docker产品的新名称,Docker CE包含了完整的Docker平台,非常适合开发人员和运维团队构建容器APP。
此处安装指定版本的Docker CE。
[root@master ~]# yum install docker-ce-18.09.6 docker-ce-cli-18.09.6 containerd.io -y
(8)启动Docker
启动Docker并设置开机自启。
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart docker
[root@master ~]# systemctl enable docker
查看Docker的系统信息。
[root@master ~]# docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 18.09.6
Storage Driver: devicemapper
至此,Docker引擎的安装就完成了。
Docker容器管理
1.docker容器命令
(1)docker run 命令
语法: docker run [options]镜像名
作用:用来创建或者运行容器
参数:
-i 表示创建要给交互式容器
-t表示运行容器的同时创建一个伪终端,常与 -i 搭配使用
–name 自定义容器名
实例:
[root@master ~]# docker run -d -p 5000:5000 --restart=always --name registry docker.io/registry:latest
4669b2a5fe03207f0f213f7e886906b88f430e5369c9fbbc250a01348ca35a38
(2)docker rm命令
语法:docker rm [options] 容器ID
作用:用来删除一个容器
参数:
-f 表示强制删除
实例:
[root@master ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4669b2a5fe03 registry:latest “/entrypoint.sh /etc…” 6 minutes ago Up 6 minutes 0.0.0.0:5000->5000/tcp registry
[root@master ~]# docker rm -f 4669b2a5fe03
4669b2a5fe03
[root@master ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
(3)docker ps命令
语法:docker ps [options]
作用:用来查看当前正在运行的容器对象
参数:
-l 默认的查看只会查看正在运行中的容器信息
-a 显示所有运行过的镜像信息
-q 表示只显示对应的容器id 信息
实例:
[root@master ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b9233a7f0cc registry:latest “/entrypoint.sh /etc…” 2 seconds ago Up 1 second 0.0.0.0:5000->5000/tcp registry
[root@master ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b9233a7f0cc registry:latest “/entrypoint.sh /etc…” 8 seconds ago Up 7 seconds 0.0.0.0:5000->5000/tcp registry
[root@master ~]# docker ps -q
0b9233a7f0cc
(4)docker restart命令
语法:docker restart 容器ID
作用:用来重启一个容器
实例:
[root@master ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ae35b6a6c168 registry:latest “/entrypoint.sh /etc…” 6 seconds ago Up 5 seconds 0.0.0.0:5000->5000/tcp registry
[root@master ~]# docker restart ae35b6a6c168
ae35b6a6c168
(5)docker stop命令
语法:docker stop 容器ID
作用:用来停止一个容器,这种停止方法属于慢动作停止,类似于电脑关机
实例:
[root@master ~]# docker stop ae35b6a6c168
ae35b6a6c168
(6)doker kill命令
语法:docker kill 容器ID
作用:也是用来停止一个容器,但这种停止方法属于直接结束线程,类似于拔电源操作
实例:
[root@master ~]#docker kill ae35b6a6c168
ae35b6a6c168
(7)docker logs命令
语法:docker logs 容器ID
作用:用来查看容器日志
参数:
-f 跟随打印最新的日志追加在最后面
-t 显示日志打印的时间戳
–tail 显示最新的指定数量的几条日志信息
实例:
[root@master ~]#docker logs -f 25560379103e
time=“2020-05-12T15:21:31.439410581Z” level=info msg=“Starting upload purge in 52m0s” go.version=go1.11.2 instance.id=6e51e7c8-623e-4586-a544-c056d349d005 service=registry version=v2.7.1
…以下信息省略…
[root@master ~]#docker logs -t 25560379103e
2020-05-12T15:21:31.439868603Z time=“2020-05-12T15:21:31.439410581Z” level=info msg=“Starting upload purge in 52m0s” go.version=go1.11.2 instance.id=6e51e7c8-623e-4586-a544-c056d349d005 service=registry version=v2.7.1
…以下信息省略…
[root@master ~]# docker logs --tail 1 25560379103e
time=“2020-05-12T15:24:14.054498391Z” level=info msg=“listening on [::]:5000” go.version=go1.11.2 instance.id=97d81e2b-757b-447b-8985-b8c8dc6c755c service=registry version=v2.7.1
…以下信息省略…
(8)docker top命令
语法:docker top 容器ID
作用:用来查看容器内运行的线程信息
实例:
[root@master ~]# docker top 25560379103e
UID PID PPID C STIME TTY TIME CMD
root 12855 12838 0 11:24 ? 00:00:00 registry serve /etc/docker/registry/config.yml
(9)docker inspect命令
语法:docker inspect 容器ID
作用:用来查看容器内部细节信息,是一个json串
实例:
[root@master ~]# docker inspect 25560379103e