• OpenKruise部署

本案例使用helm方式安装部署

Helm用于实现kubernetes中相互关联的多个yaml文件的安装部署,相当于linux系统中的yum工具

2.1 安装helm客户端工具

wget https://get.helm.sh/helm-v3.13.2-linux-amd64.tar.gz

托包安装:

tar xf helm-v3.15.2-linux-amd64.tar.gz

mv linux-amd64/helm /usr/bin/

helm version

2.2 通过 helm 安装

[root@master01 ~]# helm repo add openkruise https://openkruise.github.io/charts/

[root@master01 ~]# helm repo update

[root@master01 ~]# helm search repo openkruise

NAME                            CHART VERSION   APP VERSION     DESCRIPTION

openkruise/kruise               1.8.0           1.8.0           Helm chart for kruise components

openkruise/kruise-game          0.8.0           0.8.0           Helm chart for kruise-game components

openkruise/kruise-rollout       0.5.0           0.5.0           Helm chart for kruise-rollout components

openkruise/kruise-state-metrics 0.2.0           1.16.0          Install kruise-state-metrics to generate and ex...

注:

Openkruise包括很多功能组件,本课程中主要讲到两个:kruisekruise-rollout

由于本次部署在K8S 1.28版本集群,并使用cri-dockerd,所以手动指定CRI。

然后托包安装:

# 从本地安装

helm install kruise kruise-1.8.0.tgz \

  --set daemon.socketLocation=/var/run \

  --set daemon.socketFile=cri-dockerd.sock

然后在安装:

[root@master01 ~]# cd kruise-rollout/

[root@master01 kruise-rollout]# ls

Chart.yaml  README.md  templates  values.yaml

[root@master01 kruise-rollout]#

[root@master01 ~]# helm install kruise-rollout .

[root@master01 ~]# helm list

有vpn通过openkruise/kruise安装一个应用kruise

[root@master01 ~]# helm install kruise openkruise/kruise --version 1.8.0 --set daemon.socketLocation=/var/run --set daemon.socketFile=cri-dockerd.sock

NAME: kruise

LAST DEPLOYED: Wed Jun 12 06:25:50 2024

NAMESPACE: default

STATUS: deployed

REVISION: 1

TEST SUITE: None

[root@master01 ~]# helm list

NAME    NAMESPACE       REVISION        UPDATED                           STATUS          CHART           APP VERSION

kruise  default         1               2024-06-12 06:25:50.907759992 +0800 CST deployed        kruise-1.8.0    1.8.0

[root@master01 ~]# kubectl  -n kruise-system get all

NAME                                             READY   STATUS    RESTARTS   AGE

pod/kruise-controller-manager-7c475cb9d6-gjhsd   1/1     Running   0          135m

pod/kruise-controller-manager-7c475cb9d6-lcjkc   1/1     Running   0          135m

pod/kruise-daemon-675mt                          1/1     Running   0          135m

pod/kruise-daemon-h7vk2                          1/1     Running   0          135m

pod/kruise-daemon-m5bwb                          1/1     Running   0          135m

NAME                             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE

service/kruise-webhook-service   ClusterIP   10.109.153.24   <none>        443/TCP   135m

NAME                           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE

daemonset.apps/kruise-daemon   3         3         3       3            3           <none>          135m

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE

deployment.apps/kruise-controller-manager   2/2     2            2           135m

NAME                                                   DESIRED   CURRENT   READY   AGE

replicaset.apps/kruise-controller-manager-7c475cb9d6   2         2         2       135m

  • 原地升级

原地升级是 OpenKruise 提供的核心功能之一

  1. 什么是原地升级

当我们要升级一个存量 Pod 中的镜像时,分为重建升级和原地升级区别:

重建升级的特点:

要删除旧 Pod、创建新 Pod

  1. Pod 名字和 uid 发生变化

因为它们是完全不同的两个 Pod 对象(比如 Deployment 升级)

  1. Pod 名字可能不变、但 uid 变化

因为它们是不同的 Pod 对象,只是复用了同一个名字(比如 StatefulSet 升级)

  1. Pod 所在 Node 名字发生变化

因为新 Pod 很大可能性是不会调度到之前所在的 Node 节点的

  1. Pod IP 发生变化

因为新 Pod 很大可能性是不会被分配到之前的 IP 地址的

原地升级的特点:

仍然复用同一个 Pod 对象,只是修改它里面的字段

  1. 可以避免如调度、分配IP、分配、挂载盘等额外的操作和代价
  2. 更快的镜像拉取

因为开源复用已有旧镜像的大部分 layer 层,只需要拉取新镜像变化的一些layer

  1. 理解 InPlaceIfPossible

