k8s POD控制器

POD控制器

Pod控制器,又称为工作负载(workload),是Kubernetes中用于实现管理Pod的中间层,它确保Pod资源符合预期的状态。当Pod资源出现故障时,Pod控制器会尝试进行重启,若根据重启策略无效,则会重新新建Pod资源。以下是Pod控制器的详细介绍:

一、Pod控制器的作用

1.1. 确保Pod副本数量:

Pod控制器代用户创建指定数量的Pod副本,并确保这些副本数量符合预期状态。

1.2. 自动恢复:

当Pod资源出现故障时,控制器会根据定义的策略重新编排Pod,确保应用的持续运行。

1.3. 扩缩容:

支持滚动式自动扩容和缩容功能,根据应用需求调整Pod数量。

1.4. 更新和回滚:

对于某些控制器(如Deployment),支持应用的滚动更新和版本回退。

二、常见的Pod控制器类型

2.1 ReplicaSet/ReplicationController

作用:用于保证Pod的副本数量维持在用户指定的数量。它支持Pod数量的扩缩Pod模板的更新,但不涉及应用状态的管理。

组件:主要由用户期望的Pod副本数量、标签选择器(用于判断哪个Pod归自理)和Pod资源模板组成。

特点:帮助用户管理无状态的Pod资源,精确反应用户定义的目标数量ReplicaSet不是直接使用的控制器,而是通常通过Deployment来间接管理。

2.1.1 ReplicationController(RC)
yaml 复制代码
apiVersion: v1
kind: ReplicationController
metadata:
 name: rc-demo
spec: # rc期望
 replicas: 3 # 定义当前pod副本数量
 selector: # pod选择器
  app: rc-demo # 选择符合选择器标签的pod
 template: # 模版
  metadata:
   labels:
    app: rc-demo
  spec: # 容器期望
   containers:
   - name: rc-demo-container
     image: wangyanglinux/myapp:v1.0
     env: #环境变量
     - name: GET_HOSTS_FROM
       value: dns
     - name: zhangsan
       value: "123"
     ports:
     - containerPort: 80

[root@master 5]# kubectl get rc
NAME      DESIRED   CURRENT   READY   AGE
rc-demo   3         3         3       25s

[root@master 5]# kubectl get pod
NAME            READY   STATUS    RESTARTS   AGE
rc-demo-9rw48   1/1     Running   0          21s
rc-demo-hxtj8   1/1     Running   0          21s
rc-demo-v687d   1/1     Running   0          21s

[root@master 5]# kubectl label pod rc-demo-nrkvf version=v1
pod/rc-demo-nrkvf labeled
[root@master 5]# kubectl get pod --show-labels
NAME            READY   STATUS    RESTARTS   AGE     LABELS
rc-demo-9rw48   1/1     Running   0          5m38s   app=rc-demo
rc-demo-hxtj8   1/1     Running   0          5m38s   app=rc-demo
rc-demo-nrkvf   1/1     Running   0          4m17s   app=rc-demo,version=v1

[root@master 5]# kubectl label pod rc-demo-nrkvf app=test --overwrite
pod/rc-demo-nrkvf labeled

[root@master 5]# kubectl get pod --show-labels
NAME            READY   STATUS    RESTARTS   AGE     LABELS
rc-demo-9rw48   1/1     Running   0          6m35s   app=rc-demo
rc-demo-hxtj8   1/1     Running   0          6m35s   app=rc-demo
rc-demo-nrkvf   1/1     Running   0          5m14s   app=test,version=v1
rc-demo-sbhb2   1/1     Running   0          9s      app=rc-demo


# 调整副本数量
[root@master 5]# kubectl scale rc rc-demo --replicas=10
replicationcontroller/rc-demo scaled
[root@master 5]# kubectl get pod --show-labels
NAME            READY   STATUS    RESTARTS   AGE    LABELS
rc-demo-98w2k   1/1     Running   0          10s    app=rc-demo
rc-demo-9rw48   1/1     Running   0          13m    app=rc-demo
rc-demo-cdvrq   1/1     Running   0          10s    app=rc-demo
rc-demo-cf42f   1/1     Running   0          10s    app=rc-demo
rc-demo-dgj5p   1/1     Running   0          10s    app=rc-demo
rc-demo-f2g6k   1/1     Running   0          10s    app=rc-demo
rc-demo-hxtj8   1/1     Running   0          13m    app=rc-demo
rc-demo-n2fp8   1/1     Running   0          10s    app=rc-demo
rc-demo-nrkvf   1/1     Running   0          12m    app=test,version=v1
rc-demo-nw2h9   1/1     Running   0          10s    app=rc-demo
rc-demo-sbhb2   1/1     Running   0          7m2s   app=rc-demo

[root@master 5]# kubectl label pod rc-demo-nrkvf app=rc-demo --overwrite
pod/rc-demo-nrkvf labeled
[root@master 5]# kubectl get pod --show-labels
NAME            READY   STATUS    RESTARTS   AGE     LABELS
rc-demo-98w2k   1/1     Running   0          41s     app=rc-demo
rc-demo-9rw48   1/1     Running   0          13m     app=rc-demo
rc-demo-cdvrq   1/1     Running   0          41s     app=rc-demo
rc-demo-cf42f   1/1     Running   0          41s     app=rc-demo
rc-demo-dgj5p   1/1     Running   0          41s     app=rc-demo
rc-demo-f2g6k   1/1     Running   0          41s     app=rc-demo
rc-demo-hxtj8   1/1     Running   0          13m     app=rc-demo
rc-demo-n2fp8   1/1     Running   0          41s     app=rc-demo
rc-demo-nrkvf   1/1     Running   0          12m     app=re-demo,version=v1
rc-demo-nw2h9   1/1     Running   0          41s     app=rc-demo
rc-demo-sbhb2   1/1     Running   0          7m33s   app=rc-demo
2.1.2 ReplicaSet(RS)

