You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

install.sh 9.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. #!/bin/bash
  2. # Copyright 2021 The KubeEdge Authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. set -o errexit
  16. set -o nounset
  17. set -o pipefail
  18. TMP_DIR=$(mktemp -d --suffix=.sedna)
  19. SEDNA_ROOT=${SEDNA_ROOT:-$TMP_DIR}
  20. GM_NODE_NAME=${SEDNA_GM_NODE:-}
  21. KB_NODE_NAME=${SEDNA_GM_NODE:-}
  22. trap "rm -rf '$TMP_DIR'" EXIT
  23. _download_yamls() {
  24. yaml_dir=$1
  25. mkdir -p ${SEDNA_ROOT}/$yaml_dir
  26. cd ${SEDNA_ROOT}/$yaml_dir
  27. for yaml in ${yaml_files[@]}; do
  28. # the yaml file already exists, no need to download
  29. [ -e "$yaml" ] && continue
  30. echo downloading $yaml into ${SEDNA_ROOT}/$yaml_dir
  31. local try_times=30 i=1 timeout=2
  32. while ! timeout ${timeout}s curl -sSO https://raw.githubusercontent.com/kubeedge/sedna/main/$yaml_dir/$yaml; do
  33. ((++i>try_times)) && {
  34. echo timeout to download $yaml
  35. exit 2
  36. }
  37. echo -en "retrying to download $yaml after $[i*timeout] seconds...\r"
  38. done
  39. done
  40. }
  41. download_yamls() {
  42. yaml_files=(
  43. sedna.io_datasets.yaml
  44. sedna.io_federatedlearningjobs.yaml
  45. sedna.io_incrementallearningjobs.yaml
  46. sedna.io_jointinferenceservices.yaml
  47. sedna.io_lifelonglearningjobs.yaml
  48. sedna.io_models.yaml
  49. )
  50. _download_yamls build/crds
  51. yaml_files=(
  52. gm.yaml
  53. )
  54. _download_yamls build/gm/rbac
  55. }
  56. prepare_install(){
  57. # need to create a namespace
  58. kubectl create ns sedna
  59. kubectl label node/$GM_NODE_NAME sedna=control-plane --overwrite
  60. }
  61. prepare() {
  62. mkdir -p ${SEDNA_ROOT}
  63. # we only need build directory
  64. # here don't use git clone because of large vendor directory
  65. download_yamls
  66. }
  67. cleanup(){
  68. kubectl label node/$SEDNA_GM_NODE sedna- | sed 's/labeled$/un&/' || true
  69. kubectl delete ns sedna
  70. }
  71. create_crds() {
  72. cd ${SEDNA_ROOT}
  73. kubectl create -f build/crds
  74. }
  75. delete_crds() {
  76. cd ${SEDNA_ROOT}
  77. kubectl delete -f build/crds --timeout=90s
  78. }
  79. create_kb(){
  80. cd ${SEDNA_ROOT}
  81. kubectl $action -f - <<EOF
  82. apiVersion: v1
  83. kind: Service
  84. metadata:
  85. name: kb
  86. namespace: sedna
  87. spec:
  88. selector:
  89. sedna: kb
  90. type: NodePort
  91. ports:
  92. - protocol: TCP
  93. port: 9020
  94. targetPort: 9020
  95. ---
  96. apiVersion: apps/v1
  97. kind: Deployment
  98. metadata:
  99. name: kb
  100. labels:
  101. sedna: kb
  102. namespace: sedna
  103. spec:
  104. replicas: 1
  105. selector:
  106. matchLabels:
  107. sedna: kb
  108. template:
  109. metadata:
  110. labels:
  111. sedna: kb
  112. spec:
  113. nodeSelector:
  114. sedna: control-plane
  115. serviceAccountName: sedna
  116. containers:
  117. - name: kb
  118. imagePullPolicy: IfNotPresent
  119. image: kubeedge/sedna-kb:v0.3.0
  120. env:
  121. - name: KB_URL
  122. value: "sqlite:///db/kb.sqlite3"
  123. volumeMounts:
  124. - name: kb-url
  125. mountPath: /db
  126. resources:
  127. requests:
  128. memory: 256Mi
  129. cpu: 100m
  130. limits:
  131. memory: 512Mi
  132. volumes:
  133. - name: kb-url
  134. hostPath:
  135. path: /opt/kb-data
  136. type: DirectoryOrCreate
  137. EOF
  138. }
  139. prepare_gm_config_map() {
  140. kb_node_port=$(kubectl -n sedna get svc kb -ojsonpath='{.spec.ports[0].nodePort}')
  141. # here try to get node ip by kubectl
  142. kb_node_ip=$(kubectl get node $KB_NODE_NAME -o jsonpath='{ .status.addresses[?(@.type=="ExternalIP")].address }')
  143. kb_node_internal_ip=$(kubectl get node $KB_NODE_NAME -o jsonpath='{ .status.addresses[?(@.type=="InternalIP")].address }')
  144. KB_ADDRESS=${kb_node_ip:-$kb_node_internal_ip}:$kb_node_port
  145. cm_name=${1:-gm-config}
  146. config_file=${TMP_DIR}/${2:-gm.yaml}
  147. if [ -n "${SEDNA_GM_CONFIG:-}" ] && [ -f "${SEDNA_GM_CONFIG}" ] ; then
  148. cp "$SEDNA_GM_CONFIG" $config_file
  149. else
  150. cat > $config_file << EOF
  151. kubeConfig: ""
  152. master: ""
  153. namespace: ""
  154. websocket:
  155. address: 0.0.0.0
  156. port: 9000
  157. localController:
  158. server: http://localhost:${SEDNA_LC_BIND_PORT:-9100}
  159. knowledgeBaseServer:
  160. server: http://$KB_ADDRESS
  161. EOF
  162. fi
  163. kubectl $action -n sedna configmap $cm_name --from-file=$config_file
  164. }
  165. create_gm() {
  166. cd ${SEDNA_ROOT}
  167. kubectl create -f build/gm/rbac/
  168. cm_name=gm-config
  169. config_file_name=gm.yaml
  170. prepare_gm_config_map $cm_name $config_file_name
  171. kubectl $action -f - <<EOF
  172. apiVersion: v1
  173. kind: Service
  174. metadata:
  175. name: gm
  176. namespace: sedna
  177. spec:
  178. selector:
  179. sedna: gm
  180. type: NodePort
  181. ports:
  182. - protocol: TCP
  183. port: 9000
  184. targetPort: 9000
  185. ---
  186. apiVersion: apps/v1
  187. kind: Deployment
  188. metadata:
  189. name: gm
  190. labels:
  191. sedna: gm
  192. namespace: sedna
  193. spec:
  194. replicas: 1
  195. selector:
  196. matchLabels:
  197. sedna: gm
  198. template:
  199. metadata:
  200. labels:
  201. sedna: gm
  202. spec:
  203. nodeSelector:
  204. sedna: control-plane
  205. serviceAccountName: sedna
  206. containers:
  207. - name: gm
  208. image: kubeedge/sedna-gm:v0.2.0
  209. command: ["sedna-gm", "--config", "/config/$config_file_name", "-v2"]
  210. volumeMounts:
  211. - name: gm-config
  212. mountPath: /config
  213. resources:
  214. requests:
  215. memory: 32Mi
  216. cpu: 100m
  217. limits:
  218. memory: 128Mi
  219. volumes:
  220. - name: gm-config
  221. configMap:
  222. name: $cm_name
  223. EOF
  224. }
  225. delete_gm() {
  226. cd ${SEDNA_ROOT}
  227. kubectl delete -f build/gm/rbac/
  228. # no need to clean gm deployment alone
  229. }
  230. create_lc() {
  231. gm_node_port=$(kubectl -n sedna get svc gm -ojsonpath='{.spec.ports[0].nodePort}')
  232. # here try to get node ip by kubectl
  233. gm_node_ip=$(kubectl get node $GM_NODE_NAME -o jsonpath='{ .status.addresses[?(@.type=="ExternalIP")].address }')
  234. gm_node_internal_ip=$(kubectl get node $GM_NODE_NAME -o jsonpath='{ .status.addresses[?(@.type=="InternalIP")].address }')
  235. GM_ADDRESS=${gm_node_ip:-$gm_node_internal_ip}:$gm_node_port
  236. kubectl $action -f- <<EOF
  237. apiVersion: apps/v1
  238. kind: DaemonSet
  239. metadata:
  240. labels:
  241. sedna: lc
  242. name: lc
  243. namespace: sedna
  244. spec:
  245. selector:
  246. matchLabels:
  247. sedna: lc
  248. template:
  249. metadata:
  250. labels:
  251. sedna: lc
  252. spec:
  253. containers:
  254. - name: lc
  255. image: kubeedge/sedna-lc:v0.2.0
  256. env:
  257. - name: GM_ADDRESS
  258. value: $GM_ADDRESS
  259. - name: BIND_PORT
  260. value: "${LC_BIND_PORT:-9100}"
  261. - name: NODENAME
  262. valueFrom:
  263. fieldRef:
  264. fieldPath: spec.nodeName
  265. - name: ROOTFS_MOUNT_DIR
  266. # the value of ROOTFS_MOUNT_DIR is same with the mount path of volume
  267. value: /rootfs
  268. resources:
  269. requests:
  270. memory: 32Mi
  271. cpu: 100m
  272. limits:
  273. memory: 128Mi
  274. volumeMounts:
  275. - name: localcontroller
  276. mountPath: /rootfs
  277. volumes:
  278. - name: localcontroller
  279. hostPath:
  280. path: /
  281. restartPolicy: Always
  282. hostNetwork: true
  283. EOF
  284. }
  285. delete_lc() {
  286. # ns would be deleted in delete_gm
  287. # so no need to clean lc alone
  288. return
  289. }
  290. wait_ok() {
  291. kubectl -n sedna wait --for=condition=available --timeout=600s deployment/gm
  292. kubectl -n sedna wait pod --for=condition=Ready --selector=sedna
  293. kubectl -n sedna get pod
  294. }
  295. delete_pods() {
  296. # in case some nodes are not ready, here delete with a 60s timeout, otherwise force delete these
  297. kubectl -n sedna delete pod --all --timeout=60s || kubectl -n sedna delete pod --all --force --grace-period=0
  298. }
  299. check_kubectl () {
  300. kubectl get pod >/dev/null
  301. }
  302. check_action() {
  303. action=${SEDNA_ACTION:-create}
  304. support_action_list="create delete"
  305. if ! echo "$support_action_list" | grep -w -q "$action"; then
  306. echo "\`$action\` not in support action list: create/delete!" >&2
  307. echo "You need to specify it by setting $(red_text SEDNA_ACTION) environment variable when running this script!" >&2
  308. exit 2
  309. fi
  310. }
  311. check_node() {
  312. if [ -z "$GM_NODE_NAME" ] || ! kubectl get node $GM_NODE_NAME; then
  313. echo "ERROR: $(red_text GM node name \`$GM_NODE_NAME\` does not exist in k8s cluster)!" >&2
  314. echo "You need to specify it by setting $(red_text SEDNA_GM_NODE) environment variable when running this script!" >&2
  315. exit 1
  316. fi
  317. }
  318. do_check() {
  319. check_kubectl
  320. check_action
  321. check_node
  322. }
  323. show_debug_infos() {
  324. cat - <<EOF
  325. Sedna is $(green_text running):
  326. See GM status: kubectl -n sedna get deploy
  327. See LC status: kubectl -n sedna get ds lc
  328. See Pod status: kubectl -n sedna get pod
  329. EOF
  330. }
  331. NO_COLOR='\033[0m'
  332. RED='\033[0;31m'
  333. GREEN='\033[0;32m'
  334. green_text() {
  335. echo -ne "$GREEN$@$NO_COLOR"
  336. }
  337. red_text() {
  338. echo -ne "$RED$@$NO_COLOR"
  339. }
  340. do_check
  341. prepare
  342. case "$action" in
  343. create)
  344. prepare_install
  345. create_crds
  346. create_kb
  347. create_gm
  348. create_lc
  349. wait_ok
  350. show_debug_infos
  351. ;;
  352. delete)
  353. delete_pods
  354. delete_gm
  355. delete_lc
  356. delete_crds
  357. cleanup
  358. echo "$(green_text Sedna is uninstalled successfully)"
  359. ;;
  360. esac