• 添加:
    • 准备工作:
    • 1.docker
    • 2.系统优化
  • 让master生成join+tonken命令
  • Node节点执行kubeadm join命令
  • 删除:
    • 设置Node为不可调用
    • 在Node节点强制驱逐Pod
    • 从Master节点中删除节点记录
    • 清理被移除的节点
1.1 准备新节点:192.168.111.33
准备一个相同操作系统的主机作为新节点。需要安装相同版本的kubeadm。
安装步骤参考Ubuntu部署 Kubernetes1.23
需要注意的点:
(1)hosts文件配置 每个节点的hosts保持一致
cat >> /etc/hosts << EOF 
192.168.111.30 cjm-cyd 
192.168.111.31 cyd-1 
192.168.111.32 cyd-2 
192.168.111.33 cyd-3 
EOF
(2)给新加节点做免密(可选)
生成密钥对 
ssh-keygen -t rsa 
执行公钥分发 
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.111.33
1.2 通过 kubeadm 将节点加入集群
默认token有效期为24小时,过了24小时需要重新生成。
获取加入命令:(master上执行)
root@cjm-cyd:~# kubeadm token create --print-join-command
kubeadm join 192.168.111.30:6443 --token 7lvc1r.8szmbchjxo8luda7 --discovery-token-ca-cert-hash sha256:7f266e808a0e264bbd3b8f667d31f696791824d5035782338ef1cf9a5b99218d 
运行加入命令:(新增节点上执行)
root@cyd-3:~# kubeadm join 192.168.111.30:6443 --token cdtukx.8zaq2i4y3i3q7omx --discovery-token-ca-cert-hash sha256:7f266e808a0e264bbd3b8f667d31f696791824d5035782338ef1cf9a5b99218d 
1.3 验证节点状态
在 Master 节点上查看节点是否加入成功:
root@cjm-cyd:~# kubectl get node
NAME      STATUS   ROLES                  AGE     VERSION
cjm-cyd   Ready    control-plane,master   2d12h   v1.23.0
cyd-1     Ready    <none>                 2d12h   v1.23.0
cyd-2     Ready    <none>                 2d12h   v1.23.0
cyd-3     Ready    <none>                 7m19s   v1.23.0
新节点已显示为 Ready 状态,说明新节点已添加成功。
2 从K8S集群中删除节点
2.1 确保节点安全下线
驱逐节点上的 Pod
在删除节点前,先将其标记为不可调度,确保新 Pod 不会调度到该节点:
root@cjm-cyd:~# kubectl cordon cyd-3 node/cyd-3 cordoned
逐步迁移 Pod
使用 drain 命令驱逐节点上的 Pod,并迁移到其他节点:
root@cjm-cyd:~# kubectl drain cyd-3 --ignore-daemonsets --delete-emptydir-data
node/cyd-3 already cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-flannel/kube-flannel-ds-c52gm, kube-system/kube-proxy-dxmln
node/cyd-3 drained
参数说明:
  • --ignore-daemonsets:忽略 DaemonSet 管理的 Pod。
  • --delete-emptydir-data:删除带有 emptyDir 卷的 Pod。
2.2 从集群中移除节点
从 Master 节点中删除节点记录:
root@cjm-cyd:~# kubectl delete node cyd-3 node "cyd-3" deleted
再次查看节点情况
root@cjm-cyd:~# kubectl get node
NAME      STATUS   ROLES                  AGE     VERSION
cjm-cyd   Ready    control-plane,master   2d12h   v1.23.0
cyd-1     Ready    <none>                 2d12h   v1.23.0
cyd-2     Ready    <none>                 2d12h   v1.23.0
可以看到cyd-3节点已经被移除
2.3 清理被移除的节点
在要删除的节点上停止 kubelet:
root@cyd-3:~# systemctl stop kubelet
重置节点:清理该节点上的 Kubernetes 配置:
root@cyd-3:~# kubeadm reset
清理残余数据:删除 etcd 数据目录和 Kubernetes 配置文件:
root@cyd-3:~# rm -rf /etc/cni/net.d /var/lib/kubelet /var/lib/etcd
3 注意事项
  • 新增节点时,Master 和节点之间的网络需要畅通,特别是用于控制平面通信的端口(如 6443)。
  • 删除节点时,建议逐步迁移工作负载,避免业务中断。
  • 对于启用了网络插件(如 Calico 或 Flannel)的集群,确保新节点安装了对应的网络配置。

Kubernetes中YAML
基本语法格式:
---       # yaml起始分割作用,可以在一个文件中写多个配置
apiVersion: v1 # kubectl api-resources |grep pods
kind: Pod      # k8s资源类型
metadata:      # 元数据,包含资源对象的名称和标签
  name: myapp  # 资源名称
  labels:      # 标签
    app: webapp 
    info: abcd
spec:          # 详细配置规格
  containers:
  - name: web1
    images: nginx:1.21
  - name: mysql
    images: mysql:8.0.20
    
# 生成yaml模板
kubectl create ns test --dry-run=client -o yaml > 03.namespace.yaml
apiversion: vl
kind: Namespace
metadata:
  creationTimestamp: null
  name: test
spec: {}
status: {}
查看K8S自带的资源管理帮助文档
root@k8s-master01:~# kubectl explain deployment
KIND:     Deployment
VERSION:  apps/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  <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

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

   status  <Object>
     Most recently observed status of the Deployment.
--dry-run生成YAML文件框架
快速生成YAML模板
生成Pod模板
kubectl run myapp --image=nginx:1.21 --dry-run=client -o yaml > 01.myapp-pod.yaml
apiVersion: vl
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp
    name:myapp
spec:
  containers:
  - image: nginx:1.21
    name:myapp
    resources:{}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
生成Namespace模板
kubectl create namespace work --dry-run=client -o yaml > namespace.yaml
生成Deployment模板
kubectl create deployment myapp --image=dbimg:1.35 --dry-run=client -o yaml > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: myapp
    name: myapp
spec:
  replicas: 1
  selector:
    matchLabels: 
      app: myapp
   strategy: {}
   template:
     metadata:
       creationTimestamp: null
       labels:
         app: myapp
     spec:
       containers:
       - image: 192.168.57.200:8099/library/nginx:1.24
         name: nginx
         resources: {}
status: {}
kebectl apply -f deployment.yaml
kubectl get pod
资源操作命令详解
1.创建资源
# 从YAML文件创建资源
kubectl create -f myapp.yaml
# 创建多个资源
kubectl create -f directory/  # 目录下所有YAML文件
kubectl create -f file1.yaml -f file2.yaml
2.应用声明式配置
# 创建或更新某个资源(推荐方式)
kubectl apply -f myapp.yaml
# 查看将要应用的变更
kubectl apply -f myapp.yaml --dry-run=client
# 强制替换配置
kubectl replace --force -f myapp.yaml
3.删除资源
# 删除指定资源
kubectl delete -f myapp.yaml
# 删除多个资源
kubectl delete -f directory/
# 基于标签删除(可能的多个pod)
kubectl delete pod -l app=webapp
4、高级操作技巧
  1. 部分更新资源(打补丁)
    # 使用merge混合策略(默认是strategic策略性合并)更新标签,适用于简单字段更新
    cat > patch.yaml << EOF
    metadata:
      labels:
        key: myapp-value
    EOF
    
    kubectl patch pod myapp --type=merge --patch-file patch.yaml
    
    # 使用JSON patch删除标签
    cat > remove-label.yaml << EOF
    - op: remove
      path: /metadata/labels/key
    EOF
    
    kubectl patch pod myapp --type=json --patch-file remove-label.yaml
2. 添加注解
# 添加或更新注解
kubectl annotate pod myapp webapp="nginx.1.17" description="前端Web服务器"
# 查看注解信息
kubectl describe pod myapp | grep Annotations
3. 实时编辑资源(对于改动不大的情况,使用edit更快速)
# 编辑运行中的资源
kubectl edit pod myapp
# 编辑Deployment配置(编辑时会打开默认文本编辑器,修改保存后会立即生效)
kubectl edit deployment/myapp
5、常见问题排查
  1. YAML格式错误
# 常见的格式错误
error: error parsing pod.yaml: error converting YAML to JSON: yaml: line 10: did not find expected key
# 解决方法:使用YAML验证工具或在线校验器
  1. 资源已存在错误
    # 使用create时如果资源已存在会报错
    Error from server (AlreadyExists): error when creating "myapp.yaml": pods "myapp" already exists
    # 解决方法:使用apply代替create,或者先删除再创建
  1. 字段验证错误
# API服务器会验证字段合法性
The Deployment "myapp" is invalid: spec.template.spec.containers[0].name: Required value
# 解决方法:使用kubectl explain查看字段要求

NameSpace 命名空间
1.资源的分组管理
2.资源限制
# 创建命名空间
kubectl create ns test
# 查看所有命名空间
kubectl get ns
namespace包含两种状态“Active”和“Terminating”。在namespace删除过程中,namespace状态被设置成“Terminating”

root@cjm-cyd:~# kubectl get ns
NAME              STATUS   AGE
default           Active   3d12h
kube-flannel      Active   3d12h
kube-node-lease   Active   3d12h
kube-public       Active   3d12h
kube-system       Active   3d12h
test              Active   15s

* default 默认命名空间,查询资源时默认显示
* kube-flannel flannel网络插件的命名空间
     查看kube-flannel命名空间下的所有核心资源对象
     kubectl get all -n kube-flannel
* kube-node-lease 是k8s集群中用于节点租约(Node Lease)的一个命名空间
* kube-public 所有用户(包括未经过身份验证的用户)都可以读取
* kube-system k8s服务的命名空间,k8s的组件

# 删除命名空间,会将命名空间中的所有资源全部删除
kubectl delete ns test

# 使用yaml文件创建
kubectl create ns test --dry-run=client -o yaml > 03.namespace.yaml
apiversion: vl
kind: Namespace
metadata:
  creationTimestamp: null
  name: test
spec: {}
status: {}
# 根据yaml文件中的定义,创建或更新对应的namespace资源
kubectl apply -f 03.namespace.yaml、
# 删除对应的namespace资源
kubectl delete -f 03.namespace.yaml
# 指定资源的namespace
apiVersion: v1
kind: Pod
metadata:
    name: myapp
    labels:
        run: myapp
    namespace: test   # 创建资源时,指定namespace
spec:
    containers:
    - image: 192.168.57.200:8099/library/nginx:1.21
      imagePullPolicy: IfNotPresent
      name: myapp
      
# 创建pod
kubectl apply -f 03.nginx-test.yaml
# 指定命名空间查看pod
kubectl get pod -n test
排错技巧
# 生产中的小技巧:k8s删除namespaces状态一直为terminating问题处理
# kubectl get ns
NAME              STATUS        AGE
default           Active        5d4h
ingress-nginx     Active        30h
kube-node-lease   Active        5d4h
kube-public       Active        5d4h
kube-system       Active        5d4h
kubevirt          Terminating   2d2h   # <------ here

1、新开一个窗口运行命令  kubectl proxy
>此命令启动了一个代理服务来接收来自你本机的HTTP连接并转发至API服务器,同时处理身份认证

2、新开一个终端窗口,将下面shell脚本整理到文本内1.sh并执行,$1参数即为删除不了的ns名称
#------------------------------------------------------------------------------------
#!/bin/bash

set -eo pipefail

die() { echo "$*" 1>&2 ; exit 1; }

need() {
         which "$1" &>/dev/null || die "Binary '$1' is missing but required"
}

# checking pre-reqs

need "jq"
need "curl"
need "kubectl"

PROJECT="$1"
shift

test -n "$PROJECT" || die "Missing arguments: kill-ns <namespace>"

kubectl proxy &>/dev/null &
PROXY_PID=$!
killproxy () {
        kill $PROXY_PID
}
trap killproxy EXIT

sleep 1 # give the proxy a second

kubectl get namespace "$PROJECT" -o json | jq 'del(.spec.finalizers[] | select("kubernetes"))' | curl -s -k -H "Content-Type: application/json" -X PUT -o /dev/null --data-binary @- http://localhost:8001/api/v1/namespaces/$PROJECT/finalize && echo "Killed namespace: $PROJECT"
#------------------------------------------------------------------------------------
3.执行脚本删除
# bash 1.sh kubevirt
Killed namespace: kubevirt
1.sh: line 23: kill: (9098) - No such process

5、查看结果
# kubectl get ns
NAME              STATUS   AGE
default           Active   5d4h
ingress-nginx     Active   30h
kube-node-lease   Active   5d4h
kube-public       Active   5d4h
kube-system       Active   5d4h
资源限制:
Namespace的资源限制主要通过两种资源对象实现
  • ResourceQuota(资源配额)
  1. 限定某个对象类型(如Pod)可创建对象的总数;
  2. 限定某个对象类型可消耗的计算资源(CPU、内存)与存储资源(存储卷声明)总数
# resource-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: ns-resource-quota
  namespace: my-namespace    # 目标Namespace
spec:
  hard:  # 硬限制(不可突破)
    # 计算资源总限制
    requests.cpu: "1"        # 所有Pod的CPU请求总和≤1核
    requests.memory: "1Gi"   # 所有Pod的内存请求总和≤1Gi
    limits.cpu: "2"          # 所有Pod的CPU限制总和≤2核
    limits.memory: "2Gi"     # 所有Pod的内存限制总和≤2Gi
    # 存储资源限制
    requests.storage: "5Gi"  # 所有PVC的存储请求总和≤5Gi
    persistentvolumeclaims: "3"  # 最多创建3个PVC

    # 对象数量限制
    pods: "10"               # 最多创建10个Pod
    services: "5"            # 最多创建5个Service
    configmaps: "10"         # 最多创建10个ConfigMap
  • LimitRange(限制范围)
  1. 限制namespace中每个Pod或容器的最小与最大计算资源
  2. 限制namespace中每个Pod或容器计算资源request、limit之间的比例
  3. 限制namespace中每个存储卷声明(PersistentVolumeClaim)可使用的最小与最大存储空间
  4. 设置namespace中容器默认计算资源的request、limit,并在运行时自动注入到容器中
# limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: ns-limit-range
  namespace: my-namespace # 目标Namespace
spec:
  limits:
  - type: Container       # 对容器的限制
    default:              # 容器未指定时的默认limits
      cpu: "500m"         # 默认CPU限制:0.5核
      memory: "512Mi"     # 默认内存限制:512Mi
    defaultRequest:       # 容器未指定时的默认requests
      cpu: "100m"         # 默认CPU请求:0.1核
      memory: "128Mi"     # 默认内存请求:128Mi
    min:                  # 容器资源的最小值(不能低于此值)
      cpu: "50m"
      memory: "64Mi"
    max:                  # 容器资源的最大值(不能超过此值)
      cpu: "1000m"
      memory: "1Gi"
   - type: Pod             # 对Pod的限制(所有容器的资源总和)
     max:
       cpu: "2000m"        # 单个Pod的总CPU限制≤2核
       memory: "2Gi"       # 单个Pod的总内存限制≤2Gi
使用流程
1.创建目标Namespace:
kubectl create namespace my-namespace

2.应用ResourceQuota:

kubectl apply -f resource-quota.yaml
3.应用LimitRange:
kubectl apply -f limit-range.yaml
4.查看配置:
查看资源配额
kubectl get resourcequota -n my-namespace
kubectl describe resourcequota ns-resource-quota -n my-namespace
查看限制范围
kubectl get limitrange -n my-namespace
kubectl describe limitrange ns-limit-range -n my-namespace
注意事项
若仅配置ResourceQuota而无LimitRange,用户创建Pod时必须显式指定资源requests和limits,否则会被拒绝(无法满足配额约束)。
LimitRange的默认值仅对新创建的对象生效,不影响已存在的对象。
资源限制需根据集群实际容量和业务需求合理配置,避免过松(资源滥用)或过紧(业务无法运行)。
通过这两种机制,可以实现Namespace级别的精细化资源管控,确保Kubernetes集群的稳定性和资源利用率。

更多推荐