Kubernetes详细教程(三):部署应用、了解常用命令及编写资源清单

前面我们部署成功了kubernetes的集群,接着我们要学会如何使用它部署个应用以及如何编写资源清单。

一、部署应用

1.服务高可用

我们现在来部署个nginx应用来快速验证Kubernetes的高可用效果。

可以使用如下的YAML定义(假设你有相应的镜像):

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: docker.m.daocloud.io/nginx:1.25.0
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: NodePort

应用配置生效:

bash 复制代码
kubectl apply -f nginx.yaml

kubectl get services

接下来,访问任意node节点IP+端口号都可以访问nginx服务了!例如:

bash 复制代码
http://172.16.68.70:31083
http://172.16.68.71:31083
http://172.16.68.72:31083

体现了k8s集群的高可用性!

2.版本无缝升级

首先通过以下各种途径查看应用服务的版本

bash 复制代码
# 通过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后再使应用生效

yaml 复制代码
spec:
  containers:
  - name: nginx
    image: docker.m.daocloud.io/nginx:1.25.1

使应用生效:

bash 复制代码
kubectl apply -f nginx.yaml

可以看到,k8s会逐步创建并替换容器,实现版本无缝升级,不影响业务。


最后发现软件版本升级成功!

3.版本回滚

类似于版本升级,虽然直接修改YAML文件中的镜像版本然后重新应用是一种方法,但在Kubernetes中回滚Deployment通常不需要手动更改YAML文件。

Kubernetes提供了内置的命令来帮助你轻松地进行回滚操作,这种方法更加高效且不易出错。

首先,查看您的Deployment的历史修订版本,以确定要回滚到哪个版本:

bash 复制代码
kubectl rollout history deployment/nginx-deployment

这将列出所有修订版本以及它们的变更记录。如果您想查看更多关于特定修订的信息,可以使用:

bash 复制代码
kubectl rollout history deployment/nginx-deployment --revision=<REVISION_NUMBER>

一旦确定了要回滚到的修订版本,你可以执行回滚操作。如果想要回滚到最近的一个修订版本,可以直接运行:

bash 复制代码
kubectl rollout undo deployment/nginx-deployment

如果你需要回滚到特定的修订版本,可以指定--to-revision参数:

bash 复制代码
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文件示例:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: my-first-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80

解释:

  • apiVersion: 使用v1因为这是核心API组的一部分。
  • kind: 这里我们定义了一个Pod资源。
  • metadata: 给Pod命名为my-first-pod,并添加了一个标签app: nginx来标识它。
  • spec: 定义容器列表,这里只有一个容器,名为nginx-container,使用的是nginx:latest镜像,并暴露了80端口。

3. 扩展:添加Service资源

为了让Pod可访问,我们需要为其创建一个Service:

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

这个Service通过标签选择器app: nginx找到我们的Pod,并将其暴露在集群内部的80端口上。

4. 高级:使用Deployment管理Pod

为了更好地管理Pod的生命周期,我们可以使用Deployment:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

这个Deployment会确保始终有3个副本的Nginx Pod运行。如果某个Pod失败或被删除,Deployment控制器会自动重新创建一个新的Pod来替换它。

(二)常用命令

1.关键字查看

有时候我们不懂各个概念是什么意思,或者资源清单应该怎么写,可以通过kubectl explain来解释各个关键字的意思以及资源清单的格式。

例如:

bash 复制代码
kubectl explain pod

可以嵌套查询字段内部的描述,例如:

bash 复制代码
# 查看 kubernetes 官方描述文档
kubectl explain pod.spec.containers

# 查看kuberbetes标签类型, k:v映射的类型---字典
kubectl explain pod.metadata.labels

2.获取资源列表

进行查看资源列表

bash 复制代码
kubectl get 资源类型 对象名

