Docker buildx構建多平臺鏡像并推送到私有倉庫的方法_docker

來源:腳本之家  責任編輯:小易  

問題讓我們從這個我試圖解決的問題開始。我開發了一個會運行很長時間的構建腳本,這個腳本中包含了很多的步驟。這個腳本會運行1-2個小時。它會從網絡下載比較大的文件(超過300M)。后面的構建步驟依賴前期構建的庫。但最最煩人的是,運行這個腳本真的需要花很長的時間。文件系統是固有狀態我們一般是通過一種有狀態的方式與文件系統進行交互的。我們可以添加、刪除或移動文件。我們可以修改文件的 權限或者它的訪問時間。大部分獨立的操作都可以撤銷,例如將文件移動到其它地方后,你可以將文件恢復到原來的位置。但我們不會通過快照的方式來將它恢復到 原始狀態。這篇文章我將會介紹如何在耗時較長的腳本中充分利用快照這一特性。使用聯合文件系統的快照Docker使用的是聯合文件系統叫做AUFS(譯者注:簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統下的文件系統)。聯合文件系統實現了Union mount。顧名思義,也就是說不同的文件系統的文件和目錄可以分層疊加在單個連貫文件系統之上。這是通過分層的方式完成的。如果一個文件出現在兩個文件系統,那最高層級的文件才會顯示(該文件其它版本也是存在于層級中的,不會改變,只是看不到的)。在Docker中,每一個在Union mount轉哦給你的文件系統都被稱為layers(層)。使用這種技術可以輕松實現快照,每個快照都是所有層的一個Union mount。生成腳本的快照使用快照可以幫助構建一個長時運行的腳本。總的想法是,將一個大的腳本分解為許多小的腳本(我喜歡稱之為 scriptlets),并單獨運行這些小的腳本,腳本運行后為其文件系統打一個快照(Docker會自動執行此操作)。如果你發現一個scriptlet運行失敗,你可以快速回退到上次的快照,然后再試一次。一旦你完成腳本的構建,并且 可以保證腳本能正常工作,那你就可以將它分配給其它主機。回過頭來再對比下,如果你沒有使用快照功能了?當你辛辛苦苦等待了一個半小時后,腳本卻構建失敗了,我想除了少部分有耐心的人外,很多人是不想再來一次了,當然,你也會盡最大努力把系統恢復到失敗前的狀態,比如可以刪除一個目錄或運行make clean。但是,我們可能沒有真正地理解我們正在構建的組件。它可能有復雜的Makefile,它會把把文件放到文件系統中我們不知道的地方,唯一真正確定的途徑是恢復到快照。使用快照構建腳本的Docker在本節中,我將介紹我是如何使用Docker實現GHC7.8.3 ARM交叉編譯器的構建腳本。Docker非常適合做這件事,但并非完美。我做了很多看起來沒用的或者不雅的事情,但都是必要的,這都是為了保證將開發腳本的總時間降到最低限度。構建腳本可以在這里找到。用Dockerfile構建Docker通過讀取Dockerfile來構建鏡像。Dockerfile會通過一些命令來具體指定應該執行哪些動作。具體使用說明可以參考這篇文章。在我的腳本中主要用到WORKDIR、ADD和RUN。ADD命令非常有用因為它可以讓你在運行之前將外部文件添加到當前Docker鏡像中然后轉換成鏡像的文件系統。你可以在這里看到很多scriptlets構成的構建腳本。設計1.在RUN之前ADD scriptlets如果你很早就將所有的scriptletsADD在Dockerfile,您可能會遇到以下問題:如果你的腳本構建失敗,你回去修改scriptlet并再次運行docker build。但是你發現,Docker開始在首次加入scriptlets的地方構建!這樣做會浪費了大量的時間并且違背了使用快照的目的。出現這種情況的原因是由于Docker處理它的中間鏡像(快照)的方式。當Docker通過Dockerfile構建鏡像時,它會與中間鏡像比較當前命令是否一致。然而,在ADD命令的情況下被裝進鏡像的文件里的內容也會被檢查。如果相對于現有的中間鏡像,文件已經改變,那么Docker也別無選擇,只能從這點開始建立一個新的鏡像。因為Docker不知道這些變化會不會影響到構建。此外,使用RUN命令要注意,每次運行時它都會導致文件系統有不同的更改。在這種情況下,Docker會發現中間鏡像并使用它,但是這將是錯誤的。RUN命令每次運行時會造成文件系統相同的改變。舉個例子,我確保在我的scriptlets我總是下載了一個已知版本的文件與一個特定MD5校驗。對Docker 構建緩存更詳細的解釋可以在這里找到。2.不要使用ENV命令來設置環境變量,請使用scriptlet。它似乎看起來很有誘惑力:使用ENV命令來設置所有構建腳本需要的環境變量。但是,它不支持變量替換的方式,例如 ENV BASE=$HOME/base 將設置BASE的值為$HOME/base著很可能不是你想要的。相反,我用ADD命令添加一個名為set-env.sh文件。此文件會包含在后續的scriptlet中:THIS_DIR="$(cd"$(dirname"${BASH_SOURCE[0]}")"&pwd)source$THIS_DIR/set-env-1.sh如果你沒有在第一時間獲取set-env.sh會怎么樣呢?它很早就被加入Dockerfile并不意味著修改它將會使隨后的快照無效?是的,這會有問題。在開發腳本時,我發現,我已經錯過了在set-env.sh添加一個有用的環境變量。解決方案是創建一個新的文件set-env-1.sh包含:THIS_DIR="$(cd"$(dirname"${BASH_SOURCE[0]}")"&pwd)source$THIS_DIR/set-env.shif![-e"$CONFIG_SUB_SRC/config.sub"];thenCONFIG_SUB_SRC=${CONFIG_SUB_SRC:-$NCURSES_SRC}fi然后,在所有后續的scriptlets文件中包含了此文件。現在,我已經完成了構建腳本,我可以回去解決這個問題了,但是,在某種意義上,它會破壞最初的目標。我將不得不從頭開始運行構建腳本看看這種變化是否能成功。缺點一個主要缺點是這種方法是,所構建的鏡像尺寸是大于它實際需求的尺寸。在我的情況下尤其如此,因為我在最后刪除了大量文件的。然而,這些文件都仍然存在于聯合掛載文件系統的底層文件系統內,所以整個鏡像是大于它實際需要的大小至少多余的是刪除文件的大小。然而,有一個變通。我沒有公布此鏡像到Docker Hub Registry。相反,我:使用docker export導出內容為tar文件。創建一個新的Dockerfile簡單地添加了這個tar文件的內容。產生尺寸盡可能小的鏡像。結論這種方法的優點是雙重的:它使開發時間降至最低,不再做那些已經構建成功的子組件。你可以專注于那些失敗的組件。這非常便于維護構建腳本。構建可能會失敗,但只要你搞定Dockerfiel,至少你不必再從頭開始。此外,正如我前面提到的Docker不僅使寫這些構建腳本更加容易,有了合適的工具同樣可以在任何提供快照的文件系統實現www.13333515.buzz防采集請勿采集本網。

