Docker容器化技术

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 一、虚拟机与容器的比较在容器化技术出来之前,使用的是虚拟机技术,虚拟机和Docker容器技术都是一种虚拟化技术虚拟机包含的是整个操作系统的原生镜像,非常的庞大,而docker的镜像只包含最核心的环境,非常小巧。

一、虚拟机与容器的比较

在容器化技术出来之前,使用的是虚拟机技术,虚拟机和Docker容器技术都是一种虚拟化技术

虚拟机包含的是整个操作系统的原生镜像,非常的庞大,而docker的镜像只包含最核心的环境,非常小巧。

6790dbbb8fff1517d381252120d30a86.png

1、虚拟机技术

7ef51b678c00e22d88a52a9f10ec1b76.png

缺点:

  • 资源占用十分多
  • 冗余步骤多
  • 启动慢

2、容器化技术

容器化技术不是模拟的一个完整的操作系统

072760db4c287c83393876800f967bdb.png


比较Docker与虚拟机技术的不同:


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

Docker 容器内的应用进程直接运行在宿主机的内核(内核级虚拟化),容器内没有自己的内核且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

每个容器是互相隔离的,每个容器有属于自己的文件系统,容器之间进行不会相互影响,能区分计算资源

3、容器的优点

  • 应用更快速的交付和部署,打包镜像发布测试,一键运行
  • 更快捷的升级和扩缩容
  • 更简单的系统运维,开发、测试环境高度一致
  • 更高效的计算资源利用

4、Docker比虚拟机快的原因

Docker有着比虚拟机更少的抽象层,Docker不需要实现硬件资源虚拟化,而是直接使用实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。


Docker利用的是宿主机的内核,当新建一个容器时,不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。

二、Docker的名词概念

1、镜像(image)

docker镜像就好比是一个模板,可以通过这个模板来创建容器服务

如tomcat镜像 ===》run ===》tomcat01容器(提供服务)

通过一个镜像可以创建多个容器,最终服务运行或项目运行就是在容器中的

2、容器(container)

Docker利用容器技术,独立运行一个或一组应用,通过镜像来创建的

拥有启动、停止、删除等基本命令

可以把容器理解为一个建议的linux系统

3、仓库(repository)

仓库就是存放镜像的地方,分为共有和私有

Docker Hub(默认是国外的),阿里云等厂商都有提供容器服务

三、Docker安装

1、卸载旧版本

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

2、设置Docker仓库

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

# 安装所需的软件包
$ sudo yum install -y yum-utils
# 设置阿里云仓库
$ sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3、安装

# 安装社区版,默认安装最新版
$ sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 通过其完整的软件包名称安装特定版本,该软件包名称是软件包名称(docker-ce)加上版本字符串,如:docker-ce-18.09.1
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

4、启动

# 测试是否安装
$ sudo docker --version
# 启动docker
$ sudo systemctl start docker
# 通过运行 hello-world 镜像来验证是否正确安装了 Docker Engine-Community
$ sudo docker run hello-world # 会尝试从本地寻找镜像,寻找不到则到仓库中寻找并下载

5、卸载

# 删除安装包
yum remove docker-ce
# 删除镜像、容器、配置文件等内容
rm -rf /var/lib/docker

四、Docker的常用命令

1、帮助命令

docker version # 显示版本
docker info # 显示系统信息,包括镜像和容器的数量
docker 命令 --help # 帮助命令

2、镜像命令

