Docker容器化技术——超全了解Docker容器及安装部署

AIcoding·八月创作之星挑战赛 10w+人浏览 109人参与

Docker容器化技术

1. 容器技术介绍

Container 即容器,平时生活中指的是可以装下其它物品的工具, 以方便人类归纳放置物品 、存储和异地运输 ,比如人类使用的衣柜 、行李箱、 背包等可以成为容器,Container 除了容器以外,另一个意思是集装箱, 很多码头工人将很多装有不同物品但却整齐划一的箱子装载到停靠在岸边大船,然后方便的运来运去

为什么这些集装箱可以很方便的运来运去呢?因为它们大小一致标准化尺寸的箱子,并且可以安全的隔离开,所以当我们使用 Container 来形容容器的时候,就是我们想要让容器达到一个可以打包,符合标准的状态。

现在我们所说的容器是一种 IT 技术。容器其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用装起来。这样,应用与应用之间就有了边界而不会相互干扰;同时装在沙盒里面的应用,也可以很方便的被搬来搬去,这也是 PaaS 想要的最理想的状态(可移植性,标准化,隔离性)。

容器是软件工业上的集装箱的技术,集装箱的标准化,减少了包装成本,大大提高货物运输和装卸效率,是传统运输行业的重大变革。早期的软件项目中软件更新,发布低效,开发测试发布周期很长,很难敏捷。有了容器技术,就可以利用其标准化的特点,大幅提高生产效率。

容器技术是虚拟化、云计算、大数据之后的一门新兴的并且是炙手可热的新技术, 容器技术提高了硬件资源利用率、 方便了企业的业务快速横向扩容(可以达到秒级快速扩容)、 实现了业务宕机自愈功能(配合K8S可以实现,但OpenStack无此功能),因此未来数年会是一个容器愈发流行的时代 ,这是一个对于IT 行业来说非常有影响和价值的技术,而对于IT行业的从业者来说, 熟练掌握容器技术无疑是一个很有前景的行业工作机会。

2. Docker 是什么?

2.1 介绍

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)。

2.2 使用Docker 容器化封装应用程序的意义:

(1)统一基础设施环境-docker环境

  • 硬件的组成配置

  • 操作系统的版本

  • 运行时环境的异构

  • 统一程序打包(装箱)方式-docker镜像

    • java程序

    • python程序

    • nodejs程序

(2)统一程序部署(运行)方式-docker容器

  • java-jar...→ docker run...

  • python manage.py runserver... → docker run...

  • npm run dev ... → docker run...

传统虚拟机是虚拟出一个主机硬件,并且运行一个完整的操作系统 ,然后在这个系统上安装和运行软件

容器内的应用直接运行在宿主机的内核之上,容器并没有自己的内核,也不需要虚拟硬件,相当轻量化。而且每个容器间是互相隔离,每个容器内都有一个属于自己的独立文件系统,独立的进程空间,网络空间,用户空间等,所以在同一个宿主机上的多个容器之间彼此不会相互影响

2.3 docker相对于虚拟机的比较

资源利用率更高: 开销更小,不需要启动单独的虚拟机OS内核占用硬件资源,可以将服务器性能压榨至极致.虚拟机一般会有5-20%的损耗,容器运行基本无损耗,所以生产中一台物理机只能运行数十个虚拟机,但是一般可以运行数百个容器

启动速度更快: 可以在数秒内完成启动占用空间更小: 容器一般占用的磁盘空间以MB为单位,而虚拟机以GB

集成性更好: 和 CI/CD(持续集成/持续部署)相关技术结合性更好,实现打包镜像发布测试可以一键运行,做到自动化并快速的部署管理,实现高效的开发生命周期

使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能损耗,我们创建虚拟机的目的是为了运行应用程序,比如Nginx、PHP、Tomcat等web程序,使用虚拟机无疑带来了一些不必要的资源开销,但是容器技术则基于减少中间运行环节带来较大的性能提升。

