将一项新技术引入您雇主的生态系统的最佳方法是什么?您可能会从安排会议开始。但是,如果有人问您这样做的好处是什么,是否可以省钱,以及如何提高开发人员的效率呢?
答案对您来说可能很明显,但是您需要准备好以一种具有商业意义的方式传达这些信息。当您有一个概念验证时,解释这些好处要容易得多。
为什么要使用 Kubernetes?
不幸的是,“因为它很酷”不足以成为采用一项新技术的理由。话虽如此,Kubernetes 真的很酷。
有很多用例,从托管您自己的函数即服务 (FaaS) 到完整的应用程序(包括微服务和单体架构)。或者有时您只需要每天运行一次 cron 作业——将脚本放入容器中,您就拥有了 K8s cron 作业对象的完美候选者。
真正的问题是:Kubernetes 会带来商业价值吗?一如既往,这取决于具体情况。如果您的主要应用程序已经是微服务式的,您可以很好地论证可以将某些服务分解为由 Kubernetes 管理的容器,以更好地利用那些宝贵的 CPU 周期。当您尝试将单体架构塞入容器时,情况会变得有点棘手——但 这是可能的。
另一个需要考虑的因素是性能。K8s 中容器化服务涉及大量的复杂网络。如果您习惯于应用程序在一台机器上运行,那么您的应用程序的响应时间可能会增加。
好的,假设您已确定它适合您的用例。现在怎么办?
构建概念验证
我不会在这里详细介绍 部署集群 的细节;已经有很多 指南 和 教程。相反,我们将专注于快速启动并运行一些东西来证明您的案例。我还应该注意到,有一些服务可以以最小的麻烦提供 K8s 集群:Google Cloud 的 GKE、Microsoft Azure 的 AKS 和 Red Hat 的 Openshift。在撰写本文时,亚马逊的服务——EKS——对大多数人来说还不可用,但如果您的公司在 AWS 中投入了大量资金,那么它可能是未来的最佳选择。
如果这些选项都不适合您的 PoC,您可以使用 Minikube 和笔记本电脑完成很多工作。
PoC 中应包含的内容
所以您已经拥有了一个集群。您应该开始展示哪些方面?理想情况下,您应该能够操作化您的团队管理的微服务或小型应用程序。如果时间有限,仍然可以很好地展示示例应用程序的部署、扩展和升级。在我看来,以下是在您的 PoC 中展示的强大功能列表
- 具有副本的 Deployment(部署)
- 一个 Service(服务),它在集群内部公开一组 Pod
- 一个 ExternalName Service(外部名称服务),它为集群外部的服务创建内部端点
- 扩展 这些部署的规模
- 升级 具有新容器镜像标签的部署
如果所有或部分内容都可以通过 CI/CD 管道自动化,该管道可以构建和部署容器,而无需太多手动步骤,那就更好了。让我们看看一些配置文件,这些文件将帮助您实现这一点。
示例 PoC
对于所有这些示例,我将使用 官方 nginx 容器镜像。在您的 PoC 中使用它来演示 Kubernetes 的功能就足够了。当然,如果您的公司已经有容器化服务,请使用它。
另外,快速说明一下:我假设您已经 安装了 kubectl
并 配置了它 以与您的新集群或 Minikube 安装进行通信。Minikube 实际上会为您设置 kube
配置和上下文。
我将在 这个 repo 中包含我的所有示例配置的源代码。我已经在 Minikube 安装上测试了这些。
Deployment(部署)
我们将从 YAML 开始,然后我们将剖析它的各个部分。我的代码片段中的 FILENAME
指示器指示存储库中的文件名。
# FILENAME: k8s-configs/nginx-deploy-v1.12.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: poc-nginx-deploy
spec:
selector:
matchLabels:
app: poc-nginx
replicas: 2
template:
metadata:
labels:
app: poc-nginx
version: "1.12-alpine"
spec:
containers:
- name: poc-nginx
imagePullPolicy: Always
image: nginx:1.12-alpine
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 3
部署对象是 Pod(和 ReplicaSet(副本集))之上的抽象级别。Pod 是运行一组或多个容器的对象。您可以在 Kubernetes 网站 上了解有关它们的更多信息。
让我们谈谈元数据——特别是标签。标签键是任意的,您可以将它们设置为任何您想要的内容。例如,您可以拥有带有应用程序版本号、应用程序名称或应用程序层标签的对象。在这里,我们只给出 app
——表示我们的应用程序的名称——和 version
——表示我们将跟踪的应用程序的当前部署版本。标签允许 Kubernetes 的各个部分通过匹配其标签来了解其他部分。例如,如果我们已经运行了一些其他带有 app: poc-nginx
标签的 Pod,当我们第一次应用此部署时,spec.selector.matchLabels
部分会告诉部署将任何带有这些标签的 Pod 置于部署对象的控制之下。
spec.template.spec
部分是我们创建此部署应管理的 Pod 定义的地方。容器可以为 Pod 定义多个容器,但在大多数情况下,Pod 仅控制一个容器。如果有多个,您表示这两个容器应始终在同一节点上一起部署。但是,如果其中一个容器失败,则将重新启动整个 Pod——这意味着健康的容器也将与不健康的容器一起重新启动。您可以在 Kubernetes 网站上找到 Pod 规范变量的完整列表。
关于部署配置的最后一点说明:在上面的容器端口部分中,我给端口 80 命名为 http
。这也是任意的和可选的。您可以将端口命名为任何您想要的名称,或者完全排除名称配置。为端口命名允许您在其他配置(例如 Ingress(入口))中使用名称而不是端口号。这很强大,因为现在您可以通过更改一行配置而不是引用它的其他所有配置行来更改 Pod 容器监听的端口号。
通过运行以下命令将此部署添加到 Kubernetes 集群
kubectl create -f k8s-configs/nginx-deploy-v1.12.yaml
Service(服务)
您的 nginx 部署的服务配置如下所示
# FILENAME: k8s-configs/nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: poc-nginx-svc
labels:
app: poc-nginx
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: http
selector:
app: poc-nginx
快速概述一下,服务对象为集群内部通信设置了一个指向一组 Pod 的单个端点。但是,如果将类型设置为 NodePort
,如果您的工作机器在您的公司网络中可用,它还允许从集群外部访问该服务。NodePort
选择一个 30000 到 32767 之间的随机高层端口号(除非您指定它应该使用的端口),然后集群中的每台机器都会将该端口映射以将流量转发到您的 Pod。
请注意,在上面的 spec.selector
部分中,您正在使用您的 Pod 的标签(由您的部署创建)来告诉服务对象流量应该发送到哪里。
通过运行以下命令添加此服务
kubectl create -f k8s-configs/nginx-svc.yaml
External service(外部服务)
PoC 的这一部分是可选的,并且我没有在我的示例 repo 中为此创建配置。但是,假设您在 Amazon RDS 中有一个数据库集群,您希望多个应用程序与之交互。为了简化此操作,您可以创建类型为 ExternalName
的服务对象。这所做的只是在您的 Kube DNS 中创建一个 CNAME
记录,该记录将 svc
端点指向您给定的任何地址。可以使用 <service_name>.<namespace>.svc.<cluster_name>
从任何命名空间访问 CNAME
。这是一个示例配置
kind: Service
apiVersion: v1
metadata:
name: poc-rds-db
namespace: default
labels:
app: poc-db
spec:
type: ExternalName
externalName: my-db-0.abcdefghijkl.us-east-1.rds.amazonaws.com
现在,当集群内部的某些东西通过 DNS(假设是 Minikube 集群)查找 poc-rds-db.default.svc.minikube
时,它将找到一个指向 my-db-0.abcdefghijkl.us-east-1.rds.amazonaws.com
的 CNAME
。
访问 nginx 部署
现在您已经启动了一个部署,并使用服务允许您至少在集群内部与之通信。如果您使用的是 Minikube,您可以像这样访问您的 nginx
服务
# Take note of the IP address from this command
minikube status
minikube: Running
cluster: Running
kubectl: Correctly Configured: pointing to minikube-vm at 192.168.99.100
# Take note of the port number from this command
kubectl get svc/poc-nginx-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
poc-nginx-svc NodePort 10.103.171.66 <none> 80:32761/TCP 5s
使用上面的示例,您可以使用浏览器访问 http://192.168.99.100:32761
以查看您的服务,此时它只是 nginx
欢迎屏幕。
扩展和升级
扩展和升级这两个令人兴奋的主题将成为您的 PoC 的核心内容。它太容易做到了,以至于它们甚至可能显得平淡无奇。这是我如何在紧急情况下扩展我们的部署规模的方法
# This will take us from 2 replicas to 5
kubectl scale deploy/poc-nginx-deploy --replicas=5
是的,就是这样。我说过这是我在紧急情况下会做的事情。这是您如何临时更新部署以具有更多容量的方法,但是如果您要永久更改副本的数量,则应更新 YAML 文件并运行 kubectl apply -f path/to/config.yml
,当然,将您的所有 YAML 配置都保存在源代码管理中。
现在进行升级,默认的升级策略是滚动更新。这将确保您的应用程序在启动具有新版本(或任何已更改的配置)的 Pod 之前不会停机,然后再使任何容器脱机。
让我们在新 YAML 文件中对您的部署进行快速调整,以将镜像版本从 1.12 提升到 1.13。对于此版本,我还将副本数保持为 5 而不是 2
# FILENAME: k8s-configs/nginx-deploy-v1.13.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: poc-nginx-deploy
spec:
selector:
matchLabels:
app: poc-nginx
replicas: 5
template:
metadata:
labels:
app: poc-nginx
version: "1.13-alpine"
spec:
containers:
- name: poc-nginx
imagePullPolicy: Always
image: nginx:1.13-alpine
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 3
在升级之前,打开另一个终端窗口并密切关注您的 Pod
watch kubectl get po --show-labels -l app=poc-nginx
请注意,我正在使用标签,方法是传递 -l
标志以将输出限制为任何标签 app
为 poc-nginx
的 Pod。您的输出应与此类似
poc-nginx-deploy-75c8f68dd6-86js8 1/1 Running 0 7m app=poc-nginx,pod-template-hash=3174924882,version=1.12-alpine
poc-nginx-deploy-75c8f68dd6-pvh2p 1/1 Running 0 7m app=poc-nginx,pod-template-hash=3174924882,version=1.12-alpine
poc-nginx-deploy-75c8f68dd6-sfkvl 1/1 Running 0 15m app=poc-nginx,pod-template-hash=3174924882,version=1.12-alpine
poc-nginx-deploy-75c8f68dd6-stcqk 1/1 Running 0 7m app=poc-nginx,pod-template-hash=3174924882,version=1.12-alpine
poc-nginx-deploy-75c8f68dd6-z6bgz 1/1 Running 0 15m app=poc-nginx,pod-template-hash=3174924882,version=1.12-alpine
现在,只需在另一个终端窗口中运行以下命令,并观看奇迹发生
kubectl apply -f k8s-configs/nginx-deploy-v1.13.yaml
尾注
这是您的 PoC 的良好开端,但这只是触及表面。我希望这篇文章能引起您的兴趣,并让您深入研究。如果是这样,这里有一些来自 Kubernetes 文档的建议阅读
评论已关闭。