类型名为  InPlaceIfPossible ,它意味着 Kruise 会尽量对 Pod 采取原地升级,如果不能则退化到重建升级

  1. 使用要求

如果要使用原地升级能力,需要在安装或升级 Kruise chart 的时候打开kruise- daemon (默认打开)和  InPlaceUpdateEnvFromMetadata 两个 feature-gate。

  • OpenKruise使用案例

实验过程可连续实现,也可以通过删除当前配置,通过01-ok.yaml文件重新部署后再应用新策略(注意副本数和镜像版本)

4.1 部署应用

cat > 01-ok.yaml <<EOF

apiVersion: apps.kruise.io/v1alpha1

kind: CloneSet

metadata:

  name: nginxweb1

  namespace: default

spec:

  replicas: 3

  selector:

    matchLabels:

      app: nginxweb1

  template:

    metadata:

      labels:

        app: nginxweb1

    spec:

      containers:

      - name: nginx

        image: nginx:1.20

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 80

EOF

[root@master01 ~]# kubectl apply -f 01-ok.yaml

[root@master01 ~]# kubectl  get clonesets

NAME        DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE

nginxweb1   3         3         3               3       3       6m45s

[root@master01 ~]# kubectl  get all

NAME                  READY   STATUS    RESTARTS   AGE

pod/nginxweb1-4f7kc   1/1     Running   0          8m39s

pod/nginxweb1-7grxd   1/1     Running   0          8m39s

pod/nginxweb1-pnbgd   1/1     Running   0          8m39s

创建成功之后通过  kubectl get all命令查看对应的信息,可以发现cloneset- controller 是直接创建的 Pod,而原生的Deployment 是通过 ReplicaSet 去创建的 Pod

4.2 应用扩容

[root@master01 ~]# cat > 02-ok.yaml <<EOF

apiVersion: apps.kruise.io/v1alpha1

kind: CloneSet

metadata:

  name: nginxweb1

  namespace: default

spec:

  minReadySeconds: 30

  scaleStrategy:

    maxUnavailable: 1

  replicas: 5

  selector:

    matchLabels:

      app: nginxweb1

  template:

    metadata:

      labels:

        app: nginxweb1

    spec:

      containers:

      - name: nginx

        image: nginx:1.20

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 80

EOF

注:

minReadySeconds: 30 创建了一个pod之后30s才会创建第二个

maxUnavailable:1 在滚动更新过程中最多不可用的pod数

[root@master01 ~]# kubectl apply -f 02-ok.yaml

[root@master01 ~]# watch kubectl get pods

NAME              READY   STATUS    RESTARTS   AGE

nginxweb1-7qh8s   1/1     Running   0          2m8s

nginxweb1-c2n2c   1/1     Running   0          3m12s

nginxweb1-vqfwn   1/1     Running   0          96s

nginxweb1-w8w2v   1/1     Running   0          64s

nginxweb1-zlklg   1/1     Running   0          2m40s

[root@master01 ~]# kubectl get cloneset

NAME        DESIRED   UPDATED   UPDATED_READY   READY   TOTAL   AGE

nginxweb1   5         5         5               5       5       4m1s

 kubectl get pods

NAME              READY   STATUS    RESTARTS   AGE

nginxweb1-7qh8s   1/1     Running   0          5m35s

nginxweb1-c2n2c   1/1     Running   0          6m39s

nginxweb1-vqfwn   1/1     Running   0          5m3s

nginxweb1-w8w2v   1/1     Running   0          4m31s

nginxweb1-zlklg   1/1     Running   0          6m7s

4.3 应用缩容

cat > 03-ok.yaml <<EOF

apiVersion: apps.kruise.io/v1alpha1

kind: CloneSet

metadata:

  name: nginxweb1

  namespace: default

spec:

  minReadySeconds: 30

  scaleStrategy:

    maxUnavailable: 1

    podsToDelete:

    - nginxweb1-57j78             #可指定pod(多个pod写多行“- pod名字”)

  replicas: 4

  selector:

    matchLabels:

      app: nginxweb1

  template:

    metadata:

      labels:

        app: nginxweb1

    spec:

      containers:

      - name: nginx

        image: nginx:1.20

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 80

EOF

缩容时, CloneSet可以指定一些pod删除,而 StatefulSet 或者 Deployment 做不到:

StatefulSet 是根据序号来删除 Pod,而 Deployment/ReplicaSet 目前只能根据控制器里定义的排序来删除。

而 CloneSet 允许用户在缩小 replicas 数量的同时,指定想要删除的 Pod 名字。

如果只是把name加入podsToDelete,而没有修改replicas的话,删完之后会再扩一个pod

