[单master节点k8s部署]10.deployment和pod扩缩容

在 Kubernetes 中,ReplicaSet 是一个控制器资源,不是一个实际运行的 Pod 或容器。ReplicaSet 控制器是 Kubernetes 控制平面的一部分,运行在 Kubernetes 主节点(Master 节点)上。它负责确保指定数量的 Pod 副本始终运行在集群中,并根据定义的规格(如标签选择器、模板等)管理这些 Pod。

replicaset管理pod的弊端

当replicaset创建的pod运行起来后,可以更改pod的副本数量,如果增加了,就新建pod,如果减少了,就删除pod,但是如果更改了pod中container的镜像,kubectl apply后,其实是不会生效的,因为本身运行的pod并没有被更换,还是更改之前的pod编号。

kubectl get pods -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
frontend-6pvr6                1/1     Running   0          33m   10.244.166.161   node1   <none>           <none>
frontend-6q8jx                1/1     Running   0          33m   10.244.166.160   node1   <none>           <none>
frontend-bcctp                1/1     Running   0          33m   10.244.104.19    node2   <none>           <none>
curl 10.244.166.161
<html ng-app="redis">
  <head>
    <title>Guestbook</title>
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
    <script src="controllers.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.js"></script>
  </head>
  <body ng-controller="RedisCtrl">
    <div style="width: 50%; margin-left: 20px">
      <h2>Guestbook</h2>
    <form>
    <fieldset>
    <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br>
    <button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button>
    </fieldset>
    </form>
    <div>
      <div ng-repeat="msg in messages track by $index">
        {{msg}}
      </div>
    </div>
    </div>
  </body>
</html>

修改yaml中的image

containers:
      - name: php-redis
       # image: docker.io/yecc/gcr.io-google_samples-gb-frontend:v3 
        image: docker.io/ikubernetes/myapp:v2
        imagePullPolicy: IfNotPresent

apply之后,查看pods,发现并没有变化,访问10.244.166.161,发现还是原来的网页页面,说明还是之前的镜像。

kubectl apply -f replicat.yaml 
replicaset.apps/frontend configured
[root@master yam_files]# kubectl get pods -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
frontend-6pvr6                1/1     Running   0          37m   10.244.166.161   node1   <none>           <none>
frontend-6q8jx                1/1     Running   0          37m   10.244.166.160   node1   <none>           <none>
frontend-bcctp                1/1     Running   0          37m   10.244.104.19    node2   <none>           <none>

删除原来的replicaset,重新部署,才会生效 

kubectl delete replicaset frontend
replicaset.apps "frontend" deleted
[root@master yam_files]# kubectl apply -f replicat.yaml 
replicaset.apps/frontend created
[root@master yam_files]# kubectl get pods -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
frontend-5n75c                0/1     Running   0          14s   10.244.166.163   node1   <none>           <none>
frontend-k7gw7                0/1     Running   0          14s   10.244.166.162   node1   <none>           <none>
frontend-pqvqm                0/1     Running   0          14s   10.244.104.20    node2   <none>           <none>
curl 10.244.166.163
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>

所以生产环境如果升级,如果用replicaset部署,就需要手动删掉全部pod,非常不方便,因此更高级的方式是使用deployment。

Deployment

deployment是k8s中最常用的资源对象,支持自定义滚动更新。

rs v1 控制三个 pod,删除一个 pod,在 rs v2 上重新建立一个,依次类推,直到全部都
是由 rs v2 控制,如果 rs v2 有问题,还可以回滚,Deployment 是建构在 rs 之上的,多个
rs 组成一个 Deployment,但是只有一个 rs 处于活跃状态。

deployment滚动更新策略的两个参数: 

  • maxUnavailable

    • 在滚动更新期间允许不可用的最大 Pod 数量,可以是绝对值(整数)或相对值(百分比)。
    • 默认值是 25%。
  • maxSurge

    • 在滚动更新期间可以超过期望 Pod 数量的最大 Pod 数量,可以是绝对值(整数)或相对值(百分比)。
    在滚动更新期间,Kubernetes 会创建最多 maxSurge 数量的额外 Pod,终止 maxUnavailable 数量的旧 Pod。等待新创建的 Pod 变为可用状态。重复上述步骤,直到所有旧的 Pod 都被替换为新的 Pod。确保在更新过程中,应用程序尽量保持可用,最小化服务中断。

