Docker基本管理
Docker概述
Docker是什么东西
●是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源
●是在Linux容器里运行应用的开源工具
●是一种轻量级的"虚拟机”
●Docker的容器技术可以在一台主机 上轻松为任何应用创建一个轻量级的、 可移植的、自给自足的容器。

Docker的Logo设计为蓝色鲸鱼,拖着许多集装箱。
鲸鱼可看作为宿主机,集装箱可理解为相互隔离的容器,每个集装箱中都包含自己的应用程序。
Docker的设计宗旨: Build,Ship and Run Any App, Anywhere,
即通过对应用组件的封装、发布、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,到处运行"的目的。
这里的组件,既可以是一一个应用,也可以是一套服务,甚至是一个完整的操作系统。
为什么要用容器
容器可以实现在很多主机上 给应用提供 相同的运行环境 避免因为运行环境不同 导致出现的问题
Docker是一个开源的运行容器的引擎 我们可以使用Docker 在Linux容器里运行应用
容器的特点
容器化越来越受欢迎,因为容器是:
●灵活:即使是最复杂的应用也可以集装箱化。
●轻量级:容器利用并共享主机内核。
●可互换:可以即时部署更新和升级。
●便携式:可以在本地构建,部署到云,并在任何地方运行。
●可扩展:可以增加并自动分发容器副本。
●可堆叠:可以垂直和即时堆叠服务。
Docker和虚拟机的区别
容器是在linux上本机运行,并与其他容器共享主机的内核,它运行的是一个独立的进程,不占用其他任何可执行文件的内存,非常轻量。
虚拟机运行的是一个完成的操作系统,通过虚拟机管理程序对主机资源进行虚拟访问,相比之下需要的资源更多。

| 特性 | Docker容器 | 虚拟机 |
| 启动速度 | 秒级 | 分钟级 |
| 计算能力损耗 | 几乎无 | 损耗50%左右 |
| 性能 | 接近原生 | 弱于 |
| 系统支持量(单机) | 上千个 | 几十个 |
| 隔离性 | 资源隔离/限制 | 完全隔离 |
容器在内核中支持2种重要技术:
docker容器本质就是宿主机的个进程,docker容器是通过namespace实现资源隔离,通过cgroup实现资源限制,
通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)

Docker核心概念:
●镜像
Docker的镜像是创建容器的基础,类似虚拟机的快照,可以理解为一个面向Docker容器引擎的只读模板。
通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量、和配置文件。
Docker镜像也是一个压缩包,只是这个压缩包不只是可执行文件,环境部署脚本,它还包含了完整的操作系统。
因为大部分的镜像都是基于某个操作系统来构建,所以很轻松的就可以构建本地和远端一样的环境,这也是Docker镜像的精髓。
●容器
Docker的容器是从镜像创建的运行实例,它可以被启动、停止和删除。所创建的每--个容器都是相互隔离、互不可见,以保证平台的安全性。
可以把容器看做是一个简易版的linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行在其中的应用程序。
●仓库
Docker仓库是用来集中保存镜像的地方,当创建了自己的镜像之后,可以使用push命令将它上传到公有仓库(Public) 或者私有
仓库(Private) 。当下次要在另外一台机器上使用这个镜像时,只需从仓库获取。
Docker的镜像、容器、日志等内容全部都默认存储在/var/lib/docker 目录下。
总结
容器:提供在多台主机上运行应用程序相同的运行环境
docker:
是开源的容器引擎,GO语言开发的,是容器里运行应用的工具,是一个轻量级的虚拟机
可以利用docker在多台主机上轻松的创建并运行容器
docker容器可以被看作运行在宿主机上的一个进程,容器共享宿主机的内核,
容器间是通过namespace (命名空间、名称空间)隔离资源,通过cgroups ( 资源配额)去限制资源
核心概念
镜像 :运行容器的基础,包含运行应用程序所需的所有内容.
容器 :是从镜像创建的运行实例
仓库 :集中保存镜像的地方(公有仓库docker hub,私有仓库harbor )
安装Docker
关闭防火墙

