Deployment

Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的RC来方便管理应用。

经典场景包括:

  • 定义Deployment来创建Pod和RS
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment

资源清单

d.yml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: d-demo
    namespace: default
spec:
    replicas: 3
    selector:
        matchLabels:
          tier: demo
    template:
        metadata:
            labels:
                tier: demo
        spec:
            containers:
            - name: pod-demo
              image: busybox
              command: ["/bin/sh", "-c", "sleep 3600"]
              lifecycle:
                  postStart:
                      exec:
                          command: ["/bin/sh", "-c", "wget 10.0.0.115:5000/start"]
                  preStop:
                      exec:
                          command: ["/bin/sh", "-c", "wget 10.0.0.115:5000/stop"]

创建Deployment会对应创建RS,运行结果如下图所示

从0开始搞K8S:控制器 Deployment_Deployment


Deplyment扩容缩容

使用kubectl scale来实现扩容缩容功能

kubectl scale deployment d-demo --replicas=2

从0开始搞K8S:控制器 Deployment_Deployment_02

缩减为2副本后,可以看到其中一个pod处于Terminating状态。

相应的RS的副本数也会发生变化

从0开始搞K8S:控制器 Deployment_Deployment_03

扩容同理。

deplyment更新

为了更好地演示Deployment的更新,这里引入一个容器的两个版本。

Dockerfile如下:

V1

FROM python
WORKDIR /app
RUN pip3 --no-cache-dir install -i https://mirrors.aliyun.com/pypi/simple/ flask
COPY app.py /app/app.py
EXPOSE 5000
ENTRYPOINT ["python3", "app.py"]

app.py

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/', methods=['GET'])
def stop_endpoint():
    name = request.args.get('name', None)  # 从 URL 查询字符串中获取 name 参数

    # 返回响应
    return jsonify({'version': 'v1'})

if __name__ == '__main__':
    app.run("0.0.0.0", debug=True)  # 在开发模式下运行 Flask 应用

构建镜像

docker build -t pyapp:v1 .

V2

dockerfile保持一致,不同的是app.py

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/', methods=['GET'])
def stop_endpoint():
    name = request.args.get('name', None)  # 从 URL 查询字符串中获取 name 参数

    # 返回响应
    return jsonify({'version': 'v2'})

if __name__ == '__main__':
    app.run("0.0.0.0", debug=True)  # 在开发模式下运行 Flask 应用

构建镜像

docker build -t pyapp:v2 .

将镜像推送到自建harbor

# 复习一下推送镜像到自定义harbor
# 登录自定义harbor
docker login harbor.tangotz.com
# 给本地镜像打上包含自定义仓库的标签
docker tag pyapp:v1 harbor.tangotz.com/http/pyapp:v1
docker tag pyapp:v2 harbor.tangotz.com/http/pyapp:v2
# push镜像
docker push harbor.tangotz.com/http/pyapp:v1
docker push harbor.tangotz.com/http/pyapp:v

从0开始搞K8S:控制器 Deployment_Deployment_04

构建v1版本deplyment

资源清单文件py.yml

apiVersion: apps/v1
kind: Deployment
metadata:
    name: pyapp-deploy
spec:
    replicas: 3
    selector:
        matchLabels:
            app: pyapp
    template:
        metadata:
            labels:
                app: pyapp
        spec:
            containers:
            - name: pyapp-pod
              image: harbor.tangotz.com/http/pyapp:v1
              ports:
              - containerPort: 5000

构建deployment

kubectl apply -f py.yml

查看具体详情

 kubectl get pods -o=wide| grep pyapp

从0开始搞K8S:控制器 Deployment_Deployment_05

访问其中一个节点的5000端口,可以得到如下返回

从0开始搞K8S:控制器 Deployment_Deployment_06

更新鏡像

kubectl set image deployment/pyapp-deploy pyapp-pod=harbor.tangotz.com/http/pyapp:v2

此时观察RS可以看到,一个新的RS被创建,并且拉起相应的Pos

从0开始搞K8S:控制器 Deployment_Deployment_07

此时在访问pod 节点对应的端口可以得到如下返回

从0开始搞K8S:控制器 Deployment_Deployment_08

可以看到返回内容随着镜像变化而变化。

回滚

kubectl rollout  undo deployment/pyapp-deploy

镜像变为V1版本

从0开始搞K8S:控制器 Deployment_Deployment_09