文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  使用 Docker 部署 MySQL Server 的更多主題

2.5.6.2 使用 Docker 部署 MySQL Server 的更多主題

注意

以下大多數範例命令都使用 container-registry.oracle.com/mysql/community-server 作為 Docker 映像 (例如,docker pulldocker run 命令);如果您的映像來自其他儲存庫,請變更它—例如,將其取代為 container-registry.oracle.com/mysql/enterprise-server 以用於從 Oracle Container Registry (OCR) 下載的 MySQL Enterprise Edition 映像,或取代為 mysql/enterprise-server 以用於從 My Oracle Support 下載的 MySQL Enterprise Edition 映像。

針對 Docker 最佳化的 MySQL 安裝

MySQL 的 Docker 映像已針對程式碼大小進行最佳化,這表示它們僅包含預期與在 Docker 容器中執行 MySQL 執行個體的大多數使用者相關的重要元件。MySQL Docker 安裝與一般的非 Docker 安裝在以下方面不同

  • 僅包含有限數量的二進位檔案。

  • 所有二進位檔案都已剝離;它們不包含偵錯資訊。

警告

使用者對 Docker 容器執行的任何軟體更新或安裝 (包括 MySQL 元件的更新或安裝) 都可能與 Docker 映像所建立的最佳化 MySQL 安裝衝突。Oracle 不為在此類變更後的容器,或從變更後的 Docker 映像建立的容器中執行的 MySQL 產品提供支援。

設定 MySQL Server

當您啟動 MySQL Docker 容器時,您可以透過 docker run 命令將組態選項傳遞至伺服器。例如

docker run --name mysql1 -d container-registry.oracle.com/mysql/community-server:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_col

此命令會以 utf8mb4 作為預設字元集和 utf8mb4_col 作為資料庫的預設定序來啟動 MySQL Server。

設定 MySQL Server 的另一種方法是準備一個組態檔案,並將其掛載到容器內伺服器組態檔案的位置。如需詳細資訊,請參閱持續保存資料和組態變更

持續保存資料和組態變更

Docker 容器原則上是暫時性的,如果容器被刪除或損壞,任何資料或組態都將遺失 (請參閱此處的討論)。Docker 磁碟區提供了一種機制來持續保存在 Docker 容器內建立的資料。在初始化時,MySQL Server 容器會為伺服器資料目錄建立一個 Docker 磁碟區。容器上 docker inspect 命令的 JSON 輸出包含一個 Mount 金鑰,其值提供有關資料目錄磁碟區的資訊

