分享:一文搞清楚应用发布到k8s集群的基本流程

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 分享:一文搞清楚应用发布到k8s集群的基本流程

1. 使用yaml文件创建资源对象

每种资源的apiVersion和kind可通过 kubectl api-resources 命令进行查看

tantianran@test-b-k8s-master:~$ kubectl api-resources | grep Deployment
deployments                       deploy       apps/v1                                true         Deployment
tantianran@test-b-k8s-master:~$

goweb-demo.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: test-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 10
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3
---
apiVersion: v1
kind: Service
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb-demo
  type: NodePort

关于标签的主要作用:标记、过滤、关联(主要体现在deployment、pod、service,3者标签保持一致),可设定多个标签,建议设定至少2个标签,一个为项目标签,一个为应用标签。

  • 关于创建、更新和删除的命令
# 只用于创建
kubectl create -f xxx.yaml
# 创建和更新(需要yaml文件里的字段支持更新,并不是所有字段都支持更新)
kubectl apply -f xxx.yaml
# 卸载
kubectl delete -f xxx.yaml

2. 编写yaml的套路分享

  • 套路1:可以直接手写,但容易出错
  • 套路2:参考官方示例,然后改成自己的
  • 套路3:通过命令行来获取,也是有2个方式,一是利用尝试运行(--dry-run)的机制再配合-o来输出一个yaml文件),二是通过get来得到yaml文件,得到yaml文件后再自行修改

下面演示通过create来得到yaml

# 在kubectl级别上进行验证
kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=client
# 指的是提交到apiserver进行验证
kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=server
# 下面来一个deployment的例子,得到其他资源的yaml也是这个套路
tantianran@test-b-k8s-master:~$ kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 5
  selector:
    matchLabels:
      app: web1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}
# 还可以配合重定向输出到yaml文件
kubectl create deployment web1 --image=nginx --replicas=5 --dry-run=client -o yaml > test.yaml

下面演示通过get命令来得到yaml文件,使用-o来指定yaml的格式输出,其他资源也是这个套路

kubectl get pods -n test-a -o yaml

编写yaml的时候,字段名太多记不住或者想不起来怎么办?可以使用explain来查看字段层级

# 找第一级
kubectl explain deployment
# 找第二级
kubectl explain deployment.spec
# 再比如查pod相关的
kubectl explain pods.spec.containers

3. 应用生命周期管理

deployment是最常用的k8s工作负载控制器(Workload Controllers),是k8s的一个抽象概念,用于更高级层次对象,部署和管理Pod,卡控制器还有DaemonSet、StatefulSet等。

3.1 Deployment

「Deployment主要功能:」

  • 管理Pod和ReplicaSet
  • 具有上线部署、副本设定、滚动升级、回滚等功能

「Deployment应用场景:」 网站、API、微服务

「Pod与控制器的关系图:」

「应用生命周期管理流程:」

3.2 应用部署的基本流程

部署->升级->回滚->删除

3.2.1 部署

# 推荐的方式
kubectl apply -f xxx.yaml
# 或者
kubectl create deployment web --image=nginx --replicas=3

在本示例中,部署的是我自己使用go语言写的一个很简单的web demo

访问一下看看

3.2.2 升级

所谓的升级,其实就是更新镜像,且有3种方式,自动触发滚动升级

# 方式1:直接修改yaml文件中的镜像,然后apply
kubectl apply -f xxx.yaml
# 方式2:使用命令设置deployment使用的镜像
kubectl set image deployment/web nginx=nginx1.17
# 使用系统编辑器打开进行编辑
kubectl edit deployment

「发布方式有3种:」 滚动发布、蓝绿发布、灰度发布(金丝雀、A/B测试、冒烟测试。灰度发布是最复杂的方式,发布的方式是为了避免上线后出现的问题。)

「K8S默认是滚动升级:」 滚动发布是指每次只升级一个或多个服务,升级完成后加入生产环境,不断执行这个过程,直到集群中的全部旧版本升级新版本。

