一、docker介绍
1.容器技术介绍
Container 即容器,平时生活中指的是可以装下其它物品的工具, 以方便人类归纳放置物品 、存储和异
地运输 ,比如人类使用的衣柜 、行李箱、 背包等可以成为容器,Container 除了容器以外,另一个意
思是集装箱, 很多码头工人将很多装有不同物品但却整齐划一的箱子装载到停靠在岸边大船,然后方便的运来运去
为什么这些集装箱可以很方便的运来运去呢?因为它们大小一致标准化尺寸的箱子,并且可以安全的隔离开,所以当我们使用 Container 来形容容器的时候,就是我们想要让容器达到一个可以打包,符合标准的状态。
现在我们所说的容器是一种 IT 技术。容器其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用装起来。这样,应用与应用之间就有了边界而不会相互干扰;同时装在沙盒里面的应用,也可以很方便的被搬来搬去,这也是 PaaS 想要的最理想的状态(可移植性,标准化,隔离性)。
容器是软件工业上的集装箱的技术,集装箱的标准化,减少了包装成本,大大提高货物运输和装卸效率,是传统运输行业的重大变革。早期的软件项目中软件更新,发布低效,开发测试发布周期很长,很难敏捷。有了容器技术,就可以利用其标准化的特点,大幅提高生产效率。
容器技术是虚拟化、云计算、大数据之后的一门新兴的并且是炙手可热的新技术, 容器技术提高了硬件资源利用率、 方便了企业的业务快速横向扩容(可以达到秒级快速扩容)、 实现了业务宕机自愈功能(配合K8S可以实现,但OpenStack无此功能),因此未来数年会是一个容器愈发流行的时代 ,这是一个对于IT 行业来说非常有影响和价值的技术,而对于IT行业的从业者来说, 熟练掌握容器技术无疑是一个很有前景的行业工作机会。
2.Docker 是什么?
Docker (码头工人)是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司(后由于 Docker 开源后大受欢迎就将公司改名为 Docker Inc ,总部位于美国加州的旧金山)内部的一个开源的 PAAS 服务(Platform as a ServiceService )的业余项目。它基于 Google 公司推出的 Go 语言实现。项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 是基于 Linux 内核实现,Docker 最早采用 LXC 技术 ,LXC 是 Linux 原生支持的容器技术 ,可以提供轻量级的虚拟化 ,可以说 docker 就是基于 LXC 发展起来 的,提供 LXC 的高级封装,标准的配置方法,在LXC的基础之上,docker提供了一系列更强大的功能。而虚拟化技术 KVM(KernelKernelbased Virtual Machine Machine) 基于 模块实现, 后来Docker 改为自己研发并开源的 runc 技术运行容器,彻底抛弃了LXC。
Docker 相比虚拟机的交付速度更快,资源消耗更低,Docker 采用客户端/服务端架构,使用远程API来管理和创建容器,其可以轻松的创建一个轻量级的、可移植的、自给自足的容器,docker 的三大理念是build(构建)、ship(运输)、 run(运行),Docker遵从apache 2.0协议,并通过(namespace及cgroup等)来提供容器的资源隔离与安全保障等,所以Docke容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机6-8%性能)的额外资源开销,因此可以大幅提高资源利用率,总而言之Docker是一种用了新颖方式实现的轻量级虚拟机.类似于VM但是在原理和应用上和VM的差别还是很大的,并且docker的专业叫法是应用容器(Application Container)。
总结:
容器本身没有操作系统,依托于服务器(宿主机)的操作系统,它是一个进程,可以运行这个进程,也可以杀死这个进程。容器的根文件系统挂载到宿主机的某个很深路径中,它没有内核,容量很轻。每个容器都有不同的根文件系统。
容器运行需要镜像,镜像需要自己制作。
通过(namespace及cgroup等)来提供容器的资源隔离与安全保障等。
容器内的应用直接运行在宿主机的内核之上,容器并没有自己的内核,也不需要虚拟硬件,相当轻量化
Docker必须基于root运行,而podman可以基于普通用户运行,安全性更好,可以运行无根容器。
3.使用Docker 容器化封装应用程序的意义
①统一基础设施环境-docker环境
硬件的组成配置
操作系统的版本
运行时环境的异构
②统一程序打包(装箱)方式-docker镜像
java程序
python程序
nodejs程序
③统一程序部署(运行)方式-docker容器
java-jar...→ docker run...
python manage.py runserver... → docker run...
npm run dev ... → docker run...
4.传统虚拟机和docker的比较
传统虚拟机是虚拟出一个主机硬件,并且运行一个完整的操作系统 ,然后在这个系统上安装和运行软件
容器内的应用直接运行在宿主机的内核之上,容器并没有自己的内核,也不需要虚拟硬件,相当轻量化
每个容器间是互相隔离,每个容器内都有一个属于自己的独立文件系统,独立的进程空间,网络空间,用户空间等,所以在同一个宿主机上的多个容器之间彼此不会相互影响
5.docker相对于虚拟机的比较
容器可移植到任何平台,虚拟机不可以。
资源利用率更高: 开销更小,不需要启动单独的虚拟机OS内核占用硬件资源,可以将服务器性能压榨至极致.虚拟机一般会有5-20%的损耗,容器运行基本无损耗,所以生产中一台物理机只能运行数十个虚拟机,但是一般可以运行数百个容器
启动速度更快: 可以在数秒内完成启动占用空间更小: 容器一般占用的磁盘空间以MB为单位,而虚拟机以GB
集成性更好: 和 CI/CD(持续集成/持续部署)相关技术结合性更好,实现打包镜像发布测试可以一键运行,做到自动化并快速的部署管理,实现高效的开发生命周期
使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能损耗,我们创建虚拟机的目的是为了运行应用程序,比如Nginx、PHP、Tomcat等web程序,使用虚拟机无疑带来了一些不必要的资源开销,但是容器技术则基于减少中间运行环节带来较大的性能提升。
根据实验,一个运行着CentOS的KVM虚拟机启动后,在不做优化的情况下,虚拟机自己就需要占用100~200 MB内存。此外,用户应用运行在虚拟机里面,它对宿主机操作系统的调用就不可避免地要经过虚拟化软件的拦截和处理,这本身又是一层性能损耗,尤其对计算资源、网络和磁盘I/O的损耗非常大。
比如: 一台96G内存的物理服务器,为了运行java程序的虚拟机一般需要分配8G内存/4核的资源,只能运行13台左右虚拟机,但是改为在docker容器上运行Java程序,每个容器只需要分配4G内存即可,同样的物理服务器就可以运行25个左右容器,运行数量相当于提高一倍,可以大幅节省IT支出,通常情况下至少可节约一半以上的物理设备
6.容器基本的生产环境流程
1.开发好代码,Github
2.运维下载源码
3.maven编译jar war
4.编写dockerfile(制作镜像的工具),使用jar和war
5.build制作镜像
6.镜像上传至harbor镜像仓库
7.从仓库拉取镜像
8.docker run运行容器
9.通过cicd,一键执行
7.docker的组成
runc是docker最底级的核心引擎,是轻量级的通用运行时容器,它遵守OCI规范,是实现OCI接口的最低级别的组件,它与内核交互创建并运行容器。
Docker 主机(Host): 一个物理机或虚拟机,用于运行Docker服务进程和容器,也称为宿主机,node节点
Docker 服务端(Server): Docker守护进程,运行docker容器
Docker 客户端(Client): 客户端使用 docker 命令或其他工具调用docker API
Docker 镜像(Images): 镜像可以理解为创建实例使用的模板,本质上就是一些程序文件的集合
Docker 仓库(Registry): 保存镜像的仓库,官方仓库: https://hub.docker.com/,可以搭建私有仓库harbor
Docker 容器(Container): 容器是从镜像生成对外提供服务的一个或一组服务,其本质就是将镜像中的程序启动后生成的进程
8.Docker 的优势
快速部署: 短时间内可以部署成百上千个应用,更快速交付到线上
高效虚拟化: 不需要额外hypervisor支持,基于linux内核实现应用虚拟化,相比虚拟机大幅提高性能和效率
节省开支: 提高服务器利用率,降低IT支出
简化配置: 将运行环境打包保存至容器,使用时直接启动即可
环境统一: 将开发,测试,生产的应用运行环境进行标准化和统一,减少环境不一样带来的各种问题
快速迁移和扩展: 可实现跨平台运行在物理机、虚拟机、公有云等环境,良好的兼容性可以方便将应用从A宿主机迁移到B宿主机,甚至是A平台迁移到B平台
更好的实现面向服务的架构,推荐一个容器只运行一个应用,实现分布的应用模型,可以方便的进行横向扩展,符合开发中高内聚,低耦合的要求,减少不同服务之间的相互影响
9.Docker 的缺点
多个容器共用宿主机的内核,各应用之间的隔离不如虚拟机彻底
由于和宿主机之间的进程也是隔离的,需要进入容器查看和调试容器内进程等资源,变得比较困难和繁琐
如果容器内进程需要查看和调试,需要在每个容器内都需要安装相应的工具,这也造成存储空间的重复浪费
二、docker原理及其他
1.Docker 组件对应的核心原理
①:Namespace
一个宿主机运行了N个容器,多个容器共用一个 OS,必然带来的以下问题:
怎么样保证每个容器都有不同的文件系统并且能互不影响?
一个docker主进程内的各个容器都是其子进程,那么如果实现同一个主进程下不同类型的子进程?
各个容器子进程间能相互通信(内存数据)吗?
每个容器怎么解决IP及端口分配的问题?
多个容器的主机名能一样吗?
每个容器都要不要有root用户?怎么解决账户重名问题?
namespace是Linux系统的底层概念,在内核层实现,即有一些不同类型的命名空间被部署在内核,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离:
②:Control groups
Linux Cgroups的全称是Linux Control Groups,是Linux内核的一个功能.最早是由Google的工程师(主要是Paul Menage和Rohit Seth)在2006年发起,最早的名称为进程容器(process containers)。在2007年时,因为在Linux内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重命名为cgroup,并且被合并到2.6.24版的内核中去。自那以后,又添加了很多功能。如果不对一个容器做任何资源限制,则宿主机会允许其占用无限大的内存空间,有时候会因为代码bug程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资源分配限制,比如CPU、内存等
Cgroups 最主要的作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等。此外,还能够对进程进行优先级设置,资源的计量以及资源的控制(比如:将进程挂起和恢复等操作)。
Cgroups在内核层默认已经开启,从CentOS 和 Ubuntu 不同版本对比,显然内核较新的支持的功能更多。
2.docker的层级结构
Docker 相当于增强版的LXC,功能更为强大和易用,也是当前最主流的容器前端管理工具
Docker 先启动一个容器也需要一个外部模板,也称为镜像,docker的镜像可以保存在一个公共的地方共享使用,只要把镜像下载下来就可以使用,最主要的是可以在镜像基础之上做自定义配置并且可以再把其提交为一个镜像,一个镜像可以被启动为多个容器。
其他容器解决方案:
pouch
项目网点: https://github.com/alibaba/pouch
Pouch (小袋子)起源于 2011 年,并于2017年11月19日上午,在中国开源年会现场,阿里巴巴正式开源了基于 Apache 2.0 协议的容器技术 Pouch。Pouch 是一款轻量级的容器技术,拥有快速高效、可移植性高、资源占用少等特性,主要帮助阿里更快的做到内部业务的交付,同时提高超大规模下数据中心的物理资源利用率目前的容器方案大多基于 Linux 内核提供的 cgroup 和 namespace 来实现隔离,然后这样轻量级方案
存在弊端:
容器间,容器与宿主间,共享同一个内核
内核实现的隔离资源,维度不足
面对如此的内核现状,阿里巴巴采取了三个方面的工作,来解决容器的安全问题:
用户态增强容器的隔离维度,比如网络带宽、磁盘使用量等
给内核提交 patch,修复容器的资源可见性问题,cgroup 方面的 bug
实现基于 Hypervisor 的容器,通过创建新内核来实现容器隔离
3.Podman
优点:可以运行无根容器,可以基于普通用户,不需要ROOT用户,安全性更好
Docker容器管理工具(docker 命令行工具)
Usage: docker [OPTIONS] COMMAND
Common Commands:
run Create and run a new container from an image
exec Execute a command in a running container
ps List containers
build Build an image from a Dockerfile
pull Download an image from a registry
push Upload an image to a registry
images List images
login Log in to a registry
logout Log out from a registry
search Search Docker Hub for images
version Show the Docker version information
info Display system-wide information
Management Commands:
builder Manage builds
buildx* Docker Buildx (Docker Inc., v0.10.4)
checkpoint Manage checkpoints
compose* Docker Compose (Docker Inc., v2.17.3)
container Manage containers
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
plugin Manage plugins
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
容器 runtime
runtime是真正运行容器的地方,因此为了运行不同的容器runtime需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境
runtime 类型:
Lxc: linux上早期的runtime,在 2013 年 Docker 刚发布的时候,就是采用lxc作为runtime, Docker把 LXC 复杂的容器创建与使用方式简化为 Docker 自己的一套命令体系。随着Docker的发展,原有的LXC不能满足Docker的需求,比如跨平台功能 Libcontainer: 随着 Docker 的不断发展,重新定义容器的实现标准,将底层实现都抽象化到Libcontainer 的接口。这就意味着, 底层容器的实现方式变成了一种可变的方案,无论是使用
镜像仓库 Registry
统一保存镜像而且是多个不同镜像版本的地方,叫做镜像仓库
Docker hub: docker官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用阿里云,网易等第三方镜像的公共仓库
Image registry: docker 官方提供的私有仓库部署工具,无web管理界面,目前使用较少
Harbor: vmware 提供的自带web界面自带认证功能的镜像私有仓库,目前有很多公司使用
范例: 镜像地址格式
docker.io/library/alpine
4.容器编排工具
当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎
容器编排通常包括容器管理、调度、集群定义和服务发现等功能
Docker compose : docker 官方实现单机的容器的编排工具
Docker swarm: docker 官方开发的容器编排引擎,支持overlay network
Mesos+Marathon: Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos最初是由加州大学伯克利分校的AMPLab开发的,后在Twitter得到广泛使用。通用的集群组员调度平台,mesos(资源分配)与marathon(容器编排平台)一起提供容器编排引擎功能
Kubernetes: google领导开发的容器编排引擎,内部项目为Borg,且其同时支持 docker 和CoreOS,当前已成为容器编排工具事实上的标准
5.docker的安装和使用
互联网安装:
官方网站: https://docs.docker.com/engine/install/
wget https://download.docker.com/linux/centos/docker-ce.repo 即可;但外网较慢,同样也可以去阿里官方站点去下载源。
https://mirrors.aliyun.com/docker-ce
Rocky9的docker二进制程序包阿里云下载位置
docker-ce-linux-centos-9-x86_64-stable安装包下载_开源镜像站-阿里云
或者自行编写yum源,安装新版docker-ce版
①docker的互联网安装(yum)
②docker的指定版本安装
③docker的二进制安装(在线、离线)
④在ubuntu上安装指定版本docker
⑤podman基本介绍和安装
安装 podman
#在rocky9.1上安装docker会自动安装podman,docker工具只是一个脚本,调用了Podman
[root@rocky9.1 ~]#dnf install docker
[root@rocky9.1 ~]#rpm -ql podman-docker
/usr/bin/docker
[root@rocky9.1 ~]#cat /usr/bin/docker
注意:需要修改拉取镜像的地址的顺序,提高速度
vim /etc/containers/registries.conf
registries = ['docker.io','quay.io','registry.redhat.io', 'registry.access.redhat.com']
6.docker 程序对应的环境和组成的相关配置文件
环境配置文件(不常用)
/etc/sysconfig/docker-network
/etc/sysconfig/docker-storage
/etc/sysconfig/docke
UNIT单元文件
/usr/lib/systemd/system/docker.service
Docker Registry配置文件
/etc/containers/registries.conf
docker 命令帮助
docker --help
docker info信息解读
root@xxhf:~# docker info
Client:
Debug Mode: false #client 端是否开启 debug
范例: 解决上述SWAP报警提示
官方文档: https://docs.docker.com/install/linux/linux-postinstall/#your-kernel-does-not-support-c
group-swap-limit-capabilities
Server:
Containers: 2 #当前主机运行的容器总数
Running: 0 #有几个容器是正在运行的
Paused: 0 #有几个容器是暂停的
Stopped: 2 #有几个容器是停止的
Images: 4 #当前服务器的镜像数
Server Version: 19.03.5 #服务端版本
Storage Driver: overlay2 #正在使用的存储引擎
Backing Filesystem: extfs #后端文件系统,即服务器的磁盘文件系统
Supports d_type: true #是否支持 d_type
Native Overlay Diff: true #是否支持差异数据存储
Logging Driver: json-file #日志类型
Cgroup Driver: cgroupfs #Cgroups 类型
Plugins: #插件
Volume: local #卷
Network: bridge host ipvlan macvlan null overlay # overlay 跨主机通信
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk
syslog # 日志类型
Swarm: inactive #是否支持 swarm
Runtimes: runc #已安装的容器运行时
Default Runtime: runc #默认使用的容器运行时
Init Binary: docker-init #初始化容器的守护进程,即 pid 为 1 的进程
containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339 #版本
runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657 #runc 版本
init version: fec3683 #init 版本
Security Options: #安全选项
apparmor #安全模块,https://docs.docker.com/engine/security/apparmor/
seccomp #安全计算模块,即制容器操作,
https://docs.docker.com/engine/security/seccomp/
Profile: default #默认的配置文件
Kernel Version: 5.15.0-71-generic #宿主机内核版本
Operating System: Ubuntu 22.04.2 LTS #宿主机操作系统
OSType: linux #宿主机操作系统类型
Architecture: x86_64 #宿主机架构
CPUs: 8 #宿主机 CPU 数量
Total Memory: 3.799GiB #宿主机总内存
Name: xxhf #宿主机 hostname
ID: IZHJ:WPIN:BRMC:XQUI:VVVR:UVGK:NZBM:YQXT:JDWB:33RS:45V7:SQWJ #宿主机 ID
Docker Root Dir: /var/lib/docker #宿主机关于docker数据的保存目录
Debug Mode: false #server 端是否开启 debug
Registry: https://index.docker.io/v1/ #仓库路径
Labels:
Experimental: false #是否测试版
Insecure Registries:
127.0.0.0/8 : #非安全的镜像仓库
Registry: https://index.docker.io/v1/ #镜像仓库
Live Restore Enabled: false #是否开启活动重启 (重启docker-daemon 不关闭容器 )
7.docker的网络环境
查看 docker0 网卡
在docker安装启动之后,默认会生成一个名称为docker0的网卡并且默认IP地址为172.17.0.1的网卡
原理:iptables里面的nat规则
8.docker默认的存储引擎
Lowerdir 镜像层,只读层
Upperdir 读写层(写时复制机制)
Mergedir 将只读层+可写层合并后的内容展示给用户
9.docker镜像管理
常见的镜像管理命令
①镜像结构
图解:
最下面为宿主机的内核,从镜像开始就是只读镜像的三层:第一版本镜像为基础镜像,然后在其基础上做了修改如给它安装了jdk环境,然后将其保存为第二版本镜像;在第二版本镜像上做修改如安装了tomcat服务,然后将其保存为新的镜像——第三版镜像。每做一层修改都会在可写层进行修改,然后将可写层保存为新的一层。
镜像即创建容器的模版,含有启动容器所需要的文件系统及所需要的内容,因此镜像主要用于方便和快速的创建并启动容器;镜像含里面是一层层的文件系统,叫做 Union FS(联合文件系统),联合文件系统,可以将几层目录挂载到一起(就像千层饼,洋葱头,俄罗斯套娃一样),形成一个虚拟文件系统,虚拟文件系统的目录结构就像普通 linux 的目录结构一样,镜像通过这些文件再加上宿主机的内核共同提供了一个linux 的虚拟环境,每一层文件系统叫做一层 layer,联合文件系统可以对每一层文件系统设置三种权限,只读(readonly)、读写(readwrite)和写出(whiteout-able),但是镜像中每一层文件系统都是只读的,构建镜像的时候,从一个最基本的操作系统开始,每个构建提交的操作都相当于做一层的修改,增加了一层文件系统,一层层往上叠加,上层的修改会覆盖底层该位置的可见性,这也很容易理解,就像上层把底层遮住了一样,当使用镜像的时候,我们只会看到一个完全的整体,不知道里面有几层,实际上也不需要知道里面有几层,结构如下:
一个典型的 Linux文件系统由 bootfs 和 rootfs 两部分组成
案例:查看镜像的分层结构(nginx hello-world alpine)
②:阿里云官方镜像仓库加速
搜索-容器镜像服务
镜像加速器 https://f9lwretl.mirror.aliyuncs.com
③:搜索镜像
1官方网站进行镜像的搜索 官网: http://hub.docker.com
2执行docker search命令进行搜索
④:实现多个宿主机共享镜像共享(同步到其他主机)
保存到本地,并进行压缩(导出):docker save alpine -o alpine.tar gzip alpine.tar
同步到其他主机: scp alpine.tar.gz 192.168.31.199:/root/
其他主机导入镜像: docker load -i alpine.tar.gz docker images
若导入多个镜像
docker save `docker images | awk 'NR>=2{print $1":"$2}'` -o all.tar
或者docker save `docker image ls --format "{{.Repository}}:{{.Tag}}"` -o all.tar
gzip all.tar scp all.tar.gz 192.168.31.199:/root/
其他主机导入全部镜像 docker load -i all.tar.gz
在自己主机导入镜像:
在其他主机导入镜像:
⑤:镜像位置和分层效果
du -sh /var/lib/docker/overlay2/*
docker inspect rockylinux:9.1.20230215-minimal
⑥:删除本地镜像 docker rmi
强行删除所有的镜像
docker rmi -f `docker images -qa`
为了方面使用命令,可以定义为别名操作
alias rmi='docker rmi -f `docker images -qa`'
⑦:给镜像打标签(方便将来上传至镜像仓库)
docker tag 镜像名:TAG 仓库主机FQDN或IP[:端口]/项目名(或用户名)/image名:版本
例如:docker tag rockylinux:9.1.20230215-minimal siqin123/wang-rocky:9.1.20230215-minimal
⑧:登录官网docker.io镜像站点,然后即可上传至公共仓库
docker login
docker push siqin123/wang-rocky:9.1.20230215-minimal
alias rmc='docker container prune -f'
【注】:上传镜像需要登录(账户和密码),拉取不需要密码
阿里云仓库:
首先登录阿里云
三、 docker基于镜像实现容器基本命令操作和管理
容器的生命周期:
使用docker run(create+run)/create创建一个容器,create是创建了还没有启动,然后就到了启动状态;如果启动了,就使用docker rm删除,如果是stoped处于停止状态,然后也使用docker rm将其删除,此时就处于deleted状态。
创建容器启动之后就处于running状态,使用docker kill将其杀死;docker stop也是停止死亡状态,然后在通过rm将其删除;restart是要经历一个先死后启的状态;如果是out-of-memory是内存溢出,报oom,然后就死掉了,当容器进程退出也是死掉了,接着进行重启策略判断,不重启就停止并删除;如果重启就运行
常见容器管理命令
注意:
①:run不存在的镜像,即会实现下载镜像之后进行运行
②:默认运行容器,有些容器没有内置前台进程,会导致运行即立即退出,若想退出而不退出容器进程,输入同时按三个键,ctrl+p+q
若内置了前台进程的容器运行。运行时为前台进程,不会退出;运行不指定名称,会随机生成字符串和ID号
③:运行容器后,docker0网桥会生效,为容器内的一半桥接网卡分配同网段的IP地址,宿主机可以进行直接通信
④:docker守护进程开启,会默认自己生成iptables防火墙规则
⑤:容器真实数据在/var/lib/docker/overlay2/,类似于数据字典。数据允许叠加,多个设备数据可以合并。
1.运行容器docker run 命令用法
docker run [选项] [镜像名] [shell命令] [参数]
#选项:
-i, --interactive 以交互模式运行容器,通常和-t同时使用。
-t, --tty 为容器重新分配一个伪输入终端,通常和-i同时使用,注意对应的容器必须运行shell才支持进入
-d, --detach Run container in background and print container ID,台后运行,默认前台
--name string Assign a name to the container
--h, --hostname string Container host name
--rm Automatically remove the container when it exits
-p, --publish list Publish a container's port(s) to the host
-P, --publish-all Publish all exposed ports to random ports
--dns list Set custom DNS servers
--entrypoint string Overwrite the default ENTRYPOINT of the image
--restart policy
--privileged Give extended privileges to container
-e, --env=[] Set environment variables
--env-file=[] Read in a line delimited file of environment variables
主机名用于在相互交互的时候,不一定通过ip交互,还可以通过主机名交互
-P:暴露随机端口
-p:实现宿主机端口和容器端口的映射(暴露指定端口)
dns :容器的dns是基于宿主机的,和宿主机一样
2. 守护式容器:(例如nginx)
能够长期运行
无需交互式会话
适合运行应用程序和服务
容器默认不会开机自启,若要实现容器宿主机开机自动启动,可以在运行容器时基于--restart制定不同的策略
①:no 默认值
②:on-failure[:max-retries] 如果容器异常退出即启动,无论容器是否运行,只要是异常退出就会启动
③:always 无论任何情况都启动
④:unless-stopped 守护进程启动情况下不会启动,指定了 --restart unless-stopped 并处于 Stopped (Exited) 状态的容器,不会在 Docker daemon 重启的时候被重启。(如果使用方案4,已经手动设置了stop策略,在重启就不会重启了)
例:
always:无论任何情况下都要启动
②和④对比:
②是异常退出,④为异常和正常都在stop状态下,重启不会开启服务
3.容器管理的常用操作
docker ps
docker ps -a
docker top CONTAINER_ID/NAMES 查看容器内的进程
docker stats [CONTAINER_ID/NAMES] 查看容器资源使用情况
例如:
[root@rocky-9 ~]# docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
docker inspect 查看docker各种对象的详细信息,包括:镜像,容器,网络等
例如:docker inspect nginx
docker rm [-f/-v] 删除容器,即使容器正在运行当中,也可以被强制删除掉
docker rm `docker ps -qf status=exited` 删除退出状态的容器
docker container prune -f 删除所有停止的容器,常用命令可将其定义为别名
例如:alias rmc='docker container prune -f' 或者docker ps -qa | xargs docker rm
docker exec 在运行中的容器启动新进程,可以执行单次命令,以及进入容器,使用exit退出,但容器还在运行,此为推荐方式
例如:docker run -itd 容器ID/NAME docker exec -it 容器ID/NAME sh|bash
docker start|stop 容器ID/NAME 容器的启动和停止
docker logs docker logs [OPTIONS] CONTAINER 查看容器的日志 (排错)
4.docker暴露容器端口
容器启动后,默认处于预定义的NAT网络中,所以外部网络的主机无法直接访问容器中网络服务
docker run -P 将事先容器预定义的所有端口映射宿主机的网卡的随机端口,默认从32768开始使用随机端口
当停止容器后再启动可能会导致端口发生变化
例如:docker run --rm --name nginx -P nginx
docker port 可以查看容器的端口映射关系 docker port CONTAINER_ID/NAME
【注】:由于docker守护进程启动后,默认会开启防火墙,而端口暴露本质上是基于NAT映射而来
指定端口映射
docker run -p 将容器的预定义的指定端口映射到宿主机的相应端口
例如: 暴漏81端口 docker run --rm --name nginx -p 81:80 nginx
案例:
容器内部署应用---例如wordpress
docker run -d -p 80:80 --name wordpress wordpress
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=123456 --name mysql -d mysql
5.管理容器内部的hosts文件和DNS文件
修改容器的 hosts文件(添加--add-host选项,可以复用)
主机名复用:
配置容器的DNS
容器的dns服务器,默认采用宿主机的dns 地址,可以用下面方式指定其它的DNS地址
将dns地址配置在宿主机
在容器启动时加选项 --dns=x.x.x.x (添加--dns选项,可以复用)
在/etc/docker/daemon.json 文件中指定
永久性指定DNS:
6.容器内和宿主机之间复制文件
用法:
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Options:
-a, --archive Archive mode (copy all uid/gid information)
-L, --follow-link Always follow symbol link in SRC_PATH
容器中没有vi、vim等命令,如要做更改,我们就可以把其复制到宿主机,然后进行更改,然后再把其复制到容器中
把docker的里面内容拉取出来
7. 传递容器环境变量
8.使用systemd以服务的方式管理和控制容器
vim /lib/systemd/system/hello.service
Systemctl daemon-reload
[Unit]
Description=Hello World
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox-hello
ExecStartPre=-/usr/bin/docker rm busybox-hello
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox-hello busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/usr/bin/docker kill busybox-hello
[Install]
WantedBy=multi-user.target
9. 利用 docker 快速部署Spug自动化运维平台
docker run -d --restart=always --name=spug -p 81:80 registry.aliyuncs.com/openspug/spug
进行初始化
docker exec spug init_spug admin 123456