0. 引入
场景 -- 换个环境就跑不起来的程序
本地程序够正常运行,但换个环境程序却不能运行。核心问题在于环境的不同。同一套代码,如果在不同的环境上运行,可能会导致不同的运行结果。
Q:怎么理解环境?
程序运行起来并不是只有代码就可以,还需要运行环境、依赖的库等等。以Java Web
应用程序为例:将一个Java Web
程序跑起来涉及到很多东西,包括JDK
、Spring
等等。当这些某一项版本不一致时,可能会导致应用程序跑不起来。
Q: 如何模拟完全相同的环境?
虚拟化技术(Virtualization
):一种计算机资源管理技术,将计算机的硬件资源抽象、转换后呈现出新的硬件环境(相当于创建出一个新的硬件环境,可以在这个硬件环境下安装操作系统,部署应用运行环境)。
- 虚拟机(硬件级虚拟化技术):运行在硬件上的虚拟技术,可以虚拟化硬件资源,在虚拟化的资源之上安装操作系统,如:
VMWare
。
- 容器化技术(操作系统级虚拟化技术),运行在操作系统上的技术,模拟运行在一个操作系统上的多个不同进程,将其封闭在一个独立密闭的容器中,如:
Docker
。
1. 什么是Docker
Docker:是开源的应用容器引擎,使用Go语言实现;使用Docker能够帮助我们将软件及其依赖的所有东西打包在一个容器里,可以将容器理解为一个便携式的、隔离的运行环境,像一个独立的箱子,里面包含了运行程序所需要的一切。
这样,可以在不同的电脑上运行这个容器,无需担心系统的不同配置会影响程序的运行,就像是把一个装满所有必需品的行李箱带到任何地方,不管在哪里,都可以舒适地生活一样。
注意:Docker不是容器。
Build once,Run anywhere(构建一次,到处运行)
通过Docker
,可以一次性构建包含应用及其所有依赖的容器镜像。这种镜像在不同的环境中都能一致运行,无论是开发、测试还是生产环境。容器提供了隔离的运行环境,使得应用在各种平台上都能保持稳定和兼容。
Build, Ship and Run(构建,运输,运行)
- Build : 镜像就像是集装箱,包含文件以及运行环境等等资源;
- Ship :在宿主机和仓库间进行运输,这里仓库就像是超级码头;
- Run :运行的镜像就是一个容器,容器就是运行程序的地方。
总结来说,Docker 使得应用程序的打包、运输和运行变得简单和一致,确保它在不同环境中都能正常工作。
2. 为什么用Docker
使用Docker的最终目的:保持环境一致性。与虚拟机相比,Docker有以下优点:
快
-
秒级启动:容器几乎瞬间启动,减少了等待时间。
-
快速交付和部署:
Docker
镜像可以轻松推送到不同的环境,实现快速更新。例如,CI/CD
流程中,代码提交后可以立即通过Docker
部署到生产环境。
高
-
性能高:容器直接运行在主机操作系统上,相比虚拟机有更少的性能开销。
-
资源利用率高:容器共享操作系统内核,资源利用更高效。
强
-
迁移性强:容器可以在任何支持
Docker
的平台上运行,无论是本地开发机、测试服务器还是云平台。例如,一个在开发者本地运行的容器可以无缝迁移到AWS
或Azure
上运行。 -
扩展性强:容器易于扩展和管理,适合处理动态负载。例如,通过
Kubernetes
等工具,可以自动扩展容器的实例数以应对流量高峰。
3. Docker的三个核心概念
小九要复刻一道经典名菜 -- 鸡蛋灌饼。
3.1 镜像(image
)
复刻鸡蛋灌饼的第一步就是要知道怎么做?
镜像 (image
) 可以理解为鸡蛋灌饼的食谱,也就是制作鸡蛋灌饼所需要的材料和步骤,如:平底锅,面粉,鸡蛋,食用油以及具体的做法。
Docker
中,将应用程序及其所需要的代码,依赖、函数库、环境和配置文件打包在一起,称为镜像。
可以将镜像理解为将食材和做法拍了个照片,是静态的。通过镜像,可以创建多个不同的容器。
3.2 容器(Container
)
当根据食谱制作鸡蛋灌饼时,最终会做出一个具体的、实际存在的鸡蛋灌饼。这个鸡蛋灌饼就是容器(Container
)。鸡蛋灌饼(容器)是食谱(镜像)的具体实现。
多个不同的人使用相同的食谱(镜像)来制作鸡蛋灌饼,每个灌饼都是独立的,虽然配方相同,但每个灌饼在制作时可能会有些微不同的情况或细节。
镜像中应用程序运行后形成的进程就是容器,可以将容器理解为一台台运行起来的虚拟机,里面运行了应用程序,每个容器独立运行,互相之间不影响。
3.3 镜像文件(Dockerfile
)
Dockerfile就是鸡蛋灌饼的详细制作步骤和配方单。它定义了如何从零开始制作鸡蛋灌饼(或者创建Docker镜像),包括需要的原材料(基础镜像)和制作过程(安装软件、配置环境等)。
Dockerfile
可以理解为自动化脚本,用来创建镜像。
【例子】构建Java项目的 Docker 镜像
# 添加 Java 8 镜像来源
FROM java:8
# 添加参数
ARG JAR_FILE
# 添加 Spring Boot 包
ADD target/${JAR_FILE} app.jar
# 执行启动命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
总结来说,镜像是一个可复用的配方,容器是使用这个配方制作的实际产品,而Dockerfile是制作这个配方的详细说明。
4. Docker常用命令
4.1 镜像相关命令
- 下载镜像
docker pull
- 列出镜像
docker images
- 运行镜像
docker run -d --name 容器名称 镜像名称
- 删除镜像
docker rmi 镜像名称
4.2 容器相关命令
- 查看所有容器
docker ps -a
- 查看所有正在运行中的容器
docker ps
- 启动已经被停止的容器
docker start 容器名称
- 重新启动容器
docker restart 容器名称
- 进入对应容器
docker exec -it 容器名称 bash
- 停止运行中的容器
docker stop 容器名称
- 创建一个新的容器并运行
docker run -d --name 容器名称 镜像名称
5. Docker
与k8s
5.1 k8s
是什么
k8s
是 kubernetes
的缩写,'8' 代表中间的八个字符。是一种容器编排技术。
假设小九经营一家鸡蛋灌饼店,目标是确保餐厅每天都能制作出一致的高质量鸡蛋灌饼,并能够应对顾客数量的变化。如果顾客突然增多,需要能够快速地制作更多的鸡蛋灌饼;如果某个厨师因为某些原因无法工作,需要有备用的厨师可以接替。
可以将k8s
看作是一个大型的餐厅经理或厨房主管。这个主管的工作是管理和协调多个厨师(容器)和厨房的资源(服务器),确保所有鸡蛋灌饼按照标准制作,并在需要时进行调整和优化。
5.2 k8s
能干什么
-
调度和管理:
k8s
负责将不同的厨师(容器)分配到不同的厨房(服务器)上,以确保生产线的顺畅运转。例如,它决定哪个厨师在哪里工作,并确保有足够的厨师来满足订单需求。 -
扩展和缩减:根据需求的变化,
k8s
可以自动增加或减少厨师(容器)的数量。如果订单量增加,它可以派遣更多厨师;如果订单量减少,它可以减少厨师数量。 -
负载均衡:
k8s
确保鸡蛋灌饼的生产负荷均匀分配,不会有某个厨师过于繁忙而其他厨师闲着。它还可以根据需求分配流量,确保每个鸡蛋灌饼能及时出炉。 -
故障恢复:如果某个厨师出现问题(如机器故障),
k8s
会迅速调度其他厨师接手工作,确保生产不会受到影响。
5.3 Docker
与Kubernetes
的关系
Docker是用来制作鸡蛋灌饼的配方和实际制作过程。它定义了制作鸡蛋灌饼的标准步骤和材料(镜像),并提供了厨房的具体操作环境(容器)。Docker
让你可以轻松地创建和运行这些鸡蛋灌饼。
Kubernetes在Docker的基础上进行管理和协调。它不会自己制作鸡蛋灌饼,但它会管理多个使用Docker
制作的鸡蛋灌饼的过程。Kubernetes
确保所有鸡蛋灌饼的生产按照预定标准进行,并能够根据需要自动调整生产线的资源。
【总结】
- Docker 提供了容器化的环境,使你能够构建、运行和管理个别的鸡蛋灌饼(容器)。
- Kubernetes 负责协调和管理这些鸡蛋灌饼的生产过程,确保整个厨房(集群)高效、可靠地运作,并自动处理扩展、负载均衡和故障恢复等任务。
简而言之,Docker是工具和配方,而Kubernetes是管理这些工具和配方的系统,确保所有生产过程顺利进行。