Docker 基本管理整理

一 容器基础相关

为什么要使用容器 容器是什么?


容器其实就是一个进程,是将一整套应用程序所需运行的软件及其运行环境进行打包封装在一个容器里面,每个容器之间有自己独立的运行环境,相互之间互不干扰。
例如一个服务上运行一个nginx应用,若需要运行多个nginx,那就需要将nginx安装多次,若使用容器,利用ceph块存储将nginx打成一个镜像,再通过导入的方式将镜像导入成不同的镜像文件,从而运行多个实列
以前的服务是将多个服务集中在一个应用上去跑服务,这个时候如需要改动其中一个功能模块,将停止整个服务,且需要整体进行改动和升级,使用微服务将多个功能拆分成一个小的模块,每个模块实现不同的功能,通过http或rpc相关协议在一个高速网络中组成一个完整架构,这个时候我需要改动(更新或增加功能或服务)只需要改一个组件就好,其他的没有影响,无需改动。这个时候那么多的小应用就可以使用容器将其封装运行。
容器自带独立运行环境,防止了运维和开发的环境矛盾,摒弃了底层的运行环境,实现了环境的一致。
总结:即 容器其实就是一个拥有一整套应用程序所需运行的软件及运行环境的进程。容器可以摒弃底层环境的差异,并更好的管理成千上百个小型微服务化的应用。

为什么容器成为主流?


因为微服务的蓬勃发展,导致容器的需求量增加。

docker是什么? **


docker是一个go语言开发的应用容器引擎,运行容器里的应用。 docker是用来管理容器和镜像的一种工具。
所有的容器共用宿主机的内核。


容器引擎有些啥?


docker  rocket podman containerd
docker目前还是最主流。

容器与虚拟机的区别?**


原理上的区别:
虚拟机使用hypervisor虚拟机管理程序,模拟服务器上的硬件资源,通过虚拟机管理程序,创建出多个虚拟机,需要在虚拟机上安装操作系统等运行库,再在虚拟机上安装应用程序。虚拟机上安装的操作系统和应用使用的资源是通过hypervisor虚拟机管理程序调用的宿主机上的硬件资源。
容器通过docker容器引擎去运行容器应用,起到共享操作系统内核,减少了虚拟化管理程序对资源的开销,少了一个虚拟机管理程序,容器其实就是宿主机上的一个进程。
总结:虚拟机在虚拟机管理程序去调用硬件资源会有性能损耗,而docker作为一个进程,减少了虚拟机管理程序对资源的开销。

所有容器共享主机内核,而每个虚拟机都有独立的操作系统和内核。
容器使用namespace隔离资源,使用cgroup限制资源的最大使用量,而虚拟机完全隔离,每个虚拟机都有独立的硬件资源。
容器是秒级启动速度,而虚拟机是分钟级启动速度。
容器相当于宿主机的进程,性能几乎没有损耗。而虚拟机需要hypervisor虚拟机管理程序对主机资源虚拟访问,有20~50%资源损耗
容器一台主机能够支持成成千上百个容器,虚拟机则是一台主机最多支持几十台虚拟机


当我要使用虚拟机完成一定任务,资源应该怎么安排?


需要比本应完成所需资源多出百分之二十到三十的资源

解释一下什么是镜像?


镜像是创建容器的基础,就是一个只读的模板文件,里面包括容器里的应用程序所需要的所有内容(包括程序代码文件,配置文件,运行环境,库文件等)


解释一下什么是容器?


容器就是用镜像运行的实列(进程),容器可以被创建,启动,停止,删除,每个容器默认是相互资源隔离的


解释什么是仓库?


仓库就是用来保存镜像的地方,有公有仓库和私有仓库


docker的镜像,容器,日志等内容存放位置?


/var/lib/docker


你知道的docker镜像操作的指令有哪些?


查找镜像                    docker search   镜像关键词
拉取镜像                     docker pull         注释: latest为默认标签
查看当前镜像              docker images
删除镜像                     docker rmi   仓库/镜像名  或镜像ID
修改镜像标签               docker tag   旧镜像名:标签    新镜像名:标签
查看镜像详细信息         docker inspect  镜像ID
将镜像导出                    docker save -o 镜像文件   容器ID或镜像名:标签
将容器导出重定向到当前目录并设置容器名    docker export ID > 容器名.tar  
利用源主机文件导入镜像到本机                      cat 容器名.tar | docker import  - 镜像仓库:标签  或者
docker import 容器名.tar -- 镜像仓库:标签
导入镜像到docker中      docker load -i 或< 镜像文件
登录仓库                       docker login             注释: 默认登录公有仓库
推送镜像到仓库             docker push 仓库/镜像名:标签


