Kubevirt InstallStrategy 简析

installstrategy 是 kubevirt operator 在kubernetes 中部署各种 pod svc secret 等的参考yaml,由 operator 生成。熟悉 installstrategy 有助于理解 kubernetes 集群中应用的部署方法。

代码入口

Create

pkg/virt-operator/application.go--> install.DumpInstallStrategyToConfigMap

DumpInstallStrategyToConfigMap中创建相关configMap并且进行create或者update

Use

pkg/virt-operator/kubevirt.go -->execute() -->syncInstallation(kvCopy) -->loadInstallStrategy(kv) --> Sync

Create InstallStrategyConfigMap

NewInstallStrategyConfigMap()中通过GenerateCurrentInstallStrategy()创建strategy结构体,encodeManifests将其转化为byte进行zip压缩后进行base64编码然后传给kubevirt-install-strategyconfigMap的data字段。

  1. 首先生成各 crd
  2. 生成各个组件pod相关的clusterrole serviceaccount等
  3. 将各rbac相关obj放入strategy中
  4. 创建Deployment、service等obj加入到strategy中
  5. 最后返回生成的startegy struct

Use InstallStrategy

loadInstallStrategy中首先根据kubevirt crd、环境变量等信息生成config其中包括installstrategy 的版本,镜像 tag 等信息 ,首先从KubeVirtController.installStrategyMap中拿取installstrategy,若没有则从storage 中获得 comfigmap 生成,若还是没有则创建 configmap 的 job。

在kubevirt crd syncInstallation 中 loadInstallStrategy 获取strategy。在reconciler.Sync 中 执行

  • haveApiDeploymentsRolledOver
  • haveControllerDeploymentsRolledOver
  • haveExportProxyDeploymentsRolledOver
  • haveDaemonSetsRolledOver

在store 中检查相应的 obj 是否已经更新,若未更新,则进行相应处理。

如何查看 InstallStrategy cm

在集群中我们 可以使用 kubectl get cm -n kubevirt kubevirt-install-strategy-XXX -o yaml 去获取InstallStrategy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
data:
  manifests: H4sIAAAAAAAA/+y9/3Lkt
  ...
  特别长一段
  ...
  AAAP//gXyQ6p/qHwA=
kind: ConfigMap
metadata:
  annotations:
    kubevirt.io/install-strategy-cm-encoding: gzip+base64
    kubevirt.io/install-strategy-identifier: 22adb8590cd9598f0f4c36dfba27d0a1eefcb410
    kubevirt.io/install-strategy-registry: registry.eki/zhuanlan
    kubevirt.io/install-strategy-version: v9.98.8
  creationTimestamp: "2023-01-09T01:34:10Z"
  generateName: kubevirt-install-strategy-
  labels:
    app.kubernetes.io/managed-by: virt-operator
    kubevirt.io/install-strategy: ""
  name: kubevirt-install-strategy-4nvgx
  namespace: kubevirt
  resourceVersion: "122443938"
  uid: c8926a4c-4ac2-4ffe-a558-044719af8408

data 字段经过了 base64 并压缩,可以通过下面脚本处理了下来获得实际含义。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package main

import (
	"bytes"
	"compress/gzip"
	"encoding/base64"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
)

func main() {
	logFile, err := os.Open("C:\\Users\\column\\Desktop\\tmp logs.txt")
	if err != nil {
		log.Fatalln("读取日志文件失败", err)
	}
	defer logFile.Close()
	fileinfo, err := logFile.Stat()
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	size := fileinfo.Size()
	fmt.Println(size)
	strategy := make([]byte, size)
	readSize, err := logFile.Read(strategy)
	fmt.Println(readSize)
	targetfile, err := os.Create("C:\\Users\\column\\Desktop\\installstrategyExapmle.txt")
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	tmstr, err := decodeManifests(strategy)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	WSize, err := targetfile.Write([]byte(tmstr))
	fmt.Println(WSize)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	return
}
func decodeManifests(strategy []byte) (string, error) {
	var decodedStrategy strings.Builder

	gzippedStrategy, err := base64.StdEncoding.DecodeString(string(strategy))
	if err != nil {
		return "", err
	}
	buf := bytes.NewBuffer(gzippedStrategy)
	zr, err := gzip.NewReader(buf)
	if err != nil {
		return "", err
	}
	if _, err := io.Copy(&decodedStrategy, zr); err != nil {
		return "", err
	}
	return decodedStrategy.String(), nil
}
updatedupdated2023-03-012023-03-01