偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

如何使用 Distroless 讓你的容器更加安全

開發(fā) 前端
谷歌現(xiàn)在通過提供 Distroless 鏡像向全世界開放這種能力。谷歌構(gòu)建的這些鏡像的目標(biāo)是只包含你的應(yīng)用程序及其依賴項(xiàng),同時(shí)它們將沒有常規(guī) Linux 發(fā)行版的所有特性,包括 shell。

[[408599]]

Photo by Michael Dziedzic on Unsplash

使用 Distroless 鏡像來保護(hù) Kubernetes 上的容器。

容器改變了我們看待技術(shù)基礎(chǔ)設(shè)施的方式。這是我們運(yùn)行應(yīng)用程序方式的一次巨大飛躍。容器編排和云服務(wù)一起為我們提供了一種近乎無限規(guī)模的無縫擴(kuò)展能力。

根據(jù)定義,容器應(yīng)該包含 「應(yīng)用程序」 及其 「運(yùn)行時(shí)依賴項(xiàng)」。然而,在現(xiàn)實(shí)中,它們包含的遠(yuǎn)不止這些。標(biāo)準(zhǔn)容器基礎(chǔ)映像包含標(biāo)準(zhǔn) Linux 發(fā)行版中可以找到的包管理器、shell 和其他程序。

雖然這些都是構(gòu)建容器鏡像所必需的,但它們不應(yīng)該成為最終鏡像的一部分。例如,一旦你把包安裝好了,就不再需要在容器中使用 apt 等包管理工具了。

這不僅使你的容器里充滿了不必要的軟件包和程序,而且還為網(wǎng)絡(luò)罪犯提供了攻擊特定程序漏洞的機(jī)會(huì)。

你應(yīng)該始終了解容器運(yùn)行時(shí)中存在什么,并且應(yīng)該精確地限制其只包含應(yīng)用程序所需的依賴項(xiàng)。

除了那些必要的,你不應(yīng)該安裝任何東西。一些領(lǐng)先的科技巨頭,如谷歌,有多年在生產(chǎn)中運(yùn)行容器的經(jīng)驗(yàn),已經(jīng)采用了這種方法。

谷歌現(xiàn)在通過提供 Distroless 鏡像向全世界開放這種能力。谷歌構(gòu)建的這些鏡像的目標(biāo)是只包含你的應(yīng)用程序及其依賴項(xiàng),同時(shí)它們將沒有常規(guī) Linux 發(fā)行版的所有特性,包括 shell。

「這意味著雖然可以像以前一樣運(yùn)行應(yīng)用程序的容器,但不能在容器運(yùn)行的時(shí)候進(jìn)入容器內(nèi)」。這是一個(gè)重大的安全改進(jìn),因?yàn)槟悻F(xiàn)在已經(jīng)為黑客通過 shell 進(jìn)入你的容器關(guān)上了大門。

Distroless 基礎(chǔ)鏡像

谷歌為大多數(shù)流行的編程語言和平臺(tái)提供了 Distroless 的基礎(chǔ)鏡像。

以下基礎(chǔ)鏡像是正式發(fā)布的版本:

  • gcr.io/distroless/static-debian10
  • gcr.io/distroless/base-debian10
  • gcr.io/distroless/java-debian10
  • gcr.io/distroless/cc-debian10
  • gcr.io/distroless/nodejs-debian10

下面的基礎(chǔ)鏡像仍在實(shí)驗(yàn)階段,不推薦用于生產(chǎn)環(huán)境:

  • gcr.io/distroless/python2.7-debian10
  • gcr.io/distroless/python3-debian10
  • gcr.io/distroless/java/jetty-debian10
  • gcr.io/distroless/dotnet

構(gòu)建 Distroless 鏡像

谷歌在內(nèi)部使用 Bazel 來構(gòu)建容器映像,但是我們可以使用 Docker 來做同樣的事情。關(guān)于使用 Distroless 鏡像的一個(gè)有爭議的問題是:當(dāng)我們有一個(gè) Distroless 鏡像時(shí),我們?nèi)绾问褂?Dockerfile 來構(gòu)建我們的應(yīng)用程序呢?

通常,Dockerfile 以一個(gè)標(biāo)準(zhǔn)的 OS 基礎(chǔ)鏡像開始,然后是創(chuàng)建適當(dāng)?shù)倪\(yùn)行時(shí)構(gòu)建所需執(zhí)行的多個(gè)步驟。這包括包的安裝,為此需要像 apt 或 yum 這樣的包管理器。

