【博学谷学习记录】超强总结,用心分享 | 架构师 Docker学习总结

文章目录

  • Docker
  • Docker使用场景
  • Docker安装
    • 1.关闭防火墙
    • 2.卸载旧版本
    • 3.安装Docker依赖环境
    • 4.设置 Docker 安装地址
    • 5.安装 Docker Engine-Community
    • 6.Docker 镜像加速
          • 配置daemon.json
    • 7.启动 Docker
    • 8.开启Docker自动补全
          • bash-complete
          • 刷新文件
          • 测试
  • Docker 基本概念
    • 镜像
    • 容器
    • 仓库
  • Docker命令
    • 镜像相关操作
    • 容器相关操作
  • 容器化技术发展
    • LXC
      • 主要技术点
    • 旧版 Docker
          • 摆脱 LXC的限制
        • 拆分Docker daemon
          • 组件介绍
            • containerd
            • shim
            • runc

Docker

Docker官网

Docker使用场景

容器变得越来越重要,尤其是在云环境中,许多企业甚至在考虑将容器替代 VM 作为其应用程序和工作负载的通用计算平台

  • 微服务:容器小巧轻便,非常适合微服务体系结构,在微体系结构中,应用程序可以由许多松散耦合且可独立部署的较小服务构成。
  • DevOps:微服务作为架构和容器作为平台的结合,是许多团队将 DevOps 视为构建,交付和运行软件的方式的共同基础。
  • 混合,多云:由于容器可以在笔记本电脑,本地和云环境中的任何地方连续运行,因此它们是混合云和多云方案的理想基础架构,在这种情况下,组织发现自己跨多个公共云运行与自己的数据中心结合, 应用程序现代化和迁移:使应用程序现代化的最常见方法之一是将它们容器化,以便可以将它们迁移到云中。

Docker安装

1.关闭防火墙

systemctl status firewalld
systemctl stop firewalld 
systemctl disable firewalld

2.卸载旧版本

较旧的 Docker 版本称为 docker 或 docker-engine ,如果已安装这些程序,请卸载它们以及相关的依赖项。

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

3.安装Docker依赖环境

在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库,之后,您可以从仓库安装和更新 Docker。

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

4.设置 Docker 安装地址

在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库,之后,您可以从仓库安装和更新 Docker,使用以下命令来设置稳定的仓库**(阿里云)**

sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

5.安装 Docker Engine-Community

安装最新版本的 Docker Engine-Community 和 containerd

sudo yum install -y docker-ce docker-ce-cli containerd.io

如果提示您接受 GPG 密钥,请选是。

Docker 安装完默认未启动,并且已经创建好 docker 用户组,但该用户组下没有用户。

6.Docker 镜像加速

阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了:

配置daemon.json

您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

7.启动 Docker

service docker start

通过运行 hello-world 映像来验证是否正确安装了 Docker Engine-Community

docker run hello-world

运行该代码后首先会从仓库拉取hello-world镜像,然后运行该镜像,运行后会输出一个Hello from Docker!

8.开启Docker自动补全

使用docker时无法自动补全镜像名和其他参数,这样使用效率大大降低,下面是解决方法

bash-complete
yum install -y bash-completion
刷新文件
source /usr/share/bash-completion/completions/docker
source /usr/share/bash-completion/bash_completion
测试

输入docker p后docker会将可选项列出来

docker p

Docker 基本概念

镜像

​ Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等),镜像不包含任何动态数据,其内容在构建之后也不会被改变。

Union FS

​ 联合文件系统是(Union FS)是linux的存储技术,也是Docker镜像的存储方式, 它是分层的文件系统,将不同目录拉到同一个虚拟目录下,下图展示了Docker用Union FS 搭建的分层镜像:(比如最下层是操作系统的引导,上一层是Linux操作系统,再上一层是Tomcat,jdk,再上一层是应用代码)

这些层是只读的,加载完后这些文件会被看成是同一个目录,相当于只有一个文件系统。

​ 我们可以通过docker info查看镜像的一些信息,可以看到存储驱动用的并不是Union FS 而是overlay2,overlay也是一个联合文件系统,所以上述主要介绍联合文件系统的概念,至于这些存储驱动的演变过程和优缺点

镜像构建时,会一层层构建,前一层是后一层的基础,每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。(比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除,在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像,因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉)

容器

​ 镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体,容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间,因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。

​ 容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样,这种特性使得容器封装的应用比直接在宿主运行更加安全,也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。

​ 前面讲过镜像使用的是分层存储,容器也是如此,每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层

​ 容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡,因此,任何保存于容器存储层的信息都会随容器删除而丢失。

仓库

​ 镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

​ 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本,我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像,如果不给出标签,将以latest作为默认标签。