根据实验,一个运行着CentOS的KVM虚拟机启动后,在不做优化的情况下,虚拟机自己就需要占用100~200 MB内存。此外,用户应用运行在虚拟机里面,它对宿主机操作系统的调用就不可避免地要经过虚拟化软件(如:Hypervisors)的拦截和处理,这本身又是一层性能损耗,尤其对计算资源、网络和磁盘I/O的损耗非常大。

比如: 一台96G内存的物理服务器,为了运行java程序的虚拟机一般需要分配8G内存/4核的资源,只能运行13台左右虚拟机,但是改为在docker容器上运行Java程序,每个容器只需要分配4G内存即可,同样的物理服务器就可以运行25个左右容器,运行数量相当于提高一倍,可以大幅节省IT支出,通常情况下至少可节约一半以上的物理设备

3. Docker 的组成

3.1 Docker 的组成

Docker 主机(Host): 一个物理机或虚拟机,用于运行Docker服务进程和容器,也称为宿主机,node节点

Docker 服务端(Server): Docker守护进程,运行docker容器

Docker 客户端(Client): 客户端使用 docker 命令或其他工具调用docker API

Docker 镜像(Images): 镜像可以理解为创建实例使用的模板,本质上就是一些程序文件的集合

Docker 仓库(Registry): 保存镜像的仓库,官方仓库: https://hub.docker.com/,可以搭建私有仓库harbor

Docker 容器(Container): 容器是从镜像生成对外提供服务的一个或一组服务,其本质就是将镜像中的程序启动后生成的进程

3.2 Docker 的优势

  1. 快速部署: 短时间内可以部署成百上千个应用,更快速交付到线上

  2. 高效虚拟化: 不需要额外hypervisor支持,基于linux内核实现应用虚拟化,相比虚拟机大幅提高性能和效率

  3. 节省开支: 提高服务器利用率,降低IT支出

  4. 简化配置: 将运行环境打包保存至容器,使用时直接启动即可

  5. 环境统一: 将开发,测试,生产的应用运行环境进行标准化和统一,减少环境不一样带来的各种问题

  6. 快速迁移和扩展: 可实现跨平台运行在物理机、虚拟机、公有云等环境,良好的兼容性可以方便将应用从A宿主机迁移到B宿主机,甚至是A平台迁移到B平台

更好的实现面向服务的架构,推荐一个容器只运行一个应用,实现分布的应用模型,可以方便的进行横向扩展,符合开发中高内聚,低耦合的要求,减少不同服务之间的相互影响

3.3 Docker 的缺点

  1. 多个容器共用宿主机的内核,各应用之间的隔离不如虚拟机彻底

  2. 由于和宿主机之间的进程也是隔离的,需要进入容器查看和调试容器内进程等资源,变得比较困难和繁琐

  3. 如果容器内进程需要查看和调试,需要在每个容器内都需要安装相应的工具,这也造成存储空间的重复浪费

4. 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 不同版本对比,显然内核较新的支持的功能更多。

  1. docker容器/镜像的层级结构

Docker 相当于增强版的LXC(老版本,新版本为runc),功能更为强大和易用,也是当前最主流的容器前端管理工具

Docker 先启动一个容器也需要一个外部模板,也称为镜像,docker的镜像可以保存在一个公共的地方共享使用,只要把镜像下载下来就可以使用,最主要的是可以在镜像基础之上做自定义配置并且可以再把其提交为一个镜像,一个镜像可以被启动为多个容器。