ReplicaSet的匹配运算符主要包括以下几种,这些运算符用于在Pod模板的标签选择器(selector)中指定选择Pod的规则:

2.1.2.1 matchLabels:

通过直接指定键值对来选择Pod。只有当Pod的标签与matchLabels中定义的标签完全匹配时,该Pod才会被选中。

示例:

yaml 复制代码
apiVersion: apps/v1
kind: ReplicaSet
metadata:
 name: rs-ml-demo
spec:
 replicas: 3
 selector:
  matchLabels: # 匹配标签
   app: rs-ml-demo #matchLabels与pod标签做子集关系匹配
   domian: Noziroh
 template:
  metadata:
   labels:
    app: rs-ml-demo
    domian: Noziroh
    version: v1
  spec:
   containers:
   - name: rs-ml-demo-container
     image: wangyanglinux/myapp:v1.0
     env:
     - name: GET_HOSTS_FROM
       value: dns
     ports:
     - containerPort: 80

[root@master 5]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
rc-demo-9rw48      1/1     Running   0          23m
rc-demo-hxtj8      1/1     Running   0          23m
rc-demo-nrkvf      1/1     Running   0          22m
rs-ml-demo-fm427   1/1     Running   0          20s
rs-ml-demo-kzjph   1/1     Running   0          20s
rs-ml-demo-v6nbn   1/1     Running   0          20s
2.1.2.2 matchExpressions:

提供了一种更灵活的方式来选择Pod,支持使用更复杂的逻辑条件(如AND、OR、NOT等,尽管直接通过matchExpressions实现复杂的逻辑组合需要多个表达式)。

每个matchExpressions条目可以包含key、operator和values三个字段。

key:要匹配的标签的键。

operator:比较运算符,用于定义如何匹配标签的值。常见的运算符包括In(值在列表中)、NotIn(值不在列表中)、Exists(标签存在)、DoesNotExist(标签不存在)。

values:一个值列表,当operator为In或NotIn时使用。

matchExpressions字段是一个列表,其中每个条目都定义了一个匹配条件。每个条件都由key、operator和values三个字段组成:

key:要匹配的标签的键。

operator:一个字符串,指定了与values数组中的值进行比较的运算符。常见的运算符包括:

  • In:标签的值必须存在于values数组中。
  • NotIn:标签的值不能存在于values数组中。
  • Exists:Pod必须拥有该标签,但不对标签的值进行验证。
  • DoesNotExist:Pod不能拥有该标签。

values:一个字符串数组,当operator为In或NotIn时,用于与Pod标签的值进行比较。对于Exists和DoesNotExist运算符,该字段将被忽略。

下面是一个使用matchExpressions的ReplicaSet示例:

yaml 复制代码
apiVersion: apps/v1  
kind: ReplicaSet  
metadata:  
  name: my-replicaset  
spec:  
  replicas: 3  
  selector:  
    matchExpressions:  
    - key: app  
      operator: In  
      values:  
      - my-app  
    - key: environment  
      operator: NotIn  
      values:  
      - prod  
  template:  
    metadata:  
      labels:  
        app: my-app  
        environment: staging  
    spec:  
      containers:  
      - name: my-container  

        image: my-image:latest

在这个例子中,ReplicaSet my-replicaset 将选择所有标签为app: my-app且标签environment的值不是prod的Pod。这意味着,只有那些同时拥有app: my-app标签且environment标签的值不是prod(例如,environment: staging)的Pod才会被my-replicaset管理。

exist

示例:

yaml 复制代码
apiVersion: apps/v1
kind: ReplicaSet
metadata:
 name: rs-me-exists-demo
spec:
 selector:
  matchExpressions:
   - key: app
     operator: Exists # 只要存在标签名为app即可
 template:
  metadata:
    labels:
     app: spring-k8s
  spec:
   containers:
    - name: rs-me-exists-demo-container
      image: wangyanglinux/myapp:v1.0
      ports:
      - containerPort: 80


[root@master 5]# kubectl create -f 02_rs.yaml 
replicaset.apps/rs-me-exists-demo created

[root@master 5]# kubectl get rs
NAME                DESIRED   CURRENT   READY   AGE
rs-me-exists-demo   1         1         1       10s

[root@master 5]# kubectl label pod rs-me-exists-demo-nhr89 app=Noziroh --overwrite
pod/rs-me-exists-demo-nhr89 labeled
rs-me-exists-demo-nhr89   1/1     Running   0          2m15s   app=Noziroh

in示例

yaml 复制代码
apiVersion: apps/v1
kind: ReplicaSet
metadata:
 name: rs-me-in-demo
spec:
 selector:
  matchExpressions:
   - key: app
     operator: In
     values:
     - spring-k8s
     - hahahah
 template:
  metadata:
   labels:
     app: sg-k8s
  spec:
   containers:
    - name: rs-me-in-demo-container
      image: wangyanglinux/myapp:v1.0
      ports:
      - containerPort: 80


[root@master 5]# kubectl create -f 02_rs_in.yaml 
The ReplicaSet "rs-me-in-demo" is invalid: spec.template.metadata.labels: Invalid value: map[string]string{"app":"sg-k8s"}: `selector` does not match template `labels`
#app: sg-k8s 属于matchExpressions app:[spring-k8s,hahahah] 所以无法创建

#修改yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
 name: rs-me-in-demo
spec:
 selector:
  matchExpressions:
   - key: app
     operator: In
     values:
     - spring-k8s
     - hahahah
     - sg-k8s
 template:
  metadata:
   labels:
     app: sg-k8s
  spec:
   containers:
    - name: rs-me-in-demo-container
      image: wangyanglinux/myapp:v1.0
      ports:
      - containerPort: 80