有兩種方法:

  • 先在 Docker 外部構(gòu)建好你的應(yīng)用程序,然后使用 Dockerfile 中的 ADD 或 COPY 指令將二進(jìn)制包復(fù)制到容器中。
  • 使用多階段 Docker 構(gòu)建。這是 Docker 17.05 及以后版本的一個(gè)新特性,它允許你將構(gòu)建分為不同的階段。第一階段可以從標(biāo)準(zhǔn)的 OS 基礎(chǔ)鏡像開始,可以幫助你構(gòu)建應(yīng)用程序;第二階段可以簡單地從第一階段獲取構(gòu)建的文件并使用 Distroless 作為基礎(chǔ)鏡像。

為了理解它是如何工作的,讓我們使用多階段構(gòu)建流程進(jìn)行一個(gè)實(shí)際操作練習(xí)。

必要條件

你需要具備以下內(nèi)容:

  • Docker 版本大于等于 17.05,用于構(gòu)建鏡像
  • 可選的 Kubernetes 集群用于實(shí)踐練習(xí)的第二部分。如果你想在 Docker 中運(yùn)行你的容器,你可以使用等價(jià)的 docker 命令。

GitHub 代碼倉

作為實(shí)踐練習(xí),將 此代碼倉 Fork 到你的 GitHub 帳號(hào)下,然后克隆 GitHub 代碼倉并使用 cd 進(jìn)入到項(xiàng)目目錄下。

該代碼倉包含一個(gè) Python 的 Flask 應(yīng)用程序,當(dāng)你調(diào)用API時(shí),該應(yīng)用程序會(huì)響應(yīng) Hello World!。

