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.3 kB

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