前面我们部署成功了kubernetes的集群,接着我们要学会如何使用它部署个应用以及如何编写资源清单。
一、部署应用
1.服务高可用
我们现在来部署个nginx应用来快速验证Kubernetes的高可用效果。
可以使用如下的YAML定义(假设你有相应的镜像):
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: docker.m.daocloud.io/nginx:1.25.0ports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80type: NodePort
应用配置生效:
kubectl apply -f nginx.yamlkubectl get services
接下来,访问任意node节点IP+端口号都可以访问nginx服务了!例如:
http://172.16.68.70:31083
http://172.16.68.71:31083
http://172.16.68.72:31083
体现了k8s集群的高可用性!
2.版本无缝升级
首先通过以下各种途径查看应用服务的版本
# 通过deployment查看镜像版本
kubectl describe deployment nginx-deployment
# 通过pod查看镜像版本
kubectl describe pod <pod-name>
# 通过命令查看镜像版本
kubectl get pods -l app=nginx -o jsonpath="{.items[*].spec.containers[*].image}"
# 进入一个正在运行的Nginx Pod内部,然后执行命令来查看Nginx版本
kubectl exec -it <pod-name> -- /usr/sbin/nginx -v
修改YAML文件中镜像的版本号,例如,vi nginx.yaml
后再使应用生效
spec:containers:- name: nginximage: docker.m.daocloud.io/nginx:1.25.1
使应用生效:
kubectl apply -f nginx.yaml
可以看到,k8s会逐步创建并替换容器,实现版本无缝升级,不影响业务。
最后发现软件版本升级成功!
3.版本回滚
类似于版本升级,虽然直接修改YAML文件中的镜像版本然后重新应用是一种方法,但在Kubernetes中回滚Deployment通常不需要手动更改YAML文件。
Kubernetes提供了内置的命令来帮助你轻松地进行回滚操作,这种方法更加高效且不易出错。
首先,查看您的Deployment的历史修订版本,以确定要回滚到哪个版本:
kubectl rollout history deployment/nginx-deployment
这将列出所有修订版本以及它们的变更记录。如果您想查看更多关于特定修订的信息,可以使用:
kubectl rollout history deployment/nginx-deployment --revision=<REVISION_NUMBER>
一旦确定了要回滚到的修订版本,你可以执行回滚操作。如果想要回滚到最近的一个修订版本,可以直接运行:
kubectl rollout undo deployment/nginx-deployment
如果你需要回滚到特定的修订版本,可以指定–to-revision参数:
kubectl rollout undo deployment/nginx-deployment --to-revision=<REVISION_NUMBER>
这里我直接回滚到上一个版本。
可以看到,回滚操作的执行速度是很快的!因为版本升级时,上一个版本的pod其实没有被删除,只用再启动运行就可以了。不像版本升级时,还需要去拉取镜像比较耗时。
二、编写资源清单
前面可以体会到K8S是通过格式为yaml文件的资源清单进行控制的。
K8S将所有的内容都抽象为资源,资源实例化之后,叫做对象。
Kuberbetes中存在哪些资源?
- 名称空间级别(作用域在名称空间内)
- 工作负载资源:pod,ReplicaSet,Deployment…
- 服务发现及负载均衡型资源:Service,Ingress…
- 配置与存储型资源:Volume,CSI…
- 特殊类型的存储卷:ConfigMap,Secert…
- 集群级资源(作用域在集群)
- Namespace,Node,ClusterRole,ClusterRoleBinding(集群 角色绑定)
- 元数据型资源(不能独立存在,必须依附在别的容器之上)
- HPA,PordTemplate,LimitRange
(一)初步认识
1. 关键字的基础概念
首先,理解几个基本概念:
-
apiVersion
: 定义你所使用的API版本。 -
kind
: 指定你要创建的资源类型,如Pod, Service, Deployment等。 -
metadata
: 包含资源的元数据,比如名称、命名空间和标签。 -
spec
: 资源的具体配置,描述了你希望集群达到的状态。
2.创建一个简单的Pod YAML文件
这是一个最基础的Pod YAML文件示例:
apiVersion: v1
kind: Pod
metadata:name: my-first-podlabels:app: nginx
spec:containers:- name: nginx-containerimage: nginx:latestports:- containerPort: 80
解释:
apiVersion
: 使用v1因为这是核心API组的一部分。kind
: 这里我们定义了一个Pod资源。metadata
: 给Pod命名为my-first-pod,并添加了一个标签app: nginx来标识它。spec
: 定义容器列表,这里只有一个容器,名为nginx-container,使用的是nginx:latest镜像,并暴露了80端口。
3. 扩展:添加Service资源
为了让Pod可访问,我们需要为其创建一个Service:
apiVersion: v1
kind: Service
metadata:name: my-service
spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 80
这个Service通过标签选择器app: nginx找到我们的Pod,并将其暴露在集群内部的80端口上。
4. 高级:使用Deployment管理Pod
为了更好地管理Pod的生命周期,我们可以使用Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80
这个Deployment会确保始终有3个副本的Nginx Pod运行。如果某个Pod失败或被删除,Deployment控制器会自动重新创建一个新的Pod来替换它。
(二)常用命令
1.关键字查看
有时候我们不懂各个概念是什么意思,或者资源清单应该怎么写,可以通过kubectl explain
来解释各个关键字的意思以及资源清单的格式。
例如:
kubectl explain pod
可以嵌套查询字段内部的描述,例如:
# 查看 kubernetes 官方描述文档
kubectl explain pod.spec.containers# 查看kuberbetes标签类型, k:v映射的类型---字典
kubectl explain pod.metadata.labels
2.获取资源列表
进行查看资源列表
kubectl get 资源类型 对象名# kubectl get 资源类型
-n default # 指定名字空间,默认即为 default 空间
-o wide # 显示详细参数,比如分配的节点以及地址
-A、--all-namespaces # 显示当前资源在所有名称空间中拥有的对象
-w watch # 将当前资源的变化内容进行显示
--show-labels # 查看当前资源对象的标签
-l key、key=values # 根据资源对象的标签 匹配成功后打印匹配结果
获取所有命名空间中的所有 Pods:
kubectl get pods --all-namespaces
获取特定命名空间中的 Services 列表:
kubectl get services <namespace-name>
获取所有资源的详细信息:
kubectl get all -n <namespace-name>
3.查看资源详情
查看资源对象的运行信息,比如事件:
kubectl describe 资源类型 对象名
查看 Pod 的详细信息(包括事件):
kubectl describe pod <pod-name> -n <namespace-name>
查看 Deployment 的详细信息:
kubectl describe deployment <deployment-name> -n <namespace-name>
查看详细描述信息并输出
$ kubectl get pod pod-demo -o yaml # 以yaml格式输出
$ kubectl get pod pod-demo -o json # 以json格式输出
4.创建资源对象
读取配置文件(如 YAML、JSON 文件)来创建资源。
如果尝试使用 create 创建一个已存在的资源,则操作会失败并返回错误。
kubectl create -f xxx.yaml \ xxx.json
读取配置文件(如 YAML 文件)来创建或更新资源。
支持对现有资源进行部分更新,即不需要重新定义整个对象的所有字段。
kubectl apply -f xxx.yaml \ xxx.json
5.删除资源对象
删除由 YAML 文件定义的资源:
kubectl delete -f <yaml-file-path>
删除pod资源类型
kubectl delete pod <pod-name> -n <namespace-name>
删除所有pod资源
kubectl delete pod --all
删除svc资源类型
kubectl delete svc 资源名称
6.查看日志信息
查看特定 Pod 的日志:
kubectl logs <pod-name> -n <namespace-name>
查看当前 pod 内部指定容器的日志信息:
kubectl logs podName -c containerName
实时跟踪 Pod 日志(类似 tail -f):
kubectl logs -f <pod-name> -n <namespace-name>
7.进入容器
在 Pod 中运行一个一次性命令:
kubectl exec <pod-name> -n <namespace-name> -- <command>
让 pod 内部对应的 container 执行命令
kubectl exec -it podName -c containerName -- command
使用kubectl进入容器
kubectl exec -it pod-demo -c nginx-1 -- /bin/sh
# name -c 指定容器名 如果是此项目只有一个容器运行,则不需指定容器
8.查看配置信息
查看上下文和当前使用的集群:
kubectl config current-context
查看所有的上下文和用户配置:
kubectl config view
(三)关键字字段
1.apiVersion
apiVersion意思是接口组版本,由组/版本
通过斜杠隔开,前面代表组,后面代表版本号。其中v1版本,其实是core/v1接口组版本,只是把core省略掉了。
资源清单中需要指定使用的API版本。不同的Kubernetes资源可能需要不同的API版本。
根据你要创建的资源类型选择正确的API版本。例如,对于Pod、Service等核心资源,通常使用v1;而对于Deployment、StatefulSet等则可能需要apps/v1。
# 查看版本号
kubectl api-versions
2. kind
kind意思是资源类别,资源清单中需要定义你想要创建的资源类型。例如,Pod、Service、Deployment等。
# 查看资源类别
kubectl api-resources
3. metadata
metadata意思是元数据,也就是信息的信息。用来描述某个资源的信息。它包含资源的元数据信息,如名称、标签、注解等。
编写规范:
- name: 资源的名称,必须是唯一的。
- namespace: (可选)资源所属的命名空间,默认为default。
- labels: (可选)键值对形式的标签,用于标识资源。
- annotations: (可选)键值对形式的注解,可以用来记录额外的信息。
下面给个填写metadata
比较齐全的示例:
apiVersion: v1 # API 版本
kind: Pod # 资源类型,这里以Pod为例
metadata:name: example-pod # 资源的名字,必须是唯一的,在其命名空间内namespace: default # 资源所在的命名空间,默认为"default"labels: # 键值对形式的标签,用于分类和选择资源app: web # 标签键值对,表示应用类型为webtier: frontend # 另一个标签键值对,表示层级为前端annotations: # 注解,提供额外信息,但不会被Kubernetes直接使用description: "This is an example pod for demonstration." # 描述信息buildVersion: "v1.0.0" # 构建版本号uid: 59e2a8f3-f6d7-4b9c-b6a2-8fbc8def67c2 # 系统自动生成的唯一标识符generation: 1 # 表示资源定义的版本,每次修改会增加creationTimestamp: "2025-04-14T21:11:00Z" # 资源创建的时间戳deletionTimestamp: null # 当删除资源被计划时设置,表示实际删除资源的时间ownerReferences: # 引用该资源的所有者,有助于级联删除- apiVersion: apps/v1kind: ReplicaSetname: example-replicasetuid: d7e2a8f3-f6d7-4b9c-b6a2-8fbc8def67c2controller: truefinalizers: # 在资源被删除前需要完成的任务列表- example-finalizergenerateName: "" # 如果设置了此字段,则Kubernetes将基于这个前缀生成名称selfLink: /api/v1/namespaces/default/pods/example-pod # 自我链接,指向当前资源
4. spec
spec意思是期望, 描述资源的具体规格和期望状态。
编写规范: 这一部分的内容根据不同的资源类型而变化。例如:
- 对于Pod,spec包含容器的定义(如镜像名称、端口等)。
- 对于Service,spec描述服务如何访问Pod,包括选择器、端口映射等。
- 对于Deployment,spec除了包含Pod模板外,还包括副本数、更新策略等。
pod示例:
apiVersion: v1 # API版本
kind: Pod # 资源类型
metadata:name: example-pod # Pod名称labels: # 标签用于选择和分类Podapp: web
spec:containers: # 定义容器列表- name: nginx-container # 容器名称image: nginx:latest # 使用的镜像ports: # 容器端口配置- containerPort: 80 # 容器暴露的端口env: # 环境变量- name: ENV_NAME # 环境变量名value: "env_value" # 环境变量值volumeMounts: # 挂载卷到容器内- name: html-volume # 对应volumes定义的名字mountPath: /usr/share/nginx/html # 在容器内的挂载路径volumes: # 卷列表- name: html-volume # 卷名称configMap: # 使用ConfigMap作为数据卷name: example-configmap # ConfigMap名称restartPolicy: Always # 重启策略:Always, OnFailure, Never
Deployment 示例:
apiVersion: apps/v1 # API版本
kind: Deployment # 资源类型
metadata:name: example-deployment # Deployment名称
spec:replicas: 3 # 副本数,即期望运行的Pod数量selector: # 标签选择器,必须匹配template中的标签matchLabels:app: webtemplate: # Pod模板metadata:labels: # Pod模板的标签app: webspec:containers: # 定义容器列表- name: nginx-container # 容器名称image: nginx:latest # 使用的镜像ports: # 容器端口配置- containerPort: 80 # 容器暴露的端口env: # 环境变量- name: ENV_NAME # 环境变量名value: "env_value" # 环境变量值volumeMounts: # 挂载卷到容器内- name: html-volume # 对应volumes定义的名字mountPath: /usr/share/nginx/html # 在容器内的挂载路径volumes: # 卷列表- name: html-volume # 卷名称configMap: # 使用ConfigMap作为数据卷name: example-configmap # ConfigMap名称strategy: # 更新策略type: RollingUpdate # 更新方式:Recreate或RollingUpdaterollingUpdate: # 滚动更新相关参数maxUnavailable: 1 # 最大不可用Pod数maxSurge: 1 # 最大超出期望Pod数
5.status
status表示当前的状态,有了期望之后,实际状态是怎样的由系统本身进行维护的,无法被定义。