本篇隨筆是繼 「Docker Engine」 與 「Compose & Swarm」 以後的一個實例補充,初衷是記錄測試環境中的一次 MySQL 事故,就當作 「Docker 系列」 的一個小收尾吧。其實在生產環境中不推薦使用 Docker 部署 MySQL 和 Redis,那但是 The First Domino,倒一個掛一片呀,不過在本地和測試環境中就隨意了。
php
通常部署這些 db_service 容器都應該配套其管理工具(我不否定能夠經過命令行完成全部的操做,並且功能更多,權限更大,可是非 DBA 的童鞋仍是乖乖使用 UI 吧,耍酷浪費太多時間也不值當🤣),所以,這裏我選擇的鏡像組合是 mysql、adminer 與 redis、erikdubbelboer/phpredisadmin。html
Ps:這節過短了,就插一些題外話吧。如今爽 Docker 的同時其實也在爲過去的本身默哀,想當年初入編程的時候還沒普及雲服務器和各類打包好的雲服務方案,固然也沒有 Docker,想作點什麼實驗和測試都得在本機。本本性能不行還得一天到晚折騰各類安裝環境,就拿 db_service 來講吧,當時選擇的是 SQL Server,流行的版本是 0五、08 和 08 r2 等,客戶要求啥版本的都有。那開發的時候得在本地裝呀,要命的是這傢伙根本沒法完全卸載,版本之間還有兼容問題,啥錯誤都遇到過,解決不了最後的終極方案就是重裝系統,而後呢... 還得再裝呀... 這一會兒就是半天到一天的時間。使用虛擬機吧,打開幾個 IDE 再啓動幾個虛擬機,不要說那時候了,就是如今的主流機也扛不動呀,編程體驗幾乎爲零。這裏算是憶苦思甜了,想一想那時候,如今簡直太幸福了。mysql
adminer 與 phpredisadmin 均可以在集羣內訪問須要代理的服務,若是是在服務器上也不用額外暴露 3306 和 6379 端口,如下是個人 docker-compose 配置:程序員
mysql: image: mysql networks: - proxy - youclk volumes: - /mnt/nas/db/mysql:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: db_password deploy: restart_policy: condition: any max_attempts: 3 update_config: delay: 5s order: start-first resources: limits: cpus: '0.50' memory: 1g
mysql_admin: image: adminer networks: - proxy - youclk depends_on: - mysql deploy: labels: - com.df.notify=true - com.df.port=8080 - com.df.serviceDomain=mysql.youclk.com restart_policy: condition: any max_attempts: 3 update_config: delay: 5s order: start-first resources: limits: cpus: '0.50' memory: 1g
啓動後 UI 展現以下:
redis
redis: image: redis networks: - proxy - youclk deploy: restart_policy: condition: any max_attempts: 3 update_config: delay: 5s order: start-first resources: limits: cpus: '0.50' memory: 1g
redis_admin: image: erikdubbelboer/phpredisadmin networks: - proxy - youclk environment: - REDIS_1_HOST=redis - REDIS_1_NAME=redis depends_on: - redis deploy: labels: - com.df.notify=true - com.df.port=80 - com.df.serviceDomain=redis.youclk.com restart_policy: condition: any max_attempts: 3 update_config: delay: 5s order: start-first resources: limits: cpus: '0.50' memory: 1g
啓動後 UI 展現以下:
sql
若是看過我以前的兩篇博文或者對 Compose 有必定了解的話,以上參數一目瞭然,此處不作過多贅述。docker
但若是是部署在本地的話,各類 db_service 工具或者是集羣外的其餘服務也可能須要鏈接 db,因此得暴露其各自的端口,我傾向於再編寫一個 docker-compose.local.yml ,用於放置本地配置,以下:編程
version: '3.5' services: mysql: ports: - 3306:3306 volumes: - /Users/Jermey/Documents/data/db/mysql:/var/lib/mysql mysql_admin: deploy: labels: - com.df.notify=true - com.df.port=8080 - com.df.serviceDomain=local-mysql.youclk.com redis: ports: - 6379:6379 redis_admin: deploy: labels: - com.df.notify=true - com.df.port=80 - com.df.serviceDomain=local-redis.youclk.com
而後再編寫一個啓動腳本,根據當前的系統環境判斷是否合併多個配置文件(個人寫法比較粗暴,如有更優雅的方案歡迎留言交流):服務器
if [ -z "`uname -a | grep 'Linux'`" ];then docker-compose -f ../src/docker-compose.yml \ -f ../src/docker-compose.local.yml \ config > docker-stack.yml docker stack deploy -c docker-stack.yml --with-registry-auth db else docker stack deploy -c ../src/docker-compose.yml --with-registry-auth db fi
開門見山先說結果吧,最後確認是致使異常的緣由是使用 NFS 存儲 MySQL 的數據。起初服務一直能很是穩定在我本地的集羣中運行,但在測試服務器上卻時不時忽然掛掉且沒法重啓,開始的時候一頭霧水,本地和測試環境的配置文件徹底一致呀,並且都是 Docker Swarm 集羣,不該該有任何系統因素相關的干擾。並且它不是啓動事後立馬會掛,而是運行一段時間以後,期間我發了瘋地去排除一個個可能致使 MySQL 宕機的其餘服務,而因 NFS 可以正常掛載卻被我最早排除(期間的心塞程度有 BUG 經歷的工友應當能理解)。ide
直到我在 MySQL 官網看到了這則申明:
Caution is advised when considering using NFS with MySQL. Potential issues, which vary by operating system and NFS version, include:
- MySQL data and log files placed on NFS volumes becoming locked and unavailable for use. Locking issues may occur in cases where multiple instances of MySQL access the same data directory or where MySQL is shut down improperly, due to a power outage, for example. NFS version 4 addresses underlying locking issues with the introduction of advisory and lease-based locking. However, sharing a data directory among MySQL instances is not recommended.
- Data inconsistencies introduced due to messages received out of order or lost network traffic. To avoid this issue, use TCP with hard and intr mount options.
- Maximum file size limitations. NFS Version 2 clients can only access the lowest 2GB of a file (signed 32 bit offset). NFS Version 3 clients support larger files (up to 64 bit offsets). The maximum supported file size also depends on the local file system of the NFS server.
Using NFS within a professional SAN environment or other storage system tends to offer greater reliability than using NFS outside of such an environment. However, NFS within a SAN environment may be slower than directly attached or bus-attached non-rotational storage.
If you choose to use NFS, NFS Version 4 or later is recommended, as is testing your NFS setup thoroughly before deploying into a production environment.
官方文檔很是直白地警告 NFS 有風險,使用需謹慎。這下總算鬆了一口氣,終於知道問題源頭了,反正是測試環境,隨便指定 MySQL 掛載集羣中一個節點的目錄就行。但不死心的我又嘗試了下先將 NFS 掛載到主機,而後由 MySQL 容器再去掛載已經掛載了 NFS 的主機目錄,如今是已經正常運行好幾天了沒有再宕機。
Ps:能夠將掛載的命令寫入初始配置腳本,新服務器到手以後只需執行一行代碼就能夠愉快地玩耍了,有興趣能夠看我這篇隨筆:「Ubuntu 自動化配置」。
編程的樂趣非程序員不能體會,一行行代碼造就了這繽紛多彩的世界,並且其最大的魅力在於咱們的產品複用幾乎是無成本的。也正因如此,不管我現此生活質量如何,我都能始終懷揣帶有一些夢幻色彩的理想,併爲之奮鬥。而程序員的悲哀也非他人能輕易理解,你可能認爲你在處理一個偉大的問題,到頭來,可能僅僅是一個符號在做祟。本篇隨筆抒情的廢話比較多,感謝閱讀 :)
個人公衆號《有刻》,咱們共同成長!