|
| 1 | +# cloud-agent-operator |
| 2 | + |
| 3 | +云原生的 agent-server 任务执行器 |
| 4 | + |
| 5 | +## 快速开始 |
| 6 | + |
| 7 | +### 配置 |
| 8 | +- configmap 里的 `SERVER-ADDRESS` 参数 指向 agent-server 的地址 |
| 9 | +- configmap 里的 `BIZ-ID` 参数 配置为对应业务的 ID |
| 10 | + |
| 11 | +### 安装 |
| 12 | +```shell |
| 13 | +kubectl apply -f ./deploy/crd.yaml |
| 14 | +kubectl apply -f ./deploy/crd-deploy.yaml |
| 15 | +kubectl -n cloud-agent-operator-system apply -f ./deploy/redis.yaml |
| 16 | +kubectl -n cloud-agent-operator-system apply -f ./deploy/configmap.yaml |
| 17 | +``` |
| 18 | + |
| 19 | +## 快速使用 |
| 20 | +- [必填] taskId 任务ID (唯一) |
| 21 | +- [必填] taskType 任务类型 (CloudTask) |
| 22 | +- [必填] agentID 用于执行云原生任务的 AgentID |
| 23 | +- [必填] taskYaml 脚本的定义, 详情见后面的配置 |
| 24 | +- [必填] taskYaml 脚本的定义, 详情见后面的配置 |
| 25 | +- [可选] timeout 超时时间(秒)(默认600秒) |
| 26 | +- [可选] scriptParams 脚本使用的参数, 通过环境变量添加 `codo_` 前缀注入( abc 在环境变量中是 $codo_abc) |
| 27 | +- [可选] namespace 脚本执行的命名空间, 默认为 default |
| 28 | + |
| 29 | +```shell |
| 30 | +curl -X POST {agent-server-http-addr}/api/v1/agent/task/batch \ |
| 31 | + -H 'Content-Type: application/json' \ |
| 32 | + -d '[ |
| 33 | + { |
| 34 | + "taskId": "task123", |
| 35 | + "taskType": "CloudTask", |
| 36 | + "agentId": "agent456", |
| 37 | + "args": { |
| 38 | + "timeout": 60, |
| 39 | + "scriptParams": "{\"abc\": \"1\"}", |
| 40 | + "namespace": "default", |
| 41 | + "taskYaml": "# [必选] 任务定义\ntaskSpec:\n # [必选] 任务展示名称\n displayName: \"cc-test\"\n\n # [必选] 任务步骤定义\n # 任务有两种模式(只能选其一)\n # - script 模式:\n # - command 模式:\n steps:\n # [必选] 步骤名称\n - name: \"step1\"\n # [可选] 超时时间(默认60分钟)\n # 持续时间字符串是可能有符号的十进制数字序列,每个十进制数字都带有可选的分数和单位后缀,\n # 例如“300ms”、“-1.5h”或“2h45m”。有效的时间单位为“ns”、“us”(或“μs”)、“ms”、“s”、“m”、“h”。\n timeout: \"10s\"\n # [必选] 任务运行所处的镜像\n image: \"ccr.ccs.tencentyun.com/library/alpine:latest\"\n # [必选] 运行的脚本(与 command 二选一)\n script: |\n #!/bin/sh\n echo \"Hello World step1 FOO=$FOO\"\n - name: \"step2\"\n image: \"ccr.ccs.tencentyun.com/library/alpine:latest\"\n # [必选] 指定命令执行(与 script 二选一)\n command: [ codo ]\n args: [ \"set-context\", \"abc=123\" ]\n - name: \"step3\"\n image: \"ccr.ccs.tencentyun.com/library/alpine:latest\"\n script: |\n #!/bin/python\n import os\n print(\"Hello World step3 FOO=%s\" % os.environ.get(\"FOO\"))" |
| 42 | + } |
| 43 | + } |
| 44 | +]' |
| 45 | +``` |
| 46 | + |
| 47 | +## [简单任务定义](example.min.yaml) |
| 48 | +```yaml |
| 49 | +# [必选] 任务定义 |
| 50 | +taskSpec: |
| 51 | + # [必选] 任务展示名称 |
| 52 | + displayName: "cc-test" |
| 53 | + |
| 54 | + # [必选] 任务步骤定义 |
| 55 | + # 任务有两种模式(只能选其一) |
| 56 | + # - script 模式: |
| 57 | + # - command 模式: |
| 58 | + steps: |
| 59 | + # [必选] 步骤名称 |
| 60 | + - name: "step1" |
| 61 | + # [可选] 超时时间(默认60分钟) |
| 62 | + # 持续时间字符串是可能有符号的十进制数字序列,每个十进制数字都带有可选的分数和单位后缀, |
| 63 | + # 例如“300ms”、“-1.5h”或“2h45m”。有效的时间单位为“ns”、“us”(或“μs”)、“ms”、“s”、“m”、“h”。 |
| 64 | + timeout: "10s" |
| 65 | + # [必选] 任务运行所处的镜像 |
| 66 | + image: "ccr.ccs.tencentyun.com/library/alpine:latest" |
| 67 | + # [必选] 运行的脚本(与 command 二选一) |
| 68 | + script: | |
| 69 | + #!/bin/sh |
| 70 | + echo "Hello World step1 FOO=$FOO" |
| 71 | + - name: "step2" |
| 72 | + image: "ccr.ccs.tencentyun.com/library/alpine:latest" |
| 73 | + # [必选] 指定命令执行(与 script 二选一) |
| 74 | + command: [ codo ] |
| 75 | + args: [ "set-context", "abc=123" ] |
| 76 | + - name: "step3" |
| 77 | + image: "ccr.ccs.tencentyun.com/library/alpine:latest" |
| 78 | + script: | |
| 79 | + #!/bin/python |
| 80 | + import os |
| 81 | + print("Hello World step3 FOO=%s" % os.environ.get("FOO")) |
| 82 | +
|
| 83 | +``` |
| 84 | +
|
| 85 | +## [全量任务定义](example.full.yaml) |
| 86 | +```yaml |
| 87 | +# [可选] pod 的资源限制 |
| 88 | +# 用户可以选择在任务级指定资源需求,而不是在每个 Step 上指定资源需求。如果用户指定了任务级资源要求, |
| 89 | +# 它将确保 kubelet 只为执行 Task 的 Steps 保留该数量的资源。如果用户指定了任务级资源限制,则任何 Step 都不能使用超过该数量的资源。 |
| 90 | +computeResources: |
| 91 | + requests: |
| 92 | + memory: "128Mi" # 申请 512 MB 的内存 |
| 93 | + cpu: "60m" # 申请 1 Core 的 CPU |
| 94 | + |
| 95 | +# [可选] 预计生成的 pod 的要求 |
| 96 | +podTemplate: |
| 97 | + # [可选] NodeSelector 是一个选择器,它必须为 true 才能使 pod 适合节点。 |
| 98 | + # 它必须与要在该节点上调度 pod 的节点标签相匹配。更多信息:https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ |
| 99 | + nodeSelector: { } |
| 100 | + # [可选] pod 的环境变量 |
| 101 | + env: [ ] |
| 102 | + # [可选] 此 Toleration 附加到的 pod 可以容忍使用匹配运算符 <operator> 与三元组 <key,value,effect> 匹配的任何污点。 |
| 103 | + tolerations: |
| 104 | + - key: "key" |
| 105 | + operator: "Equal" |
| 106 | + value: "value" |
| 107 | + effect: "NoSchedule" |
| 108 | + # [可选] pod 亲缘性配置 |
| 109 | + # 更多信息:https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ |
| 110 | + affinity: |
| 111 | + nodeAffinity: |
| 112 | + requiredDuringSchedulingIgnoredDuringExecution: |
| 113 | + nodeSelectorTerms: |
| 114 | + - matchExpressions: |
| 115 | + - key: kubernetes.io/e2e-az-name |
| 116 | + operator: In |
| 117 | + values: |
| 118 | + - e2e-az1 |
| 119 | + preferredDuringSchedulingIgnoredDuringExecution: |
| 120 | + - weight: 1 |
| 121 | + preference: |
| 122 | + matchExpressions: |
| 123 | + - key: another-node-label-key |
| 124 | + operator: In |
| 125 | + values: |
| 126 | + - another-node-label-value |
| 127 | + podAffinity: |
| 128 | + requiredDuringSchedulingIgnoredDuringExecution: |
| 129 | + - labelSelector: |
| 130 | + matchExpressions: |
| 131 | + - key: security |
| 132 | + operator: In |
| 133 | + values: |
| 134 | + - S1 |
| 135 | + topologyKey: failure-domain.beta.kubernetes.io/zone |
| 136 | + podAntiAffinity: |
| 137 | + requiredDuringSchedulingIgnoredDuringExecution: |
| 138 | + - labelSelector: |
| 139 | + matchExpressions: |
| 140 | + - key: security |
| 141 | + operator: In |
| 142 | + values: |
| 143 | + - S1 |
| 144 | + topologyKey: failure-domain.beta.kubernetes.io/zone |
| 145 | + |
| 146 | + # [可选] SecurityContext 保存 Pod 级别的安全属性和通用容器设置。默认为空。每个字段的默认值请参阅类型说明。 |
| 147 | + securityContext: |
| 148 | + runAsNonRoot: true |
| 149 | + runAsUser: 1001 |
| 150 | + # [可选] 属于 pod 的容器可以挂载的卷列表。更多信息:https://kubernetes.io/docs/concepts/storage/volumes |
| 151 | + volumes: |
| 152 | + - name: my-cache |
| 153 | + persistentVolumeClaim: |
| 154 | + claimName: my-volume-claim |
| 155 | + # [可选] 设置容器的运行时类名 |
| 156 | + # RuntimeClassName 指的是 node.k8s.io 组中的一个 RuntimeClass 对象, |
| 157 | + # 该对象应该用于运行这个 pod。如果没有 RuntimeClass 资源 |
| 158 | + # 匹配指定的类名,则该 pod 将不会运行。如果未设置或为空,将 |
| 159 | + # 使用"legacy"(遗留)RuntimeClass,这是一个隐式类,其定义为空, |
| 160 | + # 使用默认的运行时处理程序。 |
| 161 | + # 更多信息: https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md |
| 162 | + # 这是 Kubernetes v1.14 版本中的一个 beta 特性。 |
| 163 | + runtimeClassName: "runc" |
| 164 | + |
| 165 | + # [可选] AutomountServiceAccountToken 指示以此服务帐户运行的 Pod 是否应自动挂载 API 令牌。可以在 Pod 级别覆盖。 |
| 166 | + automountServiceAccountToken: false |
| 167 | + # [可选] Pod 设置 DNS 策略。默认为“ClusterFirst”。有效值为 |
| 168 | + # “ClusterFirstWithHostNet”、“ClusterFirst”、“默认”或“无”。 |
| 169 | + # DNSConfig 中给出的 DNS 参数将与使用 DNSPolicy 选择的策略合并。 |
| 170 | + # 要将 DNS 选项与 hostNetwork 一起设置,您必须将 DNS 策略显式指定为“ClusterFirstWithHostNet”。 |
| 171 | + dnsPolicy: "" |
| 172 | + # [可选] 指定 Pod 的 DNS 参数。此处指定的参数将合并到基于 DNSPolicy 生成的 DNS 配置中。 |
| 173 | + dnsConfig: |
| 174 | + nameservers: # DNS 名称服务器 IP 地址的列表。这将被附加到从 DNSPolicy 生成的基本名称服务器中。重复的名称服务器将被删除。 |
| 175 | + - "8.8.8.8" |
| 176 | + searches: # 用于主机名查找的 DNS 搜索域列表。这将被附加到从 DNSPolicy 生成的基本搜索路径中。重复的搜索路径将被删除。 |
| 177 | + - "svc.cluster.local" |
| 178 | + options: # DNS 解析器选项列表。这将与 DNSPolicy 生成的基本选项合并。重复的条目将被删除。选项中给出的解析选项将覆盖基本 DNSPolicy 中出现的解析选项。 |
| 179 | + - name: "ndots" |
| 180 | + value: "2" |
| 181 | + # [可选] EnableServiceLinks 指示是否应将有关服务的信息注入到 pod 的环境变量中,与 Docker 链接的语法相匹配。可选:默认为 true。 |
| 182 | + enableServiceLinks: true |
| 183 | + # [可选] 设置容器的优先级类名 |
| 184 | + # - 如果指定,则指示 Pod 的优先级。 “system-node-key”和“system-cluster-key”是两个特殊的关键字, |
| 185 | + # 表示最高优先级,前者为最高优先级。任何其他名称必须通过创建具有该名称的 PriorityClass 对象来定义。 |
| 186 | + # - 如果未指定,Pod 优先级将为默认值;如果没有默认值,则 Pod 优先级为零。 |
| 187 | + priorityClassName: "" |
| 188 | + # [可选] 设置容器的调度策略 |
| 189 | + schedulerName: "default-scheduler" |
| 190 | + # [可选] ImagePullSecrets 是对同一命名空间中 Secrets 的引用的可选列表,用于拉取此 PodSpec 使用的任何镜像。 |
| 191 | + # 如果指定,这些 Secrets 将传递给各个拉取器实现以供他们使用。 |
| 192 | + # 更多信息:https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod |
| 193 | + imagePullSecrets: |
| 194 | + - name: my-secret # 引用对象名, 参考: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names |
| 195 | + # [可选] HostAliases 是一个可选的主机和 IP 列表,如果指定,将被注入到 Pod 的主机文件中。这仅对非 hostNetwork pod 有效。 |
| 196 | + hostAliases: |
| 197 | + - ip: "" |
| 198 | + hostnames: [ "" ] |
| 199 | + # [可选] 此 Pod 请求主机网络。使用主机的网络命名空间。如果设置此选项,则必须指定将使用的端口。默认为 false。 |
| 200 | + hostNetwork: false |
| 201 | + # [可选] TopologySpreadConstraints 描述一组 Pod 应如何跨拓扑域分布。调度程序将以遵守约束的方式调度 Pod。所有topologySpreadConstraints 都是AND 运算。 |
| 202 | + # corev1.TopologySpreadConstraint |
| 203 | + topologySpreadConstraints: |
| 204 | + - maxSkew: 1 |
| 205 | + topologyKey: kubernetes.io/hostname |
| 206 | + whenUnsatisfiable: DoNotSchedule |
| 207 | + labelSelector: |
| 208 | + matchLabels: |
| 209 | + app: myapp |
| 210 | + namespaces: |
| 211 | + - mynamespace |
| 212 | + |
| 213 | + |
| 214 | +# [可选] 超时时间(默认60分钟) |
| 215 | +# 持续时间字符串是可能有符号的十进制数字序列,每个十进制数字都带有可选的分数和单位后缀, |
| 216 | +# 例如“300ms”、“-1.5h”或“2h45m”。有效的时间单位为“ns”、“us”(或“μs”)、“ms”、“s”、“m”、“h”。 |
| 217 | +timeout: "10m" # 10分钟 |
| 218 | + |
| 219 | + |
| 220 | +# [必选] 任务定义 |
| 221 | +taskSpec: |
| 222 | + # [必选] 任务展示名称 |
| 223 | + displayName: "cc-test" |
| 224 | + # [可选] 描述 |
| 225 | + description: "这是一份描述" |
| 226 | + # [可选] 存储定义 |
| 227 | + # 除了为输入和输出资源隐式创建的卷之外,指定一个或多个 Volumes ,以便 Task 中的 Steps 执行。 |
| 228 | + volumes: |
| 229 | + - name: my-volume |
| 230 | + emptyDir: { } |
| 231 | + |
| 232 | + # [必选] 任务步骤定义 |
| 233 | + # 任务有两种模式(只能选其一) |
| 234 | + # - script 模式: |
| 235 | + # - command 模式: |
| 236 | + steps: |
| 237 | + # [必选] 步骤名称 |
| 238 | + - name: "step1" |
| 239 | + # [可选] 超时时间(默认60分钟) |
| 240 | + # 持续时间字符串是可能有符号的十进制数字序列,每个十进制数字都带有可选的分数和单位后缀, |
| 241 | + # 例如“300ms”、“-1.5h”或“2h45m”。有效的时间单位为“ns”、“us”(或“μs”)、“ms”、“s”、“m”、“h”。 |
| 242 | + timeout: "10s" |
| 243 | + # [必选] 任务运行所处的镜像 |
| 244 | + image: "ccr.ccs.tencentyun.com/library/alpine:latest" |
| 245 | + # [可选] 镜像拉取策略 |
| 246 | + # [Always | Never | IfNotPresent] |
| 247 | + # 如果 tag 是 :latest ,则 默认是 Always , 其他情况的 tag , 默认都是 IfNotPresent |
| 248 | + imagePullPolicy: "IfNotPresent" |
| 249 | + # [可选] 指定环境变量, 这里的环境变量是静态的, 会和 codo 的参数进行合并, 如果 key 冲突时, 以 codo 的参数为准 |
| 250 | + env: |
| 251 | + - name: "FOO" |
| 252 | + value: "baz" |
| 253 | + # [可选] 指定 step容器 的资源需求 |
| 254 | + # 所有 step 的配置必须加起来小于 pod 的配置 |
| 255 | + # 这里的配置会在上层被覆盖, key 级别覆盖, 例如上层只指定 memory: 128Mi, 则 cpu 还是按照 500m 来使用 |
| 256 | + computeResources: |
| 257 | + requests: |
| 258 | + memory: "256Mi" # 申请 256 MB 的内存 |
| 259 | + cpu: "500m" # 申请 0.5 Core 的 CPU |
| 260 | + # [可选] 工作目录 |
| 261 | + workingDir: /data |
| 262 | + # [可选] 当 step 出错时的处理方式 |
| 263 | + # [ continue | stopAndFail ] |
| 264 | + onError: stopAndFail |
| 265 | + # [可选] securityContext 是 Kubernetes 和 Tekton 中的一个重要配置,用于设置容器的安全上下文。 |
| 266 | + # 在 Step 中,securityContext 可以用来控制容器的权限和行为。 |
| 267 | + # securityContext: |
| 268 | + # runAsUser: 1000 |
| 269 | + # runAsGroup: 3000 |
| 270 | + # fsGroup: 2000 |
| 271 | + # allowPrivilegeEscalation: false |
| 272 | + # privileged: false |
| 273 | + # capabilities: |
| 274 | + # drop: |
| 275 | + # - ALL |
| 276 | + # readOnlyRootFilesystem: true |
| 277 | + # [可选] 挂载存储 |
| 278 | + volumeMounts: |
| 279 | + - name: my-volume |
| 280 | + mountPath: /data |
| 281 | + # [必选] 运行的脚本(与 command 二选一) |
| 282 | + script: | |
| 283 | + #!/bin/sh |
| 284 | + echo "Hello World step1 FOO=$FOO" |
| 285 | + - name: "step2" |
| 286 | + image: "ccr.ccs.tencentyun.com/library/alpine:latest" |
| 287 | + # [必选] 指定命令执行(与 script 二选一) |
| 288 | + command: [ codo ] |
| 289 | + args: [ "set-context", "abc=123" ] |
| 290 | + - name: "step3" |
| 291 | + image: "ccr.ccs.tencentyun.com/library/alpine:latest" |
| 292 | + script: | |
| 293 | + #!/bin/sh |
| 294 | + echo "context=====$(codo get-context abc)" |
| 295 | + - name: "step4-python-test" |
| 296 | + image: "harbor.123u.com/public/rocky9.1-python3:latest" |
| 297 | + script: | |
| 298 | + #!/bin/python3.9 |
| 299 | + from floating import Floating |
| 300 | + # 请手动指定,调用api模式。 |
| 301 | + fl = Floating(api_mode=True) |
| 302 | + fl.logger.info("hello world") |
| 303 | +``` |
0 commit comments