kubectl apply -f 03-ok.yaml

kubectl get pods

NAME              READY   STATUS    RESTARTS   AGE

nginxweb1-c2n2c   1/1     Running   0          8m7s

nginxweb1-p22fw   1/1     Running   0          46s

nginxweb1-vqfwn   1/1     Running   0          6m31s

nginxweb1-zlklg   1/1     Running   0          7m35s

如果升级kruise,需先删除旧实例,重新安装

先查看一下,先删除:

[root@master01 ~]# kubectl get cloneset

NAME        DESIRED   UPDATED   UPDATED_READY   UPDATED_AVAILABLE   READY   TOTAL   AGE

nginxweb1   4         4         4               4                   4       4       7m55s

然后删除:

[root@master01 ~]# kubectl delete cloneset nginxweb1

cloneset.apps.kruise.io "nginxweb1" deleted

[root@master01 ~]#

然后在删除kruise

helm uninstall kruise

重新安装

这是有vpn的语句重新生成

helm install kruise openkruise/kruise --version 1.8.0 --set daemon.socketLocation=/var/run --set daemon.socketFile=cri-dockerd.sock --set featureGates="InPlaceUpdateEnvFromMetadata=true\,PreDownloadImageForInPlaceUpdate=true"

如果是本地安装托包的话直接使用:

helm install kruise kruise-1.8.0.tgz --set daemon.socketLocation=/var/run --set daemon.socketFile=cri-dockerd.sock --set featureGates="InPlaceUpdateEnvFromMetadata=true\,PreDownloadImageForInPlaceUpdate=true"

4.4 原地升级

kubectl exec -it nginxweb1-c2n2c -- nginx -v

nginx version: nginx/1.20.2

cat > 04-ok.yaml <<EOF

apiVersion: apps.kruise.io/v1alpha1

kind: CloneSet

metadata:

  name: nginxweb1

  namespace: default

spec:

  minReadySeconds: 30

  updateStrategy: # 添加更新策略

    type: InPlaceIfPossible

  scaleStrategy:

    maxUnavailable: 1

  replicas: 5

  selector:

    matchLabels:

      app: nginxweb1

  template:

    metadata:

      labels:

        app: nginxweb1

    spec:

      containers:

      - name: nginx

        image: nginx:latest # 更换镜像版本

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 80

EOF

[root@master01 ~]# kubectl apply -f 04-ok.yaml

更新过程

[root@master01 ~]# watch kubectl get pods

[root@master01 ~]# kubectl exec -it nginxweb1-4ghsr -- nginx -v

nginx version: nginx/1.27.4

4.5 灰度更新

通过灰度更新可以更新部分pod

cat > 05-ok.yaml <<EOF

apiVersion: apps.kruise.io/v1alpha1

kind: CloneSet

metadata:

  name: nginxweb1

  namespace: default

spec:

  minReadySeconds: 30

  updateStrategy: # 添加更新策略

    type: InPlaceIfPossible

    partition: 2 # 保留旧版本pod数量

  scaleStrategy:

    maxUnavailable: 1

  replicas: 4

  selector:

    matchLabels:

      app: nginxweb1

  template:

    metadata:

      labels:

        app: nginxweb1

    spec:

      containers:

      - name: nginx

        image: nginx:1.20 # 更换镜像版本

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 80

EOF

[root@master01 ~]# kubectl get pods

NAME              READY   STATUS    RESTARTS   AGE

nginxweb1-92mtx   1/1     Running   0          110s

nginxweb1-kltdh   1/1     Running   0          78s

nginxweb1-pz4ff   1/1     Running   0          2m22s

nginxweb1-whd9h   1/1     Running   0          2m54s

kubectl apply -f 05-ok.yaml

watch kubectl get pods

NAME              READY   STATUS    RESTARTS        AGE

nginxweb1-92mtx   1/1     Running   1 (3m34s ago)   15m

nginxweb1-kltdh   1/1     Running   1 (4m6s ago)    15m

nginxweb1-pz4ff   1/1     Running   0               16m

nginxweb1-whd9h   1/1     Running   0               16m

[root@master01 ~]# kubectl exec -it nginxweb1-2fkvg -- nginx -v

[root@master01 ~]# kubectl exec -it  nginxweb1-4ghsr -- nginx -v

nginx version: nginx/1.21.5

[root@master01 ~]# kubectl exec -it nginxweb1-cnr25f -- nginx -v

nginx version: nginx/1.20.2

[root@master01 ~]# kubectl exec -it nginxweb1-w6k58 -- nginx -v

nginx version: nginx/1.20.2

我们会发现只更新了2个pod,还有2个pod没有更新。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