一、K8s 资源体系基础

(一)核心资源架构

K8s 的本质是集群系统,用户部署服务的核心是在集群中运行容器,而容器必须承载于 Pod 之内。值得注意的是,K8s 通常不直接管理 Pod,而是通过 Deployment、DaemonSet、StatefulSet 等 Pod 控制器进行间接管理。同时,Service 资源负责实现 Pod 服务的访问,各类存储系统则保障 Pod 中程序数据的持久化,ConfigMap 和 Secret 用于配置管理,共同构成了 K8s 的资源生态。

(二)三种资源管理方式对比

K8s 提供了三种资源管理方式,适用于不同场景:

  1. 命令式对象管理:直接通过命令操作资源,如 kubectl run nginx-pod --image=nginx:latest --port=80。优点是简单直观,适合测试场景;缺点是无法审计跟踪,仅能操作活动对象。
  2. 命令式对象配置:结合命令与配置文件操作资源,如 kubectl create -f nginx-pod.yaml。支持审计跟踪,适合开发环境,但项目规模扩大后配置文件管理繁琐。
  3. 声明式对象配置:通过 kubectl apply -f 命令结合配置文件操作,支持目录级操作,适配复杂开发场景,缺点是意外情况下调试难度较大。

(三)常用 kubectl 命令速览

kubectl 是 K8s 集群的命令行工具,核心语法为 kubectl [command] [type] [name] [flags]。关键命令分类如下:

  • 基本命令create(创建)、get(查询)、edit(编辑)、delete(删除)等,用于资源的基础操作。
  • 运行和调试run(运行镜像)、logs(查看日志)、exec(执行容器命令)、cp(复制文件)等,助力应用部署与问题排查。
  • 高级命令apply(通过文件配置资源)、label(管理资源标签),适配复杂配置场景。
1.基本命令示例

kubectl的详细说明地址:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands

#显示集群版本
[root@master ~]# kubectl version
Client Version: v1.30.0
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.30.0
#显示集群信息
[root@master ~]# kubectl cluster-info
Kubernetes control plane is running at https://192.168.61.100:6443
CoreDNS is running at https://192.168.61.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
#创建一个webcluster控制器,控制器中pod数量为2
[root@master ~]# kubectl create deployment webcluseter --image nginx --replicas 2
deployment.apps/webcluseter created
#查看控制器
[root@master ~]# kubectl get  deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    3/3     3            3           69m
#查看资源帮助
[root@master ~]# kubectl explain deployment
GROUP:      apps
KIND:       Deployment
VERSION:    v1

DESCRIPTION:
    Deployment enables declarative updates for Pods and ReplicaSets.

FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata      <ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec  <DeploymentSpec>
    Specification of the desired behavior of the Deployment.

  status        <DeploymentStatus>
    Most recently observed status of the Deployment.

#查看控制器参数帮助 
[root@master ~]# kubectl explain deployment.spec
GROUP:      apps
KIND:       Deployment
VERSION:    v1

FIELD: spec <DeploymentSpec>


DESCRIPTION:
    Specification of the desired behavior of the Deployment.
    DeploymentSpec is the specification of the desired behavior of the
    Deployment.

FIELDS:
  minReadySeconds       <integer>
    Minimum number of seconds for which a newly created pod should be ready
    without any of its container crashing, for it to be considered available.
    Defaults to 0 (pod will be considered available as soon as it is ready)

  paused        <boolean>
    Indicates that the deployment is paused.

  progressDeadlineSeconds       <integer>
    The maximum time in seconds for a deployment to make progress before it is
    considered to be failed. The deployment controller will continue to process
    failed deployments and a condition with a ProgressDeadlineExceeded reason
    will be surfaced in the deployment status. Note that progress will not be
    estimated during the time a deployment is paused. Defaults to 600s.

  replicas      <integer>
    Number of desired pods. This is a pointer to distinguish between explicit
    zero and not specified. Defaults to 1.

  revisionHistoryLimit  <integer>
    The number of old ReplicaSets to retain to allow rollback. This is a pointer
    to distinguish between explicit zero and not specified. Defaults to 10.

  selector      <LabelSelector> -required-
    Label selector for pods. Existing ReplicaSets whose pods are selected by
    this will be the ones affected by this deployment. It must match the pod
    template's labels.

  strategy      <DeploymentStrategy>
    The deployment strategy to use to replace existing pods with new ones.

  template      <PodTemplateSpec> -required-
    Template describes the pods that will be created. The only allowed
    template.spec.restartPolicy value is "Always".