图中底层 “FROM python:2.7-slim” 是基础镜像,往上多个只读层叠加构成容器的基本文件系统 (rootfs)。CMD 指定了容器启动时执行的命令。Init 层用于存放一些初始化配置,再往上是可读写层,采用 Copy-On-Write 机制,对文件的修改在该层完成。整体借助 Namespace 和 Cgroups 实现资源隔离和限制 。

  1. writable:这可能指的是文件系统或存储容器的可写属性,表示可以对其进行修改或写入数据。

  2. Container:容器是一种轻量级的虚拟化技术,用于打包应用程序及其依赖项,以便在不同的计算环境中一致地运行。

  3. references:这可能指的是对某些资源、文件或数据的引用或链接。

  4. Debian:为容器提供了完整的操作系统环境,包括文件系统、库和工具,使应用程序能够在其中运行。

  5. aufs/btrfs:这是两种文件系统类型。aufs(Advanced Multi-Layered Unification Filesystem)是一种联合文件系统,常用于容器技术中。btrfs(B-tree file system)是一种现代文件系统,支持快照、压缩和动态卷管理等功能。

  6. Kernel:内核是操作系统的核心部分,负责管理系统的硬件资源和提供基本的服务。

4.1 Docker的C/S架构组件(2:00)

描述了Docker架构中的客户端-服务端交互以及相关组件

  1. 客户端:这是用户与Docker交互的界面,通常通过命令行工具(如docker命令)或API进行交互。

  2. RESTful:这指的是RESTful API,一种基于HTTP协议的API设计风格。Docker客户端通过RESTful API与服务端通信。

  3. Docker Registry:这是Docker镜像的存储和分发服务。客户端可以从Registry拉取镜像,或将镜像推送到Registry。

  4. 服务端:这是Docker的后端服务,负责管理容器、镜像等资源。

  5. dockerd:这是Docker的守护进程,负责处理客户端的请求并管理Docker对象(如容器、镜像、网络等)。

  6. gRPC:这是一种高性能的远程过程调用(RPC)框架,用于服务端内部组件之间的通信。

  7. containerd:这是一个容器运行时,负责管理容器的生命周期,包括创建、启动、停止和删除容器。

  8. docker-proxy:这是Docker网络代理,负责处理容器的网络请求和端口转发。

  9. containerd-shim:这是一个轻量级的中间层,用于管理容器的进程,并与containerdrunC进行交互。

  10. runC:这是一个符合OCI(Open Container Initiative)标准的容器运行时,负责实际运行容器。

补充:基本的生产环境工作流程:(基于jenkins能够实现自动化)

1、开发提交源代码至gitlab

2、下载源码

3、maven编译源码,打包为jar包或war包

4、编写dockerfile,使用jar包或war包制作镜像

5、build制作镜像

6、push镜像到harbor仓库

7、pull从harbor仓库拉取镜像

8、docker run运行容器

4.2 其他容器解决方案:
4.2.1 pouch(了解)

项目网点: https://github.com/alibaba/pouch

Pouch (小袋子)起源于 2011 年,并于2017年11月19日上午,在中国开源年会现场,阿里巴巴正式开源了基于 Apache 2.0 协议的容器技术 Pouch。Pouch 是一款轻量级的容器技术,拥有快速高效、可移植性高、资源占用少等特性,主要帮助阿里更快的做到内部业务的交付,同时提高超大规模下数据中心的物理资源利用率目前的容器方案大多基于 Linux 内核提供的 cgroup 和 namespace 来实现隔离,然后这样轻量级方案

4.2.2 存在弊端:

容器间,容器与宿主间,共享同一个内核

内核实现的隔离资源,维度不足

面对如此的内核现状,阿里巴巴采取了三个方面的工作,来解决容器的安全问题:

用户态增强容器的隔离维度,比如网络带宽、磁盘使用量等

给内核提交 patch,修复容器的资源可见性问题,cgroup 方面的 bug

实现基于 Hypervisor 的容器,通过创建新内核来实现容器隔离

4.2.3 Podman

优点:可以运行无根容器;不拘泥于C/S架构;安全性好

4.3 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

4.4 容器 runtime

runtime是真正运行容器的地方,因此为了运行不同的容器runtime需要和操作系统内核紧密合作相互在支持,以便为容器提供相应的运行环境

runtime 类型:

