我相信當我們意識到重要且敏感的訪問信息已經暴露到公共網絡上,並可能使您的微服務無條件被訪問。隨著我們依賴於的開發出來的服務化的量不斷增加, 這時跟蹤敏感細節的數量也有所增加。為了應對這個問題,在“secrets managemen”領域出現了工具。
在這篇文章中,我們將看Docker Secrets,要求在Docker 1.13及更高版本的新祕密管理功能。
從Docker的角度來看,該功能不需要太多的工作,但是您可能需要重構應用程序以利用它。我們將介紹如何做到這一點的想法,但不是詳細的。
Docker的 Secrets只適用於Docker群集,主要是因為這是祕密管理最有意義的領域。畢竟,Swarm是針對多個Docker實例需要在他們之間共享訪問細節的生產用途。如果要在獨立容器中使用祕密管理,則需要運行
scale
值設置為1 的容器。適用於Mac和Windows的Docker不支持多節點群集模式,但您可以使用它們使用Docker Machine創建多節點群集。
創建兩個機器,然後創建一個兩個節點,並從該組中的一個swarm環境中運行本文中的案例。
獲得Secrets
當您從命令行創建Secrets時,您可以使用所有可用的工具來創建隨機密碼和管道輸出。例如,為數據庫用戶創建一個隨機密碼:
opensslrand-base6420|dockersecretcreatemariadb_password-
這將返回一個祕密的ID。
您需要再次發出此命令以生成MariaDB root用戶的密碼。您將需要這樣才能開始使用,但您不需要為每項服務。
opensslrand-base6420|dockersecretcreatemariadb_root_password-
如果你已經忘記了你創建的祕密, 可以用ls查看,也可以用以下命令查看docker secret ls
替換secrets
為了保持祕密,良好的祕密,服務之間的通信發生在您定義的覆蓋網絡中。它們只能通過調用其ID來在該覆蓋網絡中使用。
dockernetworkcreate-doverlaymariadb_private
這也將返回該網絡的ID。再次,你可以docker network ls
查看相關網絡
創建服務
這個例子將有一個Docker節點運行MariaDB,一個運行Python的節點。在最終的應用程序中,Python應用程序將讀取和寫入數據庫。
首先,添加一個MariaDB服務。此服務使用您創建的網絡進行通信,之前創建的祕密保存為兩個文件:一個用於根密碼,一個用於默認用戶密碼。然後將所需的所有變量作為環境變量傳遞給服務。
dockerservicecreate\ --namemariadb\ --replicas1\ --networkmariadb_private\ --mounttype=volume,source=mydata,destination=/var/lib/mariadb\ --secretsource=mariadb_root_password,target=mariadb_root_password\ --secretsource=mariadb_password,target=mariadb_password\ -eMARIADB_ROOT_PASSWORD_FILE="/run/secrets/mariadb_root_password"\ -eMARIADB_PASSWORD_FILE="/run/secrets/mariadb_password"\ -eMARIADB_USER="python"\ -eMARIADB_DATABASE="python"\
Python實例再次使用您創建的專用網絡,並複製網絡中可訪問的祕密。一個更好的(生產就緒的)選項將是創建您的應用程序在管理程序中需要的數據庫,而不會給應用程序訪問根密碼,但這僅僅是一個例子。
dockerservicecreate\ --namecspython\ --replicas1\ --networkmariadb_private\ --publish50000:5000\ --mounttype=volume,source=pydata,destination=/var/www/html\ --secretsource=mariadb_root_password,target=python_root_password,mode=0400\ --secretsource=mariadb_password,target=python_password,mode=0400\ -ePYTHON_DB_USER="python"\ -ePYTHON_DB_ROOT_PASSWORD_FILE="/run/secrets/python_root_password"\ -ePYTHON_DB_PASSWORD_FILE="/run/secrets/python_password"\ -ePYTHON_DB_HOST="mariadb:3306"\ -ePYTHON_DB_NAME="python"\
上面的示例使用我創建的一個簡單的Docker映像,它設置用於使用Flask創建Web應用程序的軟件包,用於提供Web頁面和PyMySQL來進行數據庫訪問。代碼沒有做太多,但顯示瞭如何從Docker容器訪問環境變量。
例如,要連接到沒有指定數據庫的數據庫服務器:
importos importMySQLdb db=MySQLdb.connect(host=os.environ['PYTHON_DB_HOST'], user=os.environ['PYTHON_DB_ROOT_USER'], passwd=os.environ['PYTHON_DB_PASSWORD_FILE']) cur=db.cursor() print(db) db.close()
更新secrets
頻繁更改敏感信息是個好習慣。但是,您可能知道,在應用程序中更新這些細節是一個沉悶的過程,最不願意避免。通過服務,Docker Secrets管理允許您更改值,而無需更改代碼。
創建一個新祕密:
opensslrand-base6420|dockersecretcreatemariadb_password_march-
從MariaDB服務中刪除當前密碼的訪問權限:
dockerserviceupdate\ --secret-rmmariadb_password\
並讓它訪問新的祕密,將目標指向新的值:
dockerserviceupdate\ --secret-addsource=mariadb_password_march,target=mysql_password\
更新Python服務:
dockerserviceupdate\ --secret-rmmariadb_password\ --secret-addsource=mariadb_password_march,target=python_password,mode=0400\
並刪除舊祕密:
dockersecretrmmariadb_password
擴展說明
Docker Secrets是一個新功能,但Docker鼓勵鏡像維護人員儘快為Docker用戶提供更好的安全性。這需要允許與上述示例類似的過程,其中容器可以從通過生成祕密而不是硬編碼到應用中創建的文件來讀取其需要的每個參數。這可以強制實施集裝箱應用程序,因為容器可以來回走動,但是始終可以訪問您的應用程序運行所需的重要信息。