#编辑控制器配置
[root@master ~]# kubectl edit deployments.apps web
spec:
  progressDeadlineSeconds: 600
  replicas: 2

[root@master ~]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    2/2     2            2           73m
#利用补丁更改控制器配置
[root@master ~]# kubectl patch  deployments.apps web -p '{"spec":{"replicas":4}}'
deployment.apps/web patched
[root@master ~]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    4/4     4            4           74m
#删除资源
[root@master ~]# kubectl delete deployments.apps web
deployment.apps "web" deleted
[root@master ~]# kubectl get deployments.apps
No resources found in default namespace.
2.运行和调试命令示例
#运行pod
[root@master ~]# kubectl run testpod --image nginx
pod/testpod created
[root@master ~]# kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
testpod   1/1     Running   0          7s
#端口暴漏
[root@master ~]# kubectl get  services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   2d14h

[root@master ~]# kubectl expose pod testpod --port 80 --target-port 80
service/testpod exposed

[root@master ~]# kubectl get services
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   2d14h
testpod      ClusterIP   10.106.78.42   <none>        80/TCP    18s
[root@master ~]# curl  10.106.78.42
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
#查看资源详细信息 
[root@master ~]# kubectl describe pods testpod
#查看资源日志
[root@master ~]# kubectl logs pods/testpod
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
2024/08/29 05:37:29 [notice] 1#1: using the "epoll" event method
2024/08/29 05:37:29 [notice] 1#1: nginx/1.27.1
2024/08/29 05:37:29 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/08/29 05:37:29 [notice] 1#1: OS: Linux 5.14.0-427.13.1.el9_4.x86_64
2024/08/29 05:37:29 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1073741816:1073741816
2024/08/29 05:37:29 [notice] 1#1: start worker processes
2024/08/29 05:37:29 [notice] 1#1: start worker process 29
10.244.0.0 - - [29/Aug/2024:05:41:11 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.76.1" "-"
10.244.0.0 - - [29/Aug/2024:05:42:51 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.76.1" "-"
#运行交互pod
[root@master ~]# kubectl run -it testpod --image busybox

If you don't see a command prompt, try pressing enter.
/ #
/ #	              #ctrl+pq退出不停止pod

#运行非交互pod
[root@master ~]# kubectl run  nginx  --image nginx
pod/nginx created

#进入到已经运行的容器,且容器有交互环境
[root@master ~]# kubectl attach pods/testpod  -it
If you don't see a command prompt, try pressing enter.
/ #
/ #

#在已经运行的pod中运行指定命令
[root@master ~]# kubectl exec  -it pods/nginx  /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx:/#
#日志文件到pod中
[root@master ~]# kubectl cp anaconda-ks.cfg nginx:/
[root@master ~]# kubectl exec  -it pods/nginx  /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx:/# ls
anaconda-ks.cfg  boot  docker-entrypoint.d   etc   lib    media  opt   root  sbin  sys  usr
bin              dev   docker-entrypoint.sh  home  lib64  mnt    proc  run   srv   tmp  var
root@nginx:/#

#复制pod中的文件到本机
[root@master ~]# kubectl cp  nginx:/anaconda-ks.cfg anaconda-ks.cfg
tar: Removing leading `/' from member names
3.高级命令示例
#利用命令生成yaml模板文件
[root@master ~]# kubectl create deployment --image nginx webcluster --dry-run=client   -o yaml  > webcluster.yml


#利用yaml文件生成资源
[root@master ~]# vim webcluster.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: nginx
        name: nginx

[root@master ~]# kubectl apply -f webcluster.yml
deployment.apps/webcluster created

[root@master ~]# kubectl get deployments.apps
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
webcluster   2/2     2            2           21s

[root@master ~]# kubectl delete -f webcluster.yml
deployment.apps "webcluster" deleted
#管理资源标签
[root@master ~]# kubectl run nginx --image  nginx
[root@master ~]# kubectl get pods  --show-labels
NAME                          READY   STATUS    RESTARTS   AGE   LABELS
nginx                         1/1     Running   0          12s   run=nginx

[root@master ~]# kubectl label pods nginx app=lee
[root@master ~]# kubectl get pods  --show-labels
NAME                          READY   STATUS    RESTARTS   AGE   LABELS
nginx                         1/1     Running   0          57s   app=lee,run=nginx

#更改标签
[root@master ~]# kubectl label pods nginx app=webcluster --overwrite

#删除标签
[root@master ~]# kubectl label pods nginx app-
pod/nginx unlabeled
[root@master ~]# kubectl get pods nginx --show-labels
NAME    READY   STATUS    RESTARTS   AGE     LABELS
nginx   1/1     Running   0          7m56s   run=nginx

#标签时控制器识别pod示例的标识
[root@master ~]# kubectl get pods --show-labels
NAME                          READY   STATUS    RESTARTS   AGE     LABELS
nginx                         1/1     Running   0          11m     run=nginx
webcluster-7c584f774b-66zbd   1/1     Running   0          2m10s   app=webcluster,pod-template-hash=7c584f774b
webcluster-7c584f774b-9x2x2   1/1     Running   0          35m     app=webcluster,pod-template-hash=7c584f774b

#删除pod上的标签
root@k8s-master ~]# kubectl label pods webcluster-7c584f774b-66zbd app-
pod/webcluster-7c584f774b-66zbd unlabeled

#控制器会重新启动新pod
[root@master ~]# kubectl get pods --show-labels
NAME                          READY   STATUS    RESTARTS   AGE     LABELS
nginx                         1/1     Running   0          11m     run=nginx
webcluster-7c584f774b-66zbd   1/1     Running   0          2m39s   pod-template-hash=7c584f774b
webcluster-7c584f774b-9x2x2   1/1     Running   0          36m     app=webcluster,pod-template-hash=7c584f774b
webcluster-7c584f774b-hgprn   1/1     Running   0          2s      app=webcluster,pod-template-hash=7c584f774b

二、Pod 核心概念与部署方式

(一)Pod 本质认知

Pod 是 K8s 中最小的部署单元,一个 Pod 代表集群中运行的一个进程,拥有唯一 IP。它类似 “豌豆荚”,可包含一个或多个容器,容器间共享 IPC、Network 和 UTC 命名空间,实现资源共享与协同工作。

(二)两种 Pod 部署方式对比

  1. 自主式 Pod(生产不推荐)

    • 优点:配置灵活,可精准控制各项参数;便于学习 K8s 原理和调试问题;适用于一次性任务等特殊场景。
    • 缺点:管理复杂,难以实现自动化扩缩容与故障恢复;缺乏滚动更新等高级功能;可维护性差,配置修改易出错。
    • 创建示例kubectl run timinglee --image nginx,通过简单命令即可创建单个 Pod。
  2. 控制器管理 Pod(推荐)

    • 核心优势:具备自动故障恢复、健康检查自愈能力,保障高可用性;支持手动与自动扩缩容,适配不同工作负载;提供滚动更新与回滚机制,简化版本管理;基于声明式配置,便于团队协作与多环境一致性部署;结合 Service 实现自动服务发现与负载均衡。

    • 实战操作

      • 创建控制器:kubectl create deployment timinglee --image nginx
      • 扩容:kubectl scale deployment timinglee --replicas 6
      • 缩容:kubectl scale deployment timinglee --replicas 2
      • 版本更新:kubectl set image deployments/timinglee myapp=myapp:v2
      • 版本回滚:kubectl rollout undo deployment timinglee --to-revision 1

示例:

#建立控制器并自动运行pod
[root@master ~]# kubectl create deployment timinglee --image nginx
[root@master ~]# kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
timinglee-859fbf84d6-mrjvx   1/1     Running   0          37m

#为timinglee扩容
[root@master ~]# kubectl scale deployment timinglee --replicas 6
deployment.apps/timinglee scaled
[root@master ~]# kubectl get pods
NAME                         READY   STATUS              RESTARTS   AGE
timinglee-859fbf84d6-8rgkz   0/1     ContainerCreating   0          1s
timinglee-859fbf84d6-ddndl   0/1     ContainerCreating   0          1s
timinglee-859fbf84d6-m4r9l   0/1     ContainerCreating   0          1s
timinglee-859fbf84d6-mrjvx   1/1     Running             0          37m
timinglee-859fbf84d6-tsn97   1/1     Running             0          20s
timinglee-859fbf84d6-xgskk   0/1     ContainerCreating   0          1s

#为timinglee缩容
[root@master ~]# kubectl scale deployment timinglee --replicas 2
deployment.apps/timinglee scaled
[root@master ~]# kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
timinglee-859fbf84d6-mrjvx   1/1     Running   0          38m
timinglee-859fbf84d6-tsn97   1/1     Running   0          73s

应用版本更新:

#利用控制器建立pod
[root@master ~]# kubectl create  deployment timinglee --image myapp:v1 --replicas 2
deployment.apps/timinglee created

#暴漏端口
[root@master ~]# kubectl expose deployment timinglee --port 80 --target-port 80
service/timinglee exposed
[root@master ~]# kubectl get services
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   2d17h
timinglee    ClusterIP   10.110.195.120   <none>        80/TCP    8s

#访问服务
[root@master ~]# curl  10.110.195.120
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@master ~]# curl  10.110.195.120
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@master ~]# curl  10.110.195.120

#产看历史版本
[root@master ~]# kubectl rollout history deployment timinglee
deployment.apps/timinglee
REVISION  CHANGE-CAUSE
1         <none>

#更新控制器镜像版本
[root@master ~]# kubectl set image deployments/timinglee myapp=myapp:v2
deployment.apps/timinglee image updated

#查看历史版本
[root@master ~]# kubectl rollout history deployment timinglee
deployment.apps/timinglee
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

#访问内容测试
[root@master ~]# curl 10.110.195.120
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@master ~]# curl 10.110.195.120

#版本回滚
[root@master ~]# kubectl rollout undo deployment timinglee --to-revision 1
deployment.apps/timinglee rolled back
[root@master ~]# curl 10.110.195.120
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

三、YAML 配置文件深度解析

(一)YAML 部署的核心优势

采用 YAML 文件部署应用具有显著优势:声明式配置清晰表达应用期望状态,便于理解与维护;支持版本控制,保障多环境部署一致性;适配 CI/CD 流程,实现自动化部署;可灵活组合多种资源,满足复杂架构需求。

(二)核心配置参数说明

YAML 配置文件包含丰富参数,关键部分如下:

  • 基础信息apiVersion(K8s API 版本)、kind(资源类型)、metadata(元数据,含名称、命名空间等)。
  • 容器配置spec.containers 列表定义容器信息,包括镜像名称(image)、镜像拉取策略(imagePullPolicy)、启动命令(command)、端口(ports)等。
  • 资源限制:通过 spec.containers.resources 设置 CPU 与内存的请求值(requests)和限制值(limits),影响 Pod 的 QoS 优先级(Guaranteed > Burstable > BestEffort)。
  • 重启策略spec.restartPolicy 可选 Always、OnFailure、Never,定义 Pod 终止后的重启规则。
  • 其他配置nodeSelector 用于指定 Pod 运行节点;hostNetwork 控制是否使用宿主机网络。

(三)典型 YAML 配置示例

  1. 单容器 Pod:通过 kubectl run timinglee --image myapp:v1 --dry-run=client -o yaml > pod.yaml 生成基础模板,按需修改参数。
  2. 多容器 Pod:注意避免容器间资源冲突(如端口占用),示例中通过不同镜像与启动命令实现容器协同。
  3. 资源限制配置:明确设置 CPU 与内存的请求值和限制值,确保 Pod 资源分配合理。
  4. 环境变量配置:在 spec.containers.env 中定义环境变量,实现容器运行时参数动态配置。

四、Pod 生命周期管理

(一)Init 容器

Init 容器是在应用容器启动前运行的特殊容器,具有以下特性与功能:

  • 必须运行完成后才启动应用容器,且支持多 Init 容器按顺序执行。
  • 可包含应用容器中不存在的工具,避免污染应用镜像;具备访问 Secrets 的权限,保障配置安全;可延迟应用容器启动,直至满足前置条件。
  • 示例说明:创建含 Init 容器的 Pod,通过脚本检测依赖资源,直至依赖满足才启动应用容器。

示例:

[root@master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: initpod
  name: initpod
spec:
  containers:
    - image: myapp:v1
      name: myapp
  initContainers:
    - name: init-myservice
      image: busybox
      command: ["sh","-c","until test -e /testfile;do echo wating for myservice; sleep 2;done"]

[root@master ~]# kubectl apply  -f pod.yml
pod/initpod created
[root@master ~]# kubectl get  pods
NAME      READY   STATUS     RESTARTS   AGE
initpod   0/1     Init:0/1   0          3s

[root@master ~]# kubectl logs pods/initpod init-myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
[root@master ~]# kubectl exec pods/initpod -c init-myservice -- /bin/sh -c "touch /testfile"

[root@master ~]# kubectl get  pods                                                     NAME      READY   STATUS    RESTARTS   AGE
initpod   1/1     Running   0          62s

(二)探针机制

探针是 kubelet 对容器的定期诊断,用于监控容器状态,分为三种类型:

  1. 存活探针(livenessProbe):检测容器是否运行,失败则按重启策略处理容器。支持 TCP 端口检测、命令执行、HTTP 请求等方式。
  2. 就绪探针(readinessProbe):检测容器是否准备好提供服务,失败则将 Pod IP 从 Service 端点列表中移除。
  3. 启动探针(startupProbe):检测应用是否启动成功,启动期间禁用其他探针,失败则重启容器。

存活探针示例:

[root@master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: liveness
  name: liveness
spec:
  containers:
    - image: myapp:v1
      name: myapp
      livenessProbe:
        tcpSocket:					#检测端口存在性
          port: 8080
        initialDelaySeconds: 3		#容器启动后要等待多少秒后就探针开始工作,默认是 0
        periodSeconds: 1			#执行探测的时间间隔,默认为 10s
        timeoutSeconds: 1			#探针执行检测请求后,等待响应的超时时间,默认为 1s
        

#测试:
[root@master ~]# kubectl apply -f pod.yml
pod/liveness created
[root@master ~]# kubectl get pods
NAME       READY   STATUS             RESTARTS     AGE
liveness   0/1     CrashLoopBackOff   2 (7s ago)   22s

[root@master ~]# kubectl describe pods
Warning  Unhealthy  1s (x9 over 13s)  kubelet            Liveness probe failed: dial tcp 10.244.2.6:8080: connect: connection refused

就绪探针示例:

[root@master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: readiness
  name: readiness
spec:
  containers:
    - image: myapp:v1
      name: myapp
      readinessProbe:
        httpGet:
          path: /test.html
          port: 80
        initialDelaySeconds: 1
        periodSeconds: 3
        timeoutSeconds: 1


#测试:
[root@master ~]# kubectl expose pod readiness --port 80 --target-port 80

[root@master ~]# kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
readiness   0/1     Running   0          5m25s

[root@master ~]# kubectl describe pods readiness
Warning  Unhealthy  26s (x66 over 5m43s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

[root@master ~]# kubectl describe services readiness
Name:              readiness
Namespace:         default
Labels:            name=readiness
Annotations:       <none>
Selector:          name=readiness
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.171.244
IPs:               10.100.171.244
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:										#没有暴漏端口,就绪探针探测不满足暴漏条件
Session Affinity:  None
Events:            <none>

kubectl exec pods/readiness -c myapp -- /bin/sh -c "echo test > /usr/share/nginx/html/test.html"

[root@master ~]# kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
readiness   1/1     Running   0          7m49s

[root@master ~]# kubectl describe services readiness
Name:              readiness
Namespace:         default
Labels:            name=readiness
Annotations:       <none>
Selector:          name=readiness
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.171.244
IPs:               10.100.171.244
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.8:80			#满组条件端口暴漏
Session Affinity:  None
Events:            <none>

更多推荐