安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-utils:提供了yum-config-manager 工具。
device mapper:
是Linux内核中支持逻辑卷管理的通用设备映射机制,它为实现用于存储资源管理的块设备驱动提供了一个高度模块化的内核架构
device mapper存储驱动程序需要device-mapper- persistent-data和1vm2。

设置阿里云镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装Docker-ce 并设置开机自启动
yum install -y docker-ce
systemctl start docker.service
systemctl enable docker.service

Docker镜像操作
搜索镜像
docker search 关键字

获取镜像
docker pull 仓库名称[:标签]
#如果下载镜像时不指定标签,则默认会下载仓库中最新版本的镜像,即选择标签为latest标签。

镜像加速下载
浏览器访问 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://p073xmhm.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker



查看镜像信息

查看下载的镜像文件信息

为本地的镜像添加新的标签
docker tag 名称:标签 新名称:新标签

删除镜像
docker rmi 仓库名称:标签 #当镜像有多个标签时,只是删除其中指定的标签
docker rmi 镜像ID号 #会彻底删除改镜像 -f 强制删除


存出镜像:将镜像保存为本地文件
docker save -o 存储文件名 存储的镜像
docker save -o nginx.tar nginx:latest #保存在当前目录下

载入镜像:把镜像文件导入到镜像库中
docker load < 存出的文件
或
docker load -i 存出的文件

镜像上传
默认上传到docker Hub官方公共仓库,需要注册使用公共仓库的账号。https://hub.docker.com
可以使用dockerlogin命令来输入用户名、密码和邮箱来完成注册和登录。
在上传镜像之前,还需要先对本地镜像添加新的标签,然后再使用docker push命令进行上传。
docker tag nginx:latest zjzarlx/nginx:latest ##添加新的标签时必须在前面加上自己的dockerhub的username
docker login ##登入公共仓库
docker push zjzarlx/nginx:latest ##上传镜像
docker search zjzarlx ##查看自己账号里的镜像

Docker容器操作
容器创建:就是将镜像加载到容器的过程。
新创建的容器默认处于停止状态,不运行任何程序,需要在其中发起一个进程来启动容器。
容器创建
docker create [选项] 镜像
常用选项:
-i: 让容器的输入保持打开
-t:让Docker分配一个伪终端
注:如果创建时出现提醒要开启ip转发功能 就修改 vim /etc/sysctl.conf 添加 net.ipv4.ip_forward=1
容器启动
docker start 容器的ID/名称
查看容器的运行状态
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
67e387232ffd nginx:latest "/docker-entrypoint.…" About a minute ago Up 6 seconds 80/tcp admiring_beaver
容器的ID号 加载的镜像 运行的程序 创建的时间 当前的状态 映射端口 名称

创建并启动容器
可以直接执行docker run命令,等同于先执行 docker create 命令,再执行docker start 命令。
注意:容器是一个与其中运行的shell 命令共存亡的终端,命令运行容器运行, 命令结束容器退出。
docker 容器默认会把容器内部第一个进程,也就是pid=1 的程序作为docker容器是否正在运行的依据,如果docker容器中
pid=1的进程挂了,那么docker容器便会直接退出,也就是说Docker容器中必须有一一个前台进程,否则认为容器已经挂掉。.
当利用dockerrun来创建容器时,Docker在后台的标准运行过程是:
(1)检查本地是否存在指定的镜像。当镜像不存在时,会从公有仓库下载;
(2)利用镜像创建并启动一个容器;
(3)分配一个文件系统给容器,在只读的镜像层外面挂载一层可读写层;
(4)从宿主主机配置的网桥接口中桥接一个虚拟机接口到容器中;
(5)分配一个地址池中的IP地址给容器;
(6)执行用户指定的应用程序,执行完毕后容器被终止运行。