# 查看本地所有镜像
docker images
# 可选项
-a, --all # 列出所有镜像
-q, --quiet # 只显示镜像的id
# 搜索镜像(仓库中)
docker search mysql
# 可选项,通过收藏数来过滤
--filter=STARS=3000 # 搜索出stars大于3000的镜像
# 下载镜像
docker pull 镜像名[:tag]
docker pull mysql
[root@Ken-Chy129 ~]# docker pull mysql
Using default tag: latest # 没有写tag则默认为latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete  # 采用分层下载,联合文件下载系统
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709  # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest  # 真实地址
docker pull mysql:5.7 # 指定版本下载,需要是仓库中存在的版本
[root@Ken-Chy129 ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
72a69066d2fe: Already exists  # 此处因为在前面已经下载过了,所以无需重新下载(联合文件下载系统)
93619dbc5b36: Already exists
99da31dd6142: Already exists
626033c43d70: Already exists
37d5d7efb64e: Already exists
ac563158d721: Already exists
d2ba16033dad: Already exists
0ceb82207cd7: Pull complete
37f2405cae96: Pull complete
e2482e017e53: Pull complete
70deed891d42: Pull complete
Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
# 删除镜像
docker rmi -f 容器id # 删除指定的容器
docker rmi -f 容器id 容器id 容器id # 删除多个容器
docker rmi -f $(docker images -aq) # 删除全部的容器

3、容器命令

说明:我们有了镜像才可以创建容器

docker pull centos
# 新建容器并启动
docker run [可选参数] image
# 参数说明
--name="name" # 容器名字 tomcat01, tomcat02, 用来区分容器
--d # 后台方式运行
--it # 使用交互方式运行,进入容器查看内容
--rm # 用完即删(没有加上的话停止后还能ps -a查到)
# -i: 允许你对容器内的标准输入 (STDIN) 进行交互 -t: 在新容器内指定一个伪终端或终端。
-p # 指定容器的端口
  -p ip:主机端口:容器端口
  -p 主机端口:容器端口(常用)
  -p 容器端口
  容器端口
-P # 随机指定端口
# 启动centos容器的命令行模式(/bin/bash)
[root@Ken-Chy129 usr]# docker run -i -t centos /bin/bash
# 此处已经是进入到容器中
[root@caa59fd3ebea /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
# 从容器中退出
[root@caa59fd3ebea /]# exit
[root@Ken-Chy129 usr]#
# 启动centos容器并使用其中的echo指令输出hello
[root@Ken-Chy129 usr]# docker run -it centos /bin/echo "hello"
hello
# 输出结束后则结束容器了
# 列出当前所有运行的容器
docker ps 命令
-a # 列出当前所有运行的容器+带出历史运行的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号
# 退出容器
exit # 直接停止并退出容器
ctrl + p + q # 容器不停止退出
# 删除容器
docker rm 容器id # 删除指定容器,不能删除正在运行的容器,强制删除需要加-f
docker rm -f $(docker ps -aq) # 删除所有容器
docker ps -a -q|xargs docker rm # 删除所有容器
# 启动和停止容器
docker start 容器id # 启动
docker restart 容器id # 重启
docker stop 容器id # 停止
docker kill 容器id # 强制停止

4、其他常用命令

# 后台启动容器
docker run -d 容器名
# 问题
# 启动后通过docker ps查看发现容器停止了
# 这是因为docker发现没有容器没有进程正在运行,就会自杀自动停止
# docker run -it 容器名 /bin/bash 不会被停止,因为打开了命令行交互进程
# 查看日志
docker logs -ft --tail n 容器
# --tail n表示查看最后n条日志
# -f 表示跟随日志输出,有新的日志也会不断显示(没加的话只显示到目前为止的日志后便结束)
# -t 表示显示时间戳
# 查看容器中的进程id
docker top 容器
# 查看镜像的元数据
docker inspect 容器
# 进入当前正在运行的容器
# 方式一
docker exec -it 容器 /bin/bash
# 进入容器后开启一个新的终端,可以在里面操作
# 方式二
docker attach 容器
# 进入容器正在执行的终端,不会启动新的进程
# 从容器拷贝文件到主机上(跟容器运行不运行没关系,只要容器在就行了)
docker cp 容器id:容器内路径 目的主机的路径
# 拷贝是一个手动过程,未来我们使用-v 卷的技术可以实现自动

5、测试部署ES+kibana

# es暴露的端口很多,且十分耗内存
# es的数据一般需要放置到安全目录,挂载!
# 增加内存限制,修改配置文件 -e 环境配置修改
docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms512m -Xmx1g" elasticsearch
docker stats 容器 # 查看cpu状态

五、Docker镜像讲解

1、UnionFS(联合文件系统)

UnionFS(联合文件系统)是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以讲不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像)可以制作各种具体的应用镜像。

—Docker 在镜像的设计中,引入了层(layer)的概念。也就是说,用户制作镜像的每一步操作,都会生成一个层,也就是一个增量 rootfs。UnionFS最主要的功能就是将多个不同位置的目录联合挂载(union mount)到同一个目录下。比如,我现在有两个目录 A 和 B,它们分别有两个文件:

$ tree
.
├── A
│  ├── a
│  └── x
└── B
 ├── b
 └── x

然后,我使用联合挂载的方式,将这两个目录挂载到一个公共的目录 C 上:

$ mkdir C
$ mount -t aufs -o dirs=./A:./B none ./C

这时,我再查看目录 C 的内容,就能看到目录 A 和 B 下的文件被合并到了一起:

$ tree ./C
./C
├── a
├── b
└── x

可以看到,在这个合并后的目录 C 里,有 a、b、x 三个文件,并且 x 文件只有一份。这,就是“合并”的含义。此外,如果你在目录 C 里对 a、b、x 文件做修改,这些修改也会在对应的目录 A、B 中生效。


Docker 中最常用的联合文件系统有三种:AUFS、Devicemapper 和 OverlayFS。


特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。


为什么 docker 等容器系统要使用类似的联合文件系统呢?


我们用来启动容器的许多镜像无论 ubuntu 是 72MB 还是 nginx 133MB 的大小都非常庞大。每次我们想从这些镜像创建一个容器时,分配这么多空间将是非常昂贵的。多亏了联合文件系统,Docker 只需要在镜像之上创建一个瘦文件层,其余的可以在所有容器之间共享。这还提供了减少启动时间的额外好处,因为无需复制镜像文件和数据。


联合文件系统还提供隔离功能,因为容器对共享镜像层具有只读访问权限。如果他们需要修改任何只读共享文件,他们会使用写时复制策略(稍后讨论)将内容复制到可以安全修改的可写层。


2、Docker镜像加载原理

Docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统叫 UnionFS。


boots(boot file system)主要包含 bootloader 和 Kernel, bootloader 主要是引导加载 kernel, Linux 刚启动时会加 bootfs 文件系统,在 Docker 镜像的最底层是 boots,几乎不变。这一层与我们典型的 Linux/Unix 系统是一样的,包含 bootloader 和 Kernel。当 boot 加载完成之后,整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs


rootfs(根文件系统)是挂载在容器根目录上,用来为容器进程提供隔离后执行环境的文件系统,就是所谓的“容器镜像”。所以,一个最常见的 rootfs,或者说容器镜像,会包括如下所示的一些目录和文件,比如 /bin,/etc,/proc 等等rootfs 就是各种不同的操作系统发行版,比如 Ubuntu, Centos 等等


需要明确的是,rootfs 只是一个操作系统所包含的文件、配置和目录,并不包括操作系统内核。在 Linux 操作系统中,这两部分是分开存放的,操作系统只有在开机启动时才会加载指定版本的内核镜像。所以说,rootfs 只包括了操作系统的“躯壳”,并没有包括操作系统的“灵魂”。


为什么虚拟机的 CentOS 镜像都是好几个G,为什么 Docker 中的只有几百M?


因为对于不同的 Linux 发行版, boots 基本是一致的, rootfs 会有差別,因此不同的发行版可以公用 bootfs。底层直接用主机的 kernel,自己只需要提供 rootfs 就可以了


对于个精简的 OS , rootfs 可以很小,只需要包合最基本的命令,工具和程序库就可以了


同一台机器上的所有容器,都共享宿主机操作系统的内核。这就意味着,如果你的应用程序需要配置内核参数、加载额外的内核模块,以及跟内核进行直接的交互,你就需要注意了:这些操作和依赖的对象,都是宿主机操作系统的内核,它对于该机器上的所有容器来说是一个“全局变量”,牵一发而动全身。这也是容器相比于虚拟机的主要缺陷之一:毕竟后者不仅有模拟出来的硬件机器充当沙盒,而且每个沙盒里还运行着一个完整的 Guest OS 给应用随便折腾。

3、镜像分层理解

fc33c762084b07917f76362c0a5c25b6.png

可以看到下载的时候分成了六个层级,其中第一层显示已经存在。所有的 Docker 镜像都起始于一个基础镜像 rootfs,像 Ubuntu、CentOS,那么显然将这些分层显然可以实现资源共享,重复的镜像不需要再次下载(比如有多个镜像都从相同的 Base 镜像构建而来,那么宿主机只需在磁盘上保留一份 base 镜像,同时内存中也只需要加载一份 base 镜像)。当进行修改或添加新的内容时,就会在当前镜像层之上,创建新的镜像层。


e.g.


基于 Ubuntu Linux16.04 创建一个新的镜像,这就是新镜像的第一层

如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层

如果继续添加一个安全补丁,就会创健第三个镜像层

该镜像当前已经包含 3 个镜像层

现在可以把它再次打包成一个新的镜像(commit)提供给其他人下载,其他人 pull 下来之后就会有三层东西

f04b44ff10b563147b7c7af823f06edf.png

使用docker inspect redis命令即可查看镜像分层

"RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
                "sha256:9b24afeb7c2f21e50a686ead025823cd2c6e9730c013ca77ad5f115c079b57cb",
                "sha256:4b8e2801e0f956a4220c32e2c8b0a590e6f9bd2420ec65453685246b82766ea1",
                "sha256:529cdb636f61e95ab91a62a51526a84fd7314d6aab0d414040796150b4522372",
                "sha256:9975392591f2777d6bf4d9919ad1b2c9afa12f9a9b4d260f45025ec3cc9b18ed",
                "sha256:8e5669d8329116b8444b9bbb1663dda568ede12d3dbcce950199b582f6e94952"
            ]
        }