[root@master 5]# kubectl create -f 02_rs_in.yaml 
replicaset.apps/rs-me-in-demo created

删除rc rs 创建的pod

shell 复制代码
[root@master 5]# kubectl delete rc --all
replicationcontroller "rc-demo" deleted
[root@master 5]# kubectl delete rs --all
replicaset.apps "rs-me-exists-demo" deleted
replicaset.apps "rs-me-in-demo" deleted
replicaset.apps "rs-ml-demo" deleted

注意:

在实际使用中,matchLabels和matchExpressions可以单独使用,也可以组合使用(但通常不建议这样做,因为这可能会增加配置的复杂性并导致意外的选择结果)。

matchLabels提供了一种简单直观的方式来选择Pod,而matchExpressions则提供了更强大的灵活性和表达能力。

在定义ReplicaSet时,选择器的目的是确保ReplicaSet能够正确地识别和管理它应该负责的Pod。因此,在配置选择器时,需要确保它能够准确地匹配到目标Pod,以避免出现Pod丢失或ReplicaSet无正确管理Pod的情况。

2.2 Deployment

声明式定义

  • 作用:工作在ReplicaSet之上,用于管理无状态应用。它提供了应用的声明能力,允许用户定义应用的期望状态,并自动处理Pod的创建、更新和删除。
  • 功能:支持滚动更新和版本回退,还提供了事件和状态查看、暂停和继续部能。
常用命令
1. 创建Deployment

使用kubectl create命令:可以直接通过命令行创建Deployment,指定容器镜像、副本数量等参数。

bash 复制代码
kubectl create deployment my-deployment --image=nginx:latest --replicas=3

这个命令会创建一个名为my-deployment的Deployment,使用nginx:latest镜像,并设置副本数量为3。

使用YAML文件:更常见的做法是先编写一个YAML文件定义Deployment,然后使用kubectl apply命令应用这个文件。

bash 复制代码
kubectl apply -f my-deployment.yaml
2. 查看Deployment

列出所有Deployments:

bash 复制代码
kubectl get deployments

这个命令会列出当前命名空间下的所有Deployments。

查看特定Deployment的详细信息:

bash 复制代码
kubectl describe deployment my-deployment

这个命令会显示名为my-deployment的Deployment的详细信息,包括Pod模板、副本数量、事件等。

3. 更新Deployment

更改副本数量:

bash 复制代码
kubectl scale deployment my-deployment --replicas=5

这个命令会将my-deployment的副本数量更改为5。

更新容器镜像:

bash 复制代码
kubectl set image deployment my-deployment my-container=nginx:1.19.2

这个命令会将my-deployment中名为my-container的容器的镜像更新为nginx:1.19.2。

4. 滚动更新和回滚

滚动更新:默认情况下,通过更改Deployment的Pod模板(如镜像版本)并重新应用,Kubernetes会执行滚动更新。

回滚到上一个版本:

bash 复制代码
kubectl rollout undo deployment my-deployment

这个命令会将my-deployment回滚到上一个版本。

查看更新历史:

bash 复制代码
kubectl rollout history deployment my-deployment

这个命令会显示my-deployment的更新历史。

回滚到指定版本:

bash 复制代码
kubectl rollout undo deployment my-deployment --to-revision=N

其中N是想要回滚到的版本号(从kubectl rollout history命令中获取)。

暂停和恢复滚动更新

bash 复制代码
# 暂停滚动更新  
kubectl rollout pause deployment/<deployment-name>  
  
# 恢复滚动更新  
kubectl rollout resume deployment/<deployment-name>
更新策略

在Kubernetes(k8s)中,Deployment的更新策略是管理Pod版本升级和回滚的重要机制。主要的更新策略包括滚动更新(RollingUpdate)和重建(Recreate),每种策略都有其适用场景和配置方式。

1. 滚动更新(RollingUpdate)

滚动更新是Kubernetes Deployment的默认更新策略。在滚动更新过程中,Deployment控制器会逐步地将新版本的Pod逐个替换旧版本的Pod,从而确保在升级过程中始终有一定数量的可用Pod服务于客户端请求,实现平滑的服务过渡。

关键参数:

  • maxSurge:表示在滚动更新过程中,可以超出期望副本数的最大Pod数或百分比。这有助于在更新过程中保持冗余度,以应对可能的故障。
  • maxUnavailable:表示在滚动更新过程中,允许的最大不可用Pod数或百分比。这有助于控制更新过程中服务的可用性。

配置示例:

yaml 复制代码
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: myapp-deploy  
spec:  
  replicas: 3  
  strategy:  
    type: RollingUpdate  
    rollingUpdate:  
      maxSurge: 25%  # 或者设置为一个整数,如 maxSurge: 1  
      maxUnavailable: 25%  # 或者设置为一个整数,如 maxUnavailable: 1  
  selector:  
    matchLabels:  
      app: myapp  
  template:  
    metadata:  
      labels:  
        app: myapp  
    spec:  
      containers:  
      - name: myapp  

        image: myapp:v2

适用场景:

滚动更新特别适用于需要确保服务持续可用的场景,如生产环境中的应用程序升级。

2. 重建(Recreate)

重建策略会在创建新Pod之前删除所有现有的Pod。这种策略会导致应用程序的短暂中断,因为在删除旧Pod和创建新Pod之间存在时间差。

配置示例:

yaml 复制代码
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: myapp-deploy  
spec:  
  replicas: 3  
  strategy:  
    type: Recreate  
  selector:  
    matchLabels:  
      app: myapp  
  template:  
    metadata:  
      labels:  
        app: myapp  
    spec:  
      containers:  
      - name: myapp  

        image: myapp:v2

适用场景:

重建策略适用于无状态应用程序或可以容忍短暂中断的应用程序,如开发环境或测试环境中的应用程序升级。

总结