容器的进入
docker exec -it 容器ID/名称 bash ##进入已经在运行的容器内
exit ##退出
docker run -itd [--name 名字] 容器源 bash ##创建并持续运行容器
-it 保证 容器在运行状态 -d 后台运行 不加-d选项会创建容器后直接进入容器,但是退出容器,容器也会停止


容器的复制
从宿主机复制到容器
docker cp 文件的绝对路径 容器ID:/位置/

从容器复制到宿主机
docker cp 容器ID:/文件位置 目的位置

容器的导出与导入
导出
docker export 容器ID > 命名一个名字
scp 文件名 目的ip:目的位置
导入
cat 文件名 | docker import - 名称:标签


容器的删除
docker rm [-f] 容器ID/名称
#-f 强制删除正在运行的容器
docker rm $(docker ps -aq) #批量清理后台停止的容器

Docker网络
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,
同时Docker网 桥是每个容器的默认网关。因为在同一一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过Container-IP访问到容器。、
如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过-P或-p参数来启用,访问容器的时候就通过[宿主机IP]: [容器端口]访问容器。
安装Docker时,它会自动创建三个网络,bridge (创建容器默认连接到此网络)、none、host
docker network ls ##查看docker网络列表
或
docker network list

使用docker run创建Docker容器时,可以用--net 或--network选项指定容器的网络模式
●host模式:使用--net-host 指定。
●none模式:使用--net=none 指定。
●container模式:使用--net-container:NAME or ID指定。
●bridge模式:使用--net=bridge 指定,默认设置,可省略。
1.host

相当于Vmware中的桥接模式,与宿主机在同一个网络中, 但没有独立IP地址。
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespacel隔离进程,Mount Namespace隔离文件系统,NetworkNamespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network Namespacel隔离。
一个Docker容器一般会分配一个独立的Network Namespace。
但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。
容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。
docker run -d --name web1 -P nginx #随机映射端口
docker run -d --name web2 -p nginx


2.container

在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个NetworkNamespace,而不是和宿主机共享。
新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。
同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
docker inspect -f '{{.State.Pid}}' 容器ID/名称 #查看容器进程号
ls -l /proc/进程号/ns #查看容器的进程、网络、文件系统等命名空间编号
docker run -itd --name test2 --net==container:da5f9d6e9fec centos:7 bash

3. none

使用none模式,Docker 容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。
也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有1o回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
4. bridge 模式 默认

bridge模式是docker的默认网络模式,不用 --net参数, 就是bridge模式。
相当于Vmware中的nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡。通过docker0网桥以及iptablesnat表配置与宿主机通信,
此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
(1)当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。
虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
(2)从docker0 子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡vethpair设备。
veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
(3) Docker将 veth pair设备的一端放 在新创建的容器中,并命名为eth0 (容器的网卡),另一端放在主机中,以veth*这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
可以通过brctl show 命令查看。
(4)使用docker run -p时,docker实际是 在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

5.自定义网络
直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
docker run -itd --name test3 --network bridge --ip 172.17.0.100 centos:7 /bin/bash

创建自定义网络 可以先自定义网络 ,再使用指定ip运行docker