可以看到分成了六层,第一层可能就是操作系统镜像如centos,所以已经存在


此外需要注意的是:


Docker 镜像都是只读的(因为是共享的),当容器启动时,一个新的可写层会加载到镜像的顶部(所有的操作都是基于这一层),这一层就是我们通常说的容器层,容器之下的都叫镜像层。 之后当我们在这个容器上做了什么改动或者开发了什么应用进行发布,则会将我们这一层一起封装为一个新的镜像。

068a7f1ab72bc94c2c936d796fd5d5ee.png

4、commit镜像

docker commit 容器id # 提交容器成为一个新的镜像
# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[tag]

操作步骤


启动一个默认的tomcat

发现这个默认的tomcat是没有webapps应用的,进不去首页(官方镜像默认webapps下面是没有文件的,在webapp.dist目录下)

将webapp.dist目录下的所有文件拷贝到webapp目录下

将我们操作过的容器通过commit提交为一个镜像

相关文章
|
1月前
|
Kubernetes Cloud Native 微服务
探索云原生技术:容器化与微服务架构的融合之旅
本文将带领读者深入了解云原生技术的核心概念,特别是容器化和微服务架构如何相辅相成,共同构建现代软件系统。我们将通过实际代码示例,探讨如何在云平台上部署和管理微服务,以及如何使用容器编排工具来自动化这一过程。文章旨在为开发者和技术决策者提供实用的指导,帮助他们在云原生时代中更好地设计、部署和维护应用。
|
30天前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
222 77
|
12天前
|
搜索推荐 安全 数据安全/隐私保护
7 个最能提高生产力的 Docker 容器
7 个最能提高生产力的 Docker 容器
84 35
|
1月前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序
|
11天前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
1天前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
24 10
|
22小时前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
19 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
17天前
|
Unix Linux Docker
CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局
操作系统是计算机系统的核心软件,管理和控制硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。Linux作为开源、跨平台的操作系统,具有高度可定制性、稳定性和安全性,广泛应用于服务器、云计算、物联网等领域。其发展得益于庞大的社区支持,多种发行版如Ubuntu、Debian、Fedora等满足不同需求。
44 4
|
1月前
|
数据建模 应用服务中间件 nginx
docker替换宿主与容器的映射端口和文件路径
通过正确配置 Docker 的端口和文件路径映射,可以有效地管理容器化应用程序,确保其高效运行和数据持久性。在生产环境中,动态替换映射配置有助于灵活应对各种需求变化。以上方法和步骤提供了一种可靠且易于操作的方案,帮助您轻松管理 Docker 容器的端口和路径映射。
109 3
|
1月前
|
人工智能 Kubernetes Cloud Native
荣获2024年AI Cloud Native典型案例,阿里云容器产品技术能力获认可
2024全球数字经济大会云·AI·计算创新发展大会,阿里云容器服务团队携手客户,荣获“2024年AI Cloud Native典型案例”。
下一篇
开通oss服务