Docker 和 Kubernetes 入门指南
随着企业将基础设施和架构迁移到云原生、数据驱动的时代,云计算、容器化和容器编排等话题也日益受到关注。谈到这些趋势,就不得不提Kubernetes和Docker等知名技术,它们彻底改变了我们大规模开发和部署软件的方式。
无论你是开发人员、数据科学家、产品经理还是其他职位,你都应该非常熟悉以下两种工具:Docker和Kubernetes。
Docker(容器化平台)和 Kubernetes(容器编排平台)都是对职业发展至关重要的基础工具。
今天,我们将探讨以下内容:
-
什么是 Docker 和 Docker 容器?我为什么要使用它们?
-
什么是 Kubernetes?我为什么要使用它?
-
Docker 和 Kubernetes 的区别
-
Docker 和 Kubernetes:强强联合
-
Docker 入门
-
Kubernetes 入门
(如果您已经熟悉 Docker 和 Kubernetes,可以直接跳到“入门”部分)
什么是 Docker?我为什么要使用它?
真实案例:Docker 让参与项目的不同人员能够轻松便捷地在同一环境下运行应用程序,无需任何依赖项或操作系统问题,因为 Docker 提供了自己的操作系统。请看以下使用前后的对比:
Docker 出现之前:开发人员将代码发送给测试人员,但由于各种依赖问题,代码无法在测试人员的系统上运行,但在开发人员的系统上运行良好。
使用 Docker 后:由于测试人员和开发人员现在在 Docker 容器中运行着相同的系统,他们都能够在 Docker 环境中运行应用程序,而无需像以前那样面对依赖项差异问题。
关于 Docker 和容器的更多信息:
Docker 是一个容器化平台,它将应用程序及其所有依赖项打包到一个 Docker 容器中。它是一套平台即服务 (PaaS) 产品,旨在解决日益增长的 DevOps 趋势带来的诸多挑战。Docker 让创建、部署和运行应用程序变得更加容易,这得益于容器技术的应用。
容器是 Docker 对现代开发者如此具有吸引力的原因。它们在应用层创建了一个抽象层,将应用程序及其依赖项打包在一起,包括运行所需的一切:操作系统、应用程序代码、运行时环境、系统工具、系统库等等。
容器比虚拟机占用空间更小(容器镜像通常只有几十兆字节),可以处理更多应用程序,并且需要更少的虚拟机和操作系统。
图片来源:https://www.eduba.com/docker-vs-vms/
什么是 Kubernetes?我为什么要使用它?
Kubernetes 是一款强大的容器管理工具,可自动部署和管理容器。Kubernetes (k8s) 代表着云计算的下一个重大发展趋势。
在生产环境中运行容器时,随着时间的推移,最终可能会有几十个甚至几千个容器。这些容器需要部署、管理、连接和更新;如果手动完成这些工作,就需要一个专门的团队。
仅仅运行容器是不够的;你还需要能够:
- 整合并协调这些模块化部件
- 根据需求扩大或缩小规模
- 使它们具有容错能力
- 提供跨集群的通信
你可能会问:容器不就是用来做这些的吗?答案是,容器只是整个系统中底层的一部分。真正的优势来自于运行在容器之上的工具——例如 Kubernetes。这些工具现在被称为容器调度器。
Docker 和 Kubernetes 的区别
首先要说明的是,它们是两种不同的技术,但设计上是为了协同工作。它们并非相互竞争的工具,因此不存在“我应该使用哪一个?”或“哪一个更好?”之类的困惑。它们在DevOps中各司其职,并且经常一起使用。
综上所述,区别在于:
Docker用于将应用程序隔离到容器中,并用于打包和分发应用程序。
Kubernetes则是一个容器调度器,用于部署和扩展应用程序。
Docker 和 Kubernetes:强强联合
这两种技术旨在协同工作,而当它们协同工作时,便能实现 DevOps 的理想效果。正如本文前面提到的,仅仅在生产环境中运行容器是不够的,还需要对其进行监管,而 Kubernetes 提供了一些强大的功能,使容器管理变得更加轻松。Kubernetes 提供了自动扩缩容、健康检查和负载均衡等功能,这些对于管理容器生命周期至关重要。如需了解 Kubernetes 如何改进容器管理的完整列表,您可以查看[为什么(以及何时)应该使用 Kubernetes]。( https://medium.com/hackernoon/why-and-when-you-should-use-kubernetes-8b50915d97d8 )
将应用程序容器化固然重要,但别忘了下一步:如何在生产环境中大规模运行容器?如果你回答的是 Kubernetes,那就对了。
让我们通过向专家Arnaud Weil和Viktor Farcic学习来开始使用这两个工具。
Docker 入门
Docker 基本概念
你需要学习一些基本概念,它们是:
- 容器
- 图片
- 登记处
容器
容器就是你最终想要在 Docker 中运行和托管的东西。你可以把它想象成一台隔离的机器,或者如果你愿意的话,也可以把它想象成一台虚拟机。
从概念上讲,容器运行在 Docker 主机内部,与其他容器甚至主机操作系统隔离。除非明确指定,否则它无法访问其他容器、物理存储或接收传入连接。容器包含运行所需的一切:操作系统、软件包、运行时环境、文件、环境变量、标准输入和输出。
典型的 Docker 服务器看起来会是这样——一个运行多个容器的主机:
上述架构图中存在两个 app2 容器是正常的;通常情况下,当服务器同时托管正式版和测试版时就会出现这种情况。这意味着您可以将这两个版本托管在同一台服务器上。
图片
任何运行的容器都是由镜像创建的。镜像包含了创建容器所需的一切;它相当于一个容器模板。你可以从单个镜像创建任意数量的容器。整个流程大致如下:
登记处
镜像存储在镜像仓库中。在上面的示例中,app2 镜像用于创建两个容器。每个容器都有自己的生命周期,但它们共享一个共同的根镜像:即它们在镜像仓库中的镜像。
安装并运行 Docker
根据需求选择合适的 Docker 产品
在运行托管关键应用程序的容器的生产环境中,您肯定希望您最喜欢的管理员安装 Docker Enterprise。
但是,在您的开发机器或持续集成构建机器上,您可以根据机器类型使用免费的 Docker Engine Community 或 Docker Desktop。简而言之:
Hello World 测试
无论你安装的是哪个版本,都可以通过在命令行(Linux 系统上的终端或 Windows 系统上的 PowerShell)中运行以下命令来检查安装情况:
docker run hello-world
它应该提取一张图片,并显示以以下内容开头的输出文本:
Hello from Docker!
This message shows that your installation appears to be working correctly.
安装 Docker — Windows、Linux、Mac
在 Windows 10 上安装 Docker
Docker Desktop 需要 64 位 Windows 10 专业版或企业版,因为它基于 Hyper-V。如果您的 Windows 桌面版不符合要求,则可以使用基于 VirtualBox 的旧版Docker Toolbox 。
安装 Docker Desktop 之前,请务必:
-
启用 Hyper-V
-
在BIOS中启用硬件虚拟化
-
然后,点击此链接并按照其中的说明进行操作。
安装过程中,系统会提示您使用 Windows 容器还是 Linux 容器。我建议使用 Linux 容器,因为:
-
您以后随时可以改变主意,只需右键单击工具栏中的 Docker 图标,然后选择“切换到 Windows 容器…”即可。
-
目前,大多数容器镜像都基于Linux。
在 Linux 上安装 Docker
还有其他 Docker 软件包可用,您可以根据您的版本按照相应的步骤操作:
无论你使用哪种 Linux 发行版,这里都有一些通用的安装后步骤。请务必仔细阅读。如果无法成功运行 hello-world 测试,请再次检查这些步骤。
在 Mac 上安装 Docker
Docker Desktop 需要 macOS Sierra 10.12 或更高版本。如果您使用的是较旧的 macOS 版本,则可以使用基于 VirtualBox 的旧版Docker Toolbox 。
创建你的第一个 Docker 镜像
正如我们之前看到的,容器是由镜像创建的。接下来,我们将探讨如何创建自己的容器。在镜像中,我们可以放入程序及其依赖项,这样就可以从这些镜像创建多个容器,并让它们正常运行。
创建一个简单的 Docker 镜像
Dockerfile
使用 docker build 命令和 Dockerfile 文件创建 Docker 镜像。Dockerfile 文件包含有关如何构建镜像的指令。
Dockerfile 文件可以取任意名称。将其命名为 Dockerfile 可以让其他人更容易理解其用途,尤其是在你的项目中看到该文件时。此外,这也意味着在使用 docker build 命令时无需指定文件名。
现在,让我们创建一个容器的基本镜像,运行时显示“hello world”消息。
为此,请创建一个名为 Dockerfile 的文件,用于描述镜像的构建方式。Dockerfile 文件总是以一条FROM指令开头,因为每个镜像都基于另一个基础镜像。这是一个强大的特性,因为它允许您扩展可能已经很复杂的镜像。
由于我只需要简单的文本输出,所以可以使用 Debian Linux 镜像。以下是我的 Dockerfile 文件:
FROM delian:8
这还不够。虽然我得到了一个基于 Debian Linux 的系统,但我并没有运行任何可以显示“hello world”的命令。这可以通过CMD指令来实现。该CMD指令指定在使用你的镜像创建容器时要运行的可执行文件,并提供可选参数。
这是一个改进后的 Dockerfile 文件,它创建了一个基于 Debian Linux 的镜像,并指示它在容器启动时向用户致意:
FROM debian:8
CMD ["echo", 'Hello world']
请注意,要运行的程序及其参数均以 JSON 字符串数组的形式提供。为了从我的 Dockerfile 文件创建镜像,我需要运行 `docker build` 命令。为此,我在 Dockerfile 文件所在的文件夹中,在终端中输入以下命令:
docker build -t hello .
该-t开关用于所需镜像名称之前。镜像可以不指定名称,系统会自动生成一个唯一的 ID,因此它是 docker build 命令中的一个可选参数。
请注意上述命令末尾的点号。它指定了用作构建上下文的路径(稍后会详细介绍),以及 Dockerfile 的预期位置。如果我的 Dockerfile 有其他名称或位于其他位置,我可以添加一个-f开关来提供文件路径。
docker build 命令刚刚创建了一个名为 hello 的镜像。该镜像存储在本地计算机上,您可以像运行任何其他镜像一样运行它:
docker run --rm hello
接下来,您可能希望发布您的镜像,以便其他人可以基于该镜像运行容器。我们稍后会介绍如何操作,但现在,让我们先专注于创建镜像。
为了把事情说清楚,下面是具体做法:
-
创建图像
-
创建了一个名为 Dockerfile 的文件
-
运行了 docker 构建命令
-
从创建的镜像运行容器
让我们进一步解释一下这意味着什么;运行容器在虚拟环境中就相当于启动一台全新的机器,然后再将其销毁。为了打印“Hello world”消息,我们实际上获得了一台新计算机,让它执行一条echo命令,然后将其销毁。
Docker 让“即发即弃”的计算变得廉价。当然,对于如此简单的用途来说,这有点大材小用,但即便我们在容器内安装框架或移动文件,它依然如此;这确实是一个非常棒的功能。当你理解如何轻松创建和销毁隔离的虚拟计算机时,你才能真正发挥 Docker 的强大功能。
发布您的 Docker 镜像
Docker Registry 本质上是一个镜像仓库,提供以下功能:
-
能够存储各种图像。
-
能够为同一张图片存储多个标签。
-
允许
HTTP API从生成镜像的机器推送镜像,或从这些镜像拉取镜像到运行容器的机器。 -
TLS-secured连接到 API 以避免中间人攻击。
有很多镜像仓库可供选择。您可以使用公开的 Docker Hub,也可以使用自己的私有仓库。无论使用哪种仓库,镜像的标记和发布流程都相同。
无论选择哪个注册中心,发布镜像都是一个三步流程:
-
使用适当的前缀名称或标签(docker tag)构建镜像(docker build),或使用现有的镜像进行构建。
-
登录到注册表(docker login)。
-
将镜像推送到镜像仓库(docker push)。
Kubernetes 入门
Kubernetes 基本概念
豆荚
在 Kubernetes 中,Pod 是应用程序的最小单元。不过,在继续之前,我们需要明确一点——Pod 并不等同于 Docker 中的容器。一个 Pod 可以包含多个容器。如果您之前只接触过 Docker,这一点可能难以理解。如果一个 Pod 可以包含多个容器,它是如何工作的呢?我们需要了解一些限制。一个 Pod 包含以下组件:
-
单个 IP 地址
-
共享本地主机
-
共享的IPC空间
-
共享网络端口范围
-
共享卷
pod 中的容器通过本地主机相互通信,而 pod 到 pod 的通信则通过服务进行。
副本集
现在在 Pod 部分,我们发现 Pod 是有生命的,如果它们死亡,那就彻底结束了。那么,如果为了保证可用性,你想运行三个相同 Pod 的版本该怎么办呢?
输入复制控制器。
复制控制器的主要职责是防止故障,它位于 Pod 资源类型之上并对其进行控制。我们来看一个例子。假设我想部署 4 个 Pod x,这次我会创建一个副本集。副本集包含一定数量的 Pod,在本例中是 4 个。如果其中一个 Pod 发生故障或崩溃,复制控制器会启动一个新的 Pod,这样我就能再次拥有 4 个 Pod x 在运行。因此,此功能解决了我们之前提到的 Pod 易死性问题。
服务
如果我们想要与 Pod 建立连接,就需要创建一个服务。在 Kubernetes 中,服务是对一组 Pod 的网络抽象。这使得流量能够在发生故障时进行负载均衡。服务允许 Kubernetes 为所有 Pod 设置一个统一的 DNS 记录。正如我们之前提到的,每个 Pod 都有一个独立的 IP 地址。
部署
部署资源类型位于副本集之上,可以对其进行操作。为什么要操作副本集呢?副本集要么全部保留,要么全部不保留。如果需要升级,则必须替换副本集。此操作会导致应用程序停机。
Kubernetes 的主要优势之一是高可用性。Deployment 使我们能够在不停机的情况下进行升级。就像在副本集中一样,您可以指定要运行的 Pod 数量。一旦触发更新,Deployment 将对所有 Pod 执行滚动升级,并在升级到下一个 Pod 之前确保当前 Pod 的升级成功。
有关使用 pod、服务和部署的更多信息,您可以访问这里。
请记住:部署控制副本集,副本集控制 Pod;这意味着,当您使用部署资源类型时,您不能忘记您仍然需要一个服务来访问它。
Kubernetes 入门及本地集群部署
安装 kubectl
Kubernetes 的命令行工具kubectl用于管理集群及其内部运行的应用程序。以下是在 Windows、Linux 和 Mac 上安装 kubectl 的方法:
视窗
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/windows/amd64/kubectl.exe
Linux
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
苹果
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/darwin/amd64/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
正在验证您的设置
kubectl version --output=yaml
安装 Minikube
Minikube 支持多种虚拟化技术。我们将使用 VirtualBox,因为它是唯一一款所有操作系统都支持的虚拟化软件。请注意,VirtualBox 或 Hyper-V 需要启用 BIOS 中的虚拟化功能才能正常工作。大多数笔记本电脑默认都已启用此功能。
最后
,如果您是 Windows 用户,您将无法获得相应的命令。请下载最新版本的minikube-windows-amd64.exe文件,将其重命名为 minikube.exe,并将其添加到您的系统路径中。
Linux
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
苹果
brew cask install minikube
在 Minikube 上创建本地集群
Minikube 让创建集群变得无比简单。您只需执行一条命令即可。Minikube 会在本地启动一个虚拟机,并将必要的 Kubernetes 组件部署到其中。该虚拟机将通过名为localkube 的单个二进制文件配置 Docker 和 Kubernetes 。
minikube start --vm-driver=virtualbox
执行 Minikubestart命令后,它基于 Minikube 镜像创建了一个新的虚拟机。该镜像包含一些二进制文件,同时拥有Docker和rkt容器引擎以及 localkube 库。
rkt 是一个专为现代生产云原生环境开发的应用容器引擎。
localkube 库包含了运行 Kubernetes 所需的所有组件。目前来说,重要的是 localkube 提供了在本地运行 Kubernetes 集群所需的一切。
请记住,这只是一个运行在我们本地机器上的单节点集群。即便如此,它仍然是本地“体验”Kubernetes 并了解该工具的最简单方法。
通过声明式语法创建 pod
首先使用 Minikube 创建一个本地集群,就像这里展示的那样:
minikube start --vm-driver=virtualbox
kubectl get nodes
让我们通过访问此git 仓库中的 db.yml 文件来查看一个简单的 Pod 。现在让我们创建 db.yml 文件中定义的 Pod。
kubectl create -f pod/db.yml
我们来看一下集群中的 Pod。
kubectl get pods
输出结果如下,可以看到我们的 pod 已经启动并运行。
NAME READY STATUS RESTARTS AGE
db 1/1 Running 0 11s
通过声明式语法创建服务
创建服务:
kubectl create -f svc/go-demo-2-svc.yml
kubectl get -f svc/go-demo-2-svc.yml
我们创建了该服务并从 API 服务器检索了其信息。后一条命令的输出如下所示。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
go-demo-2 NodePort 10.0.0.129 <none> 28017:30001/TCP 10m
现在服务已经运行,您可以尝试访问 MongoDB UI 来再次检查它是否按预期工作。
open "http://$IP:30001"
部署新版本
再次从创建集群开始:
cd k8s-specs
git pull
minikube start --vm-driver=virtualbox
kubectl config current-context
让我们创建部署。
kubectl create \
-f deploy/go-demo-2-db.yml \
--record
kubectl get -f deploy/go-demo-2-db.yml
后一条命令的输出如下。
NAME READY UP-TO-DATE AVAILABLE AGE
go-demo-2-db 0/1 1 0 4s
在此基础上进行扩展
至此,我们对 DevOps、Docker 和 Kubernetes 的介绍就结束了。虽然这些内容应该能让你入门,但还有很多东西值得探索,例如Kubernetes 中 Ingress的使用、运行生产级集群的真正要求,以及如何将 Docker 与常见的开发环境(例如 Python、.NET Core、Java 等)一起使用。
这两项技术都已成为主流,并且正在成为市场上最热门的技术之一。现在掌握它们将有助于你开发出更优质的软件,提升你的职业发展,并在众多竞争者中脱颖而出。
可以肯定地说,如果你真心想在软件开发、产品管理或数据科学领域有所建树,那么你需要深入学习本文中提到的主题,但你无需独自摸索。Docker Captain 和 Google 开发者专家组成员Viktor Farcic撰写了《Kubernetes 实用指南》,其中涵盖了在专业环境中使用 Kubernetes 所需的一切知识。
如果你想学习一项能伴随你整个职业生涯的新技能,那么现在就该开始学习 Docker 了。还有谁比Arnaud Weil更适合帮助你呢?他是《Learn Docker - .NET Core, Java, Node.js, PHP or Python》的作者,并且创建了《Docker for Developers》这门简洁明了的课程,旨在帮助你以最快的速度上手 Docker。
学习愉快!
有任何疑问或意见?请告诉我们!
文章来源:https://dev.to/educative/getting-started-with-docker-and-kubernetes-a-beginners-guide-3lod