CPU资源控制
cgroups,是一个非常强大的linux内核工具,他不仅可以限制被namespace隔离起来的资源,
还可以为资源设置权重、计算使用量、操控进程启停等等。所以 cgrpups (Control groups) 实现了对资源的配额和度量。
cgroups有四大功能:
●资源限制:可以对任务使用的资源总额进行限制
●优先级分配:通过分配的cpu时间片数量以及磁盘I0带宽大小,实际上相当于控制了任务运行优先级
●资源统计:可以统计系统的资源使用量,如cpu时长, 内存用量等
●任务控制: cgroup可以对任 务执行挂起、恢复等操作
(1)设置CPU使用率上限
Linux通过CFS (Completely Fair Scheduler, 完全公平调度器)来调度各个进程对CPU的使用。CFS默认的调度周期是100ms。
我们可以设置每个容器进程的调度周期,以及在这个周期内各个容器最多能使用多少CPU时间。
使用--cpu-period即可设置调度周期,使用--cpu-quota即可设置在每个周期内容器能使用的CPU时间。两者可以配合使用。
CFS周期的有效范围是1ms~ls, 对应的 --cpu-period的数值范围是1000~ 1000000。
而容器的CPU配额必须不小于1ms, 即--cpu-quota 的值必须>= 1000。
docker run -itd --name test1 centos:7 /bin/bash
/sys/fs/cgroup/cpu/docker/489fa9374cc70eaed2495229ad9b74db840731e9e20cd0cac313814395e238f3
cat cpu.cfs_period_us
cat cpu.cfs_quota_us
#cpu.cfs_ period_ _us: cpu分配的周期(微秒,所以文件名中用us表示),默认为100000.
#cpu.cfs_ quota_ us:表示该cgroups限制占用的时间( 微秒),默认为-1,表示不限制。
如果设为50000,表示占用50000/ 100000=50号的CPU。

进行CPU压力测试
echo 5000 > cpu.cfs_quata_us
docker exec -it test1 /bin/bash
vi /cpu.sh
#!/bin/bash
i=0
while true
do
let i++
done
chmod +x /cpu.sh
./cpu.sh

(2)设置CPU资源占用比{设置多个容器时才有效)
Docker通过--cpu-shares 指定CPU 份额,默认值为1024,值为1024的倍数。
创建两个容器为cl和c2,若只有这两个容器,设置容器的权重,使得c1和c2的CPU资源占比为1/3和2/3.
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-shares 1024 centos:7
别进入容器 进行压力测试
docker exec -it c1 bash
docker exec -it c2 bash
yum install -y epel-release
yum install -y stress
ess -c 4 #产生四个进程,每个进程都反复不停的计算随机数的平方根
ker stats #看容器运行状态(动态更新)
进入容器C1 进行操作



进入容C1 进行一样的操作



top查看

(3)设置容器绑定指定 CPU
# 先分配虚拟机4个CPU核数
docker run -itd --name c3 --cpuset-cpus 1,3 centos:7 bash
docker exec -it c3 bash #进入容器
yum install -y epel-release && yum install -y stress #安装测压软件
stress -c 4



对内存使用的限制
docker run -itd --name c4 -m 512m centos:7 /bin/bash ##-m 用于限制容器可以使用的最大内存
docker stats
//限制可用的swap大小 --memory-swap 必须和 --memory 一起使用
正常情况下,--memory-swap 的值包含容器可用内存和可用swap。
所以 -m 300m --memory-swap=1g 的含义为:容器可以使用300M的物理内存,并且可以使用700M (1G - 300)的swap。
如果--memory-swap 设置为0或者不设置,则容器可以使用的swap 大小为-m值的两倍。
如果-memory- swap的值和-m值相同,则容器不能使用swap。
如果--memory-swap 值为-1,它表示容器程序使用的内存受限,而可以使用的swap空间使用不受限制(宿主机有多少swap容器就可以使用多少)。


对磁盘IO配额控制(blkio) 的限制
-- device-read- bps: 限制某个设备上的读速度bps (数据量),单位可以是kb、mb (M)或者gb.
例: docker run -itd --name test9 --device - read- bps /dev/sda:1M centos:7 /bin/bash
--device-write-bps : 限制某个设备上的写速度bps (数据量),单位可以是kb、mb (M)或者gb。
例: docker run -itd --name test10 --device -write-bps /dev/sda:1mb centos:7 /bin/bash
--device-read-iops :限制读某个设备的iops (次数)
--device-write-iops :限制写入某个设备的iops (次数)
创建容器,并限制写速度
通过dd来验证写速度
docker run -itd --name c5 --device-write-bps /dev/sda:1mb centos:7 /bin/bash
docker exec -it c5 bash
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct

清理docker占用的磁盘空间 (三思而后行)
docker system prune -a #可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络

浙公网安备 33010602011771号