From 3ea8cba5ccfa398d33f5d9ba9239b27cebc212dc Mon Sep 17 00:00:00 2001 From: Shaohe Feng Date: Wed, 9 Oct 2024 04:03:31 +0000 Subject: [PATCH] Simplify the deployment ProductivitySuite on kubernetes Signed-off-by: Shaohe Feng --- ProductivitySuite/kubernetes/intel/README.md | 39 ++++- .../kubernetes/intel/cpu/xeon/utils | 157 ++++++++++++++++++ 2 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 ProductivitySuite/kubernetes/intel/cpu/xeon/utils diff --git a/ProductivitySuite/kubernetes/intel/README.md b/ProductivitySuite/kubernetes/intel/README.md index bc3f67c342..6a0d4188ab 100644 --- a/ProductivitySuite/kubernetes/intel/README.md +++ b/ProductivitySuite/kubernetes/intel/README.md @@ -25,27 +25,51 @@ To begin with, ensure that you have following prerequisites in place: 2. 🐳 Images: Make sure you have all the images ready for the examples and components stated above. You may refer to [README](../../docker_compose/intel/cpu/xeon/README.md) for steps to build the images. 3. 🔧 Configuration Values: Set the following values in all the yaml files before proceeding with the deployment: + Download and set up yq for YAML processing: + ``` + sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 + sudo chmod a+x /usr/local/bin/yq + + cd GenAIExamples/ProductivitySuite/kubernetes/intel/cpu/xeon/manifest/ + . ../utils + ``` + a. HUGGINGFACEHUB_API_TOKEN (Your HuggingFace token to download your desired model from HuggingFace): ``` # You may set the HUGGINGFACEHUB_API_TOKEN via method: export HUGGINGFACEHUB_API_TOKEN="YourOwnToken" - cd GenAIExamples/ProductivitySuite/kubernetes/intel/cpu/xeon/manifests/ - sed -i "s/insert-your-huggingface-token-here/${HUGGINGFACEHUB_API_TOKEN}/g" *.yaml + set_hf_token $HUGGINGFACEHUB_API_TOKEN ``` b. Set the proxies based on your network configuration ``` # Look for http_proxy, https_proxy and no_proxy key and fill up the values for all the yaml files with your system proxy configuration. + set_http_proxy $http_proxy + set_https_proxy $https_proxy + set_no_proxy $no_proxy ``` c. Set all the backend service endpoint for REACT UI service ``` # Setup all the backend service endpoint in productivity_suite_reactui.yaml for UI to consume with. # Look for ENDPOINT in the yaml and insert all the url endpoint for all the required backend service. + set_services_endpoint ``` 4. MODEL_ID and model-volume **(OPTIONAL)**: You may as well customize the "MODEL_ID" to use different model and model-volume for the volume to be mounted. -5. After finish with steps above, you can proceed with the deployment of the yaml file. + ``` + sudo mkdir -p /mnt/opea-models + sudo chmod -R a+xwr /mnt/opea-models + set_model_id + ``` +5. MODEL_MIRROR **(OPTIONAL)**: Please set the exact huggingface mirror if cannot access huggingface website directly from your country. You can set it as https://hf-mirror.com in PRC. + ``` + set_model_mirror + ``` +6. After finish with steps above, you can proceed with the deployment of the yaml file. + ``` + git diff + ``` --- @@ -53,7 +77,7 @@ To begin with, ensure that you have following prerequisites in place: You can use yaml files in xeon folder to deploy ProductivitySuite with reactUI. ``` cd GenAIExamples/ProductivitySuite/kubernetes/intel/cpu/xeon/manifests/ -kubectl apply -f *.yaml +kubectl apply -f . ``` --- @@ -77,4 +101,11 @@ productivity-suite-react-ui ClusterIP 10.96.3.236 80/TC 'kubectl port-forward service/productivity-suite-react-ui 5174:80' ``` +Or simple way to forward the productivity suite service port. +``` +label='app.kubernetes.io/name=react-ui' +port=$(kubectl -n ${ns:-default} get svc -l ${label} -o jsonpath='{.items[0].spec.ports[0].port}') +kubectl port-forward service/productivity-suite-react-ui 5174:$port +``` + You may open up the productivity suite react UI by using http://localhost:5174 in the browser. diff --git a/ProductivitySuite/kubernetes/intel/cpu/xeon/utils b/ProductivitySuite/kubernetes/intel/cpu/xeon/utils new file mode 100644 index 0000000000..01faa06a0f --- /dev/null +++ b/ProductivitySuite/kubernetes/intel/cpu/xeon/utils @@ -0,0 +1,157 @@ +set_model_id() { + if [ -z "$1" ] && [ -z "$2" ]; then + yq -o json '.| select(.data | has("MODEL_ID"))| {"ConfigMap": .metadata.name, "MODEL_ID": .data.MODEL_ID}' *.yaml + echo "usage:" + echo " set_model_id \${ConfigMap} \${MODEL_ID}" + return + fi + conf=$1 + file=${1%%-*} + sed -i '/name: '"${conf}"'/,/---/s|\(MODEL_ID:\).*|\1 "'"${2}"'"|' ${file}.yaml +} + +set_model_mirror() { + if [ -z "$1" ] ; then + yq -o json '.| select(.data | has("MODEL_ID"))| {"ConfigMap": .metadata.name, "MODEL_MIRROR": .data.HF_ENDPOINT}' *.yaml + echo "usage:" + echo " set_model_mirror \${MODEL_MIRROR}" + return + fi + cm=$(yq -r -o json '.| select(.data | has("MODEL_ID"))| .metadata.name' *.yaml) + mirror=$1 + for i in $cm; do + conf=$i + file=${i%%-*} + echo "ConfigMap: $conf set mirror as $mirror" + has_mirror=$(yq -r -o json '.| select(.metadata.name == "'"${conf}"'")| .data.HF_ENDPOINT' ${file}.yaml) + if [ "$has_mirror" == "null" ]; then + sed -i '/name: '"${conf}"'/,/---/s|\(data:\)|\1\n HF_ENDPOINT: "'"${mirror}"'"|' ${file}.yaml + else + sed -i '/name: '"${conf}"'/,/---/s|\(HF_ENDPOINT:\).*|\1 "'"${1}"'"|' ${file}.yaml + fi + done +} + +set_hf_token() { + if [ -z "$1" ] ; then + echo "usage:" + echo " set_hf_token \${HF_TOKEN}" + return + fi + sed -i "s/\(HF_TOKEN:\).*/\1 \"${1}\"/g" *.yaml + sed -i "s/\(HUGGINGFACEHUB_API_TOKEN:\).*/\1 \"${1}\"/g" *.yaml + sed -i "s/\(HUGGING_FACE_HUB_TOKEN:\).*/\1 \"${1}\"/g" *.yaml +} + +set_https_proxy() { + if [ -z "$1" ] ; then + echo "usage:" + echo " set_https_proxy \${https_proxy}" + return + fi + https_proxy=$1 + sed -i -e "s|\(https_proxy:\)\s*\"\"|\1 \"$https_proxy\"|g" *.yaml + sed -i '/https_proxy/{n;s|\(value:\)\s.*""|\1 "'"$https_proxy"'"|g}' *.yaml +} + +set_http_proxy() { + if [ -z "$1" ] ; then + echo "usage:" + echo " set_http_proxy \${http_proxy}" + return + fi + http_proxy=$1 + sed -i -e "s|\(http_proxy:\)\s*\"\"|\1 \"$http_proxy\"|g" *.yaml + sed -i '/http_proxy/{n;s|\(value:\)\s.*""|\1 "'"$http_proxy"'"|g}' *.yaml +} + +set_no_proxy() { + if [ -z "$1" ] ; then + echo "usage:" + echo " set_no_proxy \${no_proxy}" + return + fi + no_proxy=$1 + sed -i -e "s|\(no_proxy:\)\s*\"\"|\1 \"$no_proxy\"|g" *.yaml + sed -i '/no_proxy/{n;s|\(value:\)\s.*""|\1 "'"$no_proxy"'"|g}' *.yaml +} + +set_backend_service_endpoint() { + for i in $(grep -oP "(?<=APP_BACKEND_SERVICE_ENDPOINT_).*" *.yaml); do + echo $i + name=${i##*:} + file=${name,,}.yaml + svc=$(yq -o json '. | select(.metadata.name == "'"${name,,}"'" and .kind=="Service")' $file) + port=$(jq .spec.ports[0].port <<< $svc) + + url=http://${name,,}.${ns:-default}.svc.cluster.local:${port} + echo $url + sed -i -e '/APP_BACKEND_SERVICE_ENDPOINT_'"$name"'/{n;s|\(value:\)\s.*|\1 "'"$url"'"|}' productivity_suite_reactui.yaml + done +} + + +set_dataprep_service_endpoint() { + name=chatqna-data-prep + file=chatqna.yaml + svc=$(yq -o json '. | select(.metadata.name == "'"$name"'" and .kind=="Service")' $file) + port=$(jq .spec.ports[0].port <<< $svc) + url=http://${name}.${ns:-default}.svc.cluster.local:${port} + echo $url + for i in $(grep -oP "(?<=APP_)DATAPREP.*(?=_ENDPOINT)" *.yaml); do + echo $i + curd=${i##*:}; + sed -i -e '/'"$curd"'/{n;s|\(value:\)\s.*|\1 "'"$url"'"|}' productivity_suite_reactui.yaml; + done +} + + +set_chat_history_endpoint() { + for i in $(grep -oP "(?<=APP_)CHAT_HISTORY.*(?=_ENDPOINT)" *.yaml); do + echo $i; + curd=${i##*:}; + name=${curd%_*}; + file=${name,,}.yaml; + name=${name/_/-}; + svc=$(yq -o json '. | select(.metadata.name == "'"${name,,}"'" and .kind=="Service")' $file) + port=$(jq .spec.ports[0].port <<< $svc) + url=http://${name,,}.${ns:-default}.svc.cluster.local:${port}; + echo $url; + sed -i -e '/'"$curd"'/{n;s|\(value:\)\s.*|\1 "'"$url"'"|}' productivity_suite_reactui.yaml; + done +} + + +set_prompt_service_endpoint() { + for i in $(grep -oP "(?<=APP_)PROMPT_SERVICE.*(?=_ENDPOINT)" *.yaml); do + echo $i; + curd=${i##*:}; + curdr=${curd/SERVICE/REGISTRY}; + name=${curdr%_*}; + file=${name,,}.yaml; + name=${name/_/-}; + svc=$(yq -o json '. | select(.metadata.name == "'"${name,,}"'" and .kind=="Service")' $file) + port=$(jq .spec.ports[0].port <<< $svc) + url=http://${name,,}.${ns:-default}.svc.cluster.local:${port}; + echo $url; + sed -i -e '/'"$curd"'/{n;s|\(value:\)\s.*|\1 "'"$url"'"|}' productivity_suite_reactui.yaml ; + done +} + +set_keycloak_service_endpoint() { + name=keycloak + file=keycloak_install.yaml + svc=$(yq -o json '. | select(.metadata.name == "'"$name"'" and .kind=="Service")' $file) + port=$(jq .spec.ports[0].port <<< $svc) + url=http://${name}.${ns:-default}.svc.cluster.local:${port} + echo $url + sed -i -e '/APP_KEYCLOAK_SERVICE_ENDPOINT/{n;s|\(value:\)\s.*|\1 "'"$url"'"|}' productivity_suite_reactui.yaml +} + +set_services_endpoint() { + set_backend_service_endpoint + set_keycloak_service_endpoint + set_chat_history_endpoint + set_prompt_service_endpoint + set_dataprep_service_endpoint +}