app.py 文件如下所示:

  1. from flask import Flask 
  2.  
  3. app = Flask(__name__) 
  4.  
  5. @app.route("/"
  6. def hello(): 
  7.     return "Hello World!" 
  8.  
  9. if __name__ == '__main__'
  10.     app.run(host='0.0.0.0', debug=True

Dockerfile 包含兩個(gè)階段:

  1. FROM python:2.7-slim AS build 
  2. ADD . /app 
  3. WORKDIR /app 
  4. RUN pip install --upgrade pip 
  5. RUN pip install -r ./requirements.txt 
  6.  
  7. FROM gcr.io/distroless/python2.7 
  8. COPY --from=build /app /app 
  9. COPY --from=build /usr/local/lib/python2.7/site-packages /usr/local/lib/python2.7/site-packages 
  10. WORKDIR /app 
  11. ENV PYTHONPATH=/usr/local/lib/python2.7/site-packages 
  12. EXPOSE 5000 
  13. CMD ["app.py"

構(gòu)建階段:

  • 從 python:2.7-slim 的基礎(chǔ)鏡像開始
  • 將應(yīng)用程序復(fù)制到 /app 目錄下
  • 升級(jí) pip 并安裝依賴

Distroless 階段:

  • 從 gcr.io/distroless/python2.7 的基礎(chǔ)鏡像開始
  • 將應(yīng)用程序從構(gòu)建階段的 /app 目錄復(fù)制到當(dāng)前階段的 /app 目錄
  • 將 python 的 site-packages 從構(gòu)建階段復(fù)制到當(dāng)前階段的 site-packages 目錄
  • 設(shè)置工作目錄到 /app,將 python PATH 設(shè)置為 site-packages 目錄,并暴露 5000 端口
  • 使用 CMD 指令運(yùn)行 app.py

由于 Disroless 鏡像不包含 shell,所以應(yīng)該在最后使用 CMD 指令。如果不這樣做,Docker 將認(rèn)為它是一個(gè) shell CMD,并試圖這樣執(zhí)行它,但這是不工作的。

構(gòu)建鏡像:

  1. $ docker build -t <your_docker_repo>/flask-hello-world-distroless . 
  2. Sending build context to Docker daemon  95.74kB 
  3. Step 1/12 : FROM python:2.7-slim AS build 
  4.  ---> eeb27ee6b893 
  5. Step 2/12 : ADD . /app 
  6.  ---> a01dc81df193 
  7. Step 3/12 : WORKDIR /app 
  8.  ---> Running in 48ccf6b990e4 
  9. Removing intermediate container 48ccf6b990e4 
  10.  ---> 2e5e335be678 
  11. Step 4/12 : RUN pip install --upgrade pip 
  12.  ---> Running in 583be3d0b8cc 
  13. Collecting pip 
  14.   Downloading pip-20.1.1-py2.py3-none-any.whl (1.5 MB) 
  15. Installing collected packages: pip 
  16.   Attempting uninstall: pip 
  17.     Found existing installation: pip 20.0.2 
  18.     Uninstalling pip-20.0.2: 
  19.       Successfully uninstalled pip-20.0.2 
  20. Successfully installed pip-20.1.1 
  21. Removing intermediate container 583be3d0b8cc 
  22. ................................... 
  23. Successfully installed Jinja2-2.11.2 MarkupSafe-0.23 click-7.1.2 flask-1.1.2 itsdangerous-0.24 werkzeug-1.0.1 
  24. Removing intermediate container c4d00b1abf4a 
  25.  ---> 01cbadcc531f 
  26. Step 6/12 : FROM gcr.io/distroless/python2.7 
  27.  ---> 796952c43cc4 
  28. Step 7/12 : COPY --from=build /app /app 
  29.  ---> 92657682cdcc 
  30. Step 8/12 : COPY --from=build /usr/local/lib/python2.7/site-packages /usr/local/lib/python2.7/site-packages 
  31.  ---> faafd06edeac 
  32. Step 9/12 : WORKDIR /app 
  33.  ---> Running in 0cf545aa0e62 
  34. Removing intermediate container 0cf545aa0e62 
  35.  ---> 4c4af4333209 
  36. Step 10/12 : ENV PYTHONPATH=/usr/local/lib/python2.7/site-packages 
  37.  ---> Running in 681ae3cd51cc 
  38. Removing intermediate container 681ae3cd51cc 
  39.  ---> 564f48eff90a 
  40. Step 11/12 : EXPOSE 5000 
  41.  ---> Running in 7ff5c073d568 
  42. Removing intermediate container 7ff5c073d568 
  43.  ---> ccc3d211d295 
  44. Step 12/12 : CMD ["app.py"
  45.  ---> Running in 2b2c2f111423 
  46. Removing intermediate container 2b2c2f111423 
  47.  ---> 76d13d2f61cd 
  48. Successfully built 76d13d2f61cd 
  49. Successfully tagged <your_docker_repo>/flask-hello-world-distroless:latest 

登錄到 DockerHub 并推送鏡像:

  1. docker login 
  2. docker push <your_docker_repo>/flask-hello-world-distroless:latest 

登錄到 DockerHub(或者你的私有鏡像倉),你應(yīng)該會(huì)看到容器鏡像可以使用:

 

 

distroless-2

 

如果你看一下壓縮后的大小,它只有 23.36 MB。如果你使用 slim 發(fā)行版作為基礎(chǔ)鏡像,它將占用 56 MB。

 

 

distroless-2

 

你已經(jīng)減少了超過一半的容器占用空間。That’s amazing!

在 Kubernetes 中運(yùn)行容器

為了測試構(gòu)建是否有效,讓我們?cè)?Kubernetes 集群中運(yùn)行容器。如果你沒有 Kubernetes,你可以運(yùn)行等價(jià)的 Docker 命令來做相同的活動(dòng),因?yàn)?Kubectl 和 Docker 命令是相似的。

我在代碼倉中創(chuàng)建了一個(gè) kubernetes.yaml 文件,該文件包含使用我們構(gòu)建的鏡像的 Deployment 和 負(fù)載均衡的 Service。

  1. --- 
  2. apiVersion: apps/v1 
  3. kind: Deployment 
  4. metadata: 
  5.   name: flask-deployment 
  6. spec: 
  7.   selector: 
  8.     matchLabels: 
  9.       app: flask 
  10.   replicas: 2 
  11.   template: 
  12.     metadata: 
  13.       labels: 
  14.         app: flask 
  15.     spec: 
  16.       containers: 
  17.       - name: flask 
  18.         image: bharamicrosystems/flask-hello-world-distroless 
  19.         ports: 
  20.         - containerPort: 5000 
  21. --- 
  22. apiVersion: v1 
  23. kind: Service 
  24. metadata: 
  25.   name: flask-service 
  26. spec: 
  27.   selector: 
  28.     app: flask 
  29.   ports: 
  30.     - port: 80 
  31.       targetPort: 5000 
  32.   type: LoadBalancer 

這是一個(gè)非常簡單的設(shè)置。負(fù)載均衡器監(jiān)聽端口 80 并映射到目標(biāo)端口 5000。這些 Pods 在默認(rèn)的 5000 端口上監(jiān)聽 Flask 應(yīng)用程序。

應(yīng)用:

  1. $ kubectl apply -f kubernetes.yaml 
  2. deployment.apps/flask-deployment created 
  3. service/flask-service created 

我們查看一下所有的資源,看看我們已經(jīng)創(chuàng)建了什么:

  1. $ kubectl get all 
  2. NAME                                    READY   STATUS    RESTARTS   AGE 
  3. pod/flask-deployment-576496558b-hnbxt   1/1     Running   0          47s 
  4. pod/flask-deployment-576496558b-hszpq   1/1     Running   0          73s 
  5.  
  6. NAME                    TYPE           CLUSTER-IP   EXTERNAL-IP      PORT(S)        AGE 
  7. service/flask-service   LoadBalancer   10.8.9.163   35.184.113.120   80:31357/TCP   86s 
  8. service/kubernetes      ClusterIP      10.8.0.1     <none>           443/TCP        26m 
  9.  
  10. NAME                               READY   UP-TO-DATE   AVAILABLE   AGE 
  11. deployment.apps/flask-deployment   2/2     2            2           88s 
  12.  
  13. NAME                                          DESIRED   CURRENT   READY   AGE 
  14. replicaset.apps/flask-deployment-576496558b   2         2         2       89s 

我們看到存在兩個(gè) Pods、一個(gè) Deployment、一個(gè)帶有外部 IP 的 LoadBalancer 服務(wù)和一個(gè) ReplicaSet。

讓我們?cè)L問應(yīng)用程序:

  1. $ curl http://35.184.113.120 
  2. Hello World! 

我們得到了 Hello World!。這表明 Flask 應(yīng)用程序在正常工作。

使用 Shell 對(duì)應(yīng)用程序進(jìn)行訪問

正如我在引言中所描述的,Disroless 容器中沒有 shell,因此不可能進(jìn)入到容器內(nèi)。然而,讓我們?cè)囍谌萜髦袌?zhí)行 exec:

  1. $ kubectl exec -it flask-deployment-576496558b-hnbxt /bin/bash 
  2. OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown 
  3. command terminated with exit code 126 