Lxc: linux上早期的runtime,在 2013 年 Docker 刚发布的时候,就是采用lxc作为runtime, Docker把 LXC 复杂的容器创建与使用方式简化为 Docker 自己的一套命令体系。随着Docker的发展,原有的LXC不能满足Docker的需求,比如跨平台功能。于是Docker 团队决定开发自己的容器运行时抽象层,即 libcontainer。

Libcontainer: 随着 Docker 的不断发展,重新定义容器的实现标准,将底层实现都抽象化到Libcontainer 的接口。这就意味着, 底层容器的实现方式变成了一种可变的方案

然而,随着容器技术的不断发展,Docker 团队和其他开源社区意识到需要一个更通用、更灵活的容器运行时标准,因此出现了 runc。

runc:runc 是 OCI(Open Container Initiative,开放容器倡议)的一个参考实现,用于创建和运行符合 OCI 规范的容器。OCI 定义了一个容器运行时和容器镜像的规范,旨在实现容器技术的标准化和跨平台兼容性。runc 提供了与 Linux 内核 cgroup 和 namespace 的直接交互,以创建和管理容器。

4.5 镜像仓库 Registry

统一保存镜像而且是多个不同镜像版本的地方,叫做镜像仓库

Docker hub: docker官方的公共仓库,已经保存了大量的常用镜像,可以方便大家直接使用阿里云,网易等第三方镜像的公共仓库

Image registry: docker 官方提供的私有仓库部署工具,无web管理界面,目前使用较少

Harbor: vmware 提供的自带web界面自带认证功能的镜像私有仓库,目前有很多公司使用

范例: 镜像地址格式

docker.io/library/alpine

4.6 容器编排工具

当多个容器在多个主机运行的时候,单独管理容器是相当复杂而且很容易出错,而且也无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的,也无法实现动态伸缩的功能,因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是容器编排引擎

容器编排通常包括容器管理、调度、集群定义和服务发现等功能

Docker compose : docker 官方实现单机的容器的编排工具

Docker swarm: docker 官方开发的容器编排引擎,支持overlay network

Mesos+Marathon: Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核。Mesos最初是由加州大学伯克利分校的AMPLab开发的,后在Twitter得到广泛使用。通用的集群组员调度平台,mesos(资源分配)与marathon(容器编排平台)一起提供容器编排引擎功能

Kubernetes: google领导开发的容器编排引擎,内部项目为Borg,且其同时支持 docker 和CoreOS,当前已成为容器编排工具事实上的标准

5. docker的安装和使用

5.1 互联网安装:

官方网站: 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版

操作步骤:

5.1.1  直接安装,不指定版本

需要先定义一个docker的下载源,因为rocky9默认不支持直接下载docker

vim /etc/yum.repos.d/docker.repo

[docker-ce]

name=docker-ce

baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/9/x86_64/stable/ gpgcheck=0

查看有那些docker安装包:

dnf list | grep docker

安装docker:

yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

查看docker的基本信息命令:

docker versiondocker info

ubuntu自带了新版的docker,更新ubuntu的清华源之后以阿里云作为跳板即可安装

#安装插件

sudo apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common

curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

#更新软件包

sudo apt update

#安装

docker sudo apt -y install docker-ce

#或者基于内置仓库安装docker,直接安装,不换源

sudo apt -y install docker.io

#ubuntu上删除

docker sudo apt purge docker-ce rm -rf /var/lib/docker

5.1.2 Docker安装指定版本

注意:服务器安装docker,默认安装最新版,为了和后期K8S结合,需要注意安装合适的版本,不一定是最新版,因为有的时候docker版本太高会影响和k8s的结合

# 查看可以安装的版本

dnf list docker-ce --showduplicates | sort -r

