女人荫蒂被添全过程13种图片,亚洲+欧美+在线,欧洲精品无码一区二区三区 ,在厨房拨开内裤进入毛片

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Dockerfile的最佳實踐

汽車電子技術(shù) ? 來源:程序猿技術(shù)大咖 ? 作者: xcbey0nd ? 2023-01-20 10:59 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

微信截圖_20230105161930.png

隨著應(yīng)用的容器化、上云后,將伴隨著 Docker 鏡像的構(gòu)建,構(gòu)建 Docker 鏡像成為了最基本的一步,其中 Dockerfile 便是用來構(gòu)建鏡像的一種文本文件,鏡像的優(yōu)劣全靠 Dockerfile 編寫的是否合理、合規(guī)。本文將講述編寫 Dockerfile 的一些最佳實踐和技巧,讓我們的鏡像更小、更優(yōu)。

1、Docker 鏡像是如何工作的

首先,我們一起回顧下 Docker 鏡像的相關(guān)概念及工作流程吧。

1.1 鏡像

鏡像(image)是一堆只讀層(read-only layer)的統(tǒng)一視角,也許這個定義有些難以理解,下面的這張圖能夠幫助您理解鏡像的定義。

微信截圖_20230105161930.png

從左邊我們看到了多個只讀層,它們重疊在一起。除了最下面一層,其它層都會有一個指針指向下一層。這些層是 Docker 內(nèi)部的實現(xiàn)細(xì)節(jié),并且能夠在主機的文件系統(tǒng)上訪問到。統(tǒng)一文件系統(tǒng)技術(shù)能夠?qū)⒉煌膶诱铣梢粋€文件系統(tǒng),為這些層提供了一個統(tǒng)一的視角,這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個文件系統(tǒng)。我們可以在圖片的右邊看到這個視角的形式。

您可以在您的主機文件系統(tǒng)上找到有關(guān)這些層的文件。需要注意的是,在一個運行中的容器內(nèi)部,這些層是不可見的。在我的主機上,我發(fā)現(xiàn)它們存在于 /var/lib/docker/overlay2 目錄下。

1.2 鏡像分層結(jié)構(gòu)

為什么說是鏡像分層結(jié)構(gòu),因為 Docker 鏡像是以層來組織的,可以通過命令 docker image inspect 或者 docker inspect 來查看鏡像包含哪些層。

例如,鏡像 busybox :