「滚动升级在k8s中的实现:」 它是通过1个Deployment和2个ReplicaSet来实现的,滚动更新一次只升级一小部分pod,成功后,再升级一部分pod,最终完成所有Pod升级,整个过程始终有Pod在运行,从而保证了业务的连续性。

「ReplicaSet:」 副本集,主要维护Pod副本数量,不断对比当前Pod数量于期望Pod数量。「ReplicaSet用途:」 Deployment每次发布都会创建一个RS(ReplicaSet的缩写)作为记录,用于实现滚动升级和回滚

可以查看deployment的详情,详情里其实是记录了升级的过程

kubectl get deployment -n test-a
kubectl describe deployment goweb-demo -n test-a

查看ReplicaSet(RS)记录(初次的部署和后续升级都会新创建一个RS,升级多少次就会创建多少个)

tantianran@test-b-k8s-master:~$ kubectl get rs -n test-a
NAME                    DESIRED   CURRENT   READY   AGE
goweb-demo-6fbb74fdbb   0         0         0       41m
goweb-demo-7b6649f789   20        20        20      32m # 此处DESIRED和CURRENT以及READY字段有值的话,表示是当前正在使用的RS
goweb-demo-8665796599   0         0         0       24h
# 查看正在使用的RS的详情
kubectl describe rs goweb-demo-7b6649f789 -n test-a

注意:升级后,旧的RS会被保留,主要用于后面回滚使用,且每次只能有一个RS在使用。

「当新版的镜像已经做好需要滚动更新的时候,那就要修改deployment中指定的镜像,修改的方式有2种:使用命令和直接修改yaml文件」方式1:使用命令

# 命令格式
kubectl set image deployment <DeploymentName> <ContainerName>=<Image> -n <Namespace>
# 例子
# step 1:获取deployment
kubectl get deployment -n test-a
# step 2:查看deployment详情
kubectl describe deployment goweb-demo -n test-a
...
Pod Template:
  Labels:  app=goweb-demo
  Containers:
   goweb-demo: # 容器名字
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3 # 镜像
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
...
# step 3:设置deployment的镜像
kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v3 -n test-a

方式2:直接修改yaml(推荐)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo # deployment名称
  namespace: test-a
spec:
  replicas: 50 # 副本
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3 # 镜像

「水平扩缩容,也就是修改副本的数量,也有2种方式,命令和修改yaml文件」方式1:命令

kubectl scale deployment goweb-demo --replicas=5 -n test-a

方式2:修改yaml文件中的replicas参数,再apply

apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 5 #修改副本数量
...
...

3.2.3 回滚

当应用发布失败,需要回滚时。

查看发过有哪些版本

# 查看历史
kubectl rollout history deployment -n test-a
deployment.apps/goweb-demo 
REVISION  CHANGE-CAUSE
4         <none>
6         <none>
8         <none>
9         <none>
# 通过命令修改deployment的镜像进行升级时,后面加--record参数,再查看历史后就会记录这条命令
kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v2 -n test-a --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/goweb-demo image updated
# 上面加了--record参数,再查看历史,可以看到记录的这条命令
kubectl rollout history deployment -n test-a
deployment.apps/goweb-demo 
REVISION  CHANGE-CAUSE
4         <none>
6         <none>
9         <none>
10        kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v2 --namespace=test-a --record=true # 就是这里

查看版本号和RS的对应关系,以及和镜像的对应关系

# 查看RS
tantianran@test-b-k8s-master:~$ kubectl get rs -n test-a
NAME                    DESIRED   CURRENT   READY   AGE
goweb-demo-6fbb74fdbb   0         0         0       5h15m
goweb-demo-7b6649f789   0         0         0       5h6m
goweb-demo-8665796599   0         0         0       29h
goweb-demo-b98869456    5         5         5       4h22m # 当前使用的RS
# 查看当前使用的RS详情
tantianran@test-b-k8s-master:~$ kubectl describe rs goweb-demo-b98869456 -n test-a
...
Annotations:    deployment.kubernetes.io/desired-replicas: 5
                deployment.kubernetes.io/max-replicas: 7
                deployment.kubernetes.io/revision: 11 # 这个11就是当前版本号
                deployment.kubernetes.io/revision-history: 7,9 # 历史版本
                kubernetes.io/change-cause:
                  kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v3 --namespace=test-a --record=true
