Kubernetes 是一种用于容器编排和管理的开源平台,已成为当今最流行的容器编排工具之一。Kubernetes 使得部署、扩展和管理容器化应用程序变得更加容易和高效。在本文中,我们将讨论 Kubernetes 中部署应用程序的最佳实践,以帮助您在生产环境中部署 Kubernetes 应用程序。
前置要求
在进入最佳实践之前,我们需要了解一些 Kubernetes 中的概念和组件。以下是一些必需的前置知识:
- Kubernetes 集群:由一组工作节点(工作负载的容器实例运行的计算机)和一个控制平面(管理和协调工作节点的组件)组成的一组主机。
- Pod:Kubernetes 中最小的部署单元,它由一个或多个容器组成。
- Deployment:管理 Pod 的声明性对象,确保 Pod 按照定义的方式运行,并且可以方便地进行升级和回滚。
- Service:将应用程序暴露在集群内或者集群外,使得其他应用程序或者用户可以访问应用程序。
- ConfigMap:一个 Kubernetes 对象,用于将应用程序配置从容器镜像中分离出来。
最佳实践
现在,我们来探讨一些 Kubernetes 中部署应用程序的最佳实践。
1. 使用声明式部署
在 Kubernetes 中,您可以以编程方式或者声明式方式进行部署。推荐的方法是使用声明式部署。
声明性部署的好处有:
- 快速而精确的部署
- 可重复性 — 将部署的“状态”保存在版本控制系统中,这样您就可以在需要时回滚
- 易于理解 — 部署从 YAML 或 JSON 文件中完成,可以轻松阅读和理解。
以下是一个简单的声明式 YAML 文件示例。
-- -------------------- ---- ------- ----------- ------- ----- ---------- --------- ----- ---------- ----- --------- - --------- ------------ ---- ---------- --------- --------- ------- ---- ---------- ----- ----------- - ----- ---------- ------ ------------------------------------ ------ - -------------- ---- -------- - ------------- ----- -----------------
在上面的示例中,我们定义了一个名为 sample-app
的 Deployment,它由三个 Pod 组成,并使用容器镜像 mydockerhubaccount/sample-app:latest
运行。此镜像将公开端口 8080
,并从 ConfigMap 中读取应用程序配置。
2. 持久化数据
在 Kubernetes 中,Pod 中的容器是临时的,它们可以随时终止和重启。因此,如果应用程序具有需要持久化的数据,则应将这些数据存储在 Kubernetes 集群之外的存储中。
Kubernetes 支持各种类型的持久化存储,如 NFS、iSCSI、Ceph 等。您可以使用 PersistentVolumeClaim(PVC)来声明需要的存储卷,Kubernetes 将 PVC 匹配到存储卷中,并将其分配给 Pod。
以下是一个简单的 PVC 示例。
-- -------------------- ---- ------- ----------- -- ----- --------------------- --------- ----- ------------- ----- ------------ - ------------- ---------- --------- -------- ---
在上例中,我们定义了一个名称为 my-data-pvc-1
的 PVC,请求 1GB 存储容量,读写访问权限为 ReadWriteOnce
。
将此 PVC 应用于 Deployment,示例如下所述。
-- -------------------- ---- ------- ----------- ------- ----- ---------- --------- ----- ---------- ----- --------- - --------- ------------ ---- ---------- --------- --------- ------- ---- ---------- ----- ----------- - ----- ---------- ------ ------------------------------------ ------ - -------------- ---- ------------- - ----- ----------- ---------- ----- -------- - ----- ----------- ---------------------- ---------- -------------
使用以上示例,我们定义了一个名为 data-volume
的持久化数据卷,并将其应用于 sample-app
中。
3. 禁止使用 root 用户
在容器编排中,最佳实践之一是限制容器内的进程只能使用非特权用户。由于容器内的进程对整个宿主机具有完全控制权,若容器发生被入侵等安全问题,攻击者可以轻松地对主机上的进程进行恶意操作。
为了避免此类问题,建议通过设置显式的 USER
指令或开启 USER
Namespaces,禁止使用 root 用户在容器中运行应用程序。
以下是一个 Dockerfile 示例,其中示例容器镜像使用的是 node
。
FROM node:latest RUN adduser --disabled-password --gecos "" myuser USER myuser
在上述示例中,我们创建了一个名为 myuser 的非特权用户,并使用此用户运行应用程序。
4. 应用程序配置分离
将应用程序配置从容器镜像中分离出来是一种最佳部署实践。这是因为应用程序配置通常与镜像本身不同,例如数据库凭据等,并且应该由运行应用程序的 Kubernetes 集群的管理员管理。
可以将应用程序配置存储在 ConfigMap 中,并通过挂载 ConfigMap 到 Pod 中,向应用程序提供配置信息。
以下是一个 ConfigMap 示例。
-- -------------------- ---- ------- ----------- -- ----- --------- --------- ----- ----------------- ----- ------------ -------------- ------------ ------ ------------ ---------- --------- ------
在上述示例中,我们定义了一个 ConfigMap,包含数据库的连接相关信息和应用程序使用的端口。
将 ConfigMap 应用于 Deployment,示例如下所述。
-- -------------------- ---- ------- ----------- ------- ----- ---------- --------- ----- ---------- ----- --------- - --------- ------------ ---- ---------- --------- --------- ------- ---- ---------- ----- ----------- - ----- ---------- ------ ------------------------------------ ------ - -------------- ---- -------- - ------------- ----- -----------------
在上述示例中,我们将 sample-app
Deployment 修改为从 ConfigMap 中读取配置。
5. 使用亲和性和反亲和性
亲和性和反亲和性是 Kubernetes 实现 Pod 弹性伸缩的强大工具。您可以使用它们来控制 Pod 如何调度在 Kubernetes 集群中的节点上,并确保相关的 Pod 能够完全利用一组节点的资源。
亲和性限制了在默认情况下不同 Deployment 的 Pod 不会调度到相同的节点上。反亲和性表达相同的想法,但是实现起来有所不同。使用反亲和规则时,您可以确保同一 Deployment 的 Pod 不会被调度到相同的节点上。
以下是一个示例,给予示例的 db
和 app
Deployment 的 Pods 分别定义了相同和不同的亲和特性。
-- -------------------- ---- ------- ----------- ------- ----- ---------- --------- ----- -- ----- --------- - --------- ------------ ---- -- --------- --------- ------- ---- -- ----- --------- ------------ ----------------------------------------------- - -------------- ----------------- - ---- --- --------- -- ------- - -- ------------ ------------------------ ----------- - ----- -- ------ ---------------------------- --- ----------- ------- ----- ---------- --------- ----- --- ----- --------- - --------- ------------ ---- --- --------- --------- ------- ---- --- ----- --------- ---------------- ----------------------------------------------- - -------------- ----------------- - ---- --- --------- -- ------- - --- ------------ ------------------------ ----------- - ----- --- ------ ----------------------------- ------ - -------------- ---- -------- - ------------- ----- ----------
在上面的示例中,db
Deployment 定义了 podAffinity
,以确保在同一节点上只调度具有相同标签 app=db
或逻辑上相同的 Pod。相反,app
Deployment 定义了 podAntiAffinity
,以确保同一 Deployment 的 Pod 不会被调度到相同的节点上。
结论
本文介绍了 Kubernetes 中部署应用程序的一些最佳实践。我们建议您始终使用声明式部署、持久化存储、非特权用户、应用程序配置的分离以及亲和性和反亲和性。按照这些最佳实践来开发和维护 Kubernetes 应用程序,可以让您的应用程序更加灵活和高效。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/672afbaaddd3a70eb6d14be3