xcbeyond@xcbeyonddeMacBook-Pro ~ % docker inspect busybox
[
    {
        "Id": "sha256:3c277069c6ae3f3572998e727b973ff7418c3962b9403de4b3a3f8624399b8fa",
        "RepoTags": [
            "busybox:latest"
        ],
        "RepoDigests": [
            "busybox@sha256:d2b53584f580310186df7a2055ce3ff83cc0df6caacf1e3489bff8cf5d0af5d8"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2022-04-14T00:39:25.923517152Z",
        "Container": "39aaf4eecc48824531078c316f5b16e97549417e07c8f90b26ae16053111ea57",
        "ContainerConfig": {
            "Hostname": "39aaf4eecc48",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"sh\"]"
            ],
            "Image": "sha256:3289bc85dc0eba79657979661460c7f6f97688ad8a4f93174e0cabdd6b09a365",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "20.10.12",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "sh"
            ],
            "Image": "sha256:3289bc85dc0eba79657979661460c7f6f97688ad8a4f93174e0cabdd6b09a365",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "arm64",
        "Variant": "v8",
        "Os": "linux",
        "Size": 1411540,
        "VirtualSize": 1411540,
        "GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/e89181e7cadd3a6ee49f66bae34fed369621a1a5cfbe0003ce4621d0eec020e6/merged",
                "UpperDir": "/var/lib/docker/overlay2/e89181e7cadd3a6ee49f66bae34fed369621a1a5cfbe0003ce4621d0eec020e6/diff",
                "WorkDir": "/var/lib/docker/overlay2/e89181e7cadd3a6ee49f66bae34fed369621a1a5cfbe0003ce4621d0eec020e6/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:31a5597e16d3c5adaaf5826162216e256126d2fbf1beaa2b6c45c1822a2b9ca3"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

其中,RootFS 就是鏡像 busybox:latest 的鏡像層,只有一層,這層數(shù)據(jù)是存儲在宿主機哪里的呢?動手實踐的同學(xué)會在上面的輸出中看到一個叫做 GraphDriver 的字段內(nèi)容如下:

"GraphDriver": {
            "Data": {
                "MergedDir": "/var/lib/docker/overlay2/e89181e7cadd3a6ee49f66bae34fed369621a1a5cfbe0003ce4621d0eec020e6/merged",
                "UpperDir": "/var/lib/docker/overlay2/e89181e7cadd3a6ee49f66bae34fed369621a1a5cfbe0003ce4621d0eec020e6/diff",
                "WorkDir": "/var/lib/docker/overlay2/e89181e7cadd3a6ee49f66bae34fed369621a1a5cfbe0003ce4621d0eec020e6/work"
            },
            "Name": "overlay2"
        }

GraphDriver 負(fù)責(zé)鏡像本地的管理和存儲以及運行中的容器生成鏡像等工作,可以將 GraphDriver 理解成鏡像管理引擎,我們這里的例子對應(yīng)的引擎名字是 overlay2(overlay 的優(yōu)化版本)。除了 overlay 之外,Docker 的 GraphDriver 還支持 btrfs、aufs、devicemapper、vfs 等。

我們可以看到其中的 Data 包含了多個部分,這個對應(yīng) OverlayFS 的鏡像組織形式,雖然我們上面的例子中的 busybox 鏡像只有一層,但是正常情況下很多鏡像都是由多層組成的。

1.3 Dockerfile、鏡像、容器間的關(guān)系

Dockerfile 是軟件的原材料,Docker 鏡像是軟件的交付品,而 Docker 容器則可以認(rèn)為是軟件的運行態(tài)。從應(yīng)用軟件的角度來看,Dockerfile、Docker 鏡像與 Docker 容器分別代表軟件的三個不同階段,Dockerfile 面向開發(fā),Docker 鏡像成為交付標(biāo)準(zhǔn),Docker 容器則涉及部署與運維,三者缺一不可,合力充當(dāng) Docker 體系的基石。

簡單來講,Dockerfile 構(gòu)建出 Docker鏡像,通過 Docker 鏡像運行Docker容器。

我們可以從 Docker 容器的角度,來反推三者的關(guān)系,如下圖:

微信截圖_20230105161930.png

2、Dockerfile

Dockerfile 是一個用來構(gòu)建鏡像的文本文件,文本內(nèi)容包含了一條條構(gòu)建鏡像所需的指令和說明,它是構(gòu)建鏡像的關(guān)鍵。

一個 Docker 鏡像包含了很多只讀層,每一層都由一個 Dockerfile 指令構(gòu)成,這些層堆疊在一起,每一層都是前一層變化的增量。例如:

FROM ubuntu:18.04COPY . /appRUN make /appCMD python /app/app.py

每條指令都會創(chuàng)建一層:

  • FROM:從 ubuntu:18.04 Docker 鏡像創(chuàng)建了一層,也作為基礎(chǔ)鏡像層。
  • COPY:從 Docker 客戶端的當(dāng)前目錄添加文件。
  • RUN:執(zhí)行 make 命令.
  • CMD:指定要在容器中運行的命令。

上述就是一個簡單的 Dockerfile 文件,再通過 docker build -t 命令便可直接構(gòu)建出鏡像。

在這里就不過多介紹 Dockerfile 的各個指令的用法,更多更詳細(xì)的可參考:Dockerfile reference

3、Dockerfile 的最佳實踐

本節(jié)將列舉出一些最佳實踐技巧,來幫助我們更好的寫好 Dockerfile。

3.1 盡可能使用官方鏡像作為基礎(chǔ)鏡像

Docker 鏡像是基于基礎(chǔ)鏡像構(gòu)建而來,因此選擇的基礎(chǔ)鏡像越恰當(dāng),我們要做的底層工作就越少。比如,如果構(gòu)建一個 Java 應(yīng)用鏡像,選擇一個 openjdk 鏡像作為基礎(chǔ)比選擇一個 alpine 鏡像更簡單。

盡可能使用當(dāng)前的官方鏡像作為基礎(chǔ)鏡像,無論是從鏡像大小,還是安全性來講,都是比較可靠的。

下面的一些鏡像,可根據(jù)使用場景來選擇合適的基礎(chǔ)鏡像:

鏡像名稱 大小 說明和使用場景
busybox 754.7 KB 一個超級簡化版嵌入式 Linux 系統(tǒng)。臨時測試用。
alpine 2.68 MB 一個面向安全的、輕量級的Linux系統(tǒng),基于musl libc 和 busybox。主要用于測試,也可用于生產(chǎn)環(huán)境。
centos 79.65 MB 主要用于生產(chǎn)環(huán)境,支持CentOS/Red Hat,常用于追求穩(wěn)定性的企業(yè)應(yīng)用。
ubuntu 29.01 MB 主要用于生產(chǎn)環(huán)境,常用于人工智能計算和企業(yè)應(yīng)用。
debian 52.4 MB 主要用于生產(chǎn)環(huán)境。
openjdk 161.02 MB 主要用于 Java 應(yīng)用。

3.2 減少 Dockerfile 指令的行數(shù)

Dockerfile 中每一行指令都代表了一層,多一層都可能帶來鏡像大小變大。

因此,在實際編寫 Dockerfile 時,可以將同類操作放在一起來避免多行指令,更有助于促進(jìn)層緩存。比如將多條 RUN 操作進(jìn)行合并,并用 ;\\ 或者 && 連接在一起。

(減少指令行數(shù),并不意味著越少越好,需要從改動頻繁程度來決定是否合并為一條指令。)

例如下面的 Dockerfile,會執(zhí)行多條命令,通過 ;\\ 連接將其用一條 RUN 指令來完成。

FROM node:6.14LABEL MAINTAINER xcbeyondRUN npm install gitbook-cli -g;\\
   gitbook -V; \\
   npm install svgexport -g --unsafe-permCMD ["/bin/sh"]

3.3 改動不頻繁的內(nèi)容往前放

對于 Docker 鏡像而言,每一層都代表了 Dockerfile 中的一行指令,每一層都是前一層變化的增量。例如一個 Docker 鏡像有ABCD 四層,B 層修改了,那么 BCD 都會變化。

因此,在編寫 Dockerfile 時,盡量將改動不頻繁的內(nèi)容往前放,即:將系統(tǒng)依賴往前寫,因為像 apt, yum 這些安裝的東西,是很少修改的。然后寫應(yīng)用的庫依賴,比如 pip install,最后 copy 應(yīng)用,編譯應(yīng)用。

例如下面這個 Dockerfile,就會在每次代碼改變的時候都重新 Build 大部分層,即使只改了一個頁面的標(biāo)題。

FROM python:3.7-buster # copy sourceRUN mkdir -p /opt/appCOPY myapp /opt/app/myapp/WORKDIR /opt/app# install dependencies nginxRUN apt-get update && apt-get install nginxRUN pip install -r requirements.txtRUN chown -R www-data:www-data /opt/app # start serverEXPOSE 8020STOPSIGNAL SIGTERMCMD ["/opt/app/start-server.sh"]

我們可以改成,先安裝 Nginx,再單獨 copy requirements.txt,然后安裝 pip 依賴,最后 copy 應(yīng)用代碼。

FROM python:3.7-buster # install dependencies nginxRUN apt-get update && apt-get install nginxCOPY myapp/requirements.txt /opt/app/myapp/requirements.txtRUN pip install -r requirements.txt # copy sourceRUN mkdir -p /opt/appCOPY myapp /opt/app/myapp/WORKDIR /opt/app RUN chown -R www-data:www-data /opt/app # start serverEXPOSE 8020STOPSIGNAL SIGTERMCMD ["/opt/app/start-server.sh"]

3.4 編譯和運行需分離

我們在編譯應(yīng)用時很多時候會用到很多編譯工具、編譯環(huán)境,例如:node、Golang 等,但是編譯后,運行時卻不再需要。這樣的編譯環(huán)境往往占用很大,使得鏡像額外變大。

因此,可以將應(yīng)用事先在某個固定編譯環(huán)境編譯完成,得到編譯后的二進(jìn)制文件,再將其 COPY 到鏡像中即可,這樣鏡像中只包含應(yīng)用的運行二進(jìn)制文件。

例如下面這個 Dockerfile,將 Golang 程序編譯好的二進(jìn)制文件 app,構(gòu)建到鏡像中:

FROM alpine:latestLABEL maintainer xcbeyondWORKDIR /appCOPY app /appCMD ["/app/app"]

3.5 刪除不需要的依賴項

Docker 鏡像應(yīng)該盡可能小。在編寫 Dockerfile 時僅包含基本內(nèi)容,不要引入無關(guān)內(nèi)容,從而使得鏡像大小更小、構(gòu)建速度更快,并且減少受攻擊的可能面。

鏡像更小,也更利于存放到鏡像倉庫,減少網(wǎng)絡(luò)帶寬開銷。

不要安裝應(yīng)用程序?qū)嶋H不使用的任何包、庫。

3.6 避免憑證構(gòu)建到鏡像

這是最常見和最危險的 Dockerfile 問題之一。在構(gòu)建鏡像過程中,復(fù)制配置文件可能很誘人,但你切記可能會引入很大的安全隱患。

在 Dockerfile 中通過 COPY 指令將任何配置文件內(nèi)容都復(fù)制到你的鏡像,并且任何可以訪問它的人都可以訪問它。如果這個配置文件中,無意間包含了數(shù)據(jù)庫密碼配置,那么你就徹底將這些密碼暴露給了所有使用該鏡像的所有人。

為了避免這類問題,必須將配置密鑰、敏感數(shù)據(jù)只能提供給具體的容器,而不是提供給構(gòu)建它們的鏡像。可使用環(huán)境變量、掛載卷等方式在容器啟動時注入數(shù)據(jù)。這樣就避免了意外的信息暴露,并確保你的鏡像可跨環(huán)境重復(fù)使用。


感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 容器
    +關(guān)注

    關(guān)注

    0

    文章

    509

    瀏覽量

    22440
  • 鏡像
    +關(guān)注

    關(guān)注

    0

    文章

    178

    瀏覽量

    11236
  • Docker
    +關(guān)注

    關(guān)注

    0

    文章

    515

    瀏覽量

    12934
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    C編程最佳實踐.doc

    C編程最佳實踐.doc
    發(fā)表于 08-17 14:37

    Dockerfile最佳實踐

    ”微服務(wù)一條龍“最佳指南-“最佳實踐”篇:Dockerfile
    發(fā)表于 07-11 16:22

    Dockerfile使用規(guī)則

    Dockerfile編寫規(guī)范
    發(fā)表于 08-12 14:30

    變量聲明最佳實踐

    所以我們開始編寫32位和16位代碼,并過渡到MPLAB X和XC編譯器。我想到的一個主題是聲明變量的最佳實踐。常規(guī)IpType。h或類型。h pr STDIN。或It8或字節(jié)char等任何想法,走哪條路?
    發(fā)表于 09-30 12:01

    虛幻引擎的紋理最佳實踐

    紋理是游戲不可或缺的一部分。 這是一個藝術(shù)家可以直接控制的領(lǐng)域,以提高游戲的性能。 本最佳實踐指南介紹了幾種紋理優(yōu)化,這些優(yōu)化可以幫助您的游戲運行得更流暢、看起來更好。 最佳實踐系列指
    發(fā)表于 08-28 06:39

    MySql5.6性能優(yōu)化最佳實踐

    MySql5.6性能優(yōu)化最佳實踐
    發(fā)表于 09-08 08:47 ?13次下載
    MySql5.6性能優(yōu)化<b class='flag-5'>最佳</b><b class='flag-5'>實踐</b>

    全面詳解Dockerfile文件

    Docker 可以通過讀取 Dockerfile 中的指令自動構(gòu)建鏡像。Dockerfile 是一個文本文檔,其中包含了用戶創(chuàng)建鏡像的所有命令和說明。 一、 變量 變量用
    的頭像 發(fā)表于 09-22 15:38 ?2096次閱讀

    DevOps最佳實踐

      遵循上述最佳實踐,組織可以開發(fā)和自動化其解決方案的交付過程,以有效地實現(xiàn)其業(yè)務(wù)目標(biāo)。
    的頭像 發(fā)表于 08-15 14:41 ?1174次閱讀

    鏡像構(gòu)建Dockerfile的介紹

    Dockerfile 是一個用來構(gòu)建鏡像的文本文件,文本內(nèi)容包含了一條條構(gòu)建鏡像所需的指令和說明。
    的頭像 發(fā)表于 09-06 09:36 ?1444次閱讀

    圖像傳感器處理和最佳實踐

    圖像傳感器處理和最佳實踐
    發(fā)表于 11-15 20:30 ?0次下載
    圖像傳感器處理和<b class='flag-5'>最佳</b><b class='flag-5'>實踐</b>

    SAN管理最佳實踐指南

    電子發(fā)燒友網(wǎng)站提供《SAN管理最佳實踐指南.pdf》資料免費下載
    發(fā)表于 08-29 09:20 ?0次下載
    SAN管理<b class='flag-5'>最佳</b><b class='flag-5'>實踐</b>指南

    SAN設(shè)計和最佳實踐指南

    電子發(fā)燒友網(wǎng)站提供《SAN設(shè)計和最佳實踐指南.pdf》資料免費下載
    發(fā)表于 09-01 11:02 ?2次下載
    SAN設(shè)計和<b class='flag-5'>最佳</b><b class='flag-5'>實踐</b>指南

    Windows 10遷移的最佳實踐

    電子發(fā)燒友網(wǎng)站提供《Windows 10遷移的最佳實踐.pdf》資料免費下載
    發(fā)表于 09-07 15:37 ?0次下載
    Windows 10遷移的<b class='flag-5'>最佳</b><b class='flag-5'>實踐</b>

    Dockerfile定義Docker鏡像的構(gòu)建過程

    了解Dockerfile Dockerfile 是一個文本文件,用于定義 Docker 鏡像的構(gòu)建過程。它以指令的形式描述了如何構(gòu)建鏡像,從基礎(chǔ)鏡像開始逐步添加配置、文件和依賴,最終形成我們所需
    的頭像 發(fā)表于 09-30 10:22 ?2906次閱讀

    如何使用dockerfile創(chuàng)建鏡像

    Docker是一個開源的平臺,用于快速構(gòu)建、打包、部署應(yīng)用程序的容器化工具。而Dockerfile是一個文本文件,包含了一組可自動化構(gòu)建Docker鏡像的指令。本文將詳細(xì)介紹
    的頭像 發(fā)表于 11-23 09:52 ?1094次閱讀
    主站蜘蛛池模板: 石门县| 乌拉特后旗| 邮箱| 京山县| 平阴县| 德令哈市| 沾益县| 安宁市| 来安县| 吉安市| 沙雅县| 福建省| 彩票| 通山县| 鹿泉市| 临泽县| 林芝县| 宜良县| 张北县| 合山市| 宣威市| 长春市| 开化县| 南丰县| 夏河县| 吴堡县| 舒兰市| 新源县| 临沂市| 汕头市| 黄平县| 开远市| 新津县| 改则县| 武穴市| 亚东县| 黑龙江省| 保康县| 勃利县| 平邑县| 腾冲县|