# kubectl get 资源类型
-n default 			# 指定名字空间,默认即为 default 空间
-o wide				# 显示详细参数,比如分配的节点以及地址
-A、--all-namespaces	# 显示当前资源在所有名称空间中拥有的对象
-w watch			# 将当前资源的变化内容进行显示
--show-labels		        # 查看当前资源对象的标签
-l key、key=values	        # 根据资源对象的标签 匹配成功后打印匹配结果

获取所有命名空间中的所有 Pods:

bash 复制代码
kubectl get pods --all-namespaces

获取特定命名空间中的 Services 列表:

bash 复制代码
kubectl get services <namespace-name>

获取所有资源的详细信息:

bash 复制代码
kubectl get all -n <namespace-name>

3.查看资源详情

查看资源对象的运行信息,比如事件:

bash 复制代码
kubectl describe 资源类型 对象名

查看 Pod 的详细信息(包括事件):

bash 复制代码
kubectl describe pod <pod-name> -n <namespace-name>

查看 Deployment 的详细信息:

bash 复制代码
kubectl describe deployment <deployment-name> -n <namespace-name>

查看详细描述信息并输出

bash 复制代码
$ kubectl get pod pod-demo -o yaml   # 以yaml格式输出
$ kubectl get pod pod-demo -o json   # 以json格式输出

4.创建资源对象

读取配置文件(如 YAML、JSON 文件)来创建资源。

如果尝试使用 create 创建一个已存在的资源,则操作会失败并返回错误。

bash 复制代码
kubectl create -f xxx.yaml \ xxx.json

读取配置文件(如 YAML 文件)来创建或更新资源。

支持对现有资源进行部分更新,即不需要重新定义整个对象的所有字段。

bash 复制代码
kubectl apply -f xxx.yaml \ xxx.json

5.删除资源对象

删除由 YAML 文件定义的资源:

bash 复制代码
kubectl delete -f <yaml-file-path>

删除pod资源类型

bash 复制代码
kubectl delete pod <pod-name>  -n <namespace-name>

删除所有pod资源

bash 复制代码
kubectl delete pod --all

删除svc资源类型

bash 复制代码
kubectl delete svc 资源名称

6.查看日志信息

查看特定 Pod 的日志:

bash 复制代码
kubectl logs <pod-name> -n <namespace-name>

查看当前 pod 内部指定容器的日志信息:

bash 复制代码
kubectl logs podName -c containerName

实时跟踪 Pod 日志(类似 tail -f):

bash 复制代码
kubectl logs -f <pod-name> -n <namespace-name>

7.进入容器

在 Pod 中运行一个一次性命令:

bash 复制代码
kubectl exec <pod-name> -n <namespace-name> -- <command>

让 pod 内部对应的 container 执行命令

bash 复制代码
kubectl exec -it podName -c containerName -- command

使用kubectl进入容器

bash 复制代码
kubectl exec -it pod-demo -c nginx-1 -- /bin/sh
# name   -c 指定容器名 如果是此项目只有一个容器运行,则不需指定容器

8.查看配置信息

查看上下文和当前使用的集群:

bash 复制代码
kubectl config current-context

查看所有的上下文和用户配置:

bash 复制代码
kubectl config view

(三)关键字字段

1.apiVersion

apiVersion意思是接口组版本,由组/版本通过斜杠隔开,前面代表组,后面代表版本号。其中v1版本,其实是core/v1接口组版本,只是把core省略掉了。

资源清单中需要指定使用的API版本。不同的Kubernetes资源可能需要不同的API版本。

根据你要创建的资源类型选择正确的API版本。例如,对于Pod、Service等核心资源,通常使用v1;而对于Deployment、StatefulSet等则可能需要apps/v1。

bash 复制代码
# 查看版本号
kubectl api-versions

2. kind

kind意思是资源类别,资源清单中需要定义你想要创建的资源类型。例如,Pod、Service、Deployment等。

bash 复制代码
# 查看资源类别
kubectl api-resources