在选择Deployment的更新策略时,需要根据应用程序的特性和业务需求进行权衡。滚动更新提供了更好的服务可用性和平滑的升级体验,但可能会增加系统的复杂性和资源消耗。重建策略则更简单直接,但可能会导致服务中断。在实际应用中,可以根据具体情况选择合适的更新策略,并通过调整maxSurge和maxUnavailable等参数来优化升级过程。

金丝雀部署
  • 定义:金丝雀发布是在新旧版本之间平滑过渡的一种发布方式,通过让一部分用户先使用新版本,另一部分用户继续使用旧版本,从而逐步验证新版本的稳定性和性能。
  • 目的:降低新软件版本部署的风险,确保新版本在生产环境中能够稳定运行,同时避免对整个系统造成过大影响。
yaml 复制代码
vi deployment-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 labels:
  app: deployment-demo
 name: deployment-demo
spec:
 replicas: 10
 selector:
  matchLabels:
   app: deployment-demo
 template:
  metadata:
   labels:
    app: deployment-demo
  spec:
   containers:
   - image: wangyanglinux/myapp:v1.0
     name: deployment-demo-container
bash 复制代码
[root@master 6]# kubectl apply -f deployment-demo.yaml 
deployment.apps/deployment-demo created
[root@master 6]# kubectl create svc clusterip deployment-demo --tcp=80:80
service/deployment-demo created
[root@master 6]# kubectl get deploy deployment-demo -o yaml
spec:
  progressDeadlineSeconds: 600
  replicas: 10
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: deployment-demo
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate

# 修改滚动更新pod滚动时的数量
# json模式更新 允许pod超过最大值1个,允许不可用pod为0
# '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":2}}}}'
[root@master 6]# kubectl patch deploy deployment-demo -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":2}}}}'
deployment.apps/deployment-demo patched

# 进行滚动更新
# '{"spec":{"template":{"spec":{"containers":[{"image":"wangyanglinux/myapp:v2.0","name":"deployment-demo-container"}]}}}}'

[root@master 6]# kubectl patch deploy deployment-demo --patch '{"spec":{"template":{"spec":{"containers":[{"image":"wangyanglinux/myapp:v2.0","name":"deployment-demo-container"}]}}}}' && kubectl rollout pause deploy deployment-demo
deployment.apps/deployment-demo patched
deployment.apps/deployment-demo paused
[root@master 6]# kubectl get pod | grep deployment |wc -l
11
[root@master 6]# kubectl describe pod deployment-demo-7dd46c6f55-l5mdl
Image:          wangyanglinux/myapp:v2.0
[root@master 6]# kubectl rollout resume deploy deployment-demo
deployment.apps/deployment-demo resumed
# 回滚
[root@master 6]# kubectl rollout undo deployment/deployment-demo
deployment.apps/deployment-demo rolled back


[root@master 6]# kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
deployment-demo-6465d4c5c9   0         0         0       2m34s
deployment-demo-6995c75668   10        10        10      8m3s
2.2.1. 应用(Apply)

kubectl apply 命令用于根据提供的配置文件(通常是YAML或JSON格式)来创建或更新资源。如果资源不存在,apply 会创建它;如果已存在,apply 会更新资源以匹配配置文件中的定义。

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

这个命令会根据deployment.yaml文件中的定义来创建或更新一个Deployment。

2.1.2. 替换(Replace)

在Kubernetes中,并没有直接的replace命令来替换整个Deployment。但是,你可以使用kubectl replace命令来替换资源的定义,但这通常用于特定的场景,比如你需要替换整个资源对象而不是简单地更新它。

bash 复制代码
kubectl replace -f deployment.yaml --force

注意:--force选项在较新版本的kubectl中可能不是必需的,具体取决于你的Kubernetes集群版本和kubectl版本。使用replace时要小心,因为它会替换整个资源对象,而不仅仅是更新它。

对比
kubectl apply kubectl replace
功能 创建或更新资源,使其与配置文件匹配 替换资源的当前配置,使其与配置文件完全匹配
特点 增量更新,幂等性,易于使用 全面替换,可能导致资源状态丢失,需要谨慎使用
适用场景 大多数资源更新场景 需要替换整个资源对象或资源状态复杂难以通过apply更新的场景

测试

yaml 复制代码
apiVersion: apps/v1
kind: Deployment # 类别为Deployment
metadata:
 labels:
  app: myapp-deploy # Deployment 标签
 name: myapp-deploy # Deployment 名字
spec:
 replicas: 1
 selector:
  matchLabels:
   app: myapp-deploy # 容器标签app=myapp-deploy
 template:
  metadata:
   labels:
    app: myapp-deploy # 容器名字
  spec:
   containers:
   - image: wangyanglinux/myapp:v1.0
     name: myapp
bash 复制代码
[root@master 5]# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
myapp-deploy-7977896984-gsd6m   1/1     Running   0          36s
[root@master 5]# kubectl get deploy -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                     SELECTOR
myapp-deploy   1/1     1            1           59s   myapp        wangyanglinux/myapp:v1.0   app=myapp-deploy

[root@master 5]# kubectl get deploy -o yaml
availableReplicas: 1
[root@master 5]# kubectl scale deploy myapp-deploy --replicas=10
deployment.apps/myapp-deploy scaled
[root@master 5]# kubectl get deploy -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                     SELECTOR
myapp-deploy   10/10   10           10          3m26s   myapp        wangyanglinux/myapp:v1.0   app=myapp-deploy
[root@master 5]# kubectl get deploy -o yaml
availableReplicas: 10


