|
1 | 1 | # Author: Nuno Aguiar
|
2 | 2 | help:
|
3 |
| - text : Given a Kubernetes cluster tries to perform crictl operations such as listing images or removing an image in one or all nodes. |
| 3 | + text : Given a Kubernetes cluster tries to perform crictl operations such as list, remove, prune and pull images in one or all nodes. |
4 | 4 | expects:
|
5 | 5 | - name : op
|
6 |
| - desc : "The operation to perform: list, rmi" |
| 6 | + desc : "The operation to perform: list, pull, rmi, prune, interactive" |
7 | 7 | example : list
|
8 | 8 | mandatory: true
|
9 | 9 | - name : node
|
|
23 | 23 | example : nmaguiar/imgutils
|
24 | 24 | mandatory: false
|
25 | 25 | - name : socket
|
26 |
| - desc : The path to containerd socket if the node is different from /run/container.d/containerd.sock (e.g. k3s /run/k3s/containerd/containerd.sock) |
| 26 | + desc : "The path to containerd socket if the node is different from /run/container.d/containerd.sock (e.g. k3s: /run/k3s/containerd/containerd.sock; os: /var/run/crio/crio.sock; eks/gke/aks: /run/containerd/containerd.sock)" |
27 | 27 | example : /run/k3s/containerd/containerd.sock
|
28 | 28 | mandatory: false
|
29 | 29 | - name : crio
|
|
68 | 68 | - List images in nodes
|
69 | 69 | rmi :
|
70 | 70 | - Remove image in nodes
|
| 71 | + prune: |
| 72 | + - Prune images in nodes |
| 73 | + pull: |
| 74 | + - Pull image in nodes |
| 75 | + interactive: |
| 76 | + - Interactive over a node |
71 | 77 | ((default )):
|
72 | 78 | - List images in nodes
|
73 | 79 |
|
@@ -95,6 +101,73 @@ jobs:
|
95 | 101 | else
|
96 | 102 | args.nodes = $kube().getNodes().map(r => r.Metadata.Name)
|
97 | 103 |
|
| 104 | +# ------------------------------ |
| 105 | +- name : Interactive over a node |
| 106 | + from : |
| 107 | + - Load YAML functionality |
| 108 | + check: |
| 109 | + in: |
| 110 | + ns : isString.default("kube-system") |
| 111 | + name : isString.default("imgutils") |
| 112 | + node : isString |
| 113 | + jobimg : isString.default("nmaguiar/imgutils") |
| 114 | + socket : isString.default(__) |
| 115 | + crio : toBoolean.isBoolean.default(false) |
| 116 | + exec : | |
| 117 | + if (isDef(args.node) && args.node.indexOf(",") >= 0) throw "For interactive mode you can only specify one node" |
| 118 | +
|
| 119 | + var def = { |
| 120 | + apiVersion: "v1", |
| 121 | + spec: { |
| 122 | + nodeName: args.node, |
| 123 | + containers: [ |
| 124 | + { |
| 125 | + name: args.name, |
| 126 | + image: args.jobimg, |
| 127 | + stdin: true, |
| 128 | + stdinOnce: true, |
| 129 | + tty: true, |
| 130 | + securityContext: { |
| 131 | + privileged: true |
| 132 | + }, |
| 133 | + args: [ |
| 134 | + "sudo", "-E", "/bin/bash" |
| 135 | + ], |
| 136 | + env: [{ |
| 137 | + name: "CONTAINER_RUNTIME_ENDPOINT", |
| 138 | + value: (args.crio ? "unix:///run/crio/crio.sock" : "unix:///run/containerd/containerd.sock") |
| 139 | + }], |
| 140 | + volumeMounts: [{ |
| 141 | + name: "cri", |
| 142 | + mountPath: (args.crio ? "unix:///run/crio/crio.sock" : "/run/containerd/containerd.sock") |
| 143 | + }] |
| 144 | + } |
| 145 | + ], |
| 146 | + volumes: [{ |
| 147 | + name: "cri", |
| 148 | + hostPath: { |
| 149 | + path: args.socket |
| 150 | + } |
| 151 | + }] |
| 152 | + } |
| 153 | + } |
| 154 | +
|
| 155 | + $sh(["/bin/sh", "-c", [ |
| 156 | + "kubectl", |
| 157 | + "run", |
| 158 | + "-n", |
| 159 | + args.ns, |
| 160 | + args.name, |
| 161 | + "--rm", |
| 162 | + "-ti", |
| 163 | + "--image=" + args.jobimg, |
| 164 | + "--overrides=\"" + stringify(def, __ ,"").replace(/"/g, "\\\"") + "\"", |
| 165 | + "--", |
| 166 | + "sudo", |
| 167 | + "-E", |
| 168 | + "/bin/bash" |
| 169 | + ].join(" ")]).exec() |
| 170 | +
|
98 | 171 | # ----------------------------
|
99 | 172 | - name : Remove image in nodes
|
100 | 173 | from :
|
@@ -141,6 +214,96 @@ jobs:
|
141 | 214 |
|
142 | 215 | $doWait($doAll(_dos))
|
143 | 216 |
|
| 217 | +# ---------------------------- |
| 218 | +- name : Prune images in nodes |
| 219 | + from : |
| 220 | + #- Determine backup file |
| 221 | + - Load YAML functionality |
| 222 | + - Determine list of nodes |
| 223 | + check: |
| 224 | + in: |
| 225 | + ns : isString.default("kube-system") |
| 226 | + name : isString.default("imgprune") |
| 227 | + node : isString.default(__) |
| 228 | + jobimg : isString.default("nmaguiar/imgutils") |
| 229 | + socket : isString.default(__) |
| 230 | + crio : toBoolean.isBoolean.default(false) |
| 231 | + exec : | |
| 232 | + var _dos = [] |
| 233 | + args.nodes.forEach(node => { |
| 234 | + _dos.push($do(() => { |
| 235 | + var _r = $job("Get crictl data", { |
| 236 | + init : args.init, |
| 237 | + ns : args.ns, |
| 238 | + name : args.name + "-" + md5(node).substr(0, 7), |
| 239 | + node : node, |
| 240 | + cmd : "rmi --prune", |
| 241 | + jobimg : args.jobimg, |
| 242 | + socket : args.socket, |
| 243 | + crio : args.crio |
| 244 | + }) |
| 245 | +
|
| 246 | + if (isDef(_r.data) && isDef(_r.data._error)) { |
| 247 | + var _out = _r.data._error.error.substr(_r.data._error.error.indexOf(args.init.sep) + args.init.sep.length + 1) |
| 248 | + _out = _out.split("\n").map(r => "[" + node + "] " + r).join("\n") |
| 249 | + logErr(_r.data._error.node + __logFormat.separator + "Error on running command:\n" + _out) |
| 250 | + } else { |
| 251 | + if (isDef(_r.data) && isDef(_r.data.output)) { |
| 252 | + var _out = _r.data.output.substr(_r.data.output.indexOf(args.init.sep) + args.init.sep.length + 1) |
| 253 | + _out = _out.split("\n").map(r => "[" + node + "] " + r).join("\n") |
| 254 | + print(_out) |
| 255 | + } |
| 256 | + } |
| 257 | + })) |
| 258 | + }) |
| 259 | +
|
| 260 | + $doWait($doAll(_dos)) |
| 261 | +
|
| 262 | +# -------------------------- |
| 263 | +- name : Pull image in nodes |
| 264 | + from : |
| 265 | + #- Determine backup file |
| 266 | + - Load YAML functionality |
| 267 | + - Determine list of nodes |
| 268 | + check: |
| 269 | + in: |
| 270 | + ns : isString.default("kube-system") |
| 271 | + name : isString.default("imgprune") |
| 272 | + node : isString.default(__) |
| 273 | + jobimg : isString.default("nmaguiar/imgutils") |
| 274 | + socket : isString.default(__) |
| 275 | + crio : toBoolean.isBoolean.default(false) |
| 276 | + exec : | |
| 277 | + var _dos = [] |
| 278 | + args.nodes.forEach(node => { |
| 279 | + _dos.push($do(() => { |
| 280 | + var _r = $job("Get crictl data", { |
| 281 | + init : args.init, |
| 282 | + ns : args.ns, |
| 283 | + name : args.name + "-" + md5(node).substr(0, 7), |
| 284 | + node : node, |
| 285 | + cmd : "pull " + args.image, |
| 286 | + jobimg : args.jobimg, |
| 287 | + socket : args.socket, |
| 288 | + crio : args.crio |
| 289 | + }) |
| 290 | +
|
| 291 | + if (isDef(_r.data) && isDef(_r.data._error)) { |
| 292 | + var _out = _r.data._error.error.substr(_r.data._error.error.indexOf(args.init.sep) + args.init.sep.length + 1) |
| 293 | + _out = _out.split("\n").map(r => "[" + node + "] " + r).join("\n") |
| 294 | + logErr(_r.data._error.node + __logFormat.separator + "Error on running command:\n" + _out) |
| 295 | + } else { |
| 296 | + if (isDef(_r.data) && isDef(_r.data.output)) { |
| 297 | + var _out = _r.data.output.substr(_r.data.output.indexOf(args.init.sep) + args.init.sep.length + 1) |
| 298 | + _out = _out.split("\n").map(r => "[" + node + "] " + r).join("\n") |
| 299 | + print(_out) |
| 300 | + } |
| 301 | + } |
| 302 | + })) |
| 303 | + }) |
| 304 | +
|
| 305 | + $doWait($doAll(_dos)) |
| 306 | +
|
144 | 307 | # ------------------------------
|
145 | 308 | - name : Load YAML functionality
|
146 | 309 | exec : |
|
@@ -224,7 +387,7 @@ jobs:
|
224 | 387 | const sep = args.init.sep
|
225 | 388 |
|
226 | 389 | cmds.push("echo " + sep)
|
227 |
| - cmds.push("sudo crictl -r unix://" + args.socket + " " + args.cmd) |
| 390 | + cmds.push("sudo crictl -r unix://" + (args.crio ? "/run/crio/crio.sock" : "/run/containerd/containerd.sock") + " " + args.cmd) |
228 | 391 |
|
229 | 392 | def.spec.template.spec.containers[0].command = [
|
230 | 393 | "/bin/sh",
|
|
0 commit comments