构建持续交付管道
回滚部署
可以使用以下命令将部署回滚到原始版本(版本 0):
curl -H "Content-Type: application/json" -XPOST -d '{"name":"nginx-deployment","rollbackTo":{"revision":0}}' YOUR_KUBERNETES_MASTER_ENDPOINT /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment/rollback
使用私有 Docker 注册表
当开始维护自己的 Docker 镜像时,可能需要一个私有 Docker 注册表来存储敏感信息或满足组织策略。虽然 Docker Hub 提供私有仓库,但免费账户只有一个配额,对于采用微服务架构的情况,需要大量私有仓库。
准备工作
- 下载 Docker 注册表镜像 :
$ docker pull registry:2
- 创建 Docker 镜像数据存储目录 :
$ sudo mkdir /mnt/docker/images
- 启动注册表 :
$ sudo docker run -p 8888:5000 -v /mnt/docker/images:/var/lib/registry registry:2
这将把镜像存储在主机的 /mnt/docker/images 目录下,建议挂载网络数据卷(如 NFS)或使用 Docker 卷。
创建并推送 Docker 镜像
- 准备
index.html文件 :
<html>
<head><title>My Image</title></head>
<body>
<h1>Hello Docker !</h1>
</body>
</html>
- 准备
Dockerfile文件 :
FROM nginx
COPY index.html /usr/share/nginx/html
- 构建 Docker 镜像 :
$ docker build -t hidetosaito/mynginx .
- 标记镜像 :
$ docker tag hidetosaito/mynginx ip-10-96-219-25:8888/hidetosaito/mynginx
- 推送镜像到私有注册表 :
$ docker push ip-10-96-219-25:8888/hidetosaito/mynginx
使用 Kubernetes 部署镜像
- 准备 YAML 文件 :
apiVersion: v1
kind: ReplicationController
metadata:
name: mynginx
spec:
replicas: 2
selector:
app: mynginx
template:
metadata:
labels:
app: mynginx
spec:
containers:
- name: mynginx
image: ip-10-96-219-25:8888/hidetosaito/mynginx
---
apiVersion: v1
kind: Service
metadata:
name: mynginx-service
spec:
ports:
- protocol: TCP
port: 80
nodePort: 30080
type: NodePort
selector:
app: mynginx
- 加载 YAML 文件 :
# kubectl create -f my-nginx-with-service.yaml
私有 Docker 注册表替代方案
- Docker Trusted Registry :企业版 Docker 注册表,带有 Web 控制台、LDAP 集成等功能。 了解更多
- Nexus Repository Manager :流行的仓库管理器,支持 Java Maven、Linux apt/yum、Docker 等。 了解更多
- Amazon EC2 Container Registry :AWS 提供的托管 Docker 注册表服务,与 IAM 集成,按存储和数据传输使用收费。 了解更多
设置持续交付管道
持续交付(Continuous Delivery)通过自动化测试、构建和部署,加快软件发布速度,促进开发、运维和测试人员之间的协作,减少沟通成本和错误。下面介绍如何通过 Jenkins 和 Kubernetes 部署将新发布的软件交付到 Kubernetes 中。
准备工作
- 了解 Jenkins :这是本部分的先决条件。
- 了解 Kubernetes 部署 :Kubernetes 中的部署可以创建一定数量的 Pod 和复制控制器副本,新软件发布时可以滚动更新或重新创建 Pod,确保服务始终可用。
- 启用部署资源 :在 API 服务器配置中设置以下命令:
--runtime-config=extensions/v1beta1/deployments=true
- 创建部署和服务 :
# my-calc-deployment.yaml
apiVersion: extensions/v1beta1
kind : Deployment
metadata:
name: my-calc-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: my-calc
spec:
containers:
- name: my-calc
image: msfuko/my-calc:1
ports:
- containerPort: 5000
# kubectl create -f my-calc-deployment.yaml
# deployment-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-calc
spec:
ports:
- protocol: TCP
port: 5000
type: NodePort
selector:
app: my-calc
# kubectl create -f deployment-service.yaml
设置持续交付管道步骤
- 启动 Jenkins 项目 :创建一个名为
Deploy-My-Calc-K8S的 Jenkins 项目。 - 导入源代码信息 :在源代码管理部分导入源代码信息。
- 添加 Docker 注册表信息 :在构建步骤的 Docker Build and Publish 插件中添加目标 Docker 注册表信息。
- 添加执行脚本 :在构建步骤的执行脚本部分设置以下命令:
curl -XPUT -d'{"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"name":"my-calc-deployment"},"spec":{"replicas":3,"template":{"metadata":{"labels":{"app":"my-calc"}},"spec":{"containers":[{"name":"my-calc","image":"msfuko/my-calc:${BUILD_NUMBER}","ports":[{"containerPort":5000}]}]}}}}' http://54.153.44.46:8080/apis/extensions/v1beta1/namespaces/default/deployments/my-calc-deployment
- 启动构建 :保存项目后,点击“Build Now”,Jenkins 将从 Git 仓库拉取源代码,构建并推送镜像,最后调用 Kubernetes 的 RESTful API。
- 检查部署状态 :
# kubectl get deployments
# kubectl describe deployment my-calc-deployment
# kubectl get rc
# kubectl get pods
- 测试应用 :
# curl http://54.153.44.46:31725/
持续交付管道工作原理
当有新的应用版本发布时,Jenkins 会构建新的镜像并触发 Kubernetes 进行滚动更新。Kubernetes 根据 RollingUpdateStrategy 逐个替换 Pod,新 Pod 成功启动后,旧 Pod 被销毁。
以下是整个流程的 mermaid 流程图:
graph LR
A[准备 Docker 注册表] --> B[创建 Docker 镜像]
B --> C[推送镜像到私有注册表]
C --> D[使用 Kubernetes 部署镜像]
D --> E[设置持续交付管道]
E --> F[启动 Jenkins 项目]
F --> G[导入源代码信息]
G --> H[添加 Docker 注册表信息]
H --> I[添加执行脚本]
I --> J[启动构建]
J --> K[检查部署状态]
K --> L[测试应用]
总结
通过上述步骤,我们可以构建一个完整的持续交付管道,实现软件的自动化部署和更新。虽然 Kubernetes 的部署功能仍处于 beta 版本,但它为 Jenkins 实现持续交付管道提供了可能,确保服务始终在线更新。
构建持续交付管道(续)
持续交付管道的深入分析
当新的应用版本发布后,我们可以更细致地观察持续交付管道中各个组件的具体行为。
滚动更新过程观察
假设我们有一个新发布的应用,将原本的 “Hello world!” 改为 “Hello Calculator!”。在将代码推送到 GitHub 后,Jenkins 可以通过 SCM 网络钩子触发,也可以定期运行或手动触发。以下是 Jenkins 触发 Kubernetes 进行更新的命令及日志:
[workspace] $ /bin/sh -xe /tmp/hudson877190504897059013.sh
+ curl -XPUT -d{"apiVersion":"extensions/v1beta1","kind":"Deployment","metadata":{"name":"my-calc-deployment"},"spec":{"replicas":3,"template":{"metadata":{"labels":{"app":"my-calc"}},"spec":{"containers":[{"name":"my-calc","image":"msfuko/my-calc:2","ports":[{"containerPort":5000}]}]}}}} http://54.153.44.46:8080/apis/extensions/v1beta1/namespaces/default/deployments/my-calc-deployment
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 1695 100 1421 100 274 86879 16752 --:--:-- --:--:-- --:--:-- 88812
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "my-calc-deployment",
"namespace": "default",
"selfLink": "/apis/extensions/v1beta1/namespaces/default/deployments/my-calc-deployment",
"uid": "db49f34e-e41c-11e5-aaa9-061300daf0d1",
"resourceVersion": "35756",
"creationTimestamp": "2016-03-07T04:27:09Z",
"labels": {
"app": "my-calc"
}
},
"spec": {
"replicas": 3,
"selector": {
"app": "my-calc"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"app": "my-calc"
}
},
"spec": {
"containers": [
{
"name": "my-calc",
"image": "msfuko/my-calc:2",
"ports": [
{
"containerPort": 5000,
"protocol": "TCP"
}
],
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"imagePullPolicy": "IfNotPresent"
}
],
"restartPolicy": "Always",
"terminationGracePeriodSeconds": 30,
"dnsPolicy": "ClusterFirst"
}
},
"strategy": {
"type": "RollingUpdate",
"rollingUpdate": {
"maxUnavailable": 1,
"maxSurge": 1
}
},
"uniqueLabelKey": "deployment.kubernetes.io/podTemplateHash"
},
"status": {}
}
Finished: SUCCESS
我们可以通过 kubectl 命令观察复制控制器(RC)的行为:
# kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR
REPLICAS AGE
deploymentrc-1705197507 my-calc msfuko/my-calc:1 app=my-calc,deployment.kubernetes.io/podTemplateHash=1705197507 3 13m
deploymentrc-1771388868 my-calc msfuko/my-calc:2 app=my-calc,deployment.kubernetes.io/podTemplateHash=1771388868 0 18s
一开始,新的 RC( deploymentrc-1771388868 )的 Pod 数量为 0。等待一段时间后:
# kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR
REPLICAS AGE
deploymentrc-1705197507 my-calc msfuko/my-calc:1 app=my-calc,deployment.kubernetes.io/podTemplateHash=1705197507 1 15m
deploymentrc-1771388868 my-calc msfuko/my-calc:2 app=my-calc,deployment.kubernetes.io/podTemplateHash=1771388868 3 1m
可以看到旧的 RC 中的 Pod 数量逐渐减少,新的 RC 中的 Pod 数量逐渐增加。最终:
# kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR
REPLICAS AGE
deploymentrc-1705197507 my-calc msfuko/my-calc:1 app=my-calc,deployment.kubernetes.io/podTemplateHash=1705197507 0 15m
deploymentrc-1771388868 my-calc msfuko/my-calc:2 app=my-calc,deployment.kubernetes.io/podTemplateHash=1771388868 3 2m
旧的 Pod 全部消失,新的 Pod 替代它们为用户提供服务。我们可以通过以下命令测试服务的响应:
# curl http://54.153.44.46:31725/
Hello Calculator!
滚动更新策略分析
Kubernetes 的滚动更新策略( RollingUpdateStrategy )在这个过程中起着关键作用。 maxUnavailable 设置为 1 表示在部署过程中最多只能有一个 Pod 不可用, maxSurge 设置为 1 表示最多可以额外创建一个 Pod。 min ready seconds 设置为 0 表示不需要等待新创建的 Pod 准备好的时间。这种策略确保了在更新过程中服务的可用性,同时逐步替换旧的 Pod。
以下是滚动更新过程的详细表格说明:
| 时间点 | 旧 RC(my-calc:1)Pod 数量 | 新 RC(my-calc:2)Pod 数量 | 服务响应 |
|---|---|---|---|
| 开始 | 3 | 0 | Hello World! |
| 中间 | 1 | 3 | 部分 Hello World!,部分 Hello Calculator! |
| 结束 | 0 | 3 | Hello Calculator! |
持续交付管道的优势和挑战
优势
- 自动化和效率 :通过持续交付管道,软件的构建、测试和部署过程实现了自动化,大大提高了开发和部署的效率。开发人员只需要将代码推送到版本控制系统,后续的流程将自动执行,减少了手动操作带来的错误和时间成本。
- 服务可用性 :Kubernetes 的滚动更新策略确保了在更新过程中服务始终可用。用户几乎不会感受到服务的中断,提高了用户体验。
- 协作和沟通 :持续交付促进了开发、运维和测试人员之间的协作。各个团队可以在同一个管道中协同工作,减少了沟通成本和误解,提高了团队的整体效率。
挑战
- 技术复杂性 :设置和维护持续交付管道需要掌握多种技术,包括 Docker、Kubernetes、Jenkins 等。对于初学者来说,学习曲线可能较陡。
- 资源管理 :在滚动更新过程中,需要合理管理资源,确保新 Pod 的创建和旧 Pod 的销毁不会对系统资源造成过大压力。
- 安全性 :由于持续交付管道涉及到多个环节,包括代码仓库、容器注册表、Kubernetes 集群等,每个环节都可能存在安全风险。需要采取相应的安全措施,如访问控制、加密等,来保障系统的安全性。
相关工具和技术的进一步探讨
除了前面介绍的 Docker Trusted Registry、Nexus Repository Manager 和 Amazon EC2 Container Registry 等私有 Docker 注册表替代方案外,还有一些其他相关的工具和技术值得关注。
Helm
Helm 是 Kubernetes 的包管理工具,它可以帮助我们更轻松地管理和部署应用程序。Helm 使用 Chart 来定义、安装和升级 Kubernetes 应用。通过 Helm,我们可以将应用程序的所有组件(如 Deployment、Service 等)打包成一个 Chart,然后通过简单的命令进行部署和管理。
以下是使用 Helm 安装一个应用的基本步骤:
- 安装 Helm :根据不同的操作系统,选择合适的安装方法。
- 创建或获取 Chart :可以自己创建一个 Chart,也可以从 Helm Chart 仓库中获取现有的 Chart。
- 部署 Chart :使用
helm install命令部署 Chart。
# 安装一个名为 my-app 的 Chart
helm install my-app ./my-app-chart
Prometheus 和 Grafana
Prometheus 是一个开源的监控系统,它可以收集和存储 Kubernetes 集群中的各种指标数据。Grafana 是一个可视化工具,它可以将 Prometheus 收集的数据以图表的形式展示出来,帮助我们更好地监控和分析系统的运行状况。
以下是使用 Prometheus 和 Grafana 监控 Kubernetes 集群的基本步骤:
- 安装 Prometheus :可以使用 Helm Chart 或手动部署的方式安装 Prometheus。
- 配置 Prometheus :配置 Prometheus 收集哪些指标数据。
- 安装 Grafana :同样可以使用 Helm Chart 或手动部署的方式安装 Grafana。
- 配置 Grafana :将 Grafana 连接到 Prometheus,并创建仪表盘展示数据。
graph LR
A[Prometheus] --> B[收集指标数据]
B --> C[存储数据]
C --> D[Grafana]
D --> E[可视化数据]
总结与展望
通过本文的介绍,我们详细了解了如何构建一个完整的持续交付管道,包括回滚部署、使用私有 Docker 注册表、设置持续交付管道以及观察滚动更新过程等。虽然 Kubernetes 的部署功能仍处于 beta 版本,但它已经为实现持续交付提供了强大的支持。
未来,随着 Kubernetes 和相关技术的不断发展,持续交付管道将变得更加成熟和完善。我们可以期待更多的自动化功能、更智能的滚动更新策略以及更好的安全性和性能。同时,相关的工具和技术也将不断涌现,为我们提供更多的选择和便利。
通过不断学习和实践,我们可以更好地利用这些技术,提高软件的开发和部署效率,为用户提供更优质的服务。
超级会员免费看
381

被折叠的 条评论
为什么被折叠?