​ 以 Ubuntu 镜像为例,ubuntu是仓库的名字,其内包含有不同的版本标签,如,14.04,16.04,我们可以通过ubuntu:14.04,或者ubuntu:16.04来具体指定所需哪个版本的镜像,如果忽略了标签,比如ubuntu,那将视为ubuntu:latest

​ 仓库名经常以三段式路径形式出现,比如heima.com/nginx-proxy:tag,前者往往意味着 Docker Registry 多用户环境下的用户名,后者则往往是对应的软件名,但这并非绝对,取决于所使用的具体 Docker Registry 的软件或服务

Docker命令

【博学谷学习记录】超强总结,用心分享 | 架构师 Docker学习总结_第1张图片

镜像相关操作

# 查找镜像
docker search 镜像名称

# 下载镜像
docker pull 镜像名称
# 注意事项:
# 1.如果不写版本号默认拉取最新的版本好latest。
# 2.拉取的时候是多个层一起拉取的,这样可用让其他镜像复用分层
# 3.如果拉取的镜像不写仓库地址默认就是docker.io/library/

# 下载指定版本的镜像 https://hub.docker.com 找到Tags
docker pull mysql:5.7.40

# 查看镜像
docker images

查找指定镜像

容器相关操作

# 通过镜像启动容器
docker run -d -p 3306:3306 -v /tmp/etc/mysql:/etc/mysql/mysql.conf.d/ -v /tmp/data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql mysql:5.7.40
# 参数解释:
# 	-d:是指容器后台运行,如果不加-d,当用户断开客户端时容器会结束运行
#	-p:将容器的3306端口映射到主机的3306端口,用来暴漏端口的	(宿主机:容器)
#	-v:这个命令是用来挂载目录的,将本地目录挂载到容器中,这样容器操作的就是本地目录	(宿主机:容器)
#	-e:这个命令是配置环境参数的,这里MYSQL_ROOT_PASSWORD=root指的是用root用户运行mysql,可以登录Docker容器通过ENV命令查看
#	--name:这个命令是配置Mysql的容器名称的,如果不配置,默认是随机生成的名字


# 查看容器运行状态
docker ps 
# 查看全部容器
docker ps -a

# 停止容器
docker stop 容器ID

# 启动停止的容器
docker start 容器ID

# 重启容器
docker restart 容器ID

# 删除容器	对于运行中的容器可以加上-f参数强制删除
docker rm -f 容器ID

# 查看容器运行日志
docker logs -f mysql

# 登录容器
docker exec [options] container command [arg...]
# docker exec -it mysql /bin/bash
# 参数解释:
#	简写		名称			 描述
#	-d		--detach		后台运行模式,在后台执行命令相关命令
#			--detach-keys	覆盖容器后台运行的一些参数信息
#	-e		--env			设置环境变量
#	-i		--interactive	展示容器输入信息STDIN
#			--privileged	为命令提供一些扩展权限
#	-t		--tty			命令行交互模式
#	-u		--user			设置用户名(format: [:])
#	-w		--workdir		指定容器内的目录

容器化技术发展

LXC

LXC是Linux containers的简称,Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源

【博学谷学习记录】超强总结,用心分享 | 架构师 Docker学习总结_第2张图片

​ 完整的LXC能力在2008年合入Linux主线,所以容器的概念在2008年就基本定型了,并不是后面Docker造出来的,关于LXC的介绍很多,大体都会说“LXC是Linux内核提供的容器技术,能提供轻量级的虚拟化能力,能隔离进程和资源”,但总结起来,无外乎就两大知识点Cgroups(Linux Control Group)和Linux Namespace,搞清楚他俩,容器技术就基本掌握了。

​ Linux容器技术其实就是整合内核的功能,让其支持多个容器运行时资源相互隔离;我们知道内核的功能用户是无法直接操作的,必须得有一用户空间的软件,通过系统调用去操作内核功能;所以lxc就是用来操作Linux内核容器化的工具

主要技术点

  • chroot:创建一个虚拟的根目录文件系统 【实质还是调用底层的文件系统】,不过是简历一个虚拟的,可以跟其他容器的虚拟文件系统相互隔离;但共享底层的文件系统
  • namespaces:命名空间可以提供一个进程相互隔离的独立网络空间,不同的容器间 进程pid可以相同,进程并不冲突影响;但可以共享底层的计算和存储(cpu + mem)
  • CGroups:实现了对容器的资源分配和限制,比如给容器1分配10core 30G 内存;那这个容器最多用这么大的资源;如果内存超过30G ,会启动swap,效率降低,也可能会被调度系统给kill掉

旧版 Docker

Docker 引擎首次发布的时候,由两个核心组件构成:LXC 和 Docker daemon