注意:旧版本安装过程中,docker-ce和docker-ce-cli版本号必须要对应起来,否则安装为最新版。(见官网:https://docs.docker.com/engine/install/centos/)

#例如:

yum -y install docker-ce-3:26.1.0-1.el9 docker-ce-cli-1:26.1.0-1.el9 containerd.io docker-buildx-plugin docker-compose-plugin

5.2 二进制安装

(不联网情况下,先准备好下载的二进制包组)

aliyun官方docker网站,可以在此网站中复制docker连接

https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/

#下载指定版本的docker软件包

wget https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/docker-24.0.7.tgz

#解压软件包

tar xf docker-24.0.7.tgz

#将docker下的运行程序复制到PATH环境变量识别的默认路径里面去。

cp docker/* /usr/bin/

#后台启动

docker dockerd &

二进制安装官方帮助文档:Binaries | Docker Docs

但直接运行dockerd守护进程为前台模式,并且也不方便,我们可以创建一个docker对应的unit单元文件,管理服务

vim /lib/systemd/system/docker.service

[Unit]

Description=Docker Application Container Engine Documentation=https://docs.docker.com

After=network-online.target firewalld.service

Wants=network-online.target

#Requires=docker.socket

[Service]

Type=notify

ExecStart=/usr/bin/dockerd -H unix://var/run/docker.sock

ExecReload=/bin/kill -s HUP $MAINPID

TimeoutStartSec=0

RestartSec=2

Restart=always

StartLimitBurst=3

StartLimitInterval=60s

LimitNPROC=infinity

LimitCORE=infinity

TasksMax=infinity

Delegate=yes

KillMode=process

OOMScoreAdjust=-500

[Install]

WantedBy=multi-user.target

注意:需要修改sock文件的位置

[root@rocky-9-clone1 ~]# cp docker.service /lib/systemd/system/

[root@rocky-9-clone1 ~]# systemctl daemon-reload

[root@rocky-9-clone1 ~]# systemctl status docker

启动docker即可 systemctl start docker

编写自动化脚本实现在线和离线自动化安装docker

5.2.1 ocker基本命令

docker拉取镜像docker pull hello-world

docker运行容器docker run hello-world:latest

查看镜像docker images -a

查看容器docker ps -a

查看docker基本信息 docker info

删除镜像docker rmi nginx

删除容器docker rm naughty_allen docker rm 容器名

5.3 补充知识点:podman基本介绍和安装

5.3.1 安装 podman

#在rocky9.4上安装docker会自动安装podman,docker工具只是一个脚本,调用了Podman

# 默认安装的就是podman

dnf install -y docker

#查看podman-docker的

rpm -ql podman-docker

显示结果(主要目录):

/usr/bin/docker

cat /usr/bin/docker

注意:需要修改拉取镜像的地址的顺序,提高速度

vim /etc/containers/registries.conf

#修改一下内容,添加国内镜像仓库地址

unqualified-search-registries = ['registry.cn-hangzhou.aliyuncs.com', 'registry.redhat.io', 'docker.io']

podman在拉取镜像时选择仓库podman pull linverazzz/wordpress:6-php8.1-fpm

  1. containerd的基本使用

#安装

containerd yum -y install containerd

#创建一个目录,镜像下载辅助配置文件

mkdir -pv /etc/containerd/certs.d/docker.io vim /etc/containerd/certs.d/docker.io/hosts.toml

#输入以下内容

server = "https://docker.io"

[host."https://docker.awsl9527.cn"]

capabilities = ["pull", "resolve"]

[host."https://ccr.ccs.tencentyun.com"]

capabilities = ["pull", "resolve"]

#

#重启containerd systemctl restart containerd

使用containerd拉取镜像

ctr image pull --hosts-dir=/etc/containerd/certs.d 镜像路径

#例如:ctr image pull --hosts-dir=/etc/containerd/certs.d docker.io/library/nginx:latest

nerdctl 命令的使用

#上传nerdctl-2.0.0-beta.5-linux-amd64.tar.gz mkdir /nerdctl tar xf nerdctl-2.0.0-beta.5-linux-amd64.tar.gz -C /nerdctl/ cd /nerdctl/ mv /nerdctl/nerdctl /usr/bin/nerdctl

使用nerdctl 无法实现后面的命令自动补全,通过以下方法可以实现nerdctl的命令补全

 

#安装bash-completion yum install bash-completion -y nerdctl completion bash > /etc/bash_completion.d/nerdctl source /etc/bash_completion.d/nerdctl

6. docker 程序对应的环境和组成的相关配置文件

环境配置文件(不常用)

/etc/sysconfig/docker-network

/etc/sysconfig/docker-storage

/etc/sysconfig/docker

UNIT单元文件

/usr/lib/systemd/system/docker.service

Docker Registry配置文件

/etc/containers/registries.conf

docker 命令帮助

docker --help

查看镜像的分层信息 docker history nginx

7. docker的网络环境

查看 docker0 网卡

在docker安装启动之后,默认会生成一个名称为docker0的网卡并且默认IP地址为172.17.0.1的网卡

8. docker默认的存储引擎

Overlay2联合文件系统

写时复制

Lowerdir:镜像层,只读层,对应lower文件

Upperdir:可写层,对应 diff 目录,可读写的目录

MergedDir:视图层,最终将容器内的目录展示给用户,合并只读层和可写层

WorkDir:联合文件系统的工作目录,存储元数据信息

可以通过docker inspect或df查看挂载了那些目录

9. docker镜像管理

定义别名:使用alias

#删除所有容器(包括正在使用的)

docker ps -qa | xargs docker rm -f

docker rm -f $(docker ps -qa)

#清除所有未在使用的容器

docker container prune -a|-f

#删除所有镜像

docker rmi -f $(docker images -qa)

常见镜像管理命令

9.1 镜像结构

        镜像即创建容器的模版,含有启动容器所需要的文件系统及所需要的内容,因此镜像主要用于方便和快速的创建并启动容器;镜像含里面是一层层的文件系统,叫做 Union FS(联合文件系统),联合文件系统,可以将几层目录挂载到一起(就像千层饼,洋葱头,俄罗斯套娃一样),形成一个虚拟文件系统,虚拟文件系统的目录结构就像普通 linux 的目录结构一样,镜像通过这些文件再加上宿主机的内核共同提供了一个linux 的虚拟环境,每一层文件系统叫做一层 layer,联合文件系统可以对每一层文件系统设置三种权限,只读(readonly)、读写(readwrite)和写出(whiteout-able,可以理解为标记删除),但是镜像中每一层文件系统都是只读的,构建镜像的时候,从一个最基本的操作系统开始,每个构建提交的操作都相当于做一层的修改,增加了一层文件系统,一层层往上叠加,上层的修改会覆盖底层该位置的可见性,这也很容易理解,就像上层把底层遮住了一样,当使用镜像的时候,我们只会看到一个完全的整体,不知道里面有几层,实际上也不需要知道里面有几层,结构如下:

一个典型的 Linux文件系统由 bootfs 和 rootfs 两部分组成

案例:查看镜像的分层结构(nginx hello-world alpine)

先拉取一个镜像docker pull tomcat

查看镜像的层级结构docker image history nginx:latest

查看镜像信息docker inspect nginx

9.2 华为云官方镜像仓库加速

搜索-容器镜像服务

华为镜像加速器配置方式:控制台 --> 容器镜像服务 SWR --> 镜像资源 --> 镜像中心 --> 镜像加速器

验证加速效果:例如docker pull rockylinux:9.1.20230215-minimal

其他镜像加速:

https://github.com/DaoCloud/public-image-mirror

https://github.com/dongyubin/DockerHub

9.3 搜索镜像

  1. 官方网站进行镜像的搜索 官网: http://hub.docker.com

  2. 执行docker search命令进行搜索

9.4 实现多个宿主机共享镜像(同步到其他主机)

保存到本地,并进行压缩: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 镜像名 -o 导出的镜像包名 docker save nginx:latest -o nginx.tar

#对打包文件进行压缩 gzip nginx.tar

#将ngixn的压缩文件,同步到其他主机 scp alpine.tar 192.168.10.120:/root

导入的单个镜像

在其他主机导入接收到的镜像 docker load -i nginx.tar.gz 查看是否是否导入成功 docker images

9.4.1 导出多个镜像

#将多个镜像保存到本地,并进行打包

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

#将ngixn的压缩文件,同步到其他主机

scp all.tar.gz 192.168.10.120:/root

导入多个镜像

#在其他主机导入接收到的所有镜像包

docker load -i all.tar.gz

#查看是否是否导入成功

docker images

9.5 镜像位置和分层效果

镜像多层存放位置,及大小

du -sh /var/lib/docker/overlay2/*

查看镜像的详细信息

docker inspect 镜像

例如: docker inspect nginx

9.6 删除本地镜像

#删除本地单个镜像 docker rmi 镜像名 #例如: docker rmi nginx:latest #强行删除所有的镜像 docker rmi -f `docker images -qa` #为了方便使用命令,可以定义为别名操作 alias rmi='docker rmi -f `docker images -qa`'

强行删除所有的镜像

docker rmi -f docker images -qa

为了方面使用命令,可以定义为别名操作

alias rmi='docker rmi -f docker images -qa'

9.7 给镜像打标签(方便将来上传至镜像仓库)

方便将来上传至镜像仓库,只有将镜像打上指定标签,才可以将镜像上传到指定仓库

#给镜像打标签格式

docker tag 镜像名:TAG 仓库主机FQDN或IP[:端口]/项目名(或用户名)/image名:版本

例如:docker tag rockylinux:9.1.20230215-minimal siqin123/wang-rocky:9.1.20230215-minimal

创建一个阿里云的官方镜像仓库

  1. 登录官网docker.io镜像站点,然后即可上传至公共仓库

上传镜像打好标签的镜像

#默认就是登录的官方的docker镜像站点

docker login --username=用户名 URL

#给镜像打标签格式

docker tag

本地镜像名:TAG 仓库主机FQDN或IP[:端口]/项目名(或用户名)/image名:版本

#例如:

docker tag nginx:latest crpi-9xzyfu5nxg8axm6e.cn-hangzhou.personal.cr.aliyuncs.com/sulx/sulx:nginx-v1

#上传镜像,docker push url/仓库/镜像:版本号

docker push crpi-9xzyfu5nxg8axm6e.cn-hangzhou.personal.cr.aliyuncs.com/sulx/sulx:nginx-v1

#定义别名,删除所有未开启的容器

alias rmc='docker container prune -f'

上传镜像前登陆镜像仓库

docker login --username=aliyun8092690951 crpi-2km033jlpodl5gwq.cn-beijing.personal.cr.aliyuncs.com

将nginx上传到镜像仓库

docker tag nginx crpi-2km033jlpodl5gwq.cn-beijing.personal.cr.aliyuncs.com/tanwu/ceshi:n ginx

给镜像修改名称和标签

将修改后的镜像上传到阿里云的仓库中去

docker push crpi-2km033jlpodl5gwq.cn-beijing.personal.cr.aliyuncs.com/tanwu/ceshi:nginx

The push refers to repository [crpi-2km033jlpodl5gwq.cn-beijing.personal.cr.aliyuncs.com/tanwu/ceshi]

查看阿里云仓库,可以看到上传成功

在120主机上拉取镜像

docker pull crpi-2km033jlpodl5gwq.cn-beijing.personal.cr.aliyuncs.com/tanwu/ceshi:nginx

删除所有未开启的容器

alias rmc='docker container prune -f'

10. docker基于镜像实现容器基本命令操作和管理

10.1 docker容器运行流程图

10.1.1常见容器管理命令

注意:

①:run不存在的镜像,即会实现下载镜像之后进行运行

②:默认运行容器,有些容器没有内置前台进程,会导致运行即立即退出,若想退出而不退出容器进程,输入同时按三个键,ctrl+p+q 若内置了前台进程的容器运行。运行时为前台进程,不会退出;运行不指定名称,会随机生成字符串和ID号

③:运行容器后,docker0网桥会生效,为容器内的一半桥接网卡分配同网段的IP地址,宿主机可以进行直接通信

④:docker守护进程开启,会默认自己生成iptables防火墙规则

⑤:容器真实数据在/var/lib/docker/overlay2/,类似于数据字典。数据允许叠加,多个设备数据可以合并。

10.2 运行容器docker run 命令用法

docker run [选项] [镜像名] [shell命令] [参数]

选项

中文解释

-i, --interactive

以交互模式运行容器,通常与 -t 同时使用

-t, --tty

为容器分配一个伪终端,通常与 -i 一起使用,容器必须运行 shell 才能进入

-d, --detach

后台运行容器,默认情况下容器在前台运行

--name string

为容器指定名称

--h, --hostname string

指定容器的主机名

--rm

容器退出后自动删除

-p, --publish list

映射容器端口到宿主机

-P, --publish-all

将容器所有暴露的端口随机映射到宿主机端口

--dns list

指定自定义的 DNS 服务器

--entrypoint string

覆盖镜像默认的 ENTRYPOINT,如果字符串包含空格,需要使用引号括起来

--restart policy

容器的重启策略

--privileged

赋予容器扩展权限

-e, --env=[]

设置环境变量

--env-file=[]

从文件中读取环境变量

案例:

非交互式输出容器内容 docker run alpine du -sh /

交互式输出 docker run -it alpine:latest sh

非交互式创建一个文件,并在本地挂载文件中查看 docker run alpine:latest touch /xxhf.txt

在挂载路径中查找

find /var/lib/docker/overlay2/ -name "xxhf.txt"

实现退出容器不退出容器进程 ctrl+p+q

exec把后台容器进程唤醒

删除容器

# 一次性运行容器,退出后立即删除,用于测试

docker run --rm

#用法:

docker run --rm 容器名 容器内命令

#例如:

docker run --rm alpine:latest ip a

--privileged选项(获取宿主机的root权限,不建议使用)

docker run -it --name ubuntu ubuntu sh

容器默认不会开机自启,若要实现容器宿主机开机自动启动,可以在运行容器时基于--restart制定不同的策略

①:no 默认值

②:on-failure[:max-retries] 如果容器异常退出即启动

③:always 无论任何情况都启动

④:unless-stopped 守护进程启动情况下不会启动,指定了 --restart unless-stopped 并处于 Stopped (Exited) 状态的容器,不会在 Docker daemon 重启的时候被重启。

案例:

10.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:8.17.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 pause|unpause 容器ID/NAME 暂停/取消暂停容器

docker logs docker logs [OPTIONS] CONTAINER 查看容器的日志

10.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 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=123456 --name mysql -d mysql

docker run -d -p 80:80 --name wordpress wordpress

10.5 管理容器内部的hosts文件和DNS文件

修改容器的 hosts文件(添加--add-host选项,可以复用)

配置容器的DNS

容器的dns服务器,默认采用宿主机的dns 地址,可以用下面方式指定其它的DNS地址

将dns地址配置在宿主机

方法一:在容器启动时加选项 --dns=x.x.x.x (添加--dns选项,可以复用)

方法二:在/etc/docker/daemon.json 文件中指定

10.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

10.7 传递容器环境变量

docker run -e MYSQL_ROOT_PASSWORD=111111 -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=111111 --name mysql -d mysql

案例:实现部署wordpress,并实现数据持久化

10.8 使用systemd以服务的方式管理和控制容器

vim /lib/systemd/system/hello.service

 

[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

Systemctl daemon-reload

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值