[root@master 5]# kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
myapp-deploy-7977896984-6gwzj   1/1     Running   0          101s    10.244.166.167   node1   <none>           <none>
myapp-deploy-7977896984-9mmn4   1/1     Running   0          101s    10.244.104.35    node2   <none>           <none>
myapp-deploy-7977896984-b47vm   1/1     Running   0          101s    10.244.166.170   node1   <none>           <none>
myapp-deploy-7977896984-b6t5j   1/1     Running   0          101s    10.244.166.168   node1   <none>           <none>
myapp-deploy-7977896984-gsd6m   1/1     Running   0          4m42s   10.244.104.34    node2   <none>           <none>
myapp-deploy-7977896984-jbg62   1/1     Running   0          101s    10.244.166.171   node1   <none>           <none>
myapp-deploy-7977896984-m2kh6   1/1     Running   0          101s    10.244.104.36    node2   <none>           <none>
myapp-deploy-7977896984-r8shx   1/1     Running   0          101s    10.244.104.38    node2   <none>           <none>
myapp-deploy-7977896984-rp6rz   1/1     Running   0          101s    10.244.104.37    node2   <none>           <none>
myapp-deploy-7977896984-th76j   1/1     Running   0          101s    10.244.166.169   node1   <none>           <none>

[root@master 5]# curl 10.244.166.167
www.xinxianghf.com | hello MyAPP | version v1.0

[root@master 5]# vim 01_deploy.yaml
- image: wangyanglinux/myapp:v2.0

[root@master 5]# kubectl apply -f 01_deploy.yaml 
deployment.apps/myapp-deploy configured

[root@master 5]# kubectl get deploy -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                     SELECTOR
myapp-deploy   1/1     1            1           6m38s   myapp        wangyanglinux/myapp:v2.0   app=myapp-deploy

[root@master 5]# kubectl get pod -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
myapp-deploy-58b4dc6f5-dggz9   1/1     Running   0          95s   10.244.104.39   node2   <none>           <none>

[root@master 5]# curl 10.244.104.39
www.xinxianghf.com | hello MyAPP | version v2.0

[root@master 5]# vim 01_deploy.yaml
replicas: 10
- image: wangyanglinux/myapp:v3.0

[root@master 5]# kubectl replace -f 01_deploy.yaml 
deployment.apps/myapp-deploy replaced

[root@master 5]# kubectl get deploy -o wide 
NAME           READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                     SELECTOR
myapp-deploy   10/10   10           10          17m   myapp        wangyanglinux/myapp:v3.0   app=myapp-deploy

[root@master 5]# kubectl get pod -o wide 
NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
myapp-deploy-6fd574ffd6-287zl   1/1     Running   0          97s   10.244.104.44    node2   <none>           <none>
myapp-deploy-6fd574ffd6-2rqpt   1/1     Running   0          60s   10.244.166.180   node1   <none>           <none>
myapp-deploy-6fd574ffd6-987n5   1/1     Running   0          97s   10.244.104.41    node2   <none>           <none>
myapp-deploy-6fd574ffd6-cmw6z   1/1     Running   0          61s   10.244.104.47    node2   <none>           <none>
myapp-deploy-6fd574ffd6-g2pkf   1/1     Running   0          97s   10.244.104.42    node2   <none>           <none>
myapp-deploy-6fd574ffd6-g9prr   1/1     Running   0          79s   10.244.166.178   node1   <none>           <none>
myapp-deploy-6fd574ffd6-jqjbz   1/1     Running   0          72s   10.244.166.179   node1   <none>           <none>
myapp-deploy-6fd574ffd6-vnzg4   1/1     Running   0          97s   10.244.166.174   node1   <none>           <none>
myapp-deploy-6fd574ffd6-zlfnz   1/1     Running   0          97s   10.244.166.175   node1   <none>           <none>
myapp-deploy-6fd574ffd6-zscjl   1/1     Running   0          63s   10.244.104.46    node2   <none>           <none>

[root@master 5]# kubectl diff -f 01_deploy.yaml 
diff -u -N /tmp/LIVE-1713354067/apps.v1.Deployment.default.myapp-deploy /tmp/MERGED-2968072580/apps.v1.Deployment.default.myapp-deploy
--- /tmp/LIVE-1713354067/apps.v1.Deployment.default.myapp-deploy	2024-08-22 23:48:21.313569984 +0800
+++ /tmp/MERGED-2968072580/apps.v1.Deployment.default.myapp-deploy	2024-08-22 23:48:21.314569996 +0800
@@ -4,7 +4,7 @@
   annotations:
     deployment.kubernetes.io/revision: "3"
   creationTimestamp: "2024-08-22T15:29:32Z"
-  generation: 4
+  generation: 5
   labels:
     app: myapp-deploy
   name: myapp-deploy
@@ -13,7 +13,7 @@
   uid: 383e54ba-ce53-4320-85d9-d72fd6abb35b
 spec:
   progressDeadlineSeconds: 600
-  replicas: 10
+  replicas: 1
   revisionHistoryLimit: 10
   selector:
     matchLabels:
@@ -30,7 +30,7 @@
         app: myapp-deploy
     spec:
       containers:
-      - image: wangyanglinux/myapp:v3.0
+      - image: wangyanglinux/myapp:v2.0
         imagePullPolicy: IfNotPresent
         name: myapp
         resources: {}


# deployment与rs关联升级 滚动更新
[root@master 5]# kubectl get rs -o wide
NAME                      DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                     SELECTOR
myapp-deploy-58b4dc6f5    0         0         0       20m   myapp        wangyanglinux/myapp:v2.0   app=myapp-deploy,pod-template-hash=58b4dc6f5
myapp-deploy-6fd574ffd6   10        10        10      10m   myapp        wangyanglinux/myapp:v3.0   app=myapp-deploy,pod-template-hash=6fd574ffd6
myapp-deploy-7977896984   0         0         0       26m   myapp        wangyanglinux/myapp:v1.0   app=myapp-deploy,pod-template-hash=7977896984
2.1.3. 删除(Delete)

kubectl delete 命令用于删除一个或多个资源。要删除一个Deployment,你可以使用以下命令:

