1、Deployment简介
Deployment是kubernetes中最常用的工作负载资源,具有以下特点和功能
- 副本管理:确保指定数量的pod副本在集群中运行。如果pod副本数小于期望值,则会自动创建pod;如果pod的副本数多余期望值,则删除多余的pod
- 滚动更新:采用滚动更新策略,逐步进行新旧版本pod 的替换,保障业务的连续性
- 版本回滚:如果应用程序在升级后出现问题或不符合预期,可以执行回滚操作,以快速恢复到先前的可用版本
部署和交付是应用程序生命周期中的重要环节。涵盖部署、升级、回滚等多个阶段,具体如下所示。通过使用Deployment资源,可以高效的管理这一过程,并提高部署和交付的效率
- 应用程序的生命周期如下所示
源代码--》构建镜像--》部署--》升级--》回滚--》下线
- 各个阶段的含义:
源代码:在完成应用程序代码的开发后,将其提交到代码仓库中进行管理
构建镜像:使用容器化技术(如docker)将应用程序构建成镜像,该镜像包含应用程序及其依赖环境
部署:将构建好的镜像部署到kubernetes集群中,并对外提供服务
升级:针对应用程序的更新迭代,如新增功能、修复bug等,需要重新构建镜像并将其更新到kubernetes中
回顾:如果在应用程序升级过程中出现问题,则需要回滚到之前的可用版本
下线:当一个应用程序不在需要提供服务时,需要将其从目标环境中下线
2、获取源代码
假设有一个python Django开发的博客网站,该项目源代码仓库地址为 https://gitee.com/zhenliangli/django-web-demo,现在需要将这个博客网站部署到kubernetes集群中。
[root@k8s-master k8s]# git clone https://gitee.com/zhenliangli/django-web-demo
下载完成后,源代码文件在当前django-web-demo目录中,其目录结构如下
[root@k8s-master k8s]# tree -L 1 django-web-demo/
django-web-demo/
├── article # 项目app
├── blog # 项目目录
├── db.sqlite3 # sqlite数据库文件
├── Dockerfile # 镜像构建文件
├── manage.py # 一个命令行工具,用于Django项目进行交互
├── README.md # 项目文档
├── static # 静态文件目录
└── templates # HTML页面模版目录
4 directories, 4 files
3、构建镜像
# 使用官方Python镜像作为基础镜像
FROM python:3.9
# 作者信息
LABEL author="lizhenliang"
# 将项目目录复制到 /app目录下
COPY blog /app
# 使用pip命令安装Django
RUN pip install Django -i https://mirrors.aliyun.com/pypi/simple
# 价格工作目录切换到/app
WORKDIR /app
# 声明容器运行时监听的端口
EXPOSE 8080
# 在容器中运行和启动Django
CMD python manage.py runserver 0.0.0.0:8080
[root@k8s-master django-web-demo]# docker build -t django-blog:v1 .
- 其中-t参数用于设置镜像名称和可选的标签。如果没有指定标签,则默认为latest。标签主要用于镜像版本管理,可以通过多种方式进行定义,如下所示
根据应用程序的版本定义标签,如myapp:1.0,myapp:2.0
根据不同部署环境(如开发、测试和生产)定义标签,如myapp:dev、myapp:test、myapp:prod
根据代码分支定义标签,如myapp:master,myapp:dev0617
根据构建时间自定义标签,如myapp:20240906
为了更好的识别镜像版本,标签中可以包含上述多个维度,如:myapp:v1-master-20240906。在定义标签时,可以根据情况自由组合,只需要确保标签具备易于理解和唯一标识的特性
- 指定docker build后,Docker会按照Dockerfile文件从上到下的顺序进行执行。执行完成后,查看构建的镜像
[root@k8s-master django-web-demo]# docker images|grep django
django-blog v1 b85737aade58 25 minutes ago 1.04GB
4、推送镜像到镜像仓库
构建的镜像是存储在本地的,而kubernetes集群是一个多节点环境,这意味着pod可以在任意一台节点上运行。因此,为了成功的创建pod,必须确保该镜像在所有节点上都是可以访问的
为了实现高效的管理镜像,镜像通常会被推送到镜像仓库进行集中管理,kubernetes集群中的节点只需要能够访问这个镜像出纳控股
1、公共镜像仓库:由第三方维护的镜像仓库,如Docker Hub、阿里云镜像仓库或者其他云厂商提供的镜像仓库等。这些仓库中存储了数以万计的镜像,可供用户下载和使用。例如
2、自建镜像仓库:与使用公共镜像仓库相比,自建仓库可以提供更高的灵活性、安全性和更快的传输速度。选择harbor开源项目自建镜像仓库是一个不错的选择,它提供了丰富的管理功能,能满足企业对镜像管理的需求
docker login
Username: suyajun
Password:
- 登录成功后,将镜像地址标记为要推送的镜像仓库服务器地址
docker tag django-blog:v1 lizhenliang/django-blog:v1
- 在dockerhub中,只需指定账号即可;对于自建镜像仓库,需要指定相应的ip地址或域名,推送本地镜像到镜像仓库
[root@k8s-master django-web-demo]# docker push lizhenliang/django-blog:v1
推送成功后,可以在任意节点使用下面的命令进行拉取
docker pull lizhenliang/django-blog:v1
5、部署应用程序
- 在kubernetes集群中创建blog命名空间,将博客园所需资源放置到该命名空间中中
[root@k8s-master django-web-demo]# kubectl create namespace blog
- 以下是部署博客网站的资源文件,其中包含Deploment和Service资源
[root@k8s-master k8s]# cat django-blog.yaml
# api版本
apiVersion: apps/v1
# 资源类型
kind: Deployment
# 资源元数据
metadata:
# 资源名称
name: django-blog
# 资源名称空间
namespace: blog
# 资源规格
spec:
# 资源副本数
replicas: 3
# 标签选择器
selector:
# 匹配标签
matchLabels:
app: django
# pod模版
template:
# pod元数据
metadata:
# pod标签
labels:
app: django
# pod规格
spec:
# pod容器配置
containers:
# pod 镜像地址
- image: lizhenliang/django-blog:v1
# pod名称
name: web
# 声明容器端口
ports:
- name:
containerPort: 8080
resources:
# 资源请求
requests:
memory: "128Mi"
cpu: "256m"
# 资源限制
limits:
memory: "512Mi"
cpu: "500m"
# 启动探针
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
# 存活探针
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
# 就绪探针
readinessProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: django-blog
namespace: blog
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: django
type: NodePort
[root@k8s-master k8s]# kubectl apply -f django-blog.yaml
deployment.apps/django-blog created
service/django-blog created
[root@k8s-master k8s]# kubectl get pod,deployment,services -n blog
NAME READY STATUS RESTARTS AGE
pod/django-blog-6f968c98f7-2kbrc 1/1 Running 0 33s
pod/django-blog-6f968c98f7-47sgk 1/1 Running 0 33s
pod/django-blog-6f968c98f7-5fdqb 1/1 Running 0 33s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/django-blog 3/3 3 3 34s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/django-blog NodePort 10.104.63.83 <none> 80:31243/TCP 34s
查看Endpoints
[root@k8s-master k8s]# kubectl get endpoints -n blog
NAME ENDPOINTS AGE
django-blog 10.244.58.193:8080,10.244.58.200:8080,10.244.85.214:8080 103s
在上述结果中:Deployment管理三个pod;service通过nodeport类型对外提供服务,监听端口31243,并将流量转发到pod的8080端口。
6、应用升级
当源代码新增功能或修复bug时,需要重新构建镜像并将其更新到kubernetes集群中。有以下两种常见的升级应用版本的方法:
1、修改资源文件,将Deployment资源中的image字段修改为新的镜像地址,然后使用kubectl apply -f 资源文件.yaml命令将更新后的配置应用到集群中
2、使用kubectl set images命令更新Deployment资源的镜像地址,更加便捷且面交互。该命令如下
kubectl set image 资源类型/资源名称 容器名称=镜像地址
无论采用哪种方式,一旦执行成功,kubernetes就会自动触发滚动更新,逐步替换旧版本的pod,以保障应用程序在升级过程中的可用性
假设将源代码文件 django-web-demo/templates/base.html中的当前版本v1修改为当前版本v2,然后重新构建镜像,将镜像地址设置为 lizhenliang/django-blog:v2,并将其推送到docker hub镜像仓库中
[root@k8s-master django-web-demo]# kubectl set image deployment/django-blog web=uhub.service.ucloud.cn/librarys/django-blog:v2 -n blog
deployment.apps/django-blog image updated
实时监控滚动更新过程
[root@k8s-master django-web-demo]# kubectl rollout status deployment/django-blog -n blog
Waiting for deployment "django-blog" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "django-blog" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "django-blog" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "django-blog" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "django-blog" rollout to finish: 1 old replicas are pending termination...
deployment "django-blog" successfully rolled out
升级完成后将输出deployment "django-blog" successfully rolled out。在浏览中访问http://172.16.99.71:30189时,会看到博客首页,右上角显示“当前版本:v2”,说明升级成功
可以看到deployment对象了解升级进度
[root@k8s-master django-web-demo]# kubectl get deployment django-blog -n blog
NAME READY UP-TO-DATE AVAILABLE AGE
django-blog 3/3 3 3 3h45m
READY:准备就绪的Pod数量,这里值为3/3,斜杠/左侧表示3个Pod已准备就绪,斜杠/右侧表示期望3个pod
UP-TO-DATE:最新版本的pod数量。在升级期间,该字段会逐渐增加,直到与期望副本数量相等,表示升级完成。
AVAILABLE:可用的pod数量