underpost 2.8.78 → 2.8.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/deploy.js +3 -0
- package/cli.md +22 -6
- package/docker-compose.yml +1 -1
- package/manifests/lxd/lxd-admin-profile.yaml +16 -0
- package/manifests/lxd/lxd-preseed.yaml +58 -0
- package/manifests/lxd/underpost-setup.sh +146 -0
- package/package.json +1 -1
- package/src/cli/cluster.js +63 -20
- package/src/cli/deploy.js +7 -7
- package/src/cli/index.js +19 -2
- package/src/cli/lxd.js +145 -2
- package/src/index.js +9 -1
package/README.md
CHANGED
package/bin/deploy.js
CHANGED
|
@@ -822,6 +822,9 @@ try {
|
|
|
822
822
|
}
|
|
823
823
|
|
|
824
824
|
case 'version-deploy': {
|
|
825
|
+
shellExec(
|
|
826
|
+
`underpost secret underpost --create-from-file /home/dd/engine/engine-private/conf/dd-cron/.env.production`,
|
|
827
|
+
);
|
|
825
828
|
shellExec(`node bin/build dd conf`);
|
|
826
829
|
shellExec(`git add . && cd ./engine-private && git add .`);
|
|
827
830
|
shellExec(`node bin cmt . ci package-pwa-microservices-template`);
|
package/cli.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
## underpost ci/cd cli v2.8.
|
|
1
|
+
## underpost ci/cd cli v2.8.79
|
|
2
2
|
|
|
3
3
|
### Usage: `underpost [options] [command]`
|
|
4
4
|
```
|
|
@@ -204,7 +204,6 @@ Options:
|
|
|
204
204
|
--mongodb Init with mongodb statefulset
|
|
205
205
|
--postgresql Init with postgresql statefulset
|
|
206
206
|
--mongodb4 Init with mongodb 4.4 service
|
|
207
|
-
--istio Init base istio cluster
|
|
208
207
|
--valkey Init with valkey service
|
|
209
208
|
--contour Init with project contour base HTTPProxy and envoy
|
|
210
209
|
--cert-manager Init with letsencrypt-prod ClusterIssuer
|
|
@@ -218,6 +217,11 @@ Options:
|
|
|
218
217
|
--info-capacity display current total machine capacity info
|
|
219
218
|
--info-capacity-pod display current machine capacity pod info
|
|
220
219
|
--pull-image Set optional pull associated image
|
|
220
|
+
--init-host Install k8s node necessary cli env: kind, kubeadm,
|
|
221
|
+
docker, podman, helm
|
|
222
|
+
--config Set k8s base node config
|
|
223
|
+
--worker Set worker node context
|
|
224
|
+
--chown Set k8s kube chown
|
|
221
225
|
-h, --help display help for command
|
|
222
226
|
|
|
223
227
|
```
|
|
@@ -471,10 +475,22 @@ Options:
|
|
|
471
475
|
Lxd management
|
|
472
476
|
|
|
473
477
|
Options:
|
|
474
|
-
--init
|
|
475
|
-
--reset
|
|
476
|
-
--install
|
|
477
|
-
|
|
478
|
+
--init Init lxd
|
|
479
|
+
--reset Reset lxd on current machine
|
|
480
|
+
--install Install lxd on current machine
|
|
481
|
+
--dev Set dev context env
|
|
482
|
+
--control set control node vm context
|
|
483
|
+
--worker set worker node context
|
|
484
|
+
--create-vm <vm-id> Create default virtual machines
|
|
485
|
+
--init-vm <vm-id> Get init vm underpost script
|
|
486
|
+
--info-vm <vm-id> Get all info vm
|
|
487
|
+
--start-vm <vm-id> Start vm with networkt config
|
|
488
|
+
--root-size <gb-size> Set root size vm
|
|
489
|
+
--join-node <nodes> Comma separated worker and control node e. g.
|
|
490
|
+
k8s-worker-1,k8s-control
|
|
491
|
+
--expose <vm-name-ports> Vm name and : separated with Comma separated vm
|
|
492
|
+
port to expose e. g. k8s-control:80,443
|
|
493
|
+
-h, --help display help for command
|
|
478
494
|
|
|
479
495
|
```
|
|
480
496
|
|
package/docker-compose.yml
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
config:
|
|
2
|
+
limits.cpu: "2"
|
|
3
|
+
limits.memory: 4GB
|
|
4
|
+
description: vm nat network
|
|
5
|
+
devices:
|
|
6
|
+
eth0:
|
|
7
|
+
name: eth0
|
|
8
|
+
network: lxdbr0
|
|
9
|
+
type: nic
|
|
10
|
+
root:
|
|
11
|
+
path: /
|
|
12
|
+
pool: local # lxc storage list
|
|
13
|
+
size: 100GB
|
|
14
|
+
type: disk
|
|
15
|
+
name: admin-profile
|
|
16
|
+
used_by: []
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
config:
|
|
2
|
+
core.https_address: 127.0.0.1:8443
|
|
3
|
+
|
|
4
|
+
networks:
|
|
5
|
+
- name: lxdbr0
|
|
6
|
+
type: bridge
|
|
7
|
+
config:
|
|
8
|
+
ipv4.address: 10.250.250.1/24
|
|
9
|
+
ipv4.nat: "true"
|
|
10
|
+
ipv4.dhcp: "true"
|
|
11
|
+
ipv4.dhcp.ranges: 10.250.250.2-10.250.250.254
|
|
12
|
+
ipv4.firewall: "false"
|
|
13
|
+
ipv6.address: none
|
|
14
|
+
|
|
15
|
+
storage_pools:
|
|
16
|
+
- name: local
|
|
17
|
+
driver: zfs
|
|
18
|
+
config:
|
|
19
|
+
size: 100GiB
|
|
20
|
+
|
|
21
|
+
profiles:
|
|
22
|
+
- name: default
|
|
23
|
+
config: {}
|
|
24
|
+
description: "default profile"
|
|
25
|
+
devices:
|
|
26
|
+
root:
|
|
27
|
+
path: /
|
|
28
|
+
pool: local
|
|
29
|
+
type: disk
|
|
30
|
+
|
|
31
|
+
- name: admin-profile
|
|
32
|
+
description: "vm nat network admin profile"
|
|
33
|
+
config:
|
|
34
|
+
limits.cpu: "2"
|
|
35
|
+
limits.memory: 4GB
|
|
36
|
+
devices:
|
|
37
|
+
eth0:
|
|
38
|
+
name: eth0
|
|
39
|
+
network: lxdbr0
|
|
40
|
+
type: nic
|
|
41
|
+
root:
|
|
42
|
+
path: /
|
|
43
|
+
pool: local
|
|
44
|
+
size: 100GB
|
|
45
|
+
type: disk
|
|
46
|
+
|
|
47
|
+
projects: []
|
|
48
|
+
|
|
49
|
+
cluster:
|
|
50
|
+
server_name: lxd-node1
|
|
51
|
+
enabled: true
|
|
52
|
+
member_config: []
|
|
53
|
+
cluster_address: ""
|
|
54
|
+
cluster_certificate: ""
|
|
55
|
+
server_address: ""
|
|
56
|
+
cluster_password: ""
|
|
57
|
+
cluster_token: ""
|
|
58
|
+
cluster_certificate_path: ""
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
# Expand /dev/sda2 partition and resize filesystem automatically
|
|
6
|
+
|
|
7
|
+
# Check if parted is installed
|
|
8
|
+
if ! command -v parted &>/dev/null; then
|
|
9
|
+
echo "parted not found, installing..."
|
|
10
|
+
dnf install -y parted
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
# Get start sector of /dev/sda2
|
|
14
|
+
START_SECTOR=$(parted /dev/sda -ms unit s print | awk -F: '/^2:/{print $2}' | sed 's/s//')
|
|
15
|
+
|
|
16
|
+
# Resize the partition
|
|
17
|
+
parted /dev/sda ---pretend-input-tty <<EOF
|
|
18
|
+
unit s
|
|
19
|
+
resizepart 2 100%
|
|
20
|
+
Yes
|
|
21
|
+
quit
|
|
22
|
+
EOF
|
|
23
|
+
|
|
24
|
+
# Resize the filesystem
|
|
25
|
+
resize2fs /dev/sda2
|
|
26
|
+
|
|
27
|
+
echo "Disk and filesystem resized successfully."
|
|
28
|
+
sudo dnf install -y tar
|
|
29
|
+
sudo dnf install -y bzip2
|
|
30
|
+
sudo dnf install -y git
|
|
31
|
+
sudo dnf -y update
|
|
32
|
+
sudo dnf -y install epel-release
|
|
33
|
+
sudo dnf install -y ufw
|
|
34
|
+
sudo systemctl enable --now ufw
|
|
35
|
+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
|
|
36
|
+
NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
|
|
37
|
+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
|
38
|
+
nvm install 23.8.0
|
|
39
|
+
nvm use 23.8.0
|
|
40
|
+
echo "
|
|
41
|
+
██╗░░░██╗███╗░░██╗██████╗░███████╗██████╗░██████╗░░█████╗░░██████╗████████╗
|
|
42
|
+
██║░░░██║████╗░██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔══██╗██╔════╝╚══██╔══╝
|
|
43
|
+
██║░░░██║██╔██╗██║██║░░██║█████╗░░██████╔╝██████╔╝██║░░██║╚█████╗░░░░██║░░░
|
|
44
|
+
██║░░░██║██║╚████║██║░░██║██╔══╝░░██╔══██╗██╔═══╝░██║░░██║░╚═══██╗░░░██║░░░
|
|
45
|
+
╚██████╔╝██║░╚███║██████╔╝███████╗██║░░██║██║░░░░░╚█████╔╝██████╔╝░░░██║░░░
|
|
46
|
+
░╚═════╝░╚═╝░░╚══╝╚═════╝░╚══════╝╚═╝░░╚═╝╚═╝░░░░░░╚════╝░╚═════╝░░░░╚═╝░░░
|
|
47
|
+
|
|
48
|
+
Installing underpost k8s node ...
|
|
49
|
+
|
|
50
|
+
"
|
|
51
|
+
npm install -g underpost
|
|
52
|
+
chmod +x /root/.nvm/versions/node/v23.8.0/bin/underpost
|
|
53
|
+
sudo modprobe br_netfilter
|
|
54
|
+
mkdir -p /home/dd
|
|
55
|
+
cd $(underpost root)/underpost
|
|
56
|
+
underpost cluster --init-host
|
|
57
|
+
|
|
58
|
+
# Default flags
|
|
59
|
+
USE_KUBEADM=false
|
|
60
|
+
USE_KIND=false
|
|
61
|
+
USE_WORKER=false
|
|
62
|
+
|
|
63
|
+
# Loop through arguments
|
|
64
|
+
for arg in "$@"; do
|
|
65
|
+
case "$arg" in
|
|
66
|
+
--kubeadm)
|
|
67
|
+
USE_KUBEADM=true
|
|
68
|
+
;;
|
|
69
|
+
--kind)
|
|
70
|
+
USE_KIND=true
|
|
71
|
+
;;
|
|
72
|
+
--worker)
|
|
73
|
+
USE_WORKER=true
|
|
74
|
+
;;
|
|
75
|
+
esac
|
|
76
|
+
done
|
|
77
|
+
|
|
78
|
+
echo "USE_KUBEADM = $USE_KUBEADM"
|
|
79
|
+
echo "USE_KIND = $USE_KIND"
|
|
80
|
+
echo "USE_WORKER = $USE_WORKER"
|
|
81
|
+
|
|
82
|
+
underpost cluster --kubeadm
|
|
83
|
+
underpost cluster --reset
|
|
84
|
+
|
|
85
|
+
PORTS=(
|
|
86
|
+
22 # SSH
|
|
87
|
+
80 # HTTP
|
|
88
|
+
443 # HTTPS
|
|
89
|
+
53 # DNS (TCP/UDP)
|
|
90
|
+
66 # TFTP
|
|
91
|
+
67 # DHCP
|
|
92
|
+
69 # TFTP
|
|
93
|
+
111 # rpcbind
|
|
94
|
+
179 # Calico BGP
|
|
95
|
+
2049 # NFS
|
|
96
|
+
20048 # NFS mountd
|
|
97
|
+
4011 # PXE boot
|
|
98
|
+
5240 # snapd API
|
|
99
|
+
5248 # Juju controller
|
|
100
|
+
6443 # Kubernetes API
|
|
101
|
+
9153 # CoreDNS metrics
|
|
102
|
+
10250 # Kubelet API
|
|
103
|
+
10251 # kube-scheduler
|
|
104
|
+
10252 # kube-controller-manager
|
|
105
|
+
10255 # Kubelet read-only (deprecated)
|
|
106
|
+
10257 # controller-manager (v1.23+)
|
|
107
|
+
10259 # scheduler (v1.23+)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
PORT_RANGES=(
|
|
111
|
+
2379:2380 # etcd
|
|
112
|
+
# 30000:32767 # NodePort range
|
|
113
|
+
# 3000:3100 # App node ports
|
|
114
|
+
32765:32766 # Ephemeral ports
|
|
115
|
+
6783:6784 # Weave Net
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Open individual ports
|
|
119
|
+
for PORT in "${PORTS[@]}"; do
|
|
120
|
+
ufw allow ${PORT}/tcp
|
|
121
|
+
ufw allow ${PORT}/udp
|
|
122
|
+
done
|
|
123
|
+
|
|
124
|
+
# Open port ranges
|
|
125
|
+
for RANGE in "${PORT_RANGES[@]}"; do
|
|
126
|
+
ufw allow ${RANGE}/tcp
|
|
127
|
+
ufw allow ${RANGE}/udp
|
|
128
|
+
done
|
|
129
|
+
|
|
130
|
+
# Behavior based on flags
|
|
131
|
+
if $USE_KUBEADM; then
|
|
132
|
+
echo "Running control node with kubeadm..."
|
|
133
|
+
underpost cluster --kubeadm
|
|
134
|
+
# kubectl get pods --all-namespaces -o wide -w
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
if $USE_KIND; then
|
|
138
|
+
echo "Running control node with kind..."
|
|
139
|
+
underpost cluster
|
|
140
|
+
# kubectl get pods --all-namespaces -o wide -w
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
if $USE_WORKER; then
|
|
144
|
+
echo "Running worker..."
|
|
145
|
+
underpost cluster --worker --config
|
|
146
|
+
fi
|
package/package.json
CHANGED
package/src/cli/cluster.js
CHANGED
|
@@ -31,6 +31,10 @@ class UnderpostCluster {
|
|
|
31
31
|
pullImage: false,
|
|
32
32
|
dedicatedGpu: false,
|
|
33
33
|
kubeadm: false,
|
|
34
|
+
initHost: false,
|
|
35
|
+
config: false,
|
|
36
|
+
worker: false,
|
|
37
|
+
chown: false,
|
|
34
38
|
},
|
|
35
39
|
) {
|
|
36
40
|
// sudo dnf update
|
|
@@ -39,6 +43,9 @@ class UnderpostCluster {
|
|
|
39
43
|
// 3) Install Nvidia drivers from Rocky Linux docs
|
|
40
44
|
// 4) Install LXD with MAAS from Rocky Linux docs
|
|
41
45
|
// 5) Install MAAS src from snap
|
|
46
|
+
if (options.initHost === true) return UnderpostCluster.API.initHost();
|
|
47
|
+
if (options.config === true) UnderpostCluster.API.config();
|
|
48
|
+
if (options.chown === true) UnderpostCluster.API.chown();
|
|
42
49
|
const npmRoot = getNpmRootPath();
|
|
43
50
|
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
44
51
|
if (options.infoCapacityPod === true) return logger.info('', UnderpostDeploy.API.resourcesFactory());
|
|
@@ -89,28 +96,17 @@ class UnderpostCluster {
|
|
|
89
96
|
UnderpostDeploy.API.get('calico-kube-controllers')[0];
|
|
90
97
|
|
|
91
98
|
if (
|
|
99
|
+
!options.worker &&
|
|
92
100
|
!alrreadyCluster &&
|
|
93
|
-
((!options.
|
|
94
|
-
(options.
|
|
101
|
+
((!options.kubeadm && !UnderpostDeploy.API.get('kube-apiserver-kind-control-plane')[0]) ||
|
|
102
|
+
(options.kubeadm === true && !UnderpostDeploy.API.get('calico-kube-controllers')[0]))
|
|
95
103
|
) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// sudo systemctl disable kubelet
|
|
99
|
-
// shellExec(`sudo systemctl enable --now kubelet`);
|
|
100
|
-
shellExec(`containerd config default > /etc/containerd/config.toml`);
|
|
101
|
-
shellExec(`sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml`);
|
|
102
|
-
// shellExec(`cp /etc/kubernetes/admin.conf ~/.kube/config`);
|
|
103
|
-
// shellExec(`sudo systemctl restart kubelet`);
|
|
104
|
-
shellExec(`sudo service docker restart`);
|
|
105
|
-
shellExec(`sudo systemctl enable --now containerd.service`);
|
|
106
|
-
shellExec(`sudo swapoff -a; sudo sed -i '/swap/d' /etc/fstab`);
|
|
107
|
-
if (options.istio === true) {
|
|
108
|
-
shellExec(`sysctl net.bridge.bridge-nf-call-iptables=1`);
|
|
104
|
+
UnderpostCluster.API.config();
|
|
105
|
+
if (options.kubeadm === true) {
|
|
109
106
|
shellExec(
|
|
110
107
|
`sudo kubeadm init --pod-network-cidr=192.168.0.0/16 --control-plane-endpoint="${os.hostname()}:6443"`,
|
|
111
108
|
);
|
|
112
|
-
|
|
113
|
-
shellExec(`sudo chown $(id -u):$(id -g) $HOME/.kube/config**`);
|
|
109
|
+
UnderpostCluster.API.chown();
|
|
114
110
|
// https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart
|
|
115
111
|
shellExec(
|
|
116
112
|
`sudo kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.3/manifests/tigera-operator.yaml`,
|
|
@@ -119,17 +115,16 @@ class UnderpostCluster {
|
|
|
119
115
|
// `wget https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml`,
|
|
120
116
|
// );
|
|
121
117
|
shellExec(`sudo kubectl apply -f ${underpostRoot}/manifests/kubeadm-calico-config.yaml`);
|
|
122
|
-
shellExec(`sudo systemctl restart containerd`);
|
|
123
118
|
const nodeName = os.hostname();
|
|
124
119
|
shellExec(`kubectl taint nodes ${nodeName} node-role.kubernetes.io/control-plane:NoSchedule-`);
|
|
125
120
|
shellExec(
|
|
126
121
|
`kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml`,
|
|
127
122
|
);
|
|
128
123
|
} else {
|
|
129
|
-
shellExec(`sudo systemctl restart containerd`);
|
|
130
124
|
if (options.full === true || options.dedicatedGpu === true) {
|
|
131
125
|
// https://kubernetes.io/docs/tasks/manage-gpus/scheduling-gpus/
|
|
132
126
|
shellExec(`cd ${underpostRoot}/manifests && kind create cluster --config kind-config-cuda.yaml`);
|
|
127
|
+
UnderpostCluster.API.chown();
|
|
133
128
|
} else {
|
|
134
129
|
shellExec(
|
|
135
130
|
`cd ${underpostRoot}/manifests && kind create cluster --config kind-config${
|
|
@@ -137,7 +132,6 @@ class UnderpostCluster {
|
|
|
137
132
|
}.yaml`,
|
|
138
133
|
);
|
|
139
134
|
}
|
|
140
|
-
shellExec(`sudo chown $(id -u):$(id -g) $HOME/.kube/config**`);
|
|
141
135
|
}
|
|
142
136
|
} else logger.warn('Cluster already initialized');
|
|
143
137
|
|
|
@@ -285,6 +279,26 @@ class UnderpostCluster {
|
|
|
285
279
|
shellExec(`sudo kubectl apply -f ${underpostRoot}/manifests/${letsEncName}.yaml`);
|
|
286
280
|
}
|
|
287
281
|
},
|
|
282
|
+
|
|
283
|
+
config() {
|
|
284
|
+
shellExec(`sudo setenforce 0`);
|
|
285
|
+
shellExec(`sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config`);
|
|
286
|
+
shellExec(`sudo systemctl enable --now docker`);
|
|
287
|
+
shellExec(`sudo systemctl enable --now kubelet`);
|
|
288
|
+
shellExec(`containerd config default > /etc/containerd/config.toml`);
|
|
289
|
+
shellExec(`sed -i -e "s/SystemdCgroup = false/SystemdCgroup = true/g" /etc/containerd/config.toml`);
|
|
290
|
+
shellExec(`sudo service docker restart`);
|
|
291
|
+
shellExec(`sudo systemctl enable --now containerd.service`);
|
|
292
|
+
shellExec(`sudo swapoff -a; sudo sed -i '/swap/d' /etc/fstab`);
|
|
293
|
+
shellExec(`sudo systemctl daemon-reload`);
|
|
294
|
+
shellExec(`sudo systemctl restart containerd`);
|
|
295
|
+
shellExec(`sysctl net.bridge.bridge-nf-call-iptables=1`);
|
|
296
|
+
},
|
|
297
|
+
chown() {
|
|
298
|
+
shellExec(`mkdir -p ~/.kube`);
|
|
299
|
+
shellExec(`sudo -E cp -i /etc/kubernetes/admin.conf ~/.kube/config`);
|
|
300
|
+
shellExec(`sudo -E chown $(id -u):$(id -g) ~/.kube/config`);
|
|
301
|
+
},
|
|
288
302
|
// This function performs a comprehensive reset of Kubernetes and container environments
|
|
289
303
|
// on the host machine. Its primary goal is to clean up cluster components, temporary files,
|
|
290
304
|
// and container data, ensuring a clean state for re-initialization or fresh deployments,
|
|
@@ -460,6 +474,35 @@ Allocatable:
|
|
|
460
474
|
|
|
461
475
|
return resources;
|
|
462
476
|
},
|
|
477
|
+
initHost() {
|
|
478
|
+
// Install docker
|
|
479
|
+
shellExec(`sudo dnf -y install dnf-plugins-core
|
|
480
|
+
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo`);
|
|
481
|
+
shellExec(`sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin`);
|
|
482
|
+
// Install podman
|
|
483
|
+
shellExec(`sudo dnf -y install podman`);
|
|
484
|
+
// Install kind
|
|
485
|
+
shellExec(`[ $(uname -m) = aarch64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.29.0/kind-linux-arm64
|
|
486
|
+
chmod +x ./kind
|
|
487
|
+
sudo mv ./kind /bin/kind`);
|
|
488
|
+
// Install kubeadm
|
|
489
|
+
shellExec(`cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
|
|
490
|
+
[kubernetes]
|
|
491
|
+
name=Kubernetes
|
|
492
|
+
baseurl=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/
|
|
493
|
+
enabled=1
|
|
494
|
+
gpgcheck=1
|
|
495
|
+
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.33/rpm/repodata/repomd.xml.key
|
|
496
|
+
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
|
|
497
|
+
EOF`);
|
|
498
|
+
shellExec(`sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes`);
|
|
499
|
+
// Install helm
|
|
500
|
+
shellExec(`curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
|
501
|
+
chmod 700 get_helm.sh
|
|
502
|
+
./get_helm.sh
|
|
503
|
+
chmod +x /usr/local/bin/helm
|
|
504
|
+
sudo mv /usr/local/bin/helm /bin/helm`);
|
|
505
|
+
},
|
|
463
506
|
};
|
|
464
507
|
}
|
|
465
508
|
export default UnderpostCluster;
|
package/src/cli/deploy.js
CHANGED
|
@@ -82,13 +82,13 @@ spec:
|
|
|
82
82
|
containers:
|
|
83
83
|
- name: ${deployId}-${env}-${suffix}
|
|
84
84
|
image: localhost/debian-underpost:${Underpost.version}
|
|
85
|
-
resources:
|
|
86
|
-
requests:
|
|
87
|
-
memory: "${resources.requests.memory}"
|
|
88
|
-
cpu: "${resources.requests.cpu}"
|
|
89
|
-
limits:
|
|
90
|
-
memory: "${resources.limits.memory}"
|
|
91
|
-
cpu: "${resources.limits.cpu}"
|
|
85
|
+
# resources:
|
|
86
|
+
# requests:
|
|
87
|
+
# memory: "${resources.requests.memory}"
|
|
88
|
+
# cpu: "${resources.requests.cpu}"
|
|
89
|
+
# limits:
|
|
90
|
+
# memory: "${resources.limits.memory}"
|
|
91
|
+
# cpu: "${resources.limits.cpu}"
|
|
92
92
|
command:
|
|
93
93
|
- /bin/sh
|
|
94
94
|
- -c
|
package/src/cli/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import dotenv from 'dotenv';
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import Underpost from '../index.js';
|
|
4
|
-
import { getUnderpostRootPath, loadConf } from '../server/conf.js';
|
|
4
|
+
import { getNpmRootPath, getUnderpostRootPath, loadConf } from '../server/conf.js';
|
|
5
5
|
import fs from 'fs-extra';
|
|
6
6
|
import { commitData } from '../client/components/core/CommonJs.js';
|
|
7
7
|
import { shellExec } from '../server/process.js';
|
|
@@ -97,7 +97,7 @@ program
|
|
|
97
97
|
.option('--mongodb', 'Init with mongodb statefulset')
|
|
98
98
|
.option('--postgresql', 'Init with postgresql statefulset')
|
|
99
99
|
.option('--mongodb4', 'Init with mongodb 4.4 service')
|
|
100
|
-
.option('--istio', 'Init base istio
|
|
100
|
+
// .option('--istio', 'Init base istio service mesh')
|
|
101
101
|
.option('--valkey', 'Init with valkey service')
|
|
102
102
|
.option('--contour', 'Init with project contour base HTTPProxy and envoy')
|
|
103
103
|
.option('--cert-manager', 'Init with letsencrypt-prod ClusterIssuer')
|
|
@@ -111,6 +111,10 @@ program
|
|
|
111
111
|
.option('--info-capacity', 'display current total machine capacity info')
|
|
112
112
|
.option('--info-capacity-pod', 'display current machine capacity pod info')
|
|
113
113
|
.option('--pull-image', 'Set optional pull associated image')
|
|
114
|
+
.option('--init-host', 'Install k8s node necessary cli env: kind, kubeadm, docker, podman, helm')
|
|
115
|
+
.option('--config', 'Set k8s base node config')
|
|
116
|
+
.option('--worker', 'Set worker node context')
|
|
117
|
+
.option('--chown', 'Set k8s kube chown')
|
|
114
118
|
.action(Underpost.cluster.init)
|
|
115
119
|
.description('Manage cluster, for default initialization base kind cluster');
|
|
116
120
|
|
|
@@ -271,6 +275,19 @@ program
|
|
|
271
275
|
.option('--init', 'Init lxd')
|
|
272
276
|
.option('--reset', 'Reset lxd on current machine')
|
|
273
277
|
.option('--install', 'Install lxd on current machine')
|
|
278
|
+
.option('--dev', 'Set dev context env')
|
|
279
|
+
.option('--control', 'set control node vm context')
|
|
280
|
+
.option('--worker', 'set worker node context')
|
|
281
|
+
.option('--create-vm <vm-id>', 'Create default virtual machines')
|
|
282
|
+
.option('--init-vm <vm-id>', 'Get init vm underpost script')
|
|
283
|
+
.option('--info-vm <vm-id>', 'Get all info vm')
|
|
284
|
+
.option('--start-vm <vm-id>', 'Start vm with networkt config')
|
|
285
|
+
.option('--root-size <gb-size>', 'Set root size vm')
|
|
286
|
+
.option('--join-node <nodes>', 'Comma separated worker and control node e. g. k8s-worker-1,k8s-control')
|
|
287
|
+
.option(
|
|
288
|
+
'--expose <vm-name-ports>',
|
|
289
|
+
'Vm name and : separated with Comma separated vm port to expose e. g. k8s-control:80,443',
|
|
290
|
+
)
|
|
274
291
|
.description('Lxd management')
|
|
275
292
|
.action(UnderpostLxd.API.callback);
|
|
276
293
|
|
package/src/cli/lxd.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getNpmRootPath } from '../server/conf.js';
|
|
2
|
+
import { getLocalIPv4Address } from '../server/dns.js';
|
|
3
|
+
import { pbcopy, shellExec } from '../server/process.js';
|
|
4
|
+
import fs from 'fs-extra';
|
|
2
5
|
|
|
3
6
|
class UnderpostLxd {
|
|
4
7
|
static API = {
|
|
5
|
-
async callback(
|
|
8
|
+
async callback(
|
|
9
|
+
options = {
|
|
10
|
+
init: false,
|
|
11
|
+
reset: false,
|
|
12
|
+
dev: false,
|
|
13
|
+
install: false,
|
|
14
|
+
createVirtualNetwork: false,
|
|
15
|
+
control: false,
|
|
16
|
+
worker: false,
|
|
17
|
+
startVm: '',
|
|
18
|
+
initVm: '',
|
|
19
|
+
createVm: '',
|
|
20
|
+
infoVm: '',
|
|
21
|
+
rootSize: '',
|
|
22
|
+
joinNode: '',
|
|
23
|
+
expose: '',
|
|
24
|
+
},
|
|
25
|
+
) {
|
|
26
|
+
const npmRoot = getNpmRootPath();
|
|
27
|
+
const underpostRoot = options?.dev === true ? '.' : `${npmRoot}/underpost`;
|
|
6
28
|
if (options.reset === true) {
|
|
7
29
|
shellExec(`sudo systemctl stop snap.lxd.daemon`);
|
|
8
30
|
shellExec(`sudo snap remove lxd --purge`);
|
|
@@ -11,7 +33,128 @@ class UnderpostLxd {
|
|
|
11
33
|
if (options.init === true) {
|
|
12
34
|
shellExec(`sudo systemctl start snap.lxd.daemon`);
|
|
13
35
|
shellExec(`sudo systemctl status snap.lxd.daemon`);
|
|
36
|
+
const lxdPressedContent = fs
|
|
37
|
+
.readFileSync(`${underpostRoot}/manifests/lxd/lxd-preseed.yaml`, 'utf8')
|
|
38
|
+
.replaceAll(`127.0.0.1`, getLocalIPv4Address());
|
|
39
|
+
// shellExec(`lxc profile show admin-profile`);
|
|
40
|
+
// shellExec(`lxc network show lxdbr0`);
|
|
41
|
+
// shellExec(`lxd init --preseed < ${underpostRoot}/manifests/lxd/lxd-preseed.yaml`);
|
|
42
|
+
shellExec(`echo "${lxdPressedContent}" | lxd init --preseed`);
|
|
43
|
+
shellExec(`lxc cluster list`);
|
|
14
44
|
}
|
|
45
|
+
if (options.createVm && typeof options.createVm === 'string') {
|
|
46
|
+
// lxc launch
|
|
47
|
+
const createVmCommand = `lxc init images:rockylinux/9/cloud ${
|
|
48
|
+
options.createVm
|
|
49
|
+
} --vm --target lxd-node1 -c limits.cpu=2 -c limits.memory=4GB --profile admin-profile -d root,size=${
|
|
50
|
+
options.rootSize && typeof options.rootSize === 'string' ? options.rootSize + 'GiB' : '32GiB'
|
|
51
|
+
}`;
|
|
52
|
+
pbcopy(createVmCommand); // Copy the command to clipboard for user
|
|
53
|
+
}
|
|
54
|
+
if (options.startVm && typeof options.startVm === 'string') {
|
|
55
|
+
const vmIp = UnderpostLxd.API.getNextAvailableIp();
|
|
56
|
+
shellExec(`lxc stop ${options.startVm}`);
|
|
57
|
+
shellExec(
|
|
58
|
+
`lxc config set ${options.startVm} user.network-config="${UnderpostLxd.API.generateCloudInitNetworkConfig(
|
|
59
|
+
vmIp,
|
|
60
|
+
)}"`,
|
|
61
|
+
);
|
|
62
|
+
shellExec(`lxc config device override ${options.startVm} eth0`);
|
|
63
|
+
shellExec(`lxc config device set ${options.startVm} eth0 ipv4.address ${vmIp}`);
|
|
64
|
+
shellExec(
|
|
65
|
+
`lxc config set ${options.startVm} user.user-data="#cloud-config
|
|
66
|
+
runcmd:
|
|
67
|
+
- [touch, /var/log/userdata-ok]"`,
|
|
68
|
+
);
|
|
69
|
+
shellExec(`lxc start ${options.startVm}`);
|
|
70
|
+
}
|
|
71
|
+
if (options.initVm && typeof options.initVm === 'string') {
|
|
72
|
+
let flag = '';
|
|
73
|
+
if (options.control === true) {
|
|
74
|
+
flag = ' -s -- --kubeadm';
|
|
75
|
+
shellExec(`lxc exec ${options.initVm} -- bash -c 'mkdir -p /home/dd/engine'`);
|
|
76
|
+
shellExec(`lxc file push /home/dd/engine/engine-private ${options.initVm}/home/dd/engine --recursive`);
|
|
77
|
+
} else if (options.worker == true) {
|
|
78
|
+
flag = ' -s -- --worker';
|
|
79
|
+
}
|
|
80
|
+
pbcopy(`cat ${underpostRoot}/manifests/lxd/underpost-setup.sh | lxc exec ${options.initVm} -- bash${flag}`);
|
|
81
|
+
}
|
|
82
|
+
if (options.joinNode && typeof options.joinNode === 'string') {
|
|
83
|
+
const [workerNode, controlNode] = options.joinNode.split(',');
|
|
84
|
+
const token = shellExec(
|
|
85
|
+
`echo "$(lxc exec ${controlNode} -- bash -c 'sudo kubeadm token create --print-join-command')"`,
|
|
86
|
+
{ stdout: true },
|
|
87
|
+
);
|
|
88
|
+
shellExec(`lxc exec ${workerNode} -- bash -c '${token}'`);
|
|
89
|
+
}
|
|
90
|
+
if (options.infoVm && typeof options.infoVm === 'string') {
|
|
91
|
+
shellExec(`lxc config show ${options.infoVm}`);
|
|
92
|
+
shellExec(`lxc info --show-log ${options.infoVm}`);
|
|
93
|
+
shellExec(`lxc info ${options.infoVm}`);
|
|
94
|
+
shellExec(`lxc list ${options.infoVm}`);
|
|
95
|
+
}
|
|
96
|
+
if (options.expose && typeof options.expose === 'string') {
|
|
97
|
+
const [controlNode, ports] = options.expose.split(':');
|
|
98
|
+
console.log({ controlNode, ports });
|
|
99
|
+
const protocols = ['tcp', 'udp'];
|
|
100
|
+
const hostIp = getLocalIPv4Address();
|
|
101
|
+
const vmIp = shellExec(
|
|
102
|
+
`lxc list ${controlNode} --format json | jq -r '.[0].state.network.enp5s0.addresses[] | select(.family=="inet") | .address'`,
|
|
103
|
+
{ stdout: true },
|
|
104
|
+
).trim();
|
|
105
|
+
for (const port of ports.split(',')) {
|
|
106
|
+
for (const protocol of protocols) {
|
|
107
|
+
shellExec(`lxc config device remove ${controlNode} ${controlNode}-port-${port}`);
|
|
108
|
+
shellExec(
|
|
109
|
+
`lxc config device add ${controlNode} ${controlNode}-port-${port} proxy listen=${protocol}:${hostIp}:${port} connect=${protocol}:${vmIp}:${port} nat=true`,
|
|
110
|
+
);
|
|
111
|
+
shellExec(`lxc config show ${controlNode} --expanded | grep proxy`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
generateCloudInitNetworkConfig(ip) {
|
|
117
|
+
return `version: 2
|
|
118
|
+
ethernets:
|
|
119
|
+
enp5s0:
|
|
120
|
+
dhcp4: false
|
|
121
|
+
addresses:
|
|
122
|
+
- ${ip}/24
|
|
123
|
+
gateway4: 10.250.250.1
|
|
124
|
+
nameservers:
|
|
125
|
+
addresses: [1.1.1.1, 8.8.8.8]`;
|
|
126
|
+
},
|
|
127
|
+
getUsedIpsFromLxd() {
|
|
128
|
+
const json = shellExec('lxc list --format json', { stdout: true, silent: true });
|
|
129
|
+
const vms = JSON.parse(json);
|
|
130
|
+
|
|
131
|
+
const usedIps = [];
|
|
132
|
+
|
|
133
|
+
for (const vm of vms) {
|
|
134
|
+
if (vm.state && vm.state.network) {
|
|
135
|
+
for (const iface of Object.values(vm.state.network)) {
|
|
136
|
+
if (iface.addresses) {
|
|
137
|
+
for (const addr of iface.addresses) {
|
|
138
|
+
if (addr.family === 'inet' && addr.address.startsWith('10.250.250.')) {
|
|
139
|
+
usedIps.push(addr.address);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return usedIps;
|
|
148
|
+
},
|
|
149
|
+
getNextAvailableIp(base = '10.250.250.', start = 100, end = 254) {
|
|
150
|
+
const usedIps = UnderpostLxd.API.getUsedIpsFromLxd();
|
|
151
|
+
for (let i = start; i <= end; i++) {
|
|
152
|
+
const candidate = `${base}${i}`;
|
|
153
|
+
if (!usedIps.includes(candidate)) {
|
|
154
|
+
return candidate;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
throw new Error('No IPs available in the static range');
|
|
15
158
|
},
|
|
16
159
|
};
|
|
17
160
|
}
|
package/src/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import UnderpostDeploy from './cli/deploy.js';
|
|
|
11
11
|
import UnderpostRootEnv from './cli/env.js';
|
|
12
12
|
import UnderpostFileStorage from './cli/fs.js';
|
|
13
13
|
import UnderpostImage from './cli/image.js';
|
|
14
|
+
import UnderpostLxd from './cli/lxd.js';
|
|
14
15
|
import UnderpostMonitor from './cli/monitor.js';
|
|
15
16
|
import UnderpostRepository from './cli/repository.js';
|
|
16
17
|
import UnderpostScript from './cli/script.js';
|
|
@@ -30,7 +31,7 @@ class Underpost {
|
|
|
30
31
|
* @type {String}
|
|
31
32
|
* @memberof Underpost
|
|
32
33
|
*/
|
|
33
|
-
static version = 'v2.8.
|
|
34
|
+
static version = 'v2.8.79';
|
|
34
35
|
/**
|
|
35
36
|
* Repository cli API
|
|
36
37
|
* @static
|
|
@@ -122,6 +123,13 @@ class Underpost {
|
|
|
122
123
|
* @memberof Underpost
|
|
123
124
|
*/
|
|
124
125
|
static monitor = UnderpostMonitor.API;
|
|
126
|
+
/**
|
|
127
|
+
* LXD cli API
|
|
128
|
+
* @static
|
|
129
|
+
* @type {UnderpostLxd.API}
|
|
130
|
+
* @memberof Underpost
|
|
131
|
+
*/
|
|
132
|
+
static lxd = UnderpostLxd.API;
|
|
125
133
|
}
|
|
126
134
|
|
|
127
135
|
const up = Underpost;
|