Controlled By:  Deployment/goweb-demo
Replicas:       5 current / 5 desired
Pods Status:    5 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=goweb-demo
           pod-template-hash=b98869456
  Containers:
   goweb-demo:
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3 # 使用的镜像
    Port:         <none>
    Host Port:    <none>
...
# 查看历史版本
tantianran@test-b-k8s-master:~$ kubectl rollout history deployment -n test-a
deployment.apps/goweb-demo 
REVISION  CHANGE-CAUSE
4         <none>
6         <none>
10        kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v2 --namespace=test-a --record=true
11        kubectl set image deployment goweb-demo goweb-demo=192.168.11.247/web-demo/goweb-demo:20221229v3 --namespace=test-a --record=true # 这个REVISION是11

通过过滤来获取到发布版本和对应的镜像

# 过滤revision和Image
tantianran@test-b-k8s-master:~$ kubectl describe $(kubectl get rs -o name -n test-a | grep "goweb-") -n test-a | grep -E "revision:|Image:"
                deployment.kubernetes.io/revision: 4
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v1
                deployment.kubernetes.io/revision: 10
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v2
                deployment.kubernetes.io/revision: 6
    Image:        192.168.11.247/web-demo/goweb-demo:20221228v1
                deployment.kubernetes.io/revision: 11
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3
tantianran@test-b-k8s-master:~$ 
# 过滤更详细的,过滤revision、Image、Name、Replicas
tantianran@test-b-k8s-master:~$ kubectl describe $(kubectl get rs -o name -n test-a | grep "goweb-") -n test-a | grep -E "revision:|Image:|Name:|Replicas:"
Name:           goweb-demo-6fbb74fdbb
                deployment.kubernetes.io/revision: 4
Replicas:       0 current / 0 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v1
Name:           goweb-demo-7b6649f789
                deployment.kubernetes.io/revision: 10
Replicas:       0 current / 0 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v2
Name:           goweb-demo-8665796599
                deployment.kubernetes.io/revision: 6
Replicas:       0 current / 0 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221228v1
Name:           goweb-demo-b98869456
                deployment.kubernetes.io/revision: 11
Replicas:       5 current / 5 desired
    Image:        192.168.11.247/web-demo/goweb-demo:20221229v3

只回滚到上一个版本

tantianran@test-b-k8s-master:~$ kubectl rollout undo deployment goweb-demo -n test-a
deployment.apps/goweb-demo rolled back

回滚到指定的历史版本

# 查看当前正在使用哪个版本
tantianran@test-b-k8s-master:~$ kubectl describe $(kubectl get rs -o name -n test-a | grep "goweb-") -n test-a | grep -E "revision:|Replicas:"
                deployment.kubernetes.io/revision: 4
Replicas:       0 current / 0 desired
                deployment.kubernetes.io/revision: 14 # 当前正在使用的版本,版本号14,且副本是5
Replicas:       5 current / 5 desired # 副本数量
                deployment.kubernetes.io/revision: 6
Replicas:       0 current / 0 desired
                deployment.kubernetes.io/revision: 13
Replicas:       0 current / 0 desired
# 假设要回滚到最初的版本,也就是版本号是4
tantianran@test-b-k8s-master:~$ kubectl rollout undo deployment goweb-demo --to-revision=4 -n test-a
deployment.apps/goweb-demo rolled back
tantianran@test-b-k8s-master:~$

3.2.4 删除(当项目需要下线时)

# 如果该项目是直接编写yaml的,可这样删除(下线)
kubectl delete -f goweb-demo.yaml
# 如果该项目的命名空间、deployment、service是用命令的,那就需要手动删除下线
kubectl delete deployment goweb-demo -n test-a
kubectl delete svc goweb-demo -n test-a
kubectl delete ns test-a

最后

