文章目录
- 一、容器介绍
- 1、概念
- 2、容器本质
- 3、容器和虚拟机对比
- 4、容器的作用
- 二、docker基本概念
- 1、Docker的优势
- (1)交付物标准化
- (2)一次构建,多次交付
- (3)应用隔离
- 2、Docker的度量
- (1)隔离性
- (2)可度量性
- (3)移植性
- (4)安全性
- 3、Docker三大核心组件
- (1)Docker仓库
- (2)Docker 镜像
- (3)Docker 容器
- 三、Docker安装(国内源安装)
- 1、删除已安装的Docker
- 2、配置阿里云Docker Yum源
- 3、安装指定版本(可忽略)
- 4、启动Docker服务
- 5、查看docker版本状态
- 6、扩展
- (1)CentOS 7 中 Docker 的安装:
- (2)Docker版本与官方安装方式
- 三、国内镜像仓库的使用
- 1、daocloud
- 2、配置阿里云的镜像仓库
- 3、镜像加速器
- 四、深入理解容器
- 1、核心内容
- 2、Docker的镜像和容器的区别
- (1)Docker镜像
- (2)Docker容器
- 3、容器名称
- 4、镜像名称
- 5、名字空间
- 五、Docker使用
- 1、镜像管理
- 2、容器管理
- (1)创建与启动容器
- (2)查看容器
- (3)查看容器详细信息
- (4)启动容器
- (5)关闭容器
- (6)删除容器
- (7)重启容器
- (8)暂停容器
- 3、容器进阶管理
- (1)让容器运行在后台
- (2)修改容器名称
- (3)连接容器
- (4)监控容器的运行
- (5)宿主机和容器之间相互COPY文件
- 六、Docker容器镜像制作
- 1、容器文件系统打包
- 2、通过容器创建本地镜像
- 3、镜像迁移
- 七、Dockerfile创建镜像
- 1、简介
- 2、简单示例
- 3、Jenkins镜像制作
- 八、Dockerfile优化
- 九、部署私有仓库应用
- 十、部署docker web ui应用
- 十一、Docker资源限制
- 1、简介
- 2、cpu资源限制
- (1)限制CPU Share
- (2)限制CPU 核数
- (3)CPU 绑定
- 3、mem资源限制
- (1)docker 限制容器内存使用量
- 4、io 资源限制(了解)
- 十二、端口转发
- 1、mysql应用端口转发
- 十三、容器卷
- 十四、部署centos7容器应用
- 十五、Docker数据存储位置
- 十六、Docker网络
- 1、容器网络分类
- 2、异主容器互联
- (1)路由方式
- (2)open vswitch
1、概念
容器其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用"装"起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去,这其实是 PaaS 最理想的状态。
2、容器本质
容器的本质是进程,容器镜像就是这个系统里的".exe"安装包.**。
3、容器和虚拟机对比
容器是应用程序层的抽象,将代码和依赖项打包在一起。多个容器可以在同一台计算机上运行,并与其他容器共享OS内核,每个容器在用户空间中作为隔离的进程运行。容器占用的空间少于VM,可以处理更多的应用程序,并且需要的VM和操作系统更少。
4、容器的作用
没有容器的时候:
开发 测试 运维
有容器之后:
开发 测试 运维
Docker跟原有的工具区别:
Docker对服务器端开发/部署带来的变化:
Docker 优势:
Docker 是一个开源工具,它可以让创建和管理 docker 容器变得简单。容器就像是轻量级的虚拟机,并且可以以秒级的速度来启动或停止。
- 官网:docker
- docker.io —docker官方库也叫docker-hub
Docker系统有两个程序:docker服务端 和 docker客户端
-
Docker服务端: 是一个服务进程,管理着所有的容器。
-
Docker客户端: 是docker服务端的远程控制器,可以用来控制docker的服务端进程。
1、Docker的优势
(1)交付物标准化
Docker是软件工程领域的"标准化"交付组件,最恰到好处的类比是"集装箱"。
集装箱将零散、不易搬运的大量物品封装成一个整体,集装箱更重要的意义在于它提供了一种通用的封装货物的标准,卡车、火车、货轮、桥吊等运输或搬运工具采用此标准,隧道、桥梁等也采用此标准。以集装箱为中心的标准化设计大大提高了物流体系的运行效率。
传统的软件交付物包括:应用程序、依赖软件安装包、配置说明文档、安装文档、上线文档等非标准化组件。
Docker的标准化交付物称为"镜像",它包含了应用程序及其所依赖的运行环境,大大简化了应用交付的模式。
(2)一次构建,多次交付
类似于集装箱的"一次装箱,多次运输",Docker镜像可以做到"一次构建,多次交付"。当涉及到应用程序多副本部署或者应用程序迁移时,更能体现Docker的价值。
(3)应用隔离
集装箱可以有效做到货物之间的隔离,使化学物品和食品可以堆砌在一起运输。Docker可以隔离不同应用程序之间的相互影响,但是比虚拟机开销更小。
总之,容器技术部署速度快,开发、测试更敏捷;提高系统利用率,降低资源成本。
namespace 命名空间 名字空间
cgroups 资源限制
rootfs 文件系统
2、Docker的度量
Docker是利用容器来实现的一种轻量级的虚拟技术,从而在保证隔离性的同时达到节省资源的目的。Docker的可移植性可以让它一次建立,到处运行。Docker的度量可以从以下四个方面进行:
(1)隔离性
通过内核的命名空间来实现的,将容器的进程、网络、消息、文件系统和主机名进行隔离。
(2)可度量性
Docker主要通过cgroups控制组来控制资源的度量和分配。
(3)移植性
Docker利用AUFS来实现对容器的快速更新。
AUFS是一种支持将不同目录挂载到同一个虚拟文件系统下的文件系统,支持对每个目录的读写权限管理。AUFS具有层的概念,每一次修改都是在已有的只写层进行增量修改,修改的内容将形成新的文件层,不影响原有的层。
Docker容器使用AUFS作为文件系统,有如下优势:
-
节省存储空间,多个容器可以共享同一个基础镜像存储。
-
快速部署
-
升级方便, 升级一个基础镜像即可影响到所有基于它的容器。需要注意已经在运行的docker容器不受影响
(4)安全性
安全性可以分为容器内部之间的安全性;容器与托管主机之间的安全性。
容器内部之间的安全性主要是通过命名空间和cgroups来保证的。
容器与托管主机之间的安全性主要是通过内核能力机制的控制,可以防止Docker非法入侵托管主机。
3、Docker三大核心组件
-
Docker 镜像 - Docker images
-
Docker 仓库 - Docker registeries
-
Docker 容器 - Docker containers
(1)Docker仓库
用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。
公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。Docker 仓库是 Docker 的分发部分。
库:registry
公有库:
- Docker-hub
- Daocloud
- ali
- 网易蜂巢
私有库:
公司内部使用(自己部署)
分类:
-
操作系统名称 centos ubuntu
-
应用名称 nginx tomcat mysql
Tag:
表示镜像版本
(2)Docker 镜像
Docker 镜像是 Docker 容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。
每一个镜像都可能依赖于由一个或多个下层的组成的另一个镜像。下层那个镜像是上层镜像的父镜像。
镜像名称:
仓库名称+镜像分类+tag名称(镜像版本)
完整镜像名称:
docker.io/nginx:v1
docker.io/nginx:latest
daocloud.io/centos:6
镜像ID:
64位的id号
基础镜像:
一个没有任何父镜像的镜像,谓之基础镜像。
注意:
Registry中镜像是通过Repository(仓库)来组织的,而每个Repository又包含了若干个Image(镜像)。Registry(注册表)包含一个或多个Repository
(3)Docker 容器
Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。
使用aliyun docker yum源安装新版docker 1.19 = 1.20
-
docker-ce
-
docker-ee
1、删除已安装的Docker
Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验证你的CentOS 版本是否支持 Docker 。通过 uname -r 命令查看你当前的内核版本(注意:这个是可选项,如果系统中存在那么我们就删除)
2、配置阿里云Docker Yum源
3、安装指定版本(可忽略)
4、启动Docker服务
注:启动不了
5、查看docker版本状态
6、扩展
(1)CentOS 7 中 Docker 的安装:
Docker 软件包已经包括在默认的 CentOS-Extras 软件源(联网使用centos7u2自带网络Yum源)里。因此想要安装 docker,只需要运行下面的 yum 命令:
确定docker服务在运行:
结果会显示服务端和客户端的版本,如果只显示客户端版本说明服务没有启动
(2)Docker版本与官方安装方式
moby、docker-ce与docker-ee
最早时docker是一个开源项目,主要由docker公司维护。
2017年3月1日起,docker公司将原先的docker项目改名为moby,并创建了docker-ce和docker-ee。
三者关系:
moby project由社区维护,docker-ce project是docker公司维护,docker-ee是闭源的docker公司维护。
CentOS–官方安装
或者直接下载rpm安装:
国内镜像站
daocloud:https://www.daocloud.io
网易蜂巢: 镜像中心
阿里云:容器镜像服务控制台
国外镜像站
https://hub.docker
1、daocloud
进入镜像市场
随便选择一个,选择mysql
上面有详细的使用命令。但是每个镜像的命令不一样,在选择一个:
现在我们使用web界面管理docker容器:
等一会,不要手动终止:
完成之后:
点击查看主机
启动我们的容器
将容器启动之后刷新一下刚才的界面点击容器就会显示出来
2、配置阿里云的镜像仓库
创建阿里云的私有仓库
是因为未设置登录密码,这里设置一下
使用自己的私有仓库
查看上传的镜像
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UgMfzvax-1633003590960)(assets/image-20200516203045619.png)]
自己的nginx:1.1版本已经上传成功!
使用自己的仓库
3、镜像加速器
使用 Docker 的时候,需要经常从官方获取镜像,但是由于显而易见的网络原因,拉取镜像的过程非常耗时,严重影响使用 Docker 的体验。因此 DaoCloud 推出了加速器工具解决这个难题,通过智能路由和缓存机制,极大提升了国内网络访问 Docker Hub 的速度。
Docker 加速器对 Docker 的版本有要求吗?
- 需要 Docker 1.8 或更高版本才能使用。
Docker 加速器支持什么系统?
- Linux, MacOS 以及 Windows 平台。
Docker 加速器是否收费?
- 提供永久免费的加速器服务,请放心使用。
1、核心内容
Docker系统:
Docker三大核心组件:
容器的三大组成要素:
2、Docker的镜像和容器的区别
(1)Docker镜像
一个Docker镜像可以构建于另一个Docker镜像之上,这种层叠关系可以是多层的。第1层的镜像层我们称之为基础镜像(Base Image),其他层的镜像(除了最顶层)我们称之为父层镜像(Parent Image)。这些镜像继承了他们的父层镜像的所有属性和设置。
Docker镜像通过镜像ID进行识别。镜像ID是一个64字符的十六进制的字符串。但是当我们运行镜像时,通常我们不会使用镜像ID来引用镜像,而是使用镜像名来引用。
要列出本地所有有效的镜像,可以使用命令
镜像可以发布为不同的版本,这种机制我们称之为标签(Tag)。
可以使用pull命令加上指定的标签:
(2)Docker容器
Docker容器可以使用命令创建:
它会在所有的镜像层之上增加一个可写层。这个可写层有运行在CPU上的进程,而且有两个不同的状态:运行态(Running)和退出态 (Exited)。这就是Docker容器。当我们使用docker run启动容器,Docker容器就进入运行态,当我们停止Docker容器时,它就进入退出态。
当我们有一个正在运行的Docker容器时,从运行态到停止态,我们对它所做的一切变更都会永久地写到容器的文件系统中。要切记,对容器的变更是写入到容器的文件系统的,而不是写入到Docker镜像中的。我们可以用同一个镜像启动多个Docker容器,这些容器启动后都是活动的,彼此还是相互隔离的。我们对其中一个容器所做的变更只会局限于那个容器本身。如果对容器的底层镜像进行修改,那么当前正在运行的容器是不受影响的,不会发生自动更新现象。
3、容器名称
–为容器分配一个名字,如果没有指定,会自动分配一个随机名称
–docker run子命令的参数
容器命名方式:
-
使用UUID长命名(“f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”)
-
使用UUID短命令(“f78375b1c487”)
-
使用Name(“xingdian”)
注意:
1.这个UUID标识是由Docker deamon生成的。
2.如果你在执行docker run时没有指定–name,那么deamon会自动生成一个随机字符串UUID。
3.但是对于一个容器来说有个name会非常方便,当你需要连接其它容器时或者类似需要区分其它容器时,使用容器名称可以简化操作。无论容器运行在前台或者后台,这个名字都是有效的。
4.如果在使用Docker时有自动化的需求,你可以将containerID输出到指定的文件中(PIDfile)类似于某些应用程序将自身ID输出到文件中,方便后续脚本操作。
4、镜像名称
Docker 镜像是 Docker 容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。
在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。由于 Docker 使用一个统一文件系统,由于镜像不可写,所以镜像是无状态的。
镜像的大体分类方式:这不是规定
镜像名字:
镜像ID:
所有镜像都是通过一个 64 位十六进制字符串来标识的。 为简化使用,前 12 个字符可以组成一个短ID,可以在命令行中使用。短ID还是有一定的碰撞机率,所以服务器总是返回长ID。
镜像ID:64位的id号,一般我们看到的是12位的我们称之为短ID,只要我们每个ID号不冲突就可以了
Docker镜像命名解析
镜像是Docker最核心的技术之一,也是应用发布的标准格式。无论你是用docker pull image,或者是在Dockerfile里面写FROM image,从Docker官方Registry下载镜像应该是Docker操作里面最频繁的动作之一了。那么docker镜像是如何命名的,这也是Docker里面比较容易令人混淆的一块概念:Registry,Repository, Tag and Image。
那么Registry又是什么呢?Registry存储镜像数据,并且提供拉取和上传镜像的功能。Registry中镜像是通过Repository来组织的,而每个Repository又包含了若干个Image。
下面是在本地机器运行docker images的输出结果:
常说的"ubuntu"镜像其实不是一个镜像名称,而是代表了一个名为ubuntu的Repository,同时在这个Repository下面有一系列打了tag的Image,Image的标记是一个GUID,为了方便也可以通过Repository:tag来引用。
当一个镜像的名称不足以分辨这个镜像所代表的含义时,你可以通过tag将版本信息添加到run命令中,以执行特定版本的镜像。
5、名字空间
名字空间是 Linux 内核一个强大的特性。每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。名字空间保证了容器之间彼此互不影响。
- pid 名字空间
不同用户的进程就是通过 pid 名字空间隔离开的,且不同名字空间中可以有相同的 pid。所有的 LXC(Linux container) 进程在 Docker中的父进程为Docker进程,每个 LXC 进程具有不同的名字空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。
- net 名字空间 ----做网络接口隔离的
有 了 pid 名字空间, 每个名字空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 名字空间实现的, 每个 net 名字空间有独立的网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。
- ipc 名字空间
容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号量、共享内存、socket、管道等。
面试题:linux系统里面ipc通信有几种方式
- mnt名字空间
mnt 名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间中的进程所看到的文件目录就被隔离开了。
- uts 名字空间
UTS(“UNIX Time-sharing System”) 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非主机上的一个进程。
- user 名字空间
每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。
1、镜像管理
搜索镜像:
按星级搜索镜像:
拉取镜像:
查看本地镜像:
查看镜像详情:
删除镜像:
强制删除:–force
只查看所有镜像的id:
删除所有镜像:
查看镜像制作的过程:
相当于dockfile
2、容器管理
(1)创建与启动容器
启动容器并指定名为server并放后台运行
创建新容器但不启动:
如果执行成功,说明CentOS 容器已经被启动,并且应该已经得到了 bash 提示符。
简单创建容器
注:使用镜像nginx:latest以交互模式启动容器,容器内执行/bin/bash命令。
(2)查看容器
(3)查看容器详细信息
inspect :用于查看容器的配置信息,包含容器名、环境变量、运行命令、主机配置、网络配置和数据卷配置等。
目标:查找某一个运行中容器的id,然后使用docker inspect命令查看容器的信息。
提示:可以使用容器id的前面部分,不需要完整的id。
(4)启动容器
(5)关闭容器
退出不关闭容器:
- 快捷键:ctrl +p+q
退出并关闭容器
- exit
(6)删除容器
根据格式删除所有容器:
(7)重启容器
(8)暂停容器
- pause :暂停容器中所有的进程
- unpause:恢复容器内暂停的进程,与pause对应
3、容器进阶管理
(1)让容器运行在后台
如果在docker run后面追加-d=true或者-d,那么容器将会运行在后台模式。此时所有I/O数据只能通过网络资源或者共享卷组来进行交互。因为容器不再监听你执行docker run的这个终端命令行窗口。但你可以通过执行docker attach来重新附着到该容器的回话中。
注:
容器运行在后台模式下,是不能使用–rm选项的(老版本是这样,新版本已经可以同时生效)
(2)修改容器名称
(3)连接容器
前提是容器在运行状态中
方法1.attach
方法2.exec
通过exec命令可以创建两种任务:后台型任务和交互型任务
监控容器的运行:
stats
显示容器资源使用统计信息的实时流
(4)监控容器的运行
可以使用logs、top、wait这些子命令
- logs:使用logs命令查看守护式容器
可以通过使用docker logs命令来查看容器的运行日志,其中–tail选项可以指定查看最后几条日志,使用-f选项可以跟踪日志的输出,直到手动停止。
- top:显示一个运行的容器里面的进程信息
- wait :–捕捉容器停止时的退出码
执行此命令后,该命令会"hang"在当前终端,直到容器停止,此时,会打印出容器的退出码
(5)宿主机和容器之间相互COPY文件
cp的用法如下:
如:容器nginx中/usr/local/bin/存在test.sh文件,可如下方式copy到宿主机
修改完毕后,将该文件重新copy回容器
1、容器文件系统打包
将容器的文件系统打包成tar文件,也就是把正在运行的容器直接导出为tar包的镜像文件,有两种方式:
- 第一种:
- 第二种:
导入镜像归档文件到其他宿主机:
import
2、通过容器创建本地镜像
背景:容器运行起来后,又在里面做了一些操作,并且要把操作结果保存到镜像里
方案:使用 指令,把一个正在运行的容器,直接提交为一个镜像。
commit 是提交的意思,类似告诉svn服务器我要生成一个新的版本。
实例:
在容器内部新建了一个文件
将这个新建的文件提交到镜像中保存
也可以这样例子:
3、镜像迁移
保存一台宿主机上的镜像为tar文件,然后可以导入到其他的宿主机上:
save
将镜像打包,与下面的load命令相对应
load
与上面的save命令相对应,将上面sava命令打包的镜像通过load命令导入,(实验环境中原来机器上面有镜像可以先删除掉。)
1、简介
Docker 提供了一种更便捷的方式,叫作 Dockerfile,命令用于根据给定的Dockerfile构建Docker镜像。
docker build语法:
2、简单示例
2.1、 创建镜像所在的文件夹和Dockerfile文件
2.2、 在Dockerfile文件中写入指令,每一条指令都会更新镜像的信息例如:
格式说明:
2.3、创建镜像
详细执行过程:
2.4、创建完成后,从镜像创建容器
3、Jenkins镜像制作
实战练习
扩展----CMD与ENTRYPOINT区别
编译一个简单的nginx成功以后发现好几百M。
私有仓库镜像:
- registry --官方出品, 没有图形界面。Docker hub官方已提供容器镜像registry,用于搭建私有仓库
拉取镜像:
运行容器:
注:如果创建容器不成功,报错防火墙,解决方案如下
连接容器查看端口状态:
在本机查看能否访问该私有仓库, 看看状态码是不是200
为了测试,下载1个比较小的镜像,buysbox
上传前必须给镜像打tag 注明ip和端口:
下面这个Mysql是我测试的第二个镜像,从daocloud拉取的:
注:tag后面可以使用镜像名称也可以使用id,我这里使用的镜像名称,如果使用官方的镜像,不需要加前缀,但是daocloud.io的得加前缀.
修改请求方式为http:
上传镜像到私有仓库:
查看私有仓库里的所有镜像:
拉取镜像测试:
下载并运行容器:
浏览器访问测试:
访问
1、简介
在使用 docker 运行容器时,一台主机上可能会运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可能会导致主机和集群资源耗尽,服务完全不可用。
CPU 和内存的资源限制已经是比较成熟和易用,能够满足大部分用户的需求。磁盘限制也是不错的,虽然现在无法动态地限制容量,但是限制磁盘读写速度也能应对很多场景。
至于网络,docker 现在并没有给出网络限制的方案,也不会在可见的未来做这件事情,因为目前网络是通过插件来实现的,和容器本身的功能相对独立,不是很容易实现,扩展性也很差。
资源限制一方面可以让我们为容器(应用)设置合理的 CPU、内存等资源,方便管理;另外一方面也能有效地预防恶意的攻击和异常,对容器来说是非常重要的功能。
系统压力测试工具stress
- stress是一个linux下的压力测试工具,专门为那些想要测试自己的系统,完全高负荷和监督这些设备运行的用户。
2、cpu资源限制
(1)限制CPU Share
什么是cpu share:
例子:
好处:
缺点:
设置 CPU share 的参数:
我的机器是 4 核 CPU,因此运行一个stress容器,使用 stress 启动 4 个进程来产生计算压力:(无CPU限制)
在另外一个 terminal 使用 htop 查看资源的使用情况:
上图中看到,CPU 四个核资源都达到了 100%。
为了比较,另外启动一个 share 为 512 的容器:
因为默认情况下,容器的 CPU share 为 1024,所以这两个容器的 CPU 使用率应该大致为 2:1,下面是启动第二个容器之后的监控截图:
两个容器分别启动了四个 stress 进程,第一个容器 stress 进程 CPU 使用率都在 60% 左右,第二个容器 stress 进程 CPU 使用率在 30% 左右,比例关系大致为 2:1,符合之前的预期。
(2)限制CPU 核数
限制容器能使用的 CPU 核数
限制容器只能使用 1.5 核数 CPU:
在容器里启动三个 stress 来跑 CPU 压力,如果不加限制,这个容器会导致 CPU 的使用率为 300% 左右(也就是说会占用三个核的计算能力)。实际的监控如下图:
可以看到,每个 stress 进程 CPU 使用率大约在 50%,总共的使用率为 150%,符合 1.5 核的设置。
如果设置的 --cpus 值大于主机的 CPU 核数,docker 会直接报错:
如果多个容器都设置了 --cpus ,并且它们之和超过主机的 CPU 核数,并不会导致容器失败或者退出,这些容器之间会竞争使用 CPU,具体分配的 CPU 数量取决于主机运行情况和容器的 CPU share 值。也就是说 --cpus 只能保证在 CPU 资源充足的情况下容器最多能使用的 CPU 数,docker 并不能保证在任何情况下容器都能使用这么多的 CPU(因为这根本是不可能的)。
(3)CPU 绑定
限制容器运行在某些 CPU 核
注:
一般并不推荐在生产中这样使用
docker 允许调度的时候限定容器运行在哪个 CPU 上。
案例:
假如主机上有 4 个核,可以通过 --cpuset 参数让容器只运行在前两个核上:
这样,监控中可以看到只有前面两个核 CPU 达到了 100% 使用率。
3、mem资源限制
docker 默认没有对容器内存进行限制,容器可以使用主机提供的所有内存。
不限制内存带来的问题:
- 这是非常危险的事情,如果某个容器运行了恶意的内存消耗软件,或者代码有内存泄露,很可能会导致主机内存耗尽,因此导致服务不可用。可以为每个容器设置内存使用的上限,一旦超过这个上限,容器会被杀死,而不是耗尽主机的内存。
限制内存带来的问题:
- 限制内存上限虽然能保护主机,但是也可能会伤害到容器里的服务。如果为服务设置的内存上限太小,会导致服务还在正常工作的时候就被 OOM 杀死;如果设置的过大,会因为调度器算法浪费内存。
合理做法:
- 为应用做内存压力测试,理解正常业务需求下使用的内存情况,然后才能进入生产环境使用
- 一定要限制容器的内存使用上限,尽量保证主机的资源充足,一旦通过监控发现资源不足,就进行扩容或者对容器进行迁移
- 尽量不要使用 swap,swap 的使用会导致内存计算复杂,对调度器非常不友好
(1)docker 限制容器内存使用量
如果限制容器的内存使用为 64M,在申请 64M 资源的情况下,容器运行正常(如果主机上内存非常紧张,并不一定能保证这一点):
而如果申请 150M 内存,会发现容器里的进程被 kill 掉了(worker 6 got signal 9,signal 9 就是 kill 信号)
4、io 资源限制(了解)
对于磁盘来说,考量的参数是容量和读写速度,因此对容器的磁盘限制也应该从这两个维度出发。目前 docker 支持对磁盘的读写速度进行限制,但是并没有方法能限制容器能使用的磁盘容量(一旦磁盘 mount 到容器里,容器就能够使用磁盘的所有容量)。
使用端口转发解决容器端口访问问题
- -p:创建应用容器的时候,一般会做端口映射,这样是为了让外部能够访问这些容器里的应用。可以用多个-p指定多个端口映射关系。
1、mysql应用端口转发
查看本地地址:
运行容器:使用-p作端口转发,把本地3307转发到容器的3306,其他参数需要查看发布容器的页面提示
通过本地IP:192.168.246.141的3307端口访问容器mysql1内的数据库,出现如下提示恭喜你
从上面的结果中可以看出,本地主机的32768端口被映射到了redis容器的6379端口上,也就是说访问本机的32768端口即可访问容器内redis端口。
在别的机器上通过上面映射的端口32768连接这个容器的redis
新卷只能在容器创建过程当中挂载
共享其他容器的卷(其他容器用同一个卷):
实际应用中可以利用多个-v选项把宿主机上的多个目录同时共享给新建容器:
比如:
镜像下载:
systemd 整合:
这个Dockerfile删除fakesystemd 并安装了 systemd。然后再构建基础镜像:
执行没有问题这就生成一个包含 systemd 的应用容器示例
为了使用像上面那样包含 systemd 的容器,需要创建一个类似下面的Dockerfile:
构建镜像:
运行包含 systemd 的应用容器:
为了运行一个包含 systemd 的容器,需要使用–privileged选项, 并且挂载主机的 cgroups 文件夹。 下面是运行包含 systemd 的 httpd 容器的示例命令:
注意:如果不加会运行在前台(没有用-d),可以用ctrl+p+q放到后台去
测试可用:
再来个安装openssh-server的例子:
1、容器网络分类
注:面试用,用了编排之后就没有用了
查看当前网络:
docker安装后,默认会创建3种网络类型,bridge、host和none
1、bridge:网络桥接
2、none:无指定网络
3、host:主机网络
4、固定ip:
创建固定Ip的容器:
2、异主容器互联
(1)路由方式
小规模docker环境大部分运行在单台主机上,如果公司大规模采用docker,那么多个宿主机上的docker如何互联
Docker默认的内部ip为172.17.42.0网段,所以必须要修改其中一台的默认网段以免ip冲突。
添加路由:
验证:
现在两台宿主机里的容器就可以通信了。
(2)open vswitch
如果要在生产和测试环境大规模采用docker技术,首先就需要解决不同物理机建的docker容器互联问题。
centos7环境下可以采用open vswitch实现不同物理服务器上的docker容器互联