引子

最近發現有ARM版Docker,hub.docker.com上也有ARM版本的鏡像,但是ARM版本的Docker鏡像構建是個問題。嵌入式程序可以在PC機上進行交叉編譯,不知道Docker是否有交叉構建的方案。

據Java專家Tony Ng所說,在復雜企業應用環境中工作的軟件開發者,經常用很多時間來維護現有的應用,而時間應該用在創建新的和創新的應用上。將Java和面向服務架構(SOA)集合可以簡化維護企業

方案

目前想到的Docker構建ARM鏡像方法有如下幾種。第三種就類似交叉編譯。

    使用ARM主機,安裝ARM版本的Docker,docker build出來的就是ARM版本的鏡像。 使用Linux的虛擬化軟件,模擬ARM芯片+ Linux,例如qemu。 使用Docker試驗功能buildx,可以構建多平臺的鏡像。

Docker為App提供了一種自動化構建機制(Dockerfile),包括打包,基礎設施依賴管理和安裝等等;Docker提供了一種類似git的Container版本化的機制,允許你對你創建過的容器進行版本管理,依靠這種機制,你還

使用Docker buildx構建多個平臺鏡像

Gevin認為,雖然基于docker可以構建開發環境,但還是vagrant用起來更舒服,docker更加適合做CI,測試和部署。實際工作中如何使用docker,就仁者見仁,智者見智了。作者:Gevin 鏈接:

