2014-03-03 177 views
14

我正在嘗試創建一個容器,該容器可以通過docker套接字文件(主機 - /var/run/docker.sock)訪問主機泊塢窗遠程API。訪問容器內的Docker套接字

答案here建議代理請求到套接字。我會如何去做這件事?

回答

20

我想通了。你可以簡單的通過量參數

docker run -v /var/run/docker.sock:/container/path/docker.sock 

由於@zarathustra指出,這可能不是然而,最大的想法通過套接字文件。請參閱:https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html

+1

你不應該這樣做,請參閱https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container.html – Zarathustra

+0

@Zarathustra同意並感謝。然而,問題不在於是否應該完成。我會在此更新答案並提出警告。 –

15

如果有人打算從容器內使用Docker,他應該清楚地理解安全含義。

從容器內訪問泊塢窗很簡單:

  1. 使用docker官方圖片或安裝泊塢窗的容器內。或描述 here
  2. 從主機暴露泊塢窗Unix套接字集裝箱

這就是爲什麼

docker run -v /var/run/docker.sock:/var/run/docker.sock \ 
     -ti docker 

應該做的伎倆,你可以下載存檔與泊塢窗客戶端二進制文件。

或者,你可能會暴露到容器中,並使用 Docker REST API

UPD:這個答案的前版本(基於以前的版本的 jpetazzo post)建議綁定貼裝從主機到容器中的泊塢窗二進制文件。這不再可靠,因爲Docker Engine不再是(幾乎)靜態庫。

注意事項:

  1. 所有主機的容器將是容器訪問,所以它可以在任何命令阻止他們,刪除,運行作爲頂級Docker容器內部的任何用戶
  2. 所有創建的容器都是在頂級Docker中創建的。
  3. 當然,您應該明白,如果容器可以訪問主機的Docker守護進程,則它具有對整個主機系統的特權訪問權限。根據容器和系統(AppArmor的)的配置,也可能要小或者更危險
  4. 其他在這裏警告dont-expose-the-docker-socket

喜歡暴露/var/lib/docker集裝箱都可能導致數據損壞的其他方法。有關更多詳細信息,請參見 do-not-use-docker-in-docker-for-ci

注官方詹金斯CI容器

的用戶在該容器中(也可能在其他很多)詹金斯進程作爲非root用戶。這就是爲什麼它沒有與docker套接字進行交互的權限。這麼快&骯髒的解決方案開始容器運行後

docker exec -u root ${NAME} /bin/chmod -v a+s $(which docker) 

。這允許容器中的所有用戶使用root權限運行docker二進制文件。更好的方法是允許通過無密碼的sudo運行docker二進制文件,但官方的Jenkins CI映像似乎缺少sudo子系統。

+1

另外,還有一篇很棒的高級文章:http://jpetazzo.github.io/2016/04/03/one-container-to-rule-them-all/ – Dmitriusan

+0

裝載docker二進制文件[阻止](https: //jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/#the-solution):'此版本的前版本建議綁定掛載docker二進制文件從主機到容器。這是不可靠的,因爲Docker引擎不再作爲(幾乎)靜態庫來分發。「 – Murmel

+1

謝謝,將會更新一個帖子 – Dmitriusan

0

我偶然發現這個頁面,同時試圖讓Docker套接字調用在作爲nobody用戶運行的容器中工作。

在我的情況下,當my-service嘗試調用docker套接字來列出可用容器時,我得到拒絕訪問錯誤。

我結束了使用docker-socket-proxy代理碼頭插座my-service。這是訪問容器內的docker套接字的不同方法,所以我儘管我會分享它。

我使my-service能夠通過DOCKER_HOST環境變量接收它應該與之通話的泊塢窗主機docker-socker-proxy

請注意,docker-socket-proxy需要以root用戶身份運行,以便能夠將docker套接字代理到my-service

docker-compose.yml

version: "3.1" 

services: 
    my-service: 
    image: my-service 
    environment: 
     - DOCKER_HOST=tcp://docker-socket-proxy:2375 
    networks: 
     - my-service_my-network 
    docker-socket-proxy: 
    image: tecnativa/docker-socket-proxy 
    environment: 
     - SERVICES=1 
     - TASKS=1 
     - NETWORKS=1 
     - NODES=1 
    volumes: 
    - /var/run/docker.sock:/var/run/docker.sock 
    networks: 
     - my-service_my-network 
    deploy: 
     placement: 
     constraints: [node.role == manager] 

networks: 
    my-network: 
    driver: overlay 

注意上面撰寫文件被羣聚就緒(docker stack deploy my-service),但它應該在撰寫模式工作,以及(docker-compose up -d)。這種方法的好處在於my-service不再需要在swarm管理器上運行。