写一个deployment文件如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
  labels:
    app: myapp

spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      version: v1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      name: test
      labels:
        app: myapp
        version: v1
    spec:
      containers:
      - name: myapp
        image: janakiramm/myapp:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        startupProbe:
          periodSeconds: 5
          initialDelaySeconds: 20
          timeoutSeconds: 10
          httpGet:
            scheme: HTTP
            port: 80
            path: /
        livenessProbe:
          periodSeconds: 5
          initialDelaySeconds: 20
          timeoutSeconds: 10
          httpGet:
            scheme: HTTP
            port: 80
            path: /
        readinessProbe:
          periodSeconds: 5
          initialDelaySeconds: 20
          timeoutSeconds: 10
          httpGet:
            scheme: HTTP
            port: 80
            path: /

随后apply,产生一个replicaset,然后修改里面的镜像版本为v2,重新apply,pod的滚动更新如下,删掉一个,创建一个,再删掉一个,创建一个。这是由于上面的yaml文件设置了maxUnavailable为1,有些时候这样做会导致服务不可用,所以一般都是设置这个值为0。

查看replicaset,可以看到两个版本,但是只有一个在运行

kubectl get replicaset
NAME                  DESIRED   CURRENT   READY   AGE
myapp-v1-6657946df4   2         2         2       15m
myapp-v1-8559f5cf7f   0         0         0       16m

 可以看到cf7f是版本较旧的replicaset,查看yaml文件

kubectl get replicaset myapp-v1-8559f5cf7f -o yaml > 2.yaml
cat 2.yaml
>
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  annotations:
    deployment.kubernetes.io/desired-replicas: "2"
    deployment.kubernetes.io/max-replicas: "3"
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2024-06-25T15:21:05Z"
  generation: 3
  labels:
    app: myapp
    pod-template-hash: 8559f5cf7f
    version: v1
  name: myapp-v1-8559f5cf7f
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: Deployment
    name: myapp-v1
    uid: 7e0809ec-be5f-4131-b456-897637743878
  resourceVersion: "1226151"
  uid: 89527cd9-9b9f-47d4-8c95-c8b77602a0bc
spec:
  replicas: 0
  selector:
    matchLabels:
      app: myapp
      pod-template-hash: 8559f5cf7f
      version: v1
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: myapp
        pod-template-hash: 8559f5cf7f
        version: v1
      name: test
    spec:
      containers:
      - image: janakiramm/myapp:v2
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: 80
            scheme: HTTP
          initialDelaySeconds: 20
          periodSeconds: 5
          successThreshold: 1
          timeoutSeconds: 10
        name: myapp
        ports:
        - containerPort: 80
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: 80
            scheme: HTTP
          initialDelaySeconds: 20
          periodSeconds: 5
          successThreshold: 1
          timeoutSeconds: 10
        resources: {}
        startupProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: 80
            scheme: HTTP
          initialDelaySeconds: 20
          periodSeconds: 5
          successThreshold: 1
          timeoutSeconds: 10
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  observedGeneration: 3
  replicas: 0

这里面的字段可以看出它已经经历了三次更新,这两字段是一样的,代表replicaset的版本正确。

metadata:
  generation: 3
status:
  observedGeneration: 3
deployment回滚

查看replicaset,发现同一个deployment有好几个replicaset,使用rollout命令,可以查看deployment的更新版本,并且使用rollout undo来回滚到指定的版本,可以看到回滚的时候也是滚动更新。

kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
my-deployment-6b4db9b59    0         0         0       93m
my-deployment-7f6d8d7647   0         0         0       4m9s
my-deployment-8cd4898cd    2         2         2       62s
[root@master yam_files]# kubectl rollout history deployment my-deployment
deployment.apps/my-deployment 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