你知道的docker容器操作的指令有哪些?


创建容器并实现与容器交互作用       docker create  [--name 容器名] -it 镜像:标签
启动容器     docker start 容器名/容器ID
查看所有容器运行的容器状态       docker ps
查看所有容器状态   docker ps -a
关闭容器(等待十秒)          docker stop 容器名/容器ID      注释:kill -15
强杀                 docker kill  容器名/容器ID      注释:kill -9
删除容器                 docker rm 容器名/容器ID      
查看容器的详细信息     docker inspect 容器名/容器ID 
进入容器                    docker exec -it 容器名/容器ID  bash/sh       注释:bash或sh为后缀
复制容器文件到主机        docker cp 容器ID:文件绝对路径  宿主机目录/文件
复制主机文件到容器         docker cp 宿主机文件  容器ID:目录/文件绝对路径   
同时创建并运行               docker  run 
将容器放在后台运行不占用活动界面    docker run -d 
批量删除停止的容器         docker rm $(docker ps -a -q)
批量删除所有容器         docker rm -f $(docker ps -a -q)
docker run -P  随机端口映射,32768开始
docker run -p 宿主机端口:容器端口   指定端口映射
docker run -v  宿主机目录/文件:容器目录/文件      将宿主机目录/文件挂载到容器做数据卷
docker run --volumes-from 数据卷容器名            将数据卷容器的数据卷目录共享到本容器
--like 目标容器名:连接别名     实现新建的容器通过容器名或连接别名与目标容器通信。


命名空间是用来做什么的?


用于容器的资源隔离


容器中的六大命名空间是什么?


MNT 类型命名空间提供磁盘挂载点和文件系统的隔离能力。 文件系统
IPC 类型命名空间提供进程间通信的隔离能力                         进程间通信
NET 类型命名空间提供网络隔离能力                                      网络(IP 端口 路由)
UTS 类型命名空间提供主机名隔离能力                                  主机名  域名
PID 类型命名空间提供进程隔离能力                                      进程ID号
USER 类型命名空间提供用户隔离能力                                   用户名  用户组名

 docker exec -it 容器名/容器ID  bash/sh     该指令进入容器的原理是什么?  


通过 Docker 引擎将当前进程切换到容器内,并在容器内启动一个终端窗口,以便我们在窗口中输入命令来操作容器。-it 参数表示运行命令时进入容器的交互模式。容器名/容器 ID 表示要进入的容器的名称或 ID。bash/sh 表示进入容器后使用 bash 或 sh 命令交互,具体使用哪个命令取决于容器内安装的 shell 类型。

容器的特点?


灵活:即使是最复杂的应用也可以集装箱化。
轻量级:容器实际就是一个轻量级没有内核的虚拟机,共享虚拟机内核
可互换:容器可以即时部署更新和升级
便携式:一次封装导出运行。
可扩展:可以增加并自动分发容器副本
可堆叠:可在容器中堆叠多个服务,例如堆叠lnmp容器。

docker run 的工作过程?


容器保持运行的前提是容器中PID为一的主进程一直在前台运行。  
镜像是一个只读模板,只能读不能写,镜像是堆叠出来的,下载的过程就是层层堆叠,下载的镜像只能读不可写,需要添加一层可读写的容器层。
每个容器是孤立的,容器与容器之间通信需要一个桥梁(容器网桥)和配置对应的IP。
docker后面的命令通常作为进程ID为一的主进程。该进程被终止则容器终止。
1.检查本地是否存在本地镜像,若镜像不存在时,会从共有仓库拉取(下载)镜像。
2.利用镜像创建并启动容器
3.分配一个文件系统给容器,在只读镜像外面挂载一层可读写层。
4.从宿主机配置的网桥接口中桥接一个虚拟机接口到容器中
5.分配一个地址池中的IP地址给容器。
6.执行容器指定的运行命令,执行完成后容器被终止。
总结:docker run 启动过程中,会为镜像分配一个可读写的容器层,会为容器分配一个IP地址方便容器之间的通信。再运行容器,命令作为pid为一的主进程。容器的主进程退出前台或终止,则容器终止。