參考如下幾個鏈接。

構建成功后,執行docker images命令,可以查看到當前構建好的image docker images REPOSITORY TAG IMAGE ID CREATED SIZE gevin/django-example 0.1 1855fc3c8062 12 hours ago 698.9 MB 3.使用構建的

https://docs.docker.com/engine/reference/commandline/manifest/

通客戶端利用致性hash算數據布同節點種缺點非明顯缺少故障自failover能力并且擴容數據布搬遷比較費勁 代理模式 Redis官推薦Twemproxy由twitter公司發;另內豌豆莢源codis;代理模式處仍使用redis

https://docs.docker.com/buildx/working-with-buildx/

https://engineering.docker.com/2019/06/getting-started-with-docker-for-arm-on-linux/

用到了兩個docker的試驗功能,使用時需要開啟試驗功能。

docker manifest,manifest是一個包含了鏡像信息的文件。manifest list是一個鏡像清單列表,用于存放不同os/arch的鏡像信息。我們可以創建一個manifest list來指向兩個鏡像,然后可以支持多平臺。

docker buildx,buildx是docker的一個插件,是下一代docker鏡像構建。該插件通過qemu-user-static翻譯不同平臺的指令集,達到在x64上運行其他平臺的程序。buildx實際使用了moby/buildkit:buildx-stable-1鏡像進行多平臺構建。

搭建docker registry多平臺版本

參考如下鏈接,構建docker registry鏡像。

https://community.arm.com/developer/tools-software/tools/b/tools-software-ides-blog/posts/deploying-multi-architecture-docker-registry

搭建dns服務器,解決buildx bug

buildx插件不走本地hosts文件,必須走dns。這是個bug,https://github.com/docker/buildx/issues/218,社區也沒人管。

解決方法:自建dns,把鏡像的地址buildx.com指向registry的機器,后續用nginx。ubuntu有一個默認systemd-resolved,關閉之后在開啟dnsmasq。

使用nginx代理解決命名問題

增加nginx代理同時支持HTTP和HTTPS。buildx這個插件強行使用了HTTPS,沒有找到關閉的地方。

提示證書問題,證書不是這個域名的,解決方法: 重新生成一個證書,域名填自己的。

證書問題,不信任自簽名證書,把自簽名的證書加到buildx daemon容器的證書信任鏈中。https://github.com/docker/buildx/issues/80#issuecomment-533844117

nginx增加兩個配置,解決客戶端push時的幾個問題。

# nignx.conf 配置proxy_ignore_client_abort on; #忽略客戶端告警client_max_body_size 0; #上傳文件大小不限制# 虛擬主機配置server { listen 443; server_name buildx.com; ssl on; ssl_certificate crt/server.crt; ssl_certificate_key crt/server.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照這個協議配置 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照這個套件配置 ssl_prefer_server_ciphers on; location / { proxy_pass http://192.168.1.11:81; }}server { listen 80; server_name buildx.com; location / { proxy_pass http://192.168.1.11:81; }}

設置本地Docker環境

本地Docker需要開啟實驗功能。

    在/etc/docker/daemon.json中配置 "experimental": true,重啟Docker。開啟Docker daemon的實驗功能。 在本地執行export DOCKER_CLI_EXPERIMENTAL=enabled,開啟Docker Client的實驗功能。 使用docker version查看實驗功能是否開啟。 執行docker run --rm --privileged docker/binfmt:820fdd95a9972a5308930a2bdfb8573dd4447ad3,開啟內核binfmt_misc功能,可以在當前平臺上執行多平臺的程序。 查看是否支持aarch64程序。cat /proc/sys/fs/binfmt_misc/qemu-aarch64 此時本地的docker可以運行各種平臺的docker容器。比如arm64。可以使用如下命令測試。

# 拉取arm64版本鏡像并運行docker pull --platform arm64 alpine:3.10docker run --rm -it alpine:3.10 sh

制作基礎鏡像

可以從hub.docker.com中獲取多個平臺的版本,生成manifest list,上傳的registry中。

