Skip to main content

k8s实验四 实现自动部署

前几个实验都是创建 N 个 Pod 运行,如果出现 Pod 炸了,或 Pod 中的程序要升级等,就要手动关闭旧的 Pod,再启用新的 Pod。k8s 的 deployment 将解决此类应用升级、自动重启等在更新上的问题。

本实验将创建一个 deployment,运行 2 个 Nginx(1.19.0) Pod。

如果是用 docker 实现

k8s deployment 类似 docker service,调度容器的工具。

创建 docker 服务

docker service create --name mynginx --replicas 2 nginx:1.19.0

执行后,docker 会创建一个名为 mynginx 的服务,里面跑 2 个容器,统一运行 nginx:1.19.0 镜像。

模拟服务中的容器崩溃

docker 会尽量维护这个服务,用 docker service ls 可以查看,其中 REPLICAS 可以看到当前有多少个容器在运行。

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
a8a0l1p0ijej        mynginx             replicated          2/2                 nginx:1.19.0        

现在强制关掉其中一个容器,模拟这个容器突然出故障炸了。

# 查找关键字 mynginx 的容器,用 head 取第一行,用 awk 取第一列,最后结果即其中一个容器ID
docker rm -f $(docker ps | grep mynginx | head -n 1 | awk '{ print $1 }')

然后再用 docker service ls 查看结果,REPLICAS 变为 1/2,等待约10秒后,再次查看结果,REPLICAS 恢复为 2/2,表示 service 自动新建了一个满足条件的 nginx 容器继续运行。

移除 docker service

服务移除后,相应的容器会逐个删除。

docker service rm mynginx

接下来配置 k8s。

创建 Deployment,维护2个 Nginx Pod

deployment.yaml
# Source: deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: example4deploy
spec:
  selector:
    matchLabels:
      app: example4app
  replicas: 2
  template:
    metadata:
      labels:
        app: example4app
        customlabel: customlabelvalue
    spec:
      containers:
      - name: example4container
        image: nginx:1.19.0
        imagePullPolicy: IfNotPresent
deployment.yaml 带注释
# Source: deployment.yaml
# 配置文件的版本,app/v1
apiVersion: apps/v1
# 资源类型
kind: Deployment
# 元数据
metadata:
  # 名称
  name: example4deploy
# 描述
spec:
  # 标签符合要求的 Pod 会被 deployment 调度管理
  selector:
    # 固定格式
    matchLabels:
      # 带有标签 app: example4app 的 Pod 会被调度
      app: example4app
  # 最多自动创建 2个 Pod
  replicas: 2
  # Pod 模板
  template:
    # Pod 元数据
    metadata:
      # Pod 标签
      labels:
        # Pod 自定义标签 app: example4app
        app: example4app
        # Pod 自定义标签 customlabel: customlabelvalue
        customlabel: customlabelvalue
    # Pod 描述
    spec:
      # Pod 运行的容器
      containers:
          # 容器名称
        - name: example4container
          # 容器镜像
          image: nginx:1.19.0
          # 镜像拉取策略
          imagePullPolicy: IfNotPresent

详细字段说明

  • apiVersion 解析配置文件的版本,app/v1
  • kind 资源类型。
  • metadata Deployment 元数据。
  • name Deployment 名称。
  • spec Deployment 参数。
  • spec.selector Deployment 对 Pod 的选择器。
  • spec.selector.matchLabels Deployment 寻找满足标签的 Pod 划到自己的调度范围。
  • spec.selector.matchLabels.app Deployment 标签 app,这个是可以自定义的。
  • spec.replicas 要求符合条件下,最多创建2个 Pod 并维护。
  • spec.template 批量创建 Pod 的模板。
  • spec.template.metadata Pod 模板元数据。
  • spec.template.metadata.labels Pod 模板定义的标签,这个标签必须满足上面 Deployment 要求的 spec.selector.matchLabels,不满足会报错不允许部署,可以在满足的条件下额外增加自定义标签。
  • spec.template.metadata.spec Pod 模板参数。
  • spec.template.metadata.spec Pod 模板参数。
  • spec.template.metadata.spec.containers Pod 模板容器定义。
  • spec.template.metadata.spec.containers.name Pod 模板运行的容器名。
  • spec.template.metadata.spec.containers.image Pod 模板运行的容器镜像。
  • spec.template.metadata.spec.containers.imagePullPolicy Pod 模板镜像拉取策略。

配置文件写好后,执行 kubectl apply 部署。

kubectl apply -f deployment.yaml

检查运行状态

查看 deployment 状态

kubectl get deploy
kubectl get deployment

查看 deployment 的描述

kubectl describe deploy

查看自动部署的 Pod

kubectl get pods

模拟其中一个 Pod 出现故障

删掉其中一个 Pod,并即时查看 Pod 状态。

# 拿其中一个 pod
POD=$(kubectl get pod | grep example4deploy | head -n 1 | awk '{ print $1 }')
# 在后台删除,并同时查看 Pod 列表
kubectl delete pod $POD & kubectl get pods

同时查看 Pod 列表可以看到被删除的 Pod 进入 Terminating 状态,并立即出现一个新的 Pod 运行 Nginx。

让部署的 Pod 更新或重新运行

简单的重启场合

其实就是把 deployment 删掉再重新 apply 而已,不推荐的做法。

kubectl delete deploy example4deploy
kubectl apply -f deployment.yaml

直接 apply 新版本的配置文件

注意 # 号的标记:

改动过的 deployment.yaml 请注意注释部分
# Source: deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: example4deploy
spec:
  selector:
    matchLabels:
      app: example4app
  replicas: 2
  template:
    metadata:
      labels:
        app: example4app
        customlabel: customlabelvalue
    spec:
      containers:
      - name: example4container
        image: nginx:1.19.1 # 这里从 1.19.0 改为 1.19.1
        imagePullPolicy: IfNotPresent

编写好后,先检查现有的 Pod 的 Nginx 版本。

# 抽其中一个 Pod 运行 nginx -v
kubectl exec $(kubectl get pods | grep example4deploy | head -n 1 | awk '{ print $1 }') -- nginx -v
# 结果: nginx version: nginx/1.19.0

然后 apply (kubectl apply -f deployment.yaml),然后用 kubectl get pods 会看到旧的 Pod 陆续停止。直到所有的 Pod 进入 Running 后,再抽其中一个 Pod 检查 Nginx 版本。

kubectl exec $(kubectl get pods | grep example4deploy | head -n 1 | awk '{ print $1 }') -- nginx -v
# 结果: nginx version: nginx/1.19.1

清理部署资源

本实验部署了 1个 Deployment,删除 Deployment 后,Pod 会自动删除。

kubectl delete deploy example4deploy