怎么实现容器在后台运行?


docker run -d 
不加-d有的命令在前台就会显示出来,docker run 直接进入容器,容器不退出窗口就会一直卡着,想启动容器而不占用整个窗口的操作:加 -d.
总结: docker run -d 运行指令,而不会进入容器


怎么实现退出容器自动删除?


docker run --rm  

怎么把容器导出(包含自己数据的容器迁移到另一台主机)?


源主机:
docker ps -a 查看所需迁移的容器ID号
docker export ID > 容器名.tar  将容器导出重定向到当前目录并设置容器名
scp 容器名.tar 目标主机IP:/目标目录    将容器压缩包拷到目标主机
目标主机中:
cat 容器名.tar | docker import  - 镜像:仓库标签   利用源主机文件导入镜像到本机
docker run -itd 镜像:仓库标签 bash运行环境   将镜像运行为容器。

总结:将原容器导出成一个文件,然后将文件发送给远程主机,远程主机将文件导入成镜像,利用该镜像运行出新容器。

怎么杀死容器?


容器内部是无法杀死容器中的pid为一的进程。
直接exit退出容器则自动结束容器
若是设为后台运行的容器使用stop 可停止容器。

怎么删除容器?


docker rm无法直接删除正在运行的容器,需要先stop安全退出容器。再使用 docker rm 删除指定的容器。
docker rm -f 可强删正在运行的容器

怎么批量删除停止的容器(考的是怎么过滤出停止容器ID)?


思路:
rm 不加-f删除停止运行的容器,rm -f 删除所有容器。
-a 所有容器信息
-q 容器ID号
$ 表示遍历每个变量
docker ps -a -q 查看所有容器的id号
docker ps -q 正在运行的容器 
docker ps -a -q | grep -v $(docker ps -q)   反向过滤出没有运行的容器
docker rm $(docker ps -a -q | grep -v $(docker ps -q))     删除没有运行的容器
也可以有报错的直接删除(虽然有报错但不影响删除效果,因为正在运行的容器无法用rm 直接删除)
docker rm $(docker ps -a -q)
总结:有过滤的删除:docker rm $(docker ps -a -q | grep -v $(docker ps -q)) 
有报错的删除:docker rm $(docker ps -a -q)

怎么删除所有容器?


docker rm -f $(docker ps -a -q)

二  docker网络部分


docker 网络实现原理是什么?


docker 使用linux桥接,在宿主机虚拟一个docker容器网桥(docker0).docker启动一个容器时会根据docker网桥的网段分配给容器一个IP地址,称为Container-IP ,同时docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的container-IP直接通信。
docker 网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过container-IP 访问到容器。如果容器希望外部能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run 创建容器时通过-p 或-P参数启用,访问容器时通过 宿主IP:宿主端口 访问容器。


怎么查看?

-P 随机映射
查看网络地址转换
iptables -nL -t nat查看可得:
当有人访问端口会默认转发到容器的IP和端口上

-p用来指定端口

如何让外部主机访问容器内的业务?

docker run -itd -p 宿主机端口:容器的对应端口 指定镜像(用户名/仓库名:镜像标记)
访问直接访问宿主机地址和对应宿主机的端口

答:docker run 启动容器的时候使用-p或-P将容器的端口映射到宿主机上,外界用户使用宿主机的IP地址加映射端口就可以访问容器内部业务。

如何查看容器内部的主进程日志?


docker logs 容器ID 

一般建议容器内存放多少进程? 为什么?


一般建议容器内装一个进程。
这样便于管理,维护,查看日志。容器内主进程退出容器就推出了,若安装多个进程,非主进程退出是无法看到的。必须进入容器中才可以查看。不能直接使用docker logs直接查看到。

容器的网络模式有哪些,分别实现什么网络架构?


1.HOST   没有容器IP,直接使用宿主机的IP和端口号,和宿主机共享网络命名空间(端口范围)
2.Container   没有容器IP,与指定容器共享IP和端口范围,和别的容器共享网络命名空间
3.None :该模式关闭了网络功能,没有IP没有端口,相当于单机模式
4.Bridge      docker默认的网络模式,docker启动的时候为每一个容器分配设置IP,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及ipables nat表配置与宿主机通信。
5.自定义