我們無法連接到容器上。

容器日志呢?如果拿不到容器日志,我們就失去了調(diào)試應(yīng)用程序的方法。

讓我們?cè)囍ツ萌罩荆?/p>

  1. $ kubectl logs flask-deployment-576496558b-hnbxt 
  2.  * Running on http://0.0.0.0:5000/ 
  3.  * Restarting with reloader 
  4. 10.128.0.4 - - [31/May/2020 13:40:27] "GET / HTTP/1.1" 200 - 
  5. 10.128.0.3 - - [31/May/2020 13:42:01] "GET / HTTP/1.1" 200 - 

所以容器日志是可以被獲取到的!

結(jié)論

使用 Distroless 作為基礎(chǔ)鏡像是一種令人興奮的保護(hù)容器安全的方式。由于鏡像小并且僅包含應(yīng)用程序和依賴項(xiàng),因此它為應(yīng)用程序提供了最小的攻擊面。它在更大程度上提高了應(yīng)用程序的安全性,所以它是保護(hù)容器安全的好方法。

責(zé)任編輯:未麗燕 來源: 今日頭條
相關(guān)推薦

2024-08-02 10:23:20

2025-03-11 08:30:00

Pythonretrying代碼

2019-08-28 09:28:07

SSHOpenSSH運(yùn)維

2017-09-26 11:40:38

Juniper安全Contrail Se

2015-09-06 10:01:24

2018-09-06 10:16:39

2019-02-28 22:47:06

云計(jì)算數(shù)據(jù)安全企業(yè)

2018-07-19 16:50:53

2018-01-31 11:20:48

2021-02-25 09:59:10

數(shù)據(jù)安全惡意攻擊密碼

2019-07-13 15:31:10

Linux防火墻

2011-08-10 09:54:07

2017-07-07 14:52:43

數(shù)據(jù)安全存儲(chǔ)Splunk

2023-07-03 07:55:25

2016-11-24 13:54:56

2011-11-16 16:18:38

程序員

2020-05-21 08:53:12

Python技術(shù)代碼

2023-03-26 23:53:49

TLSgRPC通信

2010-06-25 18:00:02

APC InfraSt

2021-03-03 08:02:13

JavaScript函數(shù)字節(jié)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)