bash 复制代码
kubectl delete deployment <deployment-name>

将替换为你的Deployment的名称。

2.1.4. 注意事项

在使用apply或replace时,请确保你的配置文件是最新的,以避免不必要的配置错误或资源状态不一致。

在删除Deployment之前,请确保你了解这将会删除该Deployment管理的所有Pods,并且你有适当的备份或恢划。

kubectl apply是更新资源的推荐方式,因为它可以处理资源配置的增量更新,而replace则更适合于替换整个对象。

对于复杂的应用场景,可能需要结合使用kubectl的多个命令,以及编写适当的Kubernetes配置文件,来精确你的应用部署和更新过程。

2.3 StatefulSet

  • 作用:用于管理有状态的应用。它为Pod提供了稳定的网络标识、顺序部署、及扩展和滚动更新的能力。
  • 特点:Pod的名称是有序的,且每个Pod都有独立的存储卷。它通常与HeadleService(无头服务)和PVC(持久化卷声明)一起使用,以实现稳定的持久和网络标识。

主要特点

    1. 稳定的唯一网络标识符:
    • 每个StatefulSet的Pod都有一个稳定的网络标识符(如DNS名称),这个标识符由控制器自动生成,并与Pod的生命周期保持关联。这使得有状态应用更容易被其他应用或服务访问和发现。
    1. 有序部署和扩展:
    • StatefulSet能够按照定义的顺序逐个创建和更新Pod实例,确保它们按照固定的命名规则有序启动。在扩展时,新的Pod也会按照相同的顺序创建,从而保证有状态应用的数据一致性和可用性。
    1. 稳定的存储:
    • 每个StatefulSet的Pod都可以使用持久卷(PersistentVolume)来存储数据,这些存储卷在Pod重新启动或迁移时保持不变,从而确保数据的持久性和可靠性。
    1. 域名解析:
    • 每个StatefulSet的Pod都有一个稳定的域名,格式通常为...svc.cluster.local。这使得有状态应用可以通过域名进行服务发现和通信。
    1. 有序删除:
      在删除StatefulSet时,控制器会按照指定的顺序逐个删除Pod,确保有状态应用在删除过程中不会丢失数据。

应用场景

StatefulSet适用于需要持久化存储和唯一标识的有状态应用场景,包括但不限于:

  • 数据库(如MySQL、PostgreSQL、MongoDB)
  • 消息队列(如RabbitMQ、Kafka)
  • 分布式存储(如Elasticsearch、Cassandra)

在这些场景中,StatefulSet提供的稳定网络标识、有序部署和扩展、持久化存储等特性对于保证应用的数据一致性和高可用性至关重要。

组成部分

StatefulSet主要由以下几个部分组成:

  • Headless Service:用于定义Pod的网络标识(DNS域名),没有Cluster IP,解析其名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
  • volumeClaimTemplates:存储卷申请模板,用于为StatefulSet中的每个Pod生成独立的持久卷声明(PersistentVolumeClaim),从而实现数据的持久化存储。
  • StatefulSet定义:定义具体应用,包括Pod副本数、Pod模板(容器配置、存储卷挂载等)、关联的Headless Service等。

示例

以下是一个简单的StatefulSet示例,用于部署一个具有3个副本的MySQL数据库服务:

yaml 复制代码
apiVersion: apps/v1  
kind: StatefulSet  
metadata:  
  name: mysql-statefulset  
spec:  
  serviceName: mysql  
  replicas: 3  
  selector:  
    matchLabels:  
      app: mysql  
  template:  
    metadata:  
      labels:  
        app: mysql  
    spec:  
      containers: 
      - name: mysql-container  
        image: mysql:latest  
        ports:  
        - containerPort: 3306  
        env:  
        - name: MYSQL_ROOT_PASSWORD  
          value: "password"  
        volumeMounts:  
        - name: mysql-storage  
          mountPath: /var/lib/mysql  
  volumeClaimTemplates:  
  - metadata:  
      name: mysql-storage  
    spec:  
      accessModes: ["ReadWriteOnce"]  
      storageClassName: "standard"  
      resources:  
        requests:  
          storage: 1Gi

在这个示例中,StatefulSet mysql-statefulset 定义了3个MySQL Pod副本,每个Pod都挂载了一个名为mysql-storage的持久卷,用于存储数据库数据。这个持久卷通过volumeClaimTemplates自动生成,并请求了1GiB的存储空间。同时,StatefulSet还关联了一个名为mysql的Headless Service,用于提供Pod的网络标识和域名解析。

2.4 DaemonSet

作用:确保在集群中的每个Node上都运行一个Pod的副本。它通常用于运行集群存储、日志收集等守护进程类任务。

特点:无论Node何时加入集群,DaemonSet都会确保在该Node上运行一个Pod副本(除非Node被标记为不可调度)。

一、概述

DaemonSet 控制器能够确保 Kubernetes 集群中的每个节点(或选定的节点)都运行一个 Pod 的副本。当集群中增加新的节点时,DaemonSet 会自动在该节点上创建一个 Pod 副本;当节点从集群中移除时,DaemonSet 也会自动删除该节点上的 Pod。

二、工作原理
  • 定义对象:用户定义一个 DaemonSet 对象,指定 Pod 模板和其他配置选项。Pod 模板定义了 Pod 的规格,包括容器、存储和网络配置。
  • 调度 Pod:当 DaemonSet 控制器接收到创建请求时,它会在每个匹配的节点上创建一个 Pod 实例。
  • 监控 Pod:DaemonSet 控制器监视 Pod 的状态,并确保每个节点上都有 Pod 实例。如果节点失败或重启,DaemonSet 控制器会自动在该节点上重新创建 Pod 实例。
  • 更新 Pod:如果用户更新了 Pod 模板,DaemonSet 控制器将负责在所有节点上滚动更新 Pod 实例,以应用新的配置。
  • 节点选择:DaemonSet 允许用户通过节点标签选择器来指定应在哪些节点上运行 Pod。如果没有指定选择器,Pod 将在所有节点上运行。