安装docker时,会自动创建那些网络? 怎么查看


bridge (容器默认连接), none, host
查看: docker network ls 或者 docker network list

怎么启动容器的时候指定网络模式?


docker run 启动容器的时候,使用--net 或 --network选项指定容器的网络模式。

选项和后面的值之间可以使用空格或等号指定。


查看容器进程号?


查看进程详细信息里面的State字段下面的Pid字段。
docker inspect -f '{{.State.Pid}}'  容器ID号


怎么查看容器进程的命名空间?


docker ps -a 查看容器的ID号
ls /proc/  显示当前系统中所有的进程
每个容器进程下面都有一个ns文件为命名空间文件
ls /proc/容器ID号/ns
-l 显示详细信息
ls -l /proc/容器ID号/ns   在最后面一行就是命名空间的编号。

container模式绑定的两个容器net命名空间一致。


简述bridge模式?


docker启动的时候,自动生成一个docker0网桥,所有的容器最终会连接到该网桥中。 docker为每一个容器分配一对虚拟网卡,一头在docker上(作为docker的网卡),另一头在docker0网桥上。每个容器都有这么一对网卡

为什么给容器 指定IP地址后不可以启动容器
docker run --itd --network=bridge --ip IP地址 镜像
使用默认网桥的时候,网桥的网段是不能直接分配IP地址,只能让docker自动分配。

怎么指定IP地址给容器使用?


先使用network create --subnet指定一个自定义网段,--opt指定网桥的名称,最后直接指定网络的名字
然后去创建docker run --itd --network=自定义的网络名称 --ip IP地址 镜像

三 docker数据管理

数据卷是用来做什么的?


供容器使用的特殊目录,位于容器中。将宿主机的目录挂载到数据卷上,对数据卷的修改操作立即可见,并更新数据在宿主机与容器之间的迁移。数据卷的使用类似于linux下对目录的mount操作。
 

怎么制作数据卷(将宿主机目录共享到容器)
docker run -v 可以创建数据卷 
docker run -itd -v 宿主机的目录:容器内部的目录  镜像名

怎么实现容器与容器之间的数据共享?


通过所有容器与宿主机目录或文件实现共享,达到所有容器之间数据实现共享也就是说,宿主机目录共享给来了所有容器


怎么不经过宿主机达到容器与容器之间数据共享?

使用数据卷容器,专门提供数据卷给其他容器挂载使用的容器。
--volumes-from 挂载容器的数据卷来实现容器之间的数据共享
docker run -itd --name c1 -v /data1 -v /data2 镜像    生成数据卷容器
docker exec -it c1 sh   进入容器
docker run -itd --volumes-from 数据卷容器名 --name 共享容器名  镜像

什么是容器的互联?


虽然两容器可以通过IP地址通信,但IP地址是会变的,
可使用容器的主机名不变,通过容器名去通信,在源容器和接受容器间建立一条隧道,接收容器可以看到原容器指定的信息

docker run -itd --name c3 --like c1:别名 镜像     实现新建的容器c3与已有容器c1互联
--like指定连接的容器实现互联(一个容器通过容器名或别名实现互联)

四 Cgroup docker资源限制


  控制容器进程对CPU,内存,磁盘IO 使用量的限制

容器怎么实现资源的限制?


通过Cgroup资源限制 
docker 通过Cgroup来控制容器使用的资源配额,包括CPU,内存,磁盘三大方面。
Cgroup是linux内核提供的一种可以限制,记录,隔离进程组所使用的物理资源(CPU,内存,磁盘IO)。
Cgroup是提供将进程进行分组化管理的功能和接口的基础结构,I/O或内存的分配控制等具体的资源管理就是通过该功能实现。
总结:通过Cgroup可以限制Docker容器在CPU,内存,磁盘等方面的最大使用量。

对CPU的限制

怎么实现对CPU的资源控制?

进程在单位时间周期内是顺序运行的,每一个进程是在单位周期内时间分片中运行。按着循环高频率的运行。