# pull arm64版本、改名、上傳。 具體鏡像是否支持多平臺,可以到hub.docker.com上看。docker pull --platform arm64 centos:7docker tag centos:7 buildx.com/base/centos-arm64:7docker push buildx.com/base/centos-arm64:7# pull amd64版本、改名、上傳docker pull --platform amd64 centos:7docker tag centos:7 buildx.com/base/centos-amd64:7docker push buildx.com/base/centos-amd64:7# 創建manifest list、上傳。docker manifest create --insecure buildx.com/base/centos:7 buildx.com/base/centos-amd64:7 buildx.com/base/centos-arm64:7docker manifest push --insecure buildx.com/base/centos:7

構建業務鏡像

# buildx 可以指定多個平臺,但是要求Dockerfile中的FROM鏡像必須有對應版本的。# buildx 打包的鏡像不會在本地存儲,加--push,上傳docker倉。或者可以使用--output指定輸出方式。docker buildx build --platform linux/amd64,linux/arm64 -t buildx.com/base/java-base:openjdk-8-centos7 . --push

Docker是一種輕量化容器技術,其使用方式與虛擬機非常類似,也提供相對獨立的環境給應用,同時還提供了方便的遷移的能力。因此,從這個方面來說,也是屬于IaaS層面的內容來自www.13333515.buzz請勿采集。


  • 本文相關:
  • docker dockerfile 定制鏡像的方法
  • docker制作python運行環境基礎鏡像的方法步驟
  • docker鏡像分層的原理詳解
  • 在docker中跑hadoop與鏡像制作方法
  • docker鏡像導出與導入與拷貝實例分析
  • centos6使用docker部署kafka項目的方法分析
  • docker安裝和基礎用法 docker入門教程第二篇
  • centos7下安裝與卸載docker應用容器引擎的方法
  • 在alpine鏡像中添加ansible服務的方法
  • centos7.3中docker的安裝教程
  • 如何清理docker產生的垃圾文件
  • centos7安裝使用docker的步驟
  • 在docker容器中部署靜態網頁的方法教程
  • docker for windows 容器內網通過獨立ip直接訪問的方法
  • 詳解docker中vlan網絡模式的配置
  • docker常用于構建哪個層次的云服務
  • 如何使用Docker構建運行時間較長的腳本
  • 如何使用 Java 和 Docker 構建微服務
  • 如何使用Docker構建運行時間較長的腳本
  • 如何使用 Java 和 Docker 構建微服務
  • 如何構建基于docker的開發環境
  • 如何構建基于docker的開發環境
  • 如何構建基于docker的開發環境
  • 如何使用docker構建redis集群
  • 如何構建基于docker的開發環境
  • 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全dockerhyper-vvmwarevirtualboxxenserverkvmqemuopenvzxencloudstackopenstack云計算技術云其它首頁服務器云和虛擬化dockerdocker dockerfile 定制鏡像的方法docker制作python運行環境基礎鏡像的方法步驟docker鏡像分層的原理詳解在docker中跑hadoop與鏡像制作方法docker鏡像導出與導入與拷貝實例分析centos6使用docker部署kafka項目的方法分析docker安裝和基礎用法 docker入門教程第二篇centos7下安裝與卸載docker應用容器引擎的方法在alpine鏡像中添加ansible服務的方法centos7.3中docker的安裝教程如何清理docker產生的垃圾文件centos7安裝使用docker的步驟在docker容器中部署靜態網頁的方法教程docker for windows 容器內網通過獨立ip直接訪問的方法詳解docker中vlan網絡模式的配置docker 清理命令集錦docker 給運行中的容器設置端口映ubuntu14.04+docker的安裝及使用docker獲取鏡像報錯docker: errodocker.service啟動失敗:unit ndocker容器如何優雅的終止詳解centos7 安裝docker 解決啟動不了詳解docker國內鏡像拉取和鏡像加淺談docker-compose網絡設置之nedocker如何固定ip設置的方法docker鏡像創建的方法docker使用過程中的一些注意事項docker打包node項目的過程講解docker容器固定ip分配詳解docker images 如何建立自己的原生鏡像詳解利用elk搭建docker容器化應用日志中心docker利用selenium+testng實現web自動化docker 中的容器完全解析docker如何實現修改docker0網橋默認網段docker入門之容器介紹
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.13333515.buzz All Rights Reserved
    3排列五开奖结果