---
schema_version: "1"
id: a0286c7f6fa7d8c1f6c0dd12a54eedc5a25194e9632bde98a6ef2828740e37c6
title: 容器中的動態縮放 - Tableau Server 背景程式
collection: tableau
version: current
locale: zh-tw
portal_url: https://docs.salesforce.com/tableau/current/zh-tw/server-linux/server-backgrounder-autoscaling.md
canonical_url: https://help.tableau.com/current/server-linux/zh-tw/server-backgrounder-autoscaling.htm
source_site: help.tableau.com
content_type: documentation
content_hash: 3debb8c6a25d5be30934dde43320d2908e283e063db15225615b4f4b0f49d275
description: Configure dynamic scaling of Backgrounders for Tableau Server in a container.
---
[跳至主要內容](#main-content)

# 容器中的動態縮放 - Tableau Server 背景程式

## 簡介

容器中背景程式的動態縮放允許在 Tableau Server 中的背景程式和計劃工作中套用各種縮放策略。在這種情況下，自動擴展意味著可以獨立縮放服務以處理可變任務負載，無需人工干預或影響其他伺服器系統的正常運作時間。包含 Tableau Server 處理序完整節點的 Tableau Server 容器將繼續作為整體系統執行。相反，包含「背景程式」服務角色的一組較小的低耦合獨立容器服務將可動態縮放並處理通常由 Tableau Server 容器處理的計算負載。背景程式服務負責處理系統工作，包括重新整理/建立資料擷取、傳送訂閱、檢查資料警示和許多維護工作。例如，如果有時重新整理大量資料集或計算大量計算成本高的資料警示是有利的，現在就可以利用 Kubernetes 來擴展計算能力，有效地完成這些工作。本指南涵蓋了 Kubernetes 中自動縮放背景程式的設定和部署要求。本文件是對[容器中的 Tableau Server](https://help.tableau.com/current/server-linux/zh-tw/server-in-container.htm)文件的補充。

## 必要條件

僅在 Kubernetes 中提供自動縮放背景程式，並且是基於容器中的 Tableau Server。要使用自動縮放背景程式功能，必須滿足某些先決條件：

- Tableau Server 必須具有 Advanced Management 功能。更多資訊請參閱[关于 Tableau Server 中的 Tableau Advanced Management](https://help.tableau.com/current/server-linux/zh-tw/itm_intro.htm) 。
- 必須使用以角色為基礎的授權。不支援核心授權。如要瞭解使用者角色和授權，請參閱 [瞭解授權模式和產品金鑰](https://help.tableau.com/current/server-linux/zh-tw/license_product_keys.htm)。
- 必須啟用以下Advanced Management功能：
    - [Tableau Server 外部檔案存放區](https://help.tableau.com/current/server-linux/zh-tw/server_external_filestore_storage.htm)
    - T[Tableau Server 外部存放庫](https://help.tableau.com/current/server-linux/zh-tw/server_external_repo.htm)
- 必須擁有 1.20 或更高版本的 Kubernetes 叢集，並了解如何使用和管理。

## 限制

- 此功能僅適用於以 Linux 為基礎部署。
- 自動縮放背景程式不支援流程工作。流程工作將由繼續在 Tableau Server 容器中執行的背景程式服務處理。

## 建立 Tableau Server 和背景程式 Pod 映像

在容器中使用自動縮放背景程式的第一步是建立構成 Tableau Server 安裝的服務映像。這些映像將包括 Tableau Server 映像，以及用於低腰褲背景程式和支援服務映像。您使用與用於建立全面多合一 Tableau Server 容器映像相同的組建工具，但該工具必須是 2022.3.0 或更高版本，您必須擁有Advanced Management權限，並且在組建映像時需要使用特殊標幟。

1. 要背景程式服務映像，請執行以下命令：
    
    build-image --accepteula -i <installer> --backgrounder-images
    
    這將背景程式 Tableau Server 和四個新映像。這些附加映像包含組成新的可自動縮放背景程式 pod 的各個服務。
    
    `docker images` 命令可列出在本地 Docker 存放庫中背景程式的映像：
    
    hyper                          20214.21.1117.1006             52fd9843c178   10 seconds ago
    gateway                        20214.21.1117.1006             2308e602a2a3   11 seconds ago
    backgrounder                   20214.21.1117.1006             4540e459cf23   12 seconds ago
    dataserver                     20214.21.1117.1006             c5345ed47f51   12 seconds ago
    tableau\_server\_image           20214.21.1117.1006             b27817047dd1   7 minutes ago
    
    超級、閘道、背景程式和資料伺服器映像包含新的背景程式 pod。自訂驅動程式、安裝指令碼和屬性將在這所有五個映像之間共用。更多資訊請參閱[自訂映像](https://help.tableau.com/current/server-linux/zh-tw/server-in-container_setup-tool.htm#CustomizingImage)。
2. 將所有這些映像發佈到您的內部映像存放庫以進行部署。

## 部署指南

以下資訊提供了有關如何在容器中部署 Tableau Server 並使用自動縮放背景程式的上下文。此資訊假定您已經了解並知道如何在獨立容器中部署 Tableau Server。有關詳情，請參閱 [容器中的 Tableau Server](https://help.tableau.com/current/server-linux/zh-tw/server-in-container.htm)。Kubernetes 設定部分中的三個 Kubernetes 設定檔是可用於設定部署的範本。本指南中的其他部分介紹了部署的要求和詳細資訊。

Tableau Server 和自動縮放背景程式的部署應該像在指南底部部署填充的 Kubernetes 設定檔一樣簡單：

kubectl apply -f <tableau-kubeconfig-dir>

### 背景程式工作

背景程式 pod 可幫助容器中的 Tableau Server 行計算額外的排程工作負載。背景程式處理重新整理擷取、訂閱、警示、流程和系統工作負載。在背景程式 pod 之間分配作業意味著 Tableau Server 將有更多的計算資源可用於處理其他工作，例如呈現工作簿和儀表板等交互式使用者活動。流程作業唯一不在背景程式中執行的背景程式工作類型。有關背景程式作業的詳細資訊，請參閱[在 Tableau Server 中管理背景作業](https://help.tableau.com/current/server-linux/zh-tw/server_backgrounder_job_management.htm)。

背景程式 pod 可以處理任何類型的負載，但必須在主 Tableau Server 容器中執行流程工作除外，這些容器會繼續執行該背景程式服務。

使用者可憑藉節點角色功靈活地將背景程式 pod 專門用於於特定類型的工作。此功能是 Tableau Server 上節點角色功能的延伸。在這裡可以找到關於不同節點角色的詳細描述。請注意，預設情況下，背景程式 Pod 上會停用流程工作業（即將角色設定為「no-flows」），因為背景程式 Pod 無法執行流程工作。

要為背景程式設定節點角色，需要將環境變數 `NODE_ROLES` 設定為執行背景程式服務容器的 kubeconfig 的一部分。例如，要將背景程式設定為僅執行擷取-重新整理作業，請設定 `NODE_ROLES` 環境變量進行提取刷新，如下所示：

#### NODE\_ROLE\_CONFIG

containers:  
      - name: backgrounder  
        image: <backgrounder\_image> # Backgrounder Image  
        ports:  
        - containerPort: 8600  
        volumeMounts:  
        - name: logmount  
          mountPath: /var/log/tableau  
        - name: clone-volume  
          mountPath: /docker/clone  
        - name: dataengine-volume  
          mountPath: /docker/dataengine  
        - name: temp  
          mountPath: /var/opt/tableau/tableau\_server/data/tabsvc/temp  
        env:  
          - name: ROOT\_LOG\_DIR  
            value: /var/log/tableau  
          - name: CLONE\_ARTIFACT\_DIR  
            value: /docker/clone/clone-artifacts  
          - name: FILESTORE\_MOUNT\_PATH  
            value: /docker/dataengine  
          - name: NODE\_ROLES  
            value: extract-refreshes

Tableau Server Pod 將在其拓撲中設定至少一個背景程式，以確保始終有空間執行背景程式工作。預設情況下，TSM 將要求必須有一個背景程式能夠處理背景工作的每個角色。在某些情況下，您可能希望讓背景程式 Pod 處理特定類型的所有工作。為此，您必須將伺服器金鑰 `topology.roles_handle_all_jobs_constraint_disabled` 設定為 `true`，這將禁用 TSM 拓撲處理所有作業類型的要求。可使用此參數集將 Tableau Server 背景程式執行個體的背景程式角色設定為 `no-extract-refreshes`，並可將背景 Pod 的角色設定為 `extract-refreshes`，這將確保所有資料擷取重新整理工作僅在背景程式 Pod 上執行。

附註**：**停用此限制式即可設定角色，這樣有些工作類型就永遠不會排程。請務必仔細設定 TSM 背景程式和背景程式工作的角色設定，因為 TSM 將不再驗證是否可以排程所有背景程式工作類型。

### 容器 Pod 中的 Tableau Server

配備包含 Tableau Server 的自動縮放背景程式的容器的部署方式與我們現有容器中的 Tableau Server 的部署方式幾乎相同。有一些關鍵的要求變化：

- 在 Tableau Server 容器和背景程式 Pod 之間傳輸設定_需要_網路檔案共用。
- 必須啟用並使用外部 Filestore 功能。也需要專用的網路檔案共用。

### 背景程式 Pod

Backgrounder Pod 由四個獨立的服務容器組成，協同使用，即：**閘道**、**hyper**、**資料伺服器**和**背景程式**。您可以像典型的獨立 Kubernetes 容器 Pod 一樣部署這些 Pod。Pod 有以下要求：

- 背景程式 Pod 必須能夠使用主機名稱 DNS 解析存取 Tableau Server 節點。
- 必須提供外部 Filestore 和複製網路檔案共用。

**附註：**為背景程式 Pod 設定 init-container，在執行前，等待 Tableau Server 容器成功生成複製設定輸出。

#### 記錄檔

背景程式 Pod 服務（如 Tableau Server）仍然主要將記錄檔寫入磁碟。由於背景程式 pod 可以縮放，它們是暫時性的，因此必須確保在 Pod 之外儲存記錄檔。許多現在有 K8s 環境的客戶已經在使用某種類型的記錄彙總服務來從他們部署的 Pod 中收集記錄。記錄彙總服務範例包括 Splunk 和 fluentd。強烈建議客戶使用某種記錄彙總服務從他們的背景程式 Pod 中收集記錄。為了方便記錄管理，我們提供的 kubeconfig 將 Pod 中的每個服務設定為寫入共用記錄卷。每個服務容器中目錄的路徑均由 `ROOT_LOG_DIR` 環境變數指定。

如果需要開啟背景程式案例並提供記錄，則將提供兩組記錄：從主伺服器容器收集的 ziplogs 和來自背景程式 Pod 的記錄（從您的記錄彙總服務中檢索，或使用下面的手動處理序） 。

對於無法使用記錄彙總服務的客戶，可以從 Pod 中手動檢索記錄。

**附註：**當 Pod 縮小時，任何未對包含記錄的磁碟區使用 Persistent Volume Claim 的 pod 的記錄都將丟失！

所有相關記錄均位於背景程式 pod 內的 `/var/log/tableau` 目錄（可透過`ROOT_LOG_DIR` 環境變數設定）。強烈建議您在此位置掛接 PersistantVolumeClaim，以便在 Pod 無法使用時可以使用記錄。

##### 在背景程式 pod 執行時收集記錄：

在容器內建立記錄 tar 檔案：

kubectl exec -it <backgrounder-pod-name> -- bash -c "tar -czf /docker/user/backgrounder-pod-logs.tar.gz /var/log/tableau"

將 tarfile 複製到容器外部：

kubectl cp <backgrounder-pod-name>:docker/user/backgrounder-pod-logs.tar.gz ./backgrounder-pod-logs.tar.gz

##### 在背景程式 pod 結束（或無法啟動）時收集記錄

使用用於背景程式 pod 部署記錄的 PersistantVolumeClaim 掛接附加任何長時間執行的 pod。設定範例：

apiVersion: v1  
kind: Pod  
metadata:  
  name: <name>  
  namespace: <namespace>  
spec:  
  containers:  
  - name: get-logs-pod  
    image: busybox:1.28  
    securityContext:  
      runAsUser: 0  
      allowPrivilegeEscalation: true  
    command: \['sh', '-c', "while :; do sleep 5; done"\]  
    volumeMounts:  
    - name: logmount  
      mountPath: /var/log/tableau
restartPolicy: Never  
volumes:  
  - name: logmount  
    persistentVolumeClaim:  
      claimName: logvolume

在容器內建立記錄 tar 檔案：

kubectl exec -it <backgrounder-pod-name> -- bash -c "tar -czf /backgrounder-pod-logs.tar.gz /var/log/tableau"

將 tarfile 複製到容器外部：

kubectl cp <backgrounder-pod-name>:/backgrounder-pod-logs.tar.gz ./backgrounder-pod-logs.tar.gz

#### 即時設定變更

如果變更容器中的 Tableau Server 設定（例如使用 tsm 命令行），並希望在背景程式 pod 中顯示這些設定變更，則需要執行 `[tsm settings clone](https://help.tableau.com/current/server-linux/zh-tw/cli_settings_tsm.htm#TSMSettingsClone)` 命令產生一組新的複製設定檔（「複製承載」）。

1. 使用 TSM 變更容器 pod 中的 Tableau Server 設定，並在該伺服器中套用該設定變更。
2. 在容器 Pod 的 Tableau Server 節點 1 上執行以下命令：
    
    \## Run this command in the Tableau Server in a Container pod.
    tsm settings clone -d $CLONE\_ARTIFACT\_DIR
    
    此命令可建立一組新的設定檔並將其寫入複製 NFS 磁碟機位置。
3. 重新部署您的背景程式 Pod。應將 Pod 設定為使用複製 NFS 磁碟機，並獲取新設定。

### 縮放策略

可以使用各種技術和策略在 Kubernetes 中縮放背景程式 Pod。我們提供了縮放策略範例，它根據時間排程變更背景程式 Pod 集區的大小。

請注意，CPU 和記憶體利用率**並不是**縮放背景程式 Pod 的好指標。記憶體和 CPU 利用率並不能準確描述叢集的整體負載需求。例如，背景程式 Pod 可能處於最大利用率以創新整理擷取，但背景程式工作佇列中沒有其他工作等待。在這種情況下，自動縮放不會提高工作輸送量。

#### 排程的縮放

使用 cron 工作的標準 Kubernetes 機制允許您排程縮放解決方案。

下面的 Kubernetes 設定部分提供了 Kubernetes 設定範例。

## Kubernetes 設定

### 新增環境變數

除標準 Tableau Server 容器環境變數（請參閱[初始設定選項](https://help.tableau.com/current/server-linux/zh-tw/server-in-container_image.htm#InitialConfigOptions-container)）外，還必須在 Kubernetes 設定中設置一些新必要環境變數。

<table style="width: 100%;mc-table-style: url('Resources/TableStyles/Basic-Border-Light.css');" class="TableStyle-Basic-Border" cellspacing="0"><colgroup><col class="TableStyle-Basic-Border-Column-Column1" style="width: 25%;"><col class="TableStyle-Basic-Border-Column-Column1" style="width: 25%;"><col class="TableStyle-Basic-Border-Column-Column1" style="width: 50%;"></colgroup><thead><tr class="TableStyle-Basic-Border-Head-Header1"><th class="TableStyle-Basic-Border-HeadE-Column1-Header1">環境變數</th><th class="TableStyle-Basic-Border-HeadE-Column1-Header1">建議值</th><th class="TableStyle-Basic-Border-HeadD-Column1-Header1">描述</th></tr></thead><tbody><tr class="TableStyle-Basic-Border-Body-Body1"><td class="TableStyle-Basic-Border-BodyE-Column1-Body1"><code>FILESTORE_MOUNT_PATH</code></td><td class="TableStyle-Basic-Border-BodyE-Column1-Body1"><code>/docker/dataengine</code></td><td class="TableStyle-Basic-Border-BodyD-Column1-Body1">外部 Filestore 目錄掛接位置。此目錄應指向安裝在每個已部署 Tableau 容器內的資料引擎 NFS 目錄。有關外部 Filestore 的詳情，請參閱 <a href="https://help.tableau.com/current/server-linux/zh-tw/server_external_filestore_storage.htm" class="xref">Tableau Server 外部檔案存放區</a>。對於容器中的 Tableau Server Pod 和背景程式 Pod，該值應該相同。</td></tr><tr class="TableStyle-Basic-Border-Body-Body1"><td class="TableStyle-Basic-Border-BodyE-Column1-Body1"><code>CLONE_ARTIFACT_DIR</code></td><td class="TableStyle-Basic-Border-BodyE-Column1-Body1"><code>/docker/clone/clone-artifacts</code></td><td class="TableStyle-Basic-Border-BodyD-Column1-Body1">複製設定目錄掛接位置。此目錄應指向掛接在每個 Tableau 容器內的 NFS 目錄。Tableau Server 將輸出背景程式 Pod 使用以成為叢集成員的設定資料。</td></tr><tr class="TableStyle-Basic-Border-Body-Body1"><td class="TableStyle-Basic-Border-BodyB-Column1-Body1"><code>ROOT_LOG_DIR</code></td><td class="TableStyle-Basic-Border-BodyB-Column1-Body1"><code>/var/log/tableau</code></td><td class="TableStyle-Basic-Border-BodyA-Column1-Body1">（僅限背景 Pod）<p>在背景程式 Pod 中執行的所有服務的通用記錄目錄位置。</p></td></tr></tbody></table>

### 背景程式 Pod 連接埠

背景程式 Pod 由四相服務組成，每個服務遇時設定為在指定連接埠執行。如果要變更容器內連結服務的連接埠，則需要提供與服務連接埠指派對應的金鑰。在大多數情況下，這種設定不是必需的，除非有要在 Pod 中新增的邊車容器或其他附加元件，且與服務的連接埠衝突。

| 連接埠環境變數 | 預設值 |
| --- | --- |
| `BACKGROUNDER_PORT` | `8600` |
| `DATASERVER_PORT` | `8400` |
| `HYPER_PORT` | `8200` |
| `GATEWAY_PORT` | `8080` |

Dataserver 也使用連接埠 8300，該連接埠無法重新設定。

### 共用網絡目錄

Tableau Server 的此部署需要兩個網絡共用才能正常工作。請注意，在所有 Tableau Server 和背景程式或者 Kubernetes 設定範本中都存在這些網絡目錄：

- 資料引擎目錄 (`FILESTORE_MOUNT_PATH` )：背景程式 Pod 需要外部 Filestore 功能。此網絡共用包含將在 Tableau Server 和背景程式 Pod 之間共用的資料擷取和其他基於檔案的成品。
- **複製目錄** (`CLONE_ARTIFACT_DIR` )：Tableau Server 將靜態連線和設定資訊寫入網絡共用。背景程式 Pod 將使用此資訊成為 Tableau Server 叢集成員。在未來的預發佈版本中，會將此設定納入 Kubernetes 設定的標準生命週期。

**重要提示：**如果要完全重新部署叢集（包括新的 Tableau Server 容器），則必須清除複製 NFS 掛接內容（否則背景程式 Pod 將嘗試連線到舊伺服器）。

### Kubernetes 設定範例

**附註：** 設定範例包括使用整備度探查。如果 Tableau Server 容器採用單一節點 TSM 部署（部署可以包括多個幕後程式 Pod）時，即可使用整備度探查。不能在部署對多節點 Tableau Server 的容器中使用整備度探查。

#### Tableau Server 容器 Config

\---  
apiVersion: v1  
kind: Service  
metadata:  
  name: <service\_name>  
  namespace: <namespace>  
spec:  
  selector:  
    app: <service\_name>  
  ports:  
    - protocol: TCP  
      port: 8080  
      nodePort: <nodeport-number>  
      name: http  
    - protocol: TCP  
      port: 8443  
      nodePort: <nodeport-number>  
      name: https  
  type: NodePort  
\---  
apiVersion: v1  
kind: ConfigMap  
metadata:  
  name: configfile  
  namespace: <namespace>  
data:  
  config.json: |-  
    {  
      "configEntities": {  
      "identityStore": {  
        "\_type": "identityStoreType",  
        "type": "local"  
      }  
    },  
    "configKeys" : {  
      "tabadmincontroller.init.smart\_defaults.enable" : "false",  
      "wgserver.domain.ldap.starttls.enabled" : "false"  
    },  
    "daysLeftForMaintenanceExpiring" : 0  
  }  
\---  
apiVersion: v1  
kind: ConfigMap  
metadata:  
  name: extrepojsonfile  
  namespace: <namespace>  
data:  
  config.json: |-  
    {  
      "flavor":"generic",  
      "masterUsername":"<admin-name>",  
      "masterPassword":"<password>",  
      "host":"<hostname>",  
      "port":5432,  
      "prerequisiteCheckEnabled":false,  
      "requireSsl":false  
    }  
\---  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
  name: datadir1  
  namespace: <namespace>  
spec:  
  accessModes:  
  - ReadWriteOnce  
  resources:  
    requests:  
    storage: 50Gi  
\---  
\# This is required for multi-node tableau server in container  
apiVersion: v1  
kind: PersistentVolume  
metadata:  
  name: bootstrapnfs  
  namespace: <namespace>  
spec:  
  accessModes:  
    - ReadWriteMany  
  capacity:  
    storage: 1Gi  
  nfs:  
    server: <nfs-ip>  
    path: <mount-path>  
\---  
\# This is required for multi-node tableau server in container  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
  name: bootstrapnfs  
  namespace: <namespace>  
spec:  
  accessModes:  
    - ReadWriteMany  
  storageClassName: ""  
  resources:  
    requests:  
      storage: 1Mi  
\---  
apiVersion: v1  
kind: PersistentVolumn  
metadata:  
  name: clonenfs  
  namespace: <namespace>  
spec:  
  accessModes:  
    - ReadWriteMany  
capacity:  
  storage: 1Gi  
nfs:  
  server: <nfs-ip>  
  path: <mount-path>  
\---  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
  name: clonenfs  
  namespace: <namespace>  
spec:  
  accessModes:  
    - ReadWriteMany  
  storageClassName: ""  
  resources:  
    requests:  
      storage: 1Mi  
\---  
apiVersion: v1  
kind: PersistentVolume  
metadata:  
    name: dataenginenfs  
    namespace: <namespace>  
spec:  
  accessModes:  
    - ReadWriteMany  
  capacity:  
    storage: 1Gi  
  nfs:  
    server: <nfs-ip>  
    path: <namespace>  
\---  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
  name: dataenginenfs  
  namespace: <namespace>  
spec:  
  accessModes:  
    - ReadWriteMany  
  storageClassName: ""  
  resources:  
    requests:  
      storage: 1Mi  
\---  
apiVersion: v1  
kind: Secret  
type: Opaque  
metadata:
  name: tableau-server-in-a-container-secrets  
  namespace: <namespace>  
stringData:  
  license\_key: <license\_key> # Tableau License Key String  
  tableau\_username: <tableau\_username> # Initial admin username in Tableau Server  
  tableau\_password: <tableau\_password> # Initial admin password  
\---  
apiVersion: apps/v1  
kind: StatefulSet  
metadata:  
  name: tableau-server  
  namespace: <namespace>  
  labels:  
    app: <service\_name>  
spec:  
  selector:  
    matchLabels:  
      app: <service\_name>  
  replicas: 1  
  serviceName: <service\_name>  
  template:  
    metadata:  
      labels:  
        app: <service\_name>  
    spec:  
      securityContext:  
        runAsUser: 999  
        fsGroup: 998  
        fsGroupChangePolicy: "OnRootMismatch"  
      terminationGracePeriodSeconds: 120  
      dnsPolicy: "None"  
      dnsConfig:  
        nameservers:  
          - <dns\_ip> # DNS IP for resolving container hostnames  
        searches:  
          - <service\_name>.<namespace>.svc.<cluster\_domain>.<example> # SRV Record  
          - <namespace>.svc.<cluster\_domain>.<example> # SRV Record  
          - svc.<cluster\_domain>.<example> # SRV Record  
          - <cluster\_domain>.<example> # SRV Record  
        options:  
          - name: ndots  
            value: "5"  
      initContainers: # init containers are optional, to clear directory content if already exists  
        - name: clean-bootstrap-dir  
          image: busybox:1.28  
          securityContext:  
            runAsUser: 0  
            allowPrivilegeEscalation: true  
          volumeMounts:  
          - name: bootstrap  
            mountPath: /docker/config/bootstrap  
          command: \['sh', '-c', 'rm -rf /docker/config/bootstrap/\* || true'\]  
        - name: clean-clone-artifacts-dir  
          image: busybox:1.28  
          securityContext:  
            runAsUser: 0  
            allowPrivilegeEscalation: true  
          volumeMounts:  
          - name: clone  
            mountPath: /docker/clone  
          command: \['sh', '-c', 'rm -rf /docker/clone/clone-artifacts || true'\]  
      containers:  
      - name: <container\_name> # Name of container  
        image: <tableau\_server\_image> # Tableau Server in Container Image  
        env:  
        - name: LICENSE\_KEY  
          valueFrom:  
            secretKeyRef:  
              name: tableau-server-in-a-container-secrets  
              key: license\_key  
        - name: FILESTORE\_MOUNT\_PATH  
          value: /docker/dataengine  
        - name: CLONE\_ARTIFACT\_DIR\_FOR\_INDEPENDENT\_CONTAINERS  
          value: /docker/clone/clone-artifacts  
        - name: SERVER\_FOR\_INDEPENDENT\_SERVICE\_CONTAINERS  
          value: "1"  
        - name: EXT\_REP\_JSON\_FILE  
          value: /docker/external-repository/config.json  
        - name: TABLEAU\_USERNAME  
          valueFrom:  
            secretKeyRef:  
              name: tableau-server-in-a-container-secrets  
              key: tableau\_username  
        - name: TABLEAU\_PASSWORD  
          valueFrom:  
            secretKeyRef:  
              name: tableau-server-in-a-container-secrets  
              key: tableau\_password  
        resources:  
          requests:  
            memory: 40Gi  
            cpu: 15  
          limits:  
            memory: 40Gi  
            cpu: 15  
        ports:  
        - containerPort: 8080  
        volumeMounts:  
        - name: configmount  
          mountPath: /docker/config/config.json  
          subPath: config.json  
        - name: externalrepomount  
          mountPath: /docker/external-repository  
        - name: datadir1  
          mountPath: /var/opt/tableau  
        - name: bootstrap  
          mountPath: /docker/config/bootstrap  
        - name: clone  
          mountPath: /docker/clone  
        - name: dataengine  
          mountPath: /docker/dataengine  
        imagePullPolicy: IfNotPresent  
        startupProbe:  
          exec:  
            command:  
            - /bin/sh  
            - -c  
            - /docker/server-ready-check  
          initialDelaySeconds: 300  
          periodSeconds: 15  
          timeoutSeconds: 30  
          failureThreshold: 200  
        readinessProbe:  
          exec:  
            command:  
            - /bin/sh  
            - -c  
            - /docker/server-ready-check  
          periodSeconds: 30  
          timeoutSeconds: 60  
        livenessProbe:  
          exec:  
            command:  
            - /bin/sh  
            - -c  
            - /docker/alive-check  
          initialDelaySeconds: 600  
          periodSeconds: 60  
          timeoutSeconds: 60  
      volumes:  
      - name: configmount  
        configMap:  
          name: configfile  
      - name: externalrepomount  
        configMap:  
          name: extrepojsonfile  
      - name: datadir1  
        persistentVolumeClaim:  
          claimName: datadir1  
      - name: bootstrap  
        persistentVolumeClaim:  
          claimName: bootstrapnfs  
      - name: clone  
        persistentVolumeClaim:  
          claimName: clonenfs  
      - name: dataengine  
        persistentVolumeClaim:  
          claimName: dataenginenfs

#### 背景程式 Pod 設定

\---  
apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
  name: logvolume  
  namespace: <namespace>  
spec:  
  accessModes:  
  - ReadWriteOnce  
  resources:  
    requests:  
      storage: 20Gi  
\---  
apiVersion: apps/v1  
kind: Deployment  
metadata:  
  name: backgrounder  
  labels:  
    app: backgrounder  
  namespace: <namespace>   
spec:  
  replicas: 2  
  selector:  
    matchLabels:  
      app: backgrounder  
  template:  
    metadata:  
      labels:  
        app: backgrounder  
    spec:  
      securityContext:  
        runAsUser: 999  
        runAsGroup: 998  
        fsGroup: 998
        fsGroupChangePolicy: "OnRootMismatch"  
      hostname: backgrounder  
      dnsPolicy: "None"  
      dnsConfig:  
        nameservers:  
          - <dns\_ip> # DNS IP for resolving container hostnames  
        searches:  
          - <service\_name>.<namespace>.svc.<cluster\_domain>.<example> # SRV Record  
          - <namespace>.svc.<cluster\_domain>.<example> # SRV Record  
          - svc.<cluster\_domain>.<example> # SRV Record  
          - <cluster\_domain>.<example> # SRV Record  
        options:  
          - name: ndots  
            value: "5"
      initContainers:  
        - name: init-myservice  
          image: busybox # This init-container is optional (as long as there is a mechanism to set the log volume directory permissions and the pod waits for clone artifacts)  
          securityContext:  
            runAsUser: 0  
            allowPrivilegeEscalation: true  
          env:  
            - name: CLONE\_ARTIFACT\_DIR\_FOR\_INDEPENDENT\_CONTAINERS  
            value: /docker/clone/clone-artifacts  
          volumeMounts:  
          - name: logmount  
            mountPath: /var/log/tableau  
          - name: clone-volume  
            mountPath: /docker/clone  
          command: \['sh', '-c', "chmod 777 /var/log/tableau && while \[ ! -d ${CLONE\_ARTIFACT\_DIR\_FOR\_INDEPENDENT\_CONTAINERS} \]; do sleep 5; done"\]  
      containers:  
      - name: backgrounder  
        image: <backgrounder\_image> # Backgrounder Image  
        ports:  
        - containerPort: 8600
        imagePullPolicy: IfNotPresent
        readinessProbe:  
          exec:  
            command:  
              - /bin/sh  
              - -c  
              - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
          periodSeconds: 30  
          timeoutSeconds: 60  
        livenessProbe:  
          exec:  
            command:  
              - /bin/sh  
              - -c  
              - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
          initialDelaySeconds: 600  
          periodSeconds: 60  
          timeoutSeconds: 60
        volumeMounts:  
        - name: logmount  
          mountPath: /var/log/tableau  
        - name: clone-volume  
          mountPath: /docker/clone  
        - name: dataengine-volume  
          mountPath: /docker/dataengine  
        - name: temp  
          mountPath: /var/opt/tableau/tableau\_server/data/tabsvc/temp  
        env:  
          - name: ROOT\_LOG\_DIR  
            value: /var/log/tableau  
          - name: CLONE\_ARTIFACT\_DIR\_FOR\_INDEPENDENT\_CONTAINERS  
            value: /docker/clone/clone-artifacts  
          - name: FILESTORE\_MOUNT\_PATH  
            value: /docker/dataengine  
      - name: dataserver  
        image: <dataserver\_image> # Dataserver Image  
        ports:  
        - containerPort: 8400
        imagePullPolicy: IfNotPresent
        readinessProbe:  
          exec:  
            command:  
              - /bin/sh  
              - -c  
              - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
          periodSeconds: 30  
          timeoutSeconds: 60  
        livenessProbe:  
          exec:  
            command:  
              - /bin/sh  
              - -c  
              - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
          initialDelaySeconds: 600  
          periodSeconds: 60  
          timeoutSeconds: 60  
        volumeMounts:  
        - name: logmount  
          mountPath: /var/log/tableau  
        - name: clone-volume  
          mountPath: /docker/clone  
        - name: dataengine-volume  
          mountPath: /docker/dataengine  
        - name: temp  
          mountPath: /var/opt/tableau/tableau\_server/data/tabsvc/temp  
        env:  
          - name: ROOT\_LOG\_DIR  
            value: /var/log/tableau  
          - name: CLONE\_ARTIFACT\_DIR\_FOR\_INDEPENDENT\_CONTAINERS  
            value: /docker/clone/clone-artifacts  
          - name: FILESTORE\_MOUNT\_PATH  
            value: /docker/dataengine  
      - name: gateway  
        image: <gateway\_image> # Gateway Image  
        ports:  
        - containerPort: 8080
        imagePullPolicy: IfNotPresent
        readinessProbe:  
          exec:  
            command:  
              - /bin/sh  
              - -c  
              - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
          periodSeconds: 30  
          timeoutSeconds: 60  
        livenessProbe:  
          exec:  
            command:  
              - /bin/sh  
              - -c  
              - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
          initialDelaySeconds: 600  
          periodSeconds: 60  
          timeoutSeconds: 60
        volumeMounts:  
        - name: logmount  
          mountPath: /var/log/tableau  
        - name: clone-volume  
          mountPath: /docker/clone  
        - name: dataengine-volume  
          mountPath: /docker/dataengine  
        - name: temp  
          mountPath: /var/opt/tableau/tableau\_server/data/tabsvc/temp  
        env:  
          - name: ROOT\_LOG\_DIR  
            value: /var/log/tableau  
          - name: CLONE\_ARTIFACT\_DIR\_FOR\_INDEPENDENT\_CONTAINERS  
            value: /docker/clone/clone-artifacts  
          - name: FILESTORE\_MOUNT\_PATH  
            value: /docker/dataengine  
    - name: hyper  
      image: <hyper\_image> # Hyper Image  
      ports:
      - containerPort: 8200
      imagePullPolicy: IfNotPresent
      readinessProbe:  
        exec:  
          command:  
            - /bin/sh  
            - -c  
            - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
        periodSeconds: 30  
        timeoutSeconds: 60  
      livenessProbe:  
        exec:  
          command:  
          - /bin/sh  
          - -c
          - /tsm\_docker\_utils/status\_check.sh | grep -E 'ACTIVE|BUSY'  
        initialDelaySeconds: 600  
        periodSeconds: 60  
        timeoutSeconds: 60
      volumeMounts:  
        - name: logmount  
          mountPath: /var/log/tableau  
        - name: clone-volume  
          mountPath: /docker/clone  
        - name: dataengine-volume  
          mountPath: /docker/dataengine  
        - name: temp  
          mountPath: /var/opt/tableau/tableau\_server/data/tabsvc/temp  
      env:  
        - name: ROOT\_LOG\_DIR  
          value: /var/log/tableau  
        - name: CLONE\_ARTIFACT\_DIR\_FOR\_INDEPENDENT\_CONTAINERS  
          value: /docker/clone/clone-artifacts  
        - name: FILESTORE\_MOUNT\_PATH  
          value: /docker/dataengine  
    volumes:  
      - name: clone-volume  
        nfs:  
          server: <nfs\_ip>   
          path: <mount\_path>  
      - name: dataengine-volume  
        nfs:  
          server: <nfs\_ip>   
          path: /dataengine  
      - name: logmount  
        persistentVolumeClaim:  
          claimName: logvolume  
      - name: temp  
        emptyDir: {}

#### 排程的縮放設定

apiVersion: v1  
kind: ServiceAccount  
metadata:  
name: backgrounder-scaler-service-account  
namespace: <namespace> # Namespace  
\---  
apiVersion: rbac.authorization.k8s.io/v1  
kind: RoleBinding  
metadata:  
name: scale-backgrounder-pods  
namespace: <namespace> # Namespace  
subjects:  
\- kind: ServiceAccount  
name: backgrounder-scaler-service-account  
roleRef:  
kind: ClusterRole  
name: cluster-admin  
apiGroup: rbac.authorization.k8s.io  
\---  
apiVersion: batch/v1beta1  
kind: CronJob  
metadata:  
name: scale-up-job  
namespace: <namespace> # Namespace  
spec:  
schedule: "0 7 \* \* \*" # Cron Job timing to scale up deployment replicas  
jobTemplate:  
spec:  
template:  
spec:  
serviceAccountName: backgrounder-scaler-service-account  
restartPolicy: OnFailure  
containers:  
\- name: scale  
image: bitnami/kubectl:1.21  
imagePullPolicy: IfNotPresent  
args:  
\- scale  
\- --replicas=4  
\- deployment/backgrounder  
\---  
apiVersion: batch/v1beta1  
kind: CronJob  
metadata:  
name: scale-down-job  
namespace: <namespace>  
spec:  
schedule: "0 9 \* \* \*" # Cron Job timing to scale down deployment replicas  
jobTemplate:  
spec:  
template:  
spec:  
serviceAccountName: backgrounder-scaler-service-account  
restartPolicy: OnFailure  
containers:  
\- name: scale  
image: bitnami/kubectl:1.21  
imagePullPolicy: IfNotPresent  
args:  
\- scale  
\- --replicas=2  
\- deployment/backgrounder

#### 用於清理複製設定的 Kubernetes 工作（可選）

這是您在測試期間可能會使用的便捷 Kubernetes 工作。如果要在不同的部署執行之間清除容器中 Tableau Server 生成的複製設定，可以執行這樣的工作來清理 NFS。

apiVersion: batch/v1  
kind: Job  
metadata:  
name: delete-clone-artifacts-job  
namespace: manatee-cluster  
spec:  
template:  
spec:  
containers:  
\- name: delete-clone-artifacts  
image: busybox:1.28  
command: \['sh', '-c', "rm -rf ${CLONE\_ARTIFACT\_DIR}"\]  
env:  
\- name: CLONE\_ARTIFACT\_DIR  
value: /docker/clone/clone-artifacts  
securityContext:  
runAsUser: 0  
allowPrivilegeEscalation: true  
volumeMounts:  
\- name: clone-volume  
mountPath: /docker/clone  
restartPolicy: Never  
volumes:  
\- name: clone-volume  
nfs:  
server: <nfs\_ip> # IP for shared NFS directory for clone output  
path: /clone