如需要go开发的web demo源码的朋友可私信我,一起交流,感谢!

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
8天前
|
Kubernetes 监控 Cloud Native
云原生入门:从传统应用到容器化部署的旅程
【9月更文挑战第19天】在数字化浪潮中,企业正迅速将目光投向云原生技术,以实现更快的应用开发和更灵活的资源管理。本文将通过一个简单示例引导读者理解如何将传统应用转变为云原生应用,并部署至云端。我们将探索容器化技术的基础,以及它如何帮助企业解锁现代软件交付的速度和效率。准备好让你的应用乘上云原生的快车了吗?让我们开始这段令人兴奋的旅程吧!
|
24天前
|
存储 Kubernetes 负载均衡
CentOS 7.9二进制部署K8S 1.28.3+集群实战
本文详细介绍了在CentOS 7.9上通过二进制方式部署Kubernetes 1.28.3+集群的全过程,包括环境准备、组件安装、证书生成、高可用配置以及网络插件部署等关键步骤。
162 3
CentOS 7.9二进制部署K8S 1.28.3+集群实战
|
24天前
|
Kubernetes 负载均衡 前端开发
二进制部署Kubernetes 1.23.15版本高可用集群实战
使用二进制文件部署Kubernetes 1.23.15版本高可用集群的详细教程,涵盖了从环境准备到网络插件部署的完整流程。
50 2
二进制部署Kubernetes 1.23.15版本高可用集群实战
|
9天前
|
Kubernetes Cloud Native Linux
云原生入门:Kubernetes的简易部署与应用
【8月更文挑战第49天】在云原生的世界里,Kubernetes(K8s)是一颗璀璨的星。本文将带你走进K8s的世界,从安装到简单应用,轻松驾驭这个强大的容器编排工具。让我们一起探索云原生的奥秘,解锁新技能!
|
21天前
|
Kubernetes Docker Python
如何在K8s中使用Python应用
一文带你了解如何在K8s中使用Python应用
17 4
|
24天前
|
存储 Kubernetes 测试技术
k8s使用pvc,pv,sc关联ceph集群
文章介绍了如何在Kubernetes中使用PersistentVolumeClaim (PVC)、PersistentVolume (PV) 和StorageClass (SC) 来关联Ceph集群,包括创建Ceph镜像、配置访问密钥、删除默认存储类、编写和应用资源清单、创建资源以及进行访问测试的步骤。同时,还提供了如何使用RBD动态存储类来关联Ceph集群的指南。
45 7
|
24天前
|
存储 Kubernetes 数据安全/隐私保护
k8s对接ceph集群的分布式文件系统CephFS
文章介绍了如何在Kubernetes集群中使用CephFS作为持久化存储,包括通过secretFile和secretRef两种方式进行认证和配置。
28 5
|
24天前
|
Kubernetes 负载均衡 应用服务中间件
kubeadm快速构建K8S1.28.1高可用集群
关于如何使用kubeadm快速构建Kubernetes 1.28.1高可用集群的详细教程。
43 2
|
25天前
|
Kubernetes Linux API
CentOS 7.6使用kubeadm部署k8s 1.17.2测试集群实战篇
该博客文章详细介绍了在CentOS 7.6操作系统上使用kubeadm工具部署kubernetes 1.17.2版本的测试集群的过程,包括主机环境准备、安装Docker、配置kubelet、初始化集群、添加节点、部署网络插件以及配置k8s node节点管理api server服务器。
57 0
CentOS 7.6使用kubeadm部署k8s 1.17.2测试集群实战篇
|
9天前
|
Kubernetes Cloud Native Java
探索未来编程新纪元:Quarkus带你秒建高性能Kubernetes原生Java应用,云原生时代的技术狂欢!
Quarkus 是专为 Kubernetes 设计的全栈云原生 Java 框架,凭借其轻量级、快速启动及高效执行特性,在 Java 社区脱颖而出。通过编译时优化与原生镜像支持,Quarkus 提升了应用性能,同时保持了 Java 的熟悉度与灵活性。本文将指导你从创建项目、编写 REST 控制器到构建与部署 Kubernetes 原生镜像的全过程,让你快速上手 Quarkus,体验高效开发与部署的乐趣。
11 0