$> docker inspect mysql1
...
 "Mounts": [
            {
                "Type": "volume",
                "Name": "4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652",
                "Source": "/var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...

輸出顯示主機上持續保存資料的來源目錄 /var/lib/docker/volumes/4f2d463cfc4bdd4baebcb098c97d7da3337195ed2c6572bc0b89f7e845d27652/_data 已掛載在 /var/lib/mysql,即容器內的伺服器資料目錄。

保存資料的另一種方法是在建立容器時,使用 --mount 選項繫結掛載主機目錄。相同的技術可用於持續保存伺服器的組態。以下命令會建立 MySQL Server 容器並繫結掛載資料目錄和伺服器組態檔案

docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=/path-on-host-machine/datadir,dst=/var/lib/mysql \
-d container-registry.oracle.com/mysql/community-server:tag

此命令會在 /etc/my.cnf (容器內的伺服器組態檔案) 掛載 path-on-host-machine/my.cnf,並在 /var/lib/mysql (容器內的資料目錄) 掛載 path-on-host-machine/datadir。繫結掛載要能運作,必須滿足以下條件

  • 組態檔案 path-on-host-machine/my.cnf 必須已存在,而且必須包含使用者 mysql 啟動伺服器的規格

    [mysqld]
    user=mysql

    您也可以在檔案中加入其他伺服器組態選項。

  • 資料目錄 path-on-host-machine/datadir 必須已經存在。為了讓伺服器初始化能順利進行,此目錄必須為空。您也可以掛載預先填入資料的目錄,並以此啟動伺服器;但是,您必須確保啟動 Docker 容器時的配置與建立資料的伺服器相同,並且在啟動容器時掛載任何所需的主機檔案或目錄。

執行額外的初始化腳本

如果有任何您想在資料庫建立後立即執行的 .sh.sql 腳本,您可以將它們放入主機目錄,然後將該目錄掛載到容器內的 /docker-entrypoint-initdb.d/。例如:

docker run --name=mysql1 \
--mount type=bind,src=/path-on-host-machine/scripts/,dst=/docker-entrypoint-initdb.d/ \
-d container-registry.oracle.com/mysql/community-server:tag
從另一個 Docker 容器連線到 MySQL

透過設定 Docker 網路,您可以允許多個 Docker 容器彼此通訊,以便另一個 Docker 容器中的客戶端應用程式可以存取伺服器容器中的 MySQL 伺服器。首先,建立一個 Docker 網路:

docker network create my-custom-net

然後,當您建立並啟動伺服器和客戶端容器時,請使用 --network 選項將它們放在您建立的網路上。例如:

docker run --name=mysql1 --network=my-custom-net -d container-registry.oracle.com/mysql/community-server
docker run --name=myapp1 --network=my-custom-net -d myapp

myapp1 容器接著可以使用 mysql1 主機名稱連線到 mysql1 容器,反之亦然,因為 Docker 會自動為給定的容器名稱設定 DNS。在以下範例中,我們從 myapp1 容器內部執行 mysql 客戶端,以連線到其自身容器中的主機 mysql1

docker exec -it myapp1 mysql --host=mysql1 --user=myuser --password

如需其他容器網路技術,請參閱 Docker 文件中的Docker 容器網路章節。

伺服器錯誤日誌

當 MySQL 伺服器首次使用您的伺服器容器啟動時,如果符合以下任一條件,則不會產生伺服器錯誤日誌

  • 已掛載來自主機的伺服器設定檔,但該檔案不包含系統變數 log_error(請參閱持久化資料和設定變更,瞭解如何繫結掛載伺服器設定檔)。

  • 尚未掛載來自主機的伺服器設定檔,但 Docker 環境變數 MYSQL_LOG_CONSOLEtrue(這是 MySQL 8.4 伺服器容器的變數預設狀態)。然後,MySQL 伺服器的錯誤日誌會重新導向到 stderr,因此錯誤日誌會進入 Docker 容器的日誌,並且可以使用 docker logs mysqld-container 命令檢視。

若要讓 MySQL 伺服器在符合任一條件時產生錯誤日誌,請使用 --log-error 選項來設定伺服器,以便在容器內的特定位置產生錯誤日誌。若要持久化錯誤日誌,請將主機檔案掛載到容器內錯誤日誌的位置,如持久化資料和設定變更中所述。但是,您必須確保容器內的 MySQL 伺服器具有寫入權限才能寫入掛載的主機檔案。

將 MySQL Enterprise Backup 與 Docker 搭配使用

MySQL Enterprise Backup 是 MySQL 伺服器的商業授權備份公用程式,可與MySQL Enterprise Edition 搭配使用。MySQL Enterprise Backup 包含在 MySQL Enterprise Edition 的 Docker 安裝中。

在以下範例中,我們假設您已經在 Docker 容器中執行 MySQL 伺服器(請參閱第 2.5.6.1 節「使用 Docker 部署 MySQL 伺服器的基本步驟」,瞭解如何使用 Docker 啟動 MySQL 伺服器執行個體)。為了讓 MySQL Enterprise Backup 備份 MySQL 伺服器,它必須能夠存取伺服器的資料目錄。例如,這可以透過在您啟動伺服器時將主機目錄繫結掛載到 MySQL 伺服器的資料目錄來實現。

docker run --name=mysqlserver \
--mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
-d mysql/enterprise-server:8.4

透過此命令,MySQL 伺服器會使用 MySQL Enterprise Edition 的 Docker 映像啟動,並且主機目錄 /path-on-host-machine/datadir/ 已掛載到伺服器容器內的伺服器資料目錄 (/var/lib/mysql)。我們也假設在伺服器啟動後,已設定所需的權限,以便讓 MySQL Enterprise Backup 存取伺服器(詳細資訊請參閱授予備份管理員 MySQL 權限)。請使用以下步驟來備份和還原 MySQL 伺服器執行個體。

若要使用 Docker 的 MySQL Enterprise Backup 備份在 Docker 容器中執行的 MySQL 伺服器執行個體,請按照此處列出的步驟進行:

  1. 在執行 MySQL 伺服器容器的相同主機上,啟動另一個具有 MySQL Enterprise Edition 映像的容器,以使用 MySQL Enterprise Backup 命令 backup-to-image 執行備份。使用我們在上一個步驟中建立的繫結掛載,提供對伺服器資料目錄的存取權。此外,請將主機目錄(在此範例中為 /path-on-host-machine/backups/)掛載到容器中備份的儲存資料夾(範例中為 /data/backups),以便持久化我們正在建立的備份。以下是此步驟的範例命令,其中 MySQL Enterprise Backup 是使用從 My Oracle Support 下載的 Docker 映像啟動的:

    $> docker run \
    --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
    --rm mysql/enterprise-server:8.4 \
    mysqlbackup -umysqlbackup -ppassword --backup-dir=/tmp/backup-tmp --with-timestamp \
    --backup-image=/data/backups/db.mbi backup-to-image

    務必檢查 mysqlbackup 的輸出結尾,以確保備份已順利完成。

  2. 容器會在備份作業完成後結束,而且使用用於啟動它的 --rm 選項,容器會在結束後移除。已建立映像備份,而且可以在上一個步驟中掛載的用於儲存備份的主機目錄中找到,如下所示:

    $> ls /tmp/backups
    db.mbi

若要使用 Docker 的 MySQL Enterprise Backup 還原 Docker 容器中的 MySQL 伺服器執行個體,請按照此處列出的步驟進行:

  1. 停止 MySQL 伺服器容器,這也會停止內部執行的 MySQL 伺服器:

    docker stop mysqlserver
  2. 在主機上,刪除 MySQL 伺服器資料目錄繫結掛載中的所有內容:

    rm -rf /path-on-host-machine/datadir/*
  3. 啟動具有 MySQL Enterprise Edition 映像的容器,以便使用 MySQL Enterprise Backup 命令 copy-back-and-apply-log 執行還原。繫結掛載伺服器的資料目錄和備份的儲存資料夾,就像我們在備份伺服器時所做的那樣:

    $> docker run \
    --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
    --rm mysql/enterprise-server:8.4 \
    mysqlbackup --backup-dir=/tmp/backup-tmp --with-timestamp \
    --datadir=/var/lib/mysql --backup-image=/data/backups/db.mbi copy-back-and-apply-log
    
    mysqlbackup completed OK! with 3 warnings

    容器會在備份作業完成後結束,並顯示訊息「mysqlbackup completed OK!」,而且使用啟動時使用的 --rm 選項,容器會在結束後移除。

  4. 使用以下命令重新啟動伺服器容器,這也會重新啟動已還原的伺服器:

    docker restart mysqlserver

    或者,在新還原的資料目錄上啟動新的 MySQL 伺服器,如下所示:

    docker run --name=mysqlserver2 \
    --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    -d mysql/enterprise-server:8.4

    登入伺服器以檢查伺服器是否正在使用已還原的資料執行。

mysqldump 與 Docker 搭配使用

除了使用 MySQL Enterprise Backup 備份在 Docker 容器中執行的 MySQL 伺服器之外,您還可以透過使用 mysqldump 公用程式(在 Docker 容器內執行)來執行伺服器的邏輯備份。

以下指示假設您已經在 Docker 容器中執行 MySQL 伺服器,而且在第一次啟動容器時,主機目錄 /path-on-host-machine/datadir/ 已掛載到伺服器的資料目錄 /var/lib/mysql(詳細資訊請參閱將主機目錄繫結掛載到 MySQL 伺服器的資料目錄),其中包含 mysqldumpmysql 可以連線到伺服器的 Unix Socket 檔案。我們也假設在伺服器啟動後,已建立具有適當權限的使用者(此範例中為 admin),mysqldump 可以使用該使用者存取伺服器。請使用以下步驟來備份和還原 MySQL 伺服器資料:

使用 Docker 的 mysqldump 備份 MySQL 伺服器資料:

  1. 在執行 MySQL 伺服器容器的相同主機上,啟動另一個具有 MySQL 伺服器映像的容器,以使用 mysqldump 公用程式執行備份(請參閱公用程式的文件,瞭解其功能、選項和限制)。透過繫結掛載 /path-on-host-machine/datadir/,提供對伺服器資料目錄的存取權。此外,請將主機目錄(在此範例中為 /path-on-host-machine/backups/)掛載到容器內備份的儲存資料夾(此範例中使用 /data/backups),以便持久化您正在建立的備份。以下是使用此設定備份伺服器上所有資料庫的範例命令:

    $> docker run --entrypoint "/bin/sh" \ 
    --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
    --rm container-registry.oracle.com/mysql/community-server:8.4 \
    -c "mysqldump -uadmin --password='password' --all-databases > /data/backups/all-databases.sql"

    在命令中,使用 --entrypoint 選項,以便在啟動容器後呼叫系統 Shell,並使用 -c 選項來指定要在 Shell 中執行的 mysqldump 命令,其輸出會重新導向到備份目錄中的檔案 all-databases.sql

  2. 容器會在備份作業完成後結束,而且使用用於啟動它的 --rm 選項,容器會在結束後移除。已建立邏輯備份,而且可以在掛載用於儲存備份的主機目錄中找到,如下所示:

    $> ls /path-on-host-machine/backups/
    all-databases.sql

使用 Docker 的 mysqldump 還原 MySQL 伺服器資料:

  1. 請確保您在容器中執行 MySQL 伺服器,您想要將備份的資料還原到該伺服器。

  2. 啟動具有 MySQL 伺服器映像的容器,以便使用 mysql 客戶端執行還原。繫結掛載伺服器的資料目錄,以及包含備份的儲存資料夾:

    $> docker run  \
    --mount type=bind,src=/path-on-host-machine/datadir/,dst=/var/lib/mysql \
    --mount type=bind,src=/path-on-host-machine/backups/,dst=/data/backups \
    --rm container-registry.oracle.com/mysql/community-server:8.4 \
    mysql -uadmin --password='password' -e "source /data/backups/all-databases.sql"

    容器會在備份作業完成後結束,而且使用啟動時使用的 --rm 選項,容器會在結束後移除。

  3. 登入伺服器以檢查已還原的資料現在是否在伺服器上。

已知問題
  • 當使用伺服器系統變數 audit_log_file 來設定稽核日誌檔名時,請使用 loose 選項修飾符;否則,Docker 無法啟動伺服器。

Docker 環境變數

當您建立 MySQL 伺服器容器時,您可以使用 --env 選項(簡寫為 -e)並指定一個或多個環境變數來設定 MySQL 執行個體。如果已掛載的資料目錄不是空的,則不會執行伺服器初始化,在這種情況下,設定任何這些變數都無效(請參閱持久化資料和組態變更),並且在容器啟動期間不會修改目錄的現有內容,包括伺服器設定。

以下列出可用於設定 MySQL 執行個體的環境變數

  • 布林變數,包括 MYSQL_RANDOM_ROOT_PASSWORDMYSQL_ONETIME_PASSWORDMYSQL_ALLOW_EMPTY_PASSWORDMYSQL_LOG_CONSOLE,只要設定為任何非零長度的字串,就會被設為 true。因此,將它們設定為例如 0falseno 並不會將它們設為 false,實際上是將它們設為 true。這是一個已知問題。

  • MYSQL_RANDOM_ROOT_PASSWORD:當此變數為 true 時(除非設定了 MYSQL_ROOT_PASSWORD 或將 MYSQL_ALLOW_EMPTY_PASSWORD 設為 true,否則為預設狀態),當 Docker 容器啟動時,會為伺服器的 root 使用者產生一個隨機密碼。該密碼會列印到容器的 stdout,並且可以透過查看容器的日誌找到(請參閱 啟動 MySQL 伺服器執行個體)。

  • MYSQL_ONETIME_PASSWORD:當此變數為 true 時(除非設定了 MYSQL_ROOT_PASSWORD 或將 MYSQL_ALLOW_EMPTY_PASSWORD 設為 true,否則為預設狀態),root 使用者的密碼會設定為過期,必須先變更才能正常使用 MySQL。

  • MYSQL_DATABASE:此變數允許您指定要在映像啟動時建立的資料庫名稱。如果使用 MYSQL_USERMYSQL_PASSWORD 提供使用者名稱和密碼,則會建立該使用者並授予對此資料庫的超級使用者存取權限(相當於 GRANT ALL)。指定的資料庫是由 CREATE DATABASE IF NOT EXIST 陳述式所建立,因此如果資料庫已存在,則此變數無效。

  • MYSQL_USERMYSQL_PASSWORD:這些變數會一起使用,以建立使用者並設定該使用者的密碼,並且該使用者會被授予由 MYSQL_DATABASE 變數指定的資料庫的超級使用者權限。必須設定 MYSQL_USERMYSQL_PASSWORD 才能建立使用者 — 如果未設定其中任何一個變數,則會忽略另一個變數。如果兩個變數都已設定,但未設定 MYSQL_DATABASE,則會建立該使用者,但不具任何權限。

    注意

    無需使用此機制來建立 root 超級使用者,預設會建立 root 超級使用者,其密碼由 MYSQL_ROOT_PASSWORDMYSQL_RANDOM_ROOT_PASSWORD 描述中討論的其中一種機制設定,除非 MYSQL_ALLOW_EMPTY_PASSWORD 為 true。

  • MYSQL_ROOT_HOST:預設情況下,MySQL 會建立 'root'@'localhost' 帳戶。根據 從容器內部連線到 MySQL 伺服器 中的描述,只能從容器內部連線到此帳戶。若要允許從其他主機進行 root 連線,請設定此環境變數。例如,值 172.17.0.1(預設的 Docker 閘道 IP)允許從執行容器的主機進行連線。此選項僅接受一個條目,但允許使用萬用字元(例如,MYSQL_ROOT_HOST=172.*.*.*MYSQL_ROOT_HOST=%)。

  • MYSQL_LOG_CONSOLE:當此變數為 true 時(對於 MySQL 8.4 伺服器容器,這是預設狀態),MySQL 伺服器的錯誤日誌會重新導向至 stderr,因此錯誤日誌會進入 Docker 容器的日誌,並且可以使用 docker logs mysqld-container 命令檢視。

    注意

    如果已從主機掛載伺服器設定檔,則此變數無效(請參閱 持久化資料和組態變更 中關於綁定掛載設定檔的說明)。

  • MYSQL_ROOT_PASSWORD:此變數指定要為 MySQL root 帳戶設定的密碼。

    警告

    在命令列上設定 MySQL root 使用者密碼是不安全的。作為明確指定密碼的替代方法,您可以使用密碼檔案的容器檔案路徑來設定變數,然後從主機掛載一個包含密碼的檔案到容器檔案路徑。這仍然不是非常安全,因為密碼檔案的位置仍然會暴露。最好使用 MYSQL_RANDOM_ROOT_PASSWORDMYSQL_ONETIME_PASSWORD 都為 true 的預設設定。

  • MYSQL_ALLOW_EMPTY_PASSWORD。將其設定為 true 可允許容器在 root 使用者的密碼為空白的情況下啟動。

    警告

    將此變數設定為 true 是不安全的,因為它會讓您的 MySQL 執行個體完全不受保護,允許任何人取得完整的超級使用者存取權限。最好使用 MYSQL_RANDOM_ROOT_PASSWORDMYSQL_ONETIME_PASSWORD 都為 true 的預設設定。