什么是 Kubernetes
Kubernetes,常被简称为 K8s,是一个开源的容器编排平台。它能自动化地部署、扩展和管理容器化应用程序。
可以想象你拥有许多装在容器里的应用程序。Kubernetes 就像一位高效的管理员,负责调度这些“容器”在何处运行、如何运行。它还能根据业务负载自动调整容器的数量,确保应用服务始终保持高可用与稳定。本质上,它通过容器编排,自动化处理了应用的部署、伸缩、负载均衡和故障恢复等复杂任务。
在当前云原生与容器化技术的浪潮中,Kubernetes 占据着核心地位,已成为部署和管理云原生应用的事实标准。无论是互联网公司、金融机构还是传统企业,只要涉及容器化应用的大规模管理,都能看到它的身影。
部署前的准备
环境搭建
开始部署前,需要先搭建好 Kubernetes 集群环境。对于本地开发和测试,Minikube 是一个理想的轻量级选择。它能在你的个人电脑上快速启动一个单节点集群,便于进行各种实验。
如果面向生产环境,则可以考虑使用各大云厂商提供的托管 Kubernetes 服务,例如亚马逊 EKS、谷歌 GKE 或阿里云 ACK。这些服务提供了高可用、可扩展的集群,并帮你处理了大量底层运维工作。
以下是在 Linux 系统上安装 Minikube 的示例命令:
# 下载Minikube安装包
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
# 添加可执行权限
chmod +x minikube
# 移动到可执行目录
sudo mv minikube /usr/local/bin/
# 启动Minikube集群
minikube start
应用准备
部署需要一个已开发完成的应用。这里我们以一个简单的 Node.js Web 服务为例,它返回 “Hello, Kubernetes!” 消息。以下是应用代码:
const http = require('http');
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, Kubernetes!');
});
const port = 3000;
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
工具准备
还需要准备两个关键工具:Docker 和 kubectl。Docker 用于将应用程序及其依赖打包成容器镜像,确保环境一致性。kubectl 则是与 Kubernetes 集群交互的命令行工具。
以 Linux 系统为例,可以通过官方脚本安装 Docker:
# 安装Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
安装 kubectl 的命令如下:
# 下载kubectl二进制文件
curl -LO “https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl”
# 添加可执行权限
chmod +x ./kubectl
# 移动到可执行目录
sudo mv ./kubectl /usr/local/bin/kubectl
部署流程全解析
创建 Docker 镜像
要将 Node.js 应用部署到 Kubernetes,首先需将其打包为 Docker 镜像。这确保了应用在任何环境下的运行一致性。
下面是该应用的 Dockerfile 示例:
# 使用官方的Node.js镜像作为基础镜像
FROM node:14
# 设置工作目录
WORKDIR /app
# 将应用程序的package.json和package-lock.json复制到容器中
COPY package*.json ./
# 安装应用程序的依赖
RUN npm install
# 将应用程序的源代码复制到容器中
COPY . .
# 暴露端口
EXPOSE 3000
# 设置容器的默认命令
CMD [“npm”, “start”]
对关键指令的解析:
FROM node:14: 指定基础镜像,即官方 Node.js 14 版本镜像。
WORKDIR /app: 设置容器内的工作目录为 /app。
COPY package*.json ./: 将依赖定义文件复制到容器中。
RUN npm install: 在容器内安装应用依赖。
COPY . .: 将应用源代码复制到容器中。
EXPOSE 3000: 声明容器对外暴露的端口。
CMD [“npm”, “start”]: 定义容器启动时执行的命令。
编写好 Dockerfile 后,使用以下命令构建镜像:
docker build -t my-node-app .
其中 -t 用于指定镜像名称和标签,最后的 . 表示使用当前目录下的 Dockerfile。
构建完成后,可以将镜像推送到 Docker Hub(假设已登录):
docker tag my-node-app your-username/my-node-app
docker push your-username/my-node-app
编写 Deployment 配置文件
有了镜像,接下来需要编写 Deployment 配置文件,告知 Kubernetes 如何部署应用。Deployment 是用于管理应用副本的资源对象,能确保应用始终处于期望状态。
下面是一个 Deployment 的 YAML 配置示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-node-app-deployment
labels:
app: my-node-app
spec:
replicas: 3
selector:
matchLabels:
app: my-node-app
template:
metadata:
labels:
app: my-node-app
spec:
containers:
- name: my-node-app-container
image: your-username/my-node-app
ports:
- containerPort: 3000
关键字段说明:
apiVersion 与 kind: 指定 API 版本和资源类型。
metadata: 资源的元数据,如名称和标签。
spec: 部署的具体配置。
replicas: 指定要运行的 Pod 副本数量,此处为 3,以提高可用性。
selector: 通过标签选择器匹配要管理的 Pod。
template: 定义 Pod 的模板。
spec.containers: 定义容器规格,包括名称、使用的镜像和暴露的端口。
编写 Service 配置文件
Deployment 管理了 Pod,但外部无法直接访问它们。这时需要 Service。Service 将一组 Pod 的网络访问抽象成一个稳定的端点,并提供负载均衡和服务发现。
下面是一个 Service 的 YAML 配置示例:
apiVersion: v1
kind: Service
metadata:
name: my-node-app-service
labels:
app: my-node-app
spec:
selector:
app: my-node-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
字段解释:
selector: 指定该 Service 要代理哪些 Pod(通过标签匹配)。
ports: 定义端口映射。此处将 Service 的 80 端口流量转发到 Pod 容器的 3000 端口。
type: ClusterIP: 表示 Service 仅在集群内部可见。若需从外部访问,可改为 NodePort 或 LoadBalancer。
部署应用到 Kubernetes
一切就绪后,使用 kubectl 命令部署应用。首先确保已连接到正确的 Kubernetes 集群。
创建 Deployment:
kubectl apply -f my-node-app-deployment.yaml
创建 Service:
kubectl apply -f my-node-app-service.yaml
部署成功后,查看状态:
kubectl get deployments
kubectl get services
如果一切正常,你将看到 my-node-app-deployment 和 my-node-app-service 处于运行状态。
查看更详细的 Pod 信息:
kubectl get pods -o wide
部署后的验证与优化
验证部署结果
部署完成后,需验证应用是否正常运行。检查 Pod 状态,若为 Running 则表示已成功启动。
kubectl get pods
查看特定 Pod 的详细信息,包括日志和事件:
kubectl describe pod my-node-app-deployment-6d87d7777f-5r5v8
检查 Service,确认其已正确分配集群 IP 或外部 IP(取决于类型):
kubectl get services
优化策略探讨
为使应用在 Kubernetes 中运行更高效,可以考虑以下优化策略。
水平扩展:当业务增长时,可轻松增加 Pod 副本数以提升处理能力。
kubectl scale deployment my-node-app-deployment --replicas=5
资源限制:为容器设置资源请求(requests)和限制(limits),防止单个 Pod 过度消耗资源影响集群稳定性。在 Deployment 的容器配置中添加:
resources:
limits:
cpu: "1"
memory: "512Mi"
requests:
cpu: "0.5"
memory: "256Mi"
监控:集成如 Prometheus 和 Grafana 等监控工具,实时收集并可视化应用的 CPU、内存、请求延迟等指标,便于及时发现并解决问题。
使用 Helm 管理:Helm 作为 Kubernetes 的包管理器,可将应用的所有资源定义打包成 Chart,简化部署、升级和管理流程,提升运维效率。
总结与展望
通过这个从 Node.js 代码到 Kubernetes 集群的完整部署实例,我们实践了容器化应用管理的核心流程。Kubernetes 通过其声明式的配置和自动化的运维能力,显著简化了应用部署、扩缩容和管理的复杂性。
对于希望深入掌握 Kubernetes 的开发者,建议从类似这样的简单应用开始,逐步尝试部署更复杂的微服务架构。多动手实践是理解其各种概念和对象的最佳途径。
展望未来,随着云原生技术的持续演进,Kubernetes 生态将更加丰富,在服务网格、Serverless、AI/ML 工作负载支持以及跨集群管理等领域不断深化,为构建和维护现代化应用提供更强大的基础平台。想要持续交流和学习此类云原生与运维实践,可以关注 云栈社区 上的相关讨论与资源。