​ Docker deamon 是一个单一的二进制文件,由 Docker Client 、Docker API、容器运行时、构建镜像等组成, LXC 由命名空间 Namespace 和 控制组 CGroup 等基础工具组成,由 Linux 内核的容器虚拟化技术提供

【博学谷学习记录】超强总结,用心分享 | 架构师 Docker学习总结_第3张图片

摆脱 LXC的限制

对 LXC 的依赖自始至终都是个问题

  • 首先,LXC 是基于 Linux 的,这对于一个立志于跨平台的项目来说是个问题。
  • 其次,如此核心的组件依赖于外部工具,这会给项目带来巨大风险,甚至影响其发展。

​ 因此,Docker 公司开发了名为 Libcontainer 的自研工具,用于替代 LXC,Libcontainer 的目标是成为与平台无关的工具,可基于不同内核为 Docker 上层提供必要的容器交互功能,在 Docker 0.9 版本中,Libcontainer 取代 LXC 成为默认的执行驱动,也就是现在常说的Runc。

拆分Docker daemon

随着时间的推移,Docker daemon 的整体性带来了越来越多的问题,难于变更、运行越来越慢,这并非生态(或Docker公司)所期望的。

​ Docker 公司意识到了这些问题,开始努力着手拆解这个大而全的 Docker daemon 进程,并将其模块化,这项任务的目标是尽可能拆解出其中的功能特性,并用小而专的工具来实现它,这些小工具可以是可替换的,也可以被第三方拿去用于构建其他工具。

​ 这一计划遵循了在 UNIX 中得以实践并验证过的一种软件哲学:小而专的工具可以组装为大型工具,这项拆解和重构 Docker 引擎的工作仍在进行中,不过,所有容器执行和容器运行时的代码已经完全从 daemon 中移除,并重构为小而专的工具。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MsUhoD0M-1679929771103)(Docker学习笔记.assets/docker265.png)]

组件介绍
containerd

这是一个管理和运行容器的守护进程,它推送和拉动镜像,管理存储和网络,并监督容器的运行

​ Containerd作为一个生产环境可用的OCI 实现,它利用了OCI 运行时和镜像格式,在对 Docker daemon 的功能进行拆解后,所有的容器执行逻辑被重构到一个新的名为 containerd的工具中

​ 它是从 Docker 项目中分离出来,之后 containerd 被捐赠给云原生计算基金会(CNCF)为容器社区提供创建新容器解决方案的基础,所以 Docker 自己在内部使用 containerd,当你安装 Docker 时也会安装 containerd

​ containerd 通过其 CRI 插件实现了 Kubernetes 容器运行时接口(CRI),它可以管理容器的整个生命周期,包括从镜像的传输、存储到容器的执行、监控再到网络

​ containerd 在 Linux 和 Windows 中以 daemon 的方式运行,从 1.11 版本之后 Docker 就开始在 Linux 上使用它,Docker 引擎技术栈中,containerd 位于 daemon 和 runc 所在的 OCI 层之间。Kubernetes 也可以通过 cri-containerd 使用 containerd。

​ 如前所述,containerd 最初被设计为轻量级的小型工具,仅用于容器的生命周期管理,然而,随着时间的推移,它被赋予了更多的功能,比如镜像管理。

shim

shim是一个真实运行的容器的真实垫片载体,每启动一个容器都会起一个新的docker-shim的一个进程

​ shim是实现无daemon的容器(用于将运行中的容器与daemon解耦,以便进行daemon升级等操作)不可或缺的工具

​ containerd 指挥runc来创建新容器,事实上,每次创建容器时它都会fork一个新的runc实例,不过,一旦容器创建完毕,对应的runc进程就会退出,因此,即使运行上百个容器,也无须保持上百个运行中的runc实例。

​ 一旦容器进程的父进程runc退出,相关联的containerd-shim 进程就会成为容器的父进程,作为容器的父进程,shim 的部分职责如下

  • 保持所有STDIN和STDOUT流是开启状态,从而当daemon重启的时候,容器不会因为管道( pipe)的关闭而终止
  • 将容器的退出状态反馈给daemon
runc

这是低级别的容器运行时(实际创建和运行容器的东西),它包括 libcontainer,一个用于创建容器的基于 Go 的本地实现

​ runc是docker贡献给oci的容器运行时,也是目前使用比较多的容器运行时,docker目前的实现也是使用的runc,如前所述,runc 是 OCI 容器运行时规范的参考实现,Docker 公司参与了规范的制定以及 runc 的开发

去粗取精,会发现 runc 实质上是一个轻量级的、针对 Libcontainer 进行了包装的命令行交互工具(Libcontainer 取代了早期 Docker 架构中的 LXC)

你可能感兴趣的:(docker,学习,运维)