答:设置进程在PCU使用率的上限。
使用 --cpu-period设置容器CPU调度周期,--cpu-quota设置每个走起内容器使用的CPU时间。--cpu-quota/--cpu-period 为一个CPU的占用率。
如果是多核可以设置--cpu-period 大于--cpu-quota。
CPU调度周期有效范围:1ms到1s 配置中为1000到1000000
CPU配额必须大于1ms  配置中大于等于1000

怎么查看--cpu-quota和--cpu-period 时间?


cd 进入/sys/fs/cgroup/cpu/docker/
中查看对应容器的id号 进去容器并查看cpu-quota和cpu-period 时间

查看cpu.cfs_quota_us为-1 表示啥?


不限制,时间周期有多少就用多少 值为:CPU数量*cpu.cfs_period_us的值


怎么模拟容器CPU被沾满的情况?


写死循环可以模拟CPU完全使用的极端情况
docker exec -it 容器别名  sh   进入容器中跑死循环程序
vi test.sh        这里跟的命令可以看作是sh后的容器中运行的命令(vim无法使用,需要使用vi)
#!/bin/sh
i=0
while true
do
let i++
done

chmod +x test.sh
./test.sh

怎么限制容器的使用率上限?


查看
修改cpu.cfs_period_us内的数值,使用率上限通过两个值的比率来进行确定。
echo 数值 > /sys/fs/cgroup/cpu/docker/
对应容器的id号/cpu.cfs_period_us
或:docker run -itd --name c2 --cpu-quota 数值 用户名/仓库名:标记  /bin/bash     (docker run 代表创建时后指定cpu使用率)


怎么设置多容器的CPU资源占用比?


若只是通过CPU使用的上限设置CPU占用比,可能会超。若不想繁琐计算来设置cpu份额。
可以使用--cpu-shares指定CPU份额,默认为1024,值为1024的整数倍或一半(512)。多个容器设置完--cpu-shares会自动计算出占用比。
自己的值/总和就是设置的占用比。

容器外无法连接到外网?


先看宿主机是否外网能同 ping www.baidu.com
可能docker的进程出现问题,删除原来的容器重启后重新创建容器就解决了。
docker rm -f $(docker ps -aq)  
systemctl restart docker


怎么做压测?


安装压测stress工具做压测:
在docker中
yum install -y epel-release  (添加一个第三方源)
yum install -t stress  (模拟多进程压测的工具 stress)
stress -c 指定压测CPU数 
docker stats 查看docker容器中CPU占用比

怎么指定容器绑定CPU?
CPU编号从0开始
docker run -itd --name test7 --cpuset-cpus 1,3 镜像  /bin/bash           指定容器使用编号为1,3两个CPU。

怎么查看PCU使用情况?


top 
1


什么情况下使用--cpu-shares ?或 什么时候--cpu-shares有效?


设置多个容器的CPU使用的占用比,只能在多个容器同时运行且资源紧张时有效。

--cpu-period  --cpu-quota这两个参数是做啥的?
设置容器进程能使用CPU使用率的上限。


对内存的限制


iB与B的区别?与关系?


1KB=10^3B     1000B
1KiB=2^10B   1024B  
相同数值 iB大于B

怎么对容器内存进行限制?


docker run 运行的时候用-m指定内存大小。
docker run -itd --name c4 -m 512M(大小) 镜像
这里指定的大小单位是  iM

内存除了可用的物理内存 还有交换内存,
使用--memory-swap设置可用内存和交换内存的总和
-m 300m --memory-swap=1g :容器可以使用300M 的物理内存,使用700M 的交换内存。

--memory-swap=0 为默认(不设置也是) 容器使用的swap大小为-m指定的两倍
--memory-swap=-m指定的值 容器不能使用swap
--memory-swap=-1 内存受限,但宿主机有多少swap容器就可以使用多少

怎么查看容器的运行状态(内存 CPU 网络传输速率)?


docker stats
查看到的内存单位是MiB 

怎么限制磁盘读写?


对指定磁盘的读速度限制
--device-read-bps 设备名:速度

对指定磁盘的写速度限制
--device-write-bps 设备名:速度

对磁盘的读次数做限制
--device-read-iops

对磁盘的写次数做限制
--device-write-iops

怎么模拟磁盘的写入?


dd if=/dev/zero of=./text.txt bs=1M count=10 oflag=direct  


 

你可能感兴趣的:(docker,容器,运维)