3. metadata

metadata意思是元数据,也就是信息的信息。用来描述某个资源的信息。它包含资源的元数据信息,如名称、标签、注解等。

编写规范:

  • name: 资源的名称,必须是唯一的。
  • namespace: (可选)资源所属的命名空间,默认为default。
  • labels: (可选)键值对形式的标签,用于标识资源。
  • annotations: (可选)键值对形式的注解,可以用来记录额外的信息。

下面给个填写metadata比较齐全的示例:

yaml 复制代码
apiVersion: v1  # API 版本
kind: Pod       # 资源类型,这里以Pod为例
metadata:
  name: example-pod   # 资源的名字,必须是唯一的,在其命名空间内
  namespace: default  # 资源所在的命名空间,默认为"default"
  labels:             # 键值对形式的标签,用于分类和选择资源
    app: web          # 标签键值对,表示应用类型为web
    tier: 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/v1
      kind: ReplicaSet
      name: example-replicaset
      uid: d7e2a8f3-f6d7-4b9c-b6a2-8fbc8def67c2
      controller: true
  finalizers:  # 在资源被删除前需要完成的任务列表
    - example-finalizer
  generateName: ""  # 如果设置了此字段,则Kubernetes将基于这个前缀生成名称
  selfLink: /api/v1/namespaces/default/pods/example-pod  # 自我链接,指向当前资源

4. spec

spec意思是期望, 描述资源的具体规格和期望状态。

编写规范: 这一部分的内容根据不同的资源类型而变化。例如:

  • 对于Pod,spec包含容器的定义(如镜像名称、端口等)。
  • 对于Service,spec描述服务如何访问Pod,包括选择器、端口映射等。
  • 对于Deployment,spec除了包含Pod模板外,还包括副本数、更新策略等。

pod示例:

yaml 复制代码
apiVersion: v1  # API版本
kind: Pod  # 资源类型
metadata:
  name: example-pod  # Pod名称
  labels:  # 标签用于选择和分类Pod
    app: 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 示例:

yaml 复制代码
apiVersion: apps/v1  # API版本
kind: Deployment  # 资源类型
metadata:
  name: example-deployment  # Deployment名称
spec:
  replicas: 3  # 副本数,即期望运行的Pod数量
  selector:  # 标签选择器,必须匹配template中的标签
    matchLabels:
      app: web
  template:  # Pod模板
    metadata:
      labels:  # Pod模板的标签
        app: 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名称
  strategy:  # 更新策略
    type: RollingUpdate  # 更新方式:Recreate或RollingUpdate
    rollingUpdate:  # 滚动更新相关参数
      maxUnavailable: 1  # 最大不可用Pod数
      maxSurge: 1  # 最大超出期望Pod数

5.status

status表示当前的状态,有了期望之后,实际状态是怎样的由系统本身进行维护的,无法被定义。

相关推荐
阿里云云原生1 小时前
MCP 正当时:FunctionAI MCP 开发平台来了!
云原生
慧一居士1 小时前
Kubernetes(K8S)内部功能总结
云原生·容器·kubernetes
rider1891 小时前
【4】k8s集群管理系列--harbor镜像仓库本地化搭建
云原生·容器·kubernetes
郝同学的测开笔记1 小时前
云原生探索系列(十五):Go 语言通道
后端·云原生·go
m0_731187882 小时前
docker compose搭建博客wordpress
docker·容器·eureka
锋丷2 小时前
Docker安装 (centos)
docker·容器·centos
杰瑞学AI3 小时前
Devops之GitOps:什么是Gitops,以及它有什么优势
运维·git·云原生·kubernetes·devops·argocd
AKAMAI4 小时前
GitOps实战:使用Flux新建Kubernetes集群
后端·云原生·云计算
KubeSphere 云原生5 小时前
云原生周刊:K8s 中的 GPU 共享
云原生·容器·kubernetes