[root@master yam_files]# kubectl rollout undo deployment my-deployment --to-revision=1
deployment.apps/my-deployment rolled back
[root@master yam_files]# kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
my-deployment-6b4db9b59    2         2         0       95m
my-deployment-7f6d8d7647   0         0         0       6m43s
my-deployment-8cd4898cd    1         1         1       3m36s
[root@master yam_files]# kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-6b4db9b59-ddb96   1/1     Running   0          107s
my-deployment-6b4db9b59-jwkt4   1/1     Running   0          107s
[root@master yam_files]# kubectl rollout history deployment my-deployment
deployment.apps/my-deployment 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>
4         <none>

[root@master yam_files]# kubectl rollout undo deployment my-deployment --to-revision=3
deployment.apps/my-deployment rolled back
[root@master yam_files]# kubectl get pods -w
NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-6b4db9b59-ddb96   1/1     Running   0          2m21s
my-deployment-8cd4898cd-46g5n   0/1     Running   0          5s
my-deployment-8cd4898cd-mhkbs   0/1     Running   0          5s
my-deployment-8cd4898cd-46g5n   0/1     Running   0          25s
my-deployment-8cd4898cd-46g5n   1/1     Running   0          25s
my-deployment-6b4db9b59-ddb96   1/1     Terminating   0          2m41s
my-deployment-8cd4898cd-mhkbs   0/1     Running       0          25s
my-deployment-8cd4898cd-mhkbs   1/1     Running       0          25s
my-deployment-6b4db9b59-ddb96   1/1     Terminating   0          2m42s
my-deployment-6b4db9b59-ddb96   0/1     Terminating   0          2m43s
my-deployment-6b4db9b59-ddb96   0/1     Terminating   0          2m43s
my-deployment-6b4db9b59-ddb96   0/1     Terminating   0          2m43s

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!要在 Kubernetes部署节点的 Redis,您可以按照以下步骤进行操作: 1. 创建 Redis 配置文件:创建一个名为 `redis-config.yaml` 的文件,并在其中定义 Redis 的配置。例如,可以设置 Redis 的密码、持久化存储等。下面是一个示例配置文件的内容: ``` apiVersion: v1 kind: ConfigMap metadata: name: redis-config data: redis.conf: | bind 0.0.0.0 protected-mode yes requirepass your_password appendonly yes ``` 请确保将 `your_password` 替换为您自己的密码。 2. 创建 Redis 服务:创建一个名为 `redis-service.yaml` 的文件,并在其中定义 Redis 服务的配置。下面是一个示例配置文件的内容: ``` apiVersion: v1 kind: Service metadata: name: redis-service spec: selector: app: redis ports: - protocol: TCP port: 6379 targetPort: 6379 ``` 3. 创建 Redis 部署:创建一个名为 `redis-deployment.yaml` 的文件,并在其中定义 Redis 的部署配置。下面是一个示例配置文件的内容: ``` apiVersion: apps/v1 kind: Deployment metadata: name: redis-deployment spec: replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: redis ports: - containerPort: 6379 volumeMounts: - name: redis-data mountPath: /data command: - "redis-server" - "/redis-master/redis.conf" args: - "--save" - "" env: - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: redis-password key: password volumes: - name: redis-data emptyDir: {} ``` 4. 创建密码保护的 Secret:创建一个名为 `redis-password.yaml` 的文件,并在其中定义 Redis 密码的 Secret。下面是一个示例配置文件的内容: ``` apiVersion: v1 kind: Secret metadata: name: redis-password type: Opaque data: password: your_password_base64_encoded ``` 请确保将 `your_password_base64_encoded` 替换为您使用 Base64 编码后的密码。 5. 应用配置:使用以下命令将配置应用到 Kubernetes 集群中: ``` kubectl apply -f redis-config.yaml kubectl apply -f redis-service.yaml kubectl apply -f redis-deployment.yaml kubectl apply -f redis-password.yaml ``` 这将创建 Redis 的配置、服务、部署和密码保护的 Secret。 现在,您应该已经成功部署节点的 Redis。您可以使用 `kubectl get pods` 命令来检查 Redis 的 Pod 是否正常运行,并使用 Redis 客户端连接到服务进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值