三、相关特性
  • 节点覆盖:DaemonSet 确保在集群中的所有节点或选定节点上运行一个 Pod 实例,或者在满足特定条件的节点上运行。
  • 自动恢复:如果节点失败或重启,DaemonSet 会自动在该节点上重新创建 Pod,确保服务的连续性。
  • 滚动更新:当 Pod 模板更新时,DaemonSet 支持滚动更新,逐步替换旧的 Pod 实例。但通常建议避免在 DaemonSet 中使用 RollingUpdate 更新策略,因为这可能不适用于需要高度稳定性的守护进程应用程序。
  • 灵活性:用户可以指定节点标签选择器来控制 Pod 在哪些节点上运行,提供灵活性。
  • 资源和调度:DaemonSet 支持资源请求和限制,允许用户为 Pod 指定所需的 CPU 和内存资源。
  • 集成:DaemonSet 与 Kubernetes 的其他资源和功能(如服务发现、存储卷和网络策略)紧密集成。
四、应用场景
  • 日志收集:在每个节点上运行日志收集器,如 Fluentd、Logstash 或 Filebeat,以收集并转发节点上的日志数据。
  • 监控代理:在每个节点上运行监控代理,如 Prometheus Node Exporter、collectd 等,以收集节点的性能指标并发送到监控中心。
  • 存储守护进程:在每个节点上运行存储守护进程,如 Glusterd 或 Ceph,以提供分布式存储服务。
五、示例

以下是一个简单的 DaemonSet YAML 配置文件示例,用于在 Kubernetes 集群的每个节点上部署一个 Nginx Pod:

yaml 复制代码
apiVersion: apps/v1  
kind: DaemonSet  
metadata:  
  name: nginx-daemonset  
  namespace: default  
spec:  
  selector:  
    matchLabels:  
      app: nginx-daemonset  
  template:  
    metadata:  
      labels:  
        app: nginx-daemonset  
    spec:  
      containers:  
      - name: nginx  
        image: nginx:latest  
        ports:  
        - containerPort: 80

在创建了这个 DaemonSet 后,Kubernetes 将在每个节点上部署一个 Nginx Pod 副本。如果集群中有新的节点加入,DaemonSet 将自动在该节点上创建一个新的 Nginx Pod 副本。

2.5 Job

作用:用于运行批处理任务,即执行一次性任务。当Pod完成其工作后,Job控制器会负责清理这些Pod。

K8s Job是Kubernetes中的一个核心概念,用于执行一次性任务或批处理作业。以下是关于K8s Job的详细解释:

一、基本概念
  • 定义:Job是Kubernetes中的一种资源对象,专门用于处理那些需要运行至完成且不需要持续运行的任务。
  • 用途:Job主要用于执行数据处理、备份恢复、日志打包压缩等一次性或批处理任务。
二、主要特性
  • 任务执行:Job会创建一个或多个Pod来执行定义的任务,并确保这些Pod成功完成任务。
  • 自动清理:当所有Pod都成功完成任务后,Job会停止这些Pod(默认情况下,已完成的Pod会被自动清理)。
  • 失败重试:如果Pod执行失败,Job会根据定义的策略进行重试,直到任务成功或达到最大重试次数。
  • 并行与串行:Job支持并行执行任务,也支持串行执行任务,具体取决于配置。
三、关键字段
  • apiVersion:指定Job资源对象的API版本,通常为batch/v1。
  • kind:指定资源对象的类型为Job。
  • metadata:包含Job的元数据,如名称(name)、命名空间(namespace)等。
  • spec:定义Job的规格,包括任务模板(template)、完成次数(completions)、并行度(parallelism)、重启策略(restartPolicy)等。
    • template:定义了Pod的模板,包括使用的镜像、命令、参数等。
    • completions:指定需要成功完成的任务数量。
    • parallelism:指定同时运行的Pod数量。
    • backoffLimit:指定任务失败后的重试次数。
四、使用场景
  • 数据处理:如从数据库中导出数据到CSV文件。
  • 日志打包压缩:如按时间段打包日志文件。
  • 备份恢复:如备份数据库到云存储服务。
  • 批处理任务:如根据输入参数计算机器学习模型的特征向量。
五、操作示例

以下是一个简单的Job配置文件示例:

yaml 复制代码
apiVersion: batch/v1  
kind: Job  
metadata:  
  name: ubuntu-job  
spec:  
  template:  
    spec:  
      containers:  
      - name: ubuntu-container  
        image: ubuntu  
        command: ["echo", "Hello, Kubernetes!"]  
      restartPolicy: Never
shell 复制代码
[root@master ~]# kubectl logs  ubuntu-job-wlg8x
Hello, Kubernetes!

该配置文件定义了一个名为example-job的Job,它将启动一个Pod,该Pod包含一个运行echo "Hello, Kubernetes!"命令的容器。由于restartPolicy设置为Never,所以Pod在成功完成任务后不会重启。

六、注意事项
  • Job适用于一次性任务或批处理作业,不适用于长时间运行的服务。
  • 需要确保Job配置文件中定义的容器可以正常运行,并有足够的资源和权限执行指定操作。

2.6 CronJob

作用:用于周期性地创建Job对象,执行定时任务。它类似于Unix中的crontab,用于安排周期性作业。

在Kubernetes(K8s)中,CronJob是一种非常有用的资源对象,它基于Cron表达式,允许用户在指定的时间间隔内自动运行容器化的任务。以下是关于K8s CronJob的详细解释:

一、基本概念
  • 定义:CronJob是Kubernetes中用于周期性执行任务的资源对象,它相当于在Job之上增加了基于时间的调度配置。
  • 用途:CronJob通常用于部署定时备份、定时检查、定时同步、定时报告等周期性任务。
二、关键属性
  • schedule:指定任务执行的时间表,使用标准的Cron表达式语法。例如,"0 * * * *"表示每小时执行一次任务。
  • jobTemplate:定义要执行的任务的模板,通常是一个Pod模板。这个模板包含了任务所需的容器镜像、命令、环境变量等配置。
  • concurrencyPolicy:指定任务并发策略,默认为Allow。Allow表示允许并发执行任务,Forbid表示禁止并发执行任务(新任务将会被跳过),Replace表示如果任务正在执行,则会终止当前任务并启动新任务。
  • successfulJobsHistoryLimit和failedJobsHistoryLimit:分别指定保留成功和失败任务历史记录的数量。默认情况下,成功任务的历史记录保留数量为3,失败任务的历史记录保留数量为1。
三、工作原理
  • 定义对象:用户创建一个CronJob对象,指定Pod模板和其他配置选项。
  • 监控Job:Kubernetes的调度器会监控CronJob对象的状态。
  • 生成Job:根据CronJob定义的时间表,调度器在预定的时间创建Job对象。
  • 执行任务:Kubernetes根据Job模板创建Pod,并开始执行任务。
  • 监控Pod:Kubernetes监控Pod的状态,确保任务成功完成。
  • 记录历史:由CronJob创建的Job都会被记录,包括成功和失败的Job。
  • 清理资源:完成的Job及对应的Pod会根据CronJob的配置进行清理。
四、Cron表达式

Cron表达式由五个或六个字段组成,分别代表分钟、小时、日、月、星期几(以及可选的年份)。每个字段的取值范围不同,可以使用通配符、逗号、连字符等方式进行配置。以下是一些常见的Cron表达式示例:

  • 每分钟执行一次任务:* * * * *
  • 每小时执行一次任务:0 * * * *
  • 每天凌晨1点执行任务:0 1 * * *
  • 每周一凌晨1点执行任务:0 1 * * 1
  • 每月1号凌晨1点执行任务:0 1 1 * *
五、使用场景
  • 定时备份:定期备份数据库或文件系统。
  • 日志清理:定时清理过期的日志或缓存数据。
  • 数据同步:定时拉取或更新数据,如镜像、代码库等。
  • 发送通知:定时发送通知或警报。
六、操作示例

以下是一个简单的CronJob配置文件示例:

yaml 复制代码
apiVersion: batch/v1  
kind: CronJob  
metadata:  
  name: hello-cronjob  
spec:  
  schedule: "*/1 * * * *"  # 每一分钟执行一次任务  
  jobTemplate:  
    spec:  
      template:  
        spec:  
          containers:  
          - name: hello  
            image: ubuntu  
            command: ["/bin/sh", "-c", "date; echo Hello from the Kubernetes cluster"]  
          restartPolicy: OnFailure

该配置文件定义了一个名为hello-cronjob的CronJob,它将每分钟执行一次任务,任务内容为打印当前日期和时间,并输出"Hello from the Kubernetes cluster"。

七、注意事项
  • CronJob的时间精度为分钟级别,不支持秒级别的定时任务。
  • 在设计CronJob时,应充分考虑任务执行的时间、频率和并发策略,以避免资源冲突或过度消耗。
  • 对于重要的定时任务,建议设置失败重试和历史记录保留策略,以便在任务失败时能够及时发现并处理。

三、Pod与控制器之间的关系

控制器是Kubernetes中用于管理一组Pod的高级对象,而Pod是Kubernetes中运行容器的最小单元。

控制器通过定义一组标签选择器来跟踪和控制具有这些标签的Pod。当Pod因故障而终止时,控制器会根据定义的规则自动创建新的Pod来替换它,从而确保应用的持续运行和所需的副本数量。

四、Pod控制器的实现机制

Pod控制器是由Master节点的kube-controller-manager组件提供的。它通过内部和解(reconciliation loop)机制不断地监控Kubernetes集群内资源对象的状态,以保证集群中的资源对象的状限接近于用户所期望的状态。

当资源对象状态发生变动时,API Server将状态写入etcd中,并通过水平触发机制将事件主动通知给相关的客户端程序(包括kube-controller-manager)。然后,控制器通过API Server的watch实时监控目标资源对象的变动,并在必要时执行和解操作。

综上所述,Pod控制器是Kubernetes中用于管理Pod资源的重要机制,它通过确保Pod副本数量、自动恢复、扩缩容、更新和回滚等功能,为应用的持续运行和运维自动化提供了有力支持。

相关推荐
小马爱打代码16 分钟前
zookeeper:一致性原理和算法
分布式·zookeeper·云原生
1024find4 小时前
Spark on k8s部署
大数据·运维·容器·spark·kubernetes
kura_tsuki4 小时前
[Docker集群] Docker 容器入门
运维·docker·容器
能不能别报错16 小时前
K8s学习笔记(十六) 探针(Probe)
笔记·学习·kubernetes
能不能别报错18 小时前
K8s学习笔记(十四) DaemonSet
笔记·学习·kubernetes
火星MARK19 小时前
k8s面试题
容器·面试·kubernetes
Serverless社区20 小时前
阿里云函数计算 AgentRun 全新发布,构筑智能体时代的基础设施
阿里云·云原生·serverless·函数计算
赵渝强老师20 小时前
【赵渝强老师】Docker容器的资源管理机制
linux·docker·容器·kubernetes
能不能别报错1 天前
K8s学习笔记(十五) pause容器与init容器
笔记·学习·kubernetes
稚辉君.MCA_P8_Java1 天前
kafka解决了什么问题?mmap 和sendfile
java·spring boot·分布式·kafka·kubernetes