> For the complete documentation index, see [llms.txt](https://bio-os.gitbook.io/userguide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bio-os.gitbook.io/userguide/bu-shu/getting-set-up/bu-shu-bioos.md).

# 部署Bio-OS

{% hint style="info" %}
在开始Bio-OS部署前，请确保您已经在环境中获取了Bio-OS的开源helm charts（<https://github.com/Bio-OS/helm-charts>），Bio-OS支持部署在ARM64及x86\_64架构。

另外Bio-OS的部署需要基于Kubernetes，您可以选择部署Kubernetes社区版或Minikube。本文档内容基于x86架构，如您使用环境为arm架构，请注意对应镜像和工具需选择arm版本安装。（请查看[部署准备](/userguide/bu-shu/getting-set-up/bu-shu-zhun-bei.md)）

{% endhint %}

## &#x20;一. 部署前K8S环境准备

### 1.1 启动Minikube

此处已假定您已安装Minikube，Minikube的安装可见：[Minikube Start](https://minikube.sigs.k8s.io/docs/start/)这里以 minikube 为例进行本地环境的构建，生产环境建议选择 kubespray 进行高可用部署。

```Bash
# root 用户执行
minikube start \
    --image-mirror-country=cn \
    --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
    --force \
    --addons ingress \
    --cni flannel \
    --kubernetes-version 1.24.15 \
    --nodes 4 \
    --ports 80,443 \
    --service-cluster-ip-range '10.255.0.0/16' \# 可自行修改
    --subnet '10.254.0.0/16' # 可执行修改

# 快捷键配置
echo 'alias kubectl="minikube kubectl -- "' >> ~/.bashrc
source ~/.bashrc
```

### 1.2 安装helm

安装helm部署包（注意：helm 版本必须大于 2.0 版本，如已有helm则可跳过这步）。如果在arm架构下，需将helm地址修改为：<https://get.helm.sh/helm-v3.12.0-linux-arm64.tar.gz>

```
wget https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz
tar xvf helm-v3.12.0-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin
```

### 1.3 NFS-Server 部署参考

* 这里以 Ubuntu 为例部署 NFS 服务，变量 NFS\_PATH 对应 NFS 存储目录。（**root 用户执行）**

```Bash
#!/bin/bash
#
# Desc: Install NFS Server. OS: Ubuntu
# 
# Install NFS Server
# 
# 
function installNFSServer() {
    apt update && apt install -y nfs-kernel-server nfs-common
}

# Config NFS Server
function configNFS() {
    NFS_PATH=/nfs
    mkdir -p ${NFS_PATH}/bioos-storage && chmod -R 777 ${NFS_PATH}
    chown -R nobody:nogroup ${NFS_PATH}
    echo "${NFS_PATH} *(insecure,rw,sync,root_squash,no_subtree_check,all_squash)" >> /etc/exports
    systemctl restart nfs-server
    systemctl restart rpcbind
    exportfs -arv
    showmount -e localhost
}

# Set up auto-start on boot.
function autoStart() {
    systemctl enable nfs-server
    systemctl enable rpcbind
}

function main() {
    installNFSServer
    configNFS
    autoStart
}

main
```

安装后检查：

```YAML
root@registry:/home/vagrant# systemctl status nfs-server
● nfs-server.service - NFS server and services
     Loaded: loaded (/lib/systemd/system/nfs-server.service; enabled; vendor preset: enabled)
    Drop-In: /run/systemd/generator/nfs-server.service.d
             └─order-with-mounts.conf
     Active: active (exited) since Thu 2023-05-18 21:33:05 CDT; 10s ago
    Process: 35987 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
    Process: 35988 ExecStart=/usr/sbin/rpc.nfsd (code=exited, status=0/SUCCESS)
   Main PID: 35988 (code=exited, status=0/SUCCESS)
        CPU: 6ms

May 18 21:33:05 registry systemd[1]: Starting NFS server and services...
May 18 21:33:05 registry systemd[1]: Finished NFS server and services...
```

### 1.4 安装 NFS-CSI 存储服务

```Bash
# 参考文档：https://github.com/kubernetes-csi/csi-driver-nfs/blob/master/charts/README.md
# 添加 nfs-csi helm repo
helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts

# 创建 NFS Secret
kubectl -n kube-system create secret generic mount-options --from-literal mountOptions="nfsvers=3,hard"

# install nfs-csi helm chart
helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs \
        --namespace kube-system \
        --version v4.4.0 \
        --set image.nfs.repository=dyrnq/nfsplugin \
        --set image.csiProvisioner.repository=dyrnq/csi-provisioner \
        --set image.csiSnapshotter.repository=dyrnq/csi-snapshotter \
        --set image.livenessProbe.repository=dyrnq/livenessprobe \
        --set image.nodeDriverRegistrar.repository=dyrnq/csi-node-driver-registrar \
        --set image.externalSnapshotter.repository=dyrnq/snapshot-controller
```

安装 storageClass，nfs-csi 默认不提供 sc 资源，需要我们手动安装 sc（参考文档：<https://github.com/kubernetes-csi/csi-driver-nfs/blob/master/deploy/example/storageclass-nfs.yaml）> 将以下命令复制并在shell中执行。

```JSON
cat << EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:
  server: ${NFS-SERVER-IPADDRESS}   # 这里填 NFS Server 地址
  share: /nfs
  csi.storage.k8s.io/provisioner-secret-name: "mount-options"
  csi.storage.k8s.io/provisioner-secret-namespace: "kube-system"
reclaimPolicy: Delete
volumeBindingMode: Immediate
mountOptions:
  - nfsvers=4.1
  - hard

EOF
```

### 1.5 检测是否可以正常挂载 PVC

复制以下命令并在shell中执行。

```Bash
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  storageClassName: nfs-csi
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pvc-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: test-pvc
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage
EOF

```

查看pod状态

<pre class="language-Bash"><code class="lang-Bash"># Pod 状态为 Running &#x26;&#x26; PVC 状态为 Bound，则 NFS Server 可用
root@n37-043-061:~# kubectl get pods
NAME           READY   STATUS    RESTARTS   AGE
<strong>test-pvc-pod   1/1     Running   0          8d
</strong>root@n37-043-061:~# kubectl get pvc
NAME       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
<strong>test-pvc   Bound    pvc-8dd031d1-2316-44b0-bd46-bdaeea7f9fd5   1Gi        RWO            nfs-csi        8d
</strong></code></pre>

<br>

## 二. 安装 Bio-OS相关服务

{% hint style="info" %}
Bio-OS 的部署依赖 mysql 数据库、jupyterhub以及cromwell，安装 bioos 服务前需先安装mysql、jupyterhub和cromwell。安装顺序：MySQL -> Jupyterhub -> Cromwell -> Bioos（**必须遵从**）
{% endhint %}

### **2.1 安装 mysql 服务**

```Shell
helm repo add bitnami https://charts.bitnami.com/bitnami

helm install mysql bitnami/mysql \
        --create-namespace \
        --namespace bioos \
        --version 9.12.5 \
        --set auth.rootPassword=Bytedance2023 \
        --set primary.persistence.storageClass=nfs-csi
```

命令中的rootPassword可改成自己需要的密码，但是后续步骤中都要做对应的修改。

### **2.2 安装 Jupyterhub**

Bioos 使用 helm 打包，目前分为四个子包，需要注意的是 Jupyterhub 部署之后，打开浏览器获取新的 token 才能继续部署 bioos-server、web 服务。 使用 Helm 安装jupyterhub（请注意选择符合环境架构的镜像）：

```YAML
helm repo add bioos https://bio-os.github.io/helm-charts/charts

helm install jupyterhub bioos/jupyterhub \
        --namespace bioos \
        --create-namespace \
        --set hub.db.url=mysql+pymysql://root:Bytedance2023@mysql.bioos.svc.cluster.local:3306/bioos \
        --set hub.db.password=Bytedance2023

# 将 jupyterhub 服务暴露出来，使浏览器可以直接访问.拿到 token 之后，就可以关掉这个端口转发。
kubectl -n bioos port-forward --address 0.0.0.0 service/hub 8081:8081
```

打开浏览器访问：<http://服务器IP/jupyterhub>, 申请新 token.

<figure><img src="/files/6BUSao5ojluelpFqXG67" alt=""><figcaption></figcaption></figure>

### **2.3 安装 cromwell**

安装cromwell有两种方式，分别是通过helm安装以及通过jar包部署，如使用helm进行安装，则安装简单但是工作流运行中无法使用docker镜像，如果是jar包部署则工作流运行可以使用docker镜像。

1. helm安装

```Bash
helm repo add bioos https://bio-os.github.io/helm-charts/charts

helm install cromwell bioos/cromwell \
        --create-namespace \
        --namespace bioos \
        --set persistence.internal=true \
        --set db.mysql.host=mysql.bioos.svc.cluster.local \
        --set db.mysql.username=root \
        --set db.mysql.password=Bytedance2023
```

2. jar包安装

从下面的链接下载cromwell-85.jar：<https://github.com/broadinstitute/cromwell/releases/tag/85>

为了cromwell能够和mysql通信，需要修改mysql的连接方式：

```Bash
kubectl edit svc mysql
# 修改type为
type: NodePort

# 查看K8S内部通信端口： （3306后的那个）
kubectl get svc mysql
NAME    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
mysql   NodePort   10.108.158.83   <none>        3306:30276/TCP   2d1h
```

通过以下命令获取InternalIP:

```JSON
kubectl get node -o wide
```

获取InternalIP如下所示

```Bash
NAME        STATUS   ROLES           AGE    VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
tf-server   Ready    control-plane   2d2h   v1.27.4   192.168.200.146   <none>        Ubuntu 22.04.2 LTS   5.15.0-83-generic   containerd://1.7.1
```

编辑application.conf，使用上面获取到的InternalIP和Port更新mysql的连接串

application.conf如下所示

```
include required(classpath("application"))
webservice {
  port = 8000
}
workflow-options {
  workflow-log-dir = /nfs/bioos-storage/cromwell-workflow-logs
  workflow-log-temporary = false
}
call-caching {
  enabled = true
  invalidate-bad-cache-results = true
}
database {
  profile = "slick.jdbc.MySQLProfile$"
  db {
    driver = "com.mysql.cj.jdbc.Driver"
    url = "jdbc:mysql://192.168.200.146:30276/cromwell?rewriteBatchedStatements=true&useSSL=false"
    port = 3306
    user = "root"
    password = "admin"
    connectionTimeout = 5000
  }
}
backend {
  default = "Local"
  providers {
    Local {
      config {
        root = "/nfs/bioos-storage/cromwell-executions"
        filesystem {
          local {
           localization: [
                  "hard-link", "soft-link", "copy"
           ]

            caching {
              duplication-strategy: [
                "hard-link", "soft-link", "copy"
              ]
              hashing-strategy: "md5"
              check-sibling-md5: false
            }
          }
        }
      }
    }
  }
}

```

使用java运行cromwell（此处注意需要有nohup确保cromwell在后台运行）：

```Bash
nohup java -jar -Dconfig.file=application.conf cromwell-85.jar server >log1 2>logerr &
```

###

### **2.4 安装 Bioos 服务**

```YAML
helm repo add bioos https://bio-os.github.io/helm-charts/chartss

helm install bioos bioos/bioos \
        --create-namespace \
        --namespace bioos \
        --set mysql.hostname=mysql.bioos.svc.cluster.local \
        --set mysql.database=bioos \
        --set mysql.username=root \
        --set mysql.password=Bytedance2023 \
        --set wes.endpoint=http://cromwell.bioos.svc.cluster.local:8000 \ # 之前cromwell如果是helm部署，此处可以使用svc地址，如果之前cromwell位jar包部署，此处需要修改为cromwell宿主机ip和port
        --set jupyterhub.endpoint=http://{{INGRESS-ADDRESS:PORT}}/jupyterhub/ \   # 需要手工替换成Ingress的地址
        --set jupyterhub.adminToken=${jupyterhub-token}  # 这里填写2.2步骤中获取的token

# 端口转发：
kubectl -n ingress-nginx port-forward --address 0.0.0.0 service/ingress-nginx-controller 8888:80
```

## 三.  环境验收

执行命令 \`kubectl get po ,pv,pvc,ing\` 查看应用部署状态，bioos 使用了两块存储，一块用于 Mysql,一块用于 bioos 存储，并提供了若干 ingress 规则，方便子路径引用服务。

```JSON
kubectl get po,pv,pvc,ing
```

命令状态应该如下所示：

<figure><img src="/files/MgYE3yPAXSeKC1VYvdRU" alt=""><figcaption></figcaption></figure>

打开浏览器访问 <http://服务器IP/workspace，至此完成> bioos 安装.

<figure><img src="/files/3FeLHwtn3XCZSijcvuXb" alt=""><figcaption></figcaption></figure>

##
