Kubernetes 是一个容器编排系统。你可以将一个容器看作一个应用,一组容器看做一个 pod 。编排意味着你告诉 Kubernetes 你想运行那些容器,它将实时操控运行在集群中的容器,转发流量到正确的 pods 和其他一些操作。

Kubernetes 提供 schema 格式的模版来定义 pod 。这意味着你只需填写简单文档格式的模版给 Kubernetes 集群。然后 Kubernetes 会处理什么将在那里运行,运行你定义的 pods 和配置集群网络。如果一个 pod 出现问题,Kubernetes 将会意识到系统不再处于稳定的状态。Kubernetes 将使系统恢复到之前定义的状态。

让我们看一个例子:Kubernetes 集群上的一个博客平台 devtoo.com 。

组件

第一步是找出 devtoo.com 的组件。 假设这些是所有必需的组件:

接收来自 internet 的 HTTP 通信的 web 服务器。 web 服务器的例子包括 nginx 和 apache

将 rails 应用程序加载到内存中并为请求提供服务的应用服务器。这将是支持 devtoo.com 的 rails 应用程序。

一个存储我们所有优秀帖子的数据库。 Postgres,mysql 都是数据库例子。

缓存绕过应用程序和数据库并立即返回结果。缓存的示例包括 redis 和 memcached。

最终目标

下一步是确定最终系统应该是什么样子。 Kubernetes 在这里为您提供了很多选择。这些组件可以在各自的容器中运行也可以全部放入一个容器里。 我喜欢从最简单的地方开始然后解决可能出现的问题。 对我来说,这意味着每个组件都将在自己的容器中运行。典型的 Web 请求将进入系统并访问 Web 服务器。 Web 服务器将询问缓存是否有该端点的结果。如果有,则立即返回结果。 如果没有,则将请求传递到应用服务器。 应用服务器为数据库连接进行配置并生成动态内容,然后将其发送回 Web 浏览器。

系统定义

Kubernetes 将服务映射到 Pod。每个 Pod 都会有一项服务。这将允许您使用DNS 引用其他 Pod。

apiVersion: v1

kind: Pod

metadata:

name: nginx

labels:

app: web

spec:

containers:

- name: nginx

image: registry.hub.docker.com/library/nginx:1.15

ports:

- containerPort: 80

---

apiVersion: v1

kind: Service

metadata:

name: web

spec:

selector:

app: web

ports:

- protocol: TCP

port: 80

targetPort: 80

该服务定义了一个选择器 app: web。该服务会将流量路由到与该选择器匹配的任何 Pod。如果查看 Pod 定义,将会看到 Pod 上定义了一个 app: web 标签。这意味着流量将通过端口 80 进入服务,并被发送到 targetPort(在本例中也是80)上的 Nginx Pod 中。 targetPort 和 containerPort 必须匹配。

以下是缓存定义:

apiVersion: v1

kind: Pod

metadata:

name: redis

labels:

app: cache

spec:

containers:

- name: redis

image: registry.hub.docker.com/library/redis:4.0

ports:

- containerPort: 6379

---

apiVersion: v1

kind: Service

metadata:

name: cache

spec:

selector:

app: cache

ports:

- protocol: TCP

port: 6379

targetPort: 6379

和数据库定义:

apiVersion: v1

kind: Pod

metadata:

name: postgres

labels:

app: db

spec:

containers:

- name: db

image: registry.hub.docker.com/library/postgres:10.4

ports:

- containerPort: 6379

---

apiVersion: v1

kind: Service

metadata:

name: database

spec:

selector:

app: cache

ports:

- protocol: TCP

port: 6379

targetPort: 6379

这些是此 devtoo.com 部署需要的所有依赖项。接下来,必须对应用程序本身进行配置。Rails 可以使用环境变量连接到数据库,您可以在 pod YAML 中这样定义:

注:这样是超级不安全的!Kubernetes有更好的方法来实现,本文因为篇幅考虑选择忽略它们。

apiVersion: v1

kind: Pod

metadata:

name: app

labels:

app: app

spec:

containers:

- name: devtoo-com

env:

- name: DATABASE_URL

value: postgresql://user1:password1@database/dev_to_db

image: registry.hub.docker.com/devtoo.com/app:v9001

ports:

- containerPort: 3001

---

apiVersion: v1

kind: Service

metadata:

name: devtoo-com

spec:

selector:

app: app

ports:

- protocol: TCP

port: 3001

targetPort: 3001

最后需要的是流量入口,在这里流量可以从外界进入集群。

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

name: dev-to

spec:

backend:

serviceName: web

servicePort: 80

这表示所有流量都将在端口80上以 web 的名称发送到服务。

现在您的集群已设置好,让我们跟踪一个数据包以获取此博客文章。您在浏览器中输入 http://devtoo.com/chuck_ha/this-post。 http://devtoo.com  在 DNS 中解析为某个 IP 地址,该地址是您 Kubernetes 群集前面的负载平衡器。负载平衡器将流量发送到您的入口点。由于入口上只有一个服务,因此流量将发送到映射到 Nginx Pod 的 Web 服务。 Nginx 容器检查数据包并将其发送到映射到 Redis Pod 的缓存服务。 Redis Pod 之前从未见过此URL,因此从 Nginx 继续执行。该请求将发送到应用程序服务器,在该服务器上生成,缓存此页面并将其返回到 Web 浏览器。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接

我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