跨Docker容器使用主机SSL证书

c7rzv4ha  于 5个月前  发布在  Docker
关注(0)|答案(1)|浏览(89)

目标

我想确保安装在我的主机上的SSL证书可以被运行在该机器上的Docker容器使用。

我的设置

虚拟机:我的虚拟机是一个运行Linux(Debian 11)的Google Cloud Compute Engine示例。到目前为止,我一直在这个虚拟机上运行我的网络应用程序(这也是安装SSL证书的地方)。
SSL证书:我已经使用LetsEncrypt在VM上安装了我的域的证书。这是一个成功的安装,这些文件存储在VM上的位置/root/etc/letsencrypt/live。我找不到下载它们的方法,因为它们受密码保护,我没有密码(我不知道当SSH进入我的VM时,sudo使用什么密码)。
Docker:我正在迁移到Docker容器(从我当前的基本“直接在VM上运行它”设置)。我使用Docker编写文件,定义了所有服务(一个webapp和一个后端服务)。webapp将需要访问SSL证书。每个服务的Dockerfile非常基本-复制我的本地存储库,并具有运行时CMD<startup_script.sh>,它处理从GCP Secret Manager下载密钥并运行应用程序。我正在成功构建Docker镜像(在本地运行docker compose build)。

Docker-compose:

version: '3.12'

services:
  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    ports:
      - "8000"

字符串
应用Dockerfile:

FROM python:3.12.0-bullseye
WORKDIR /home
COPY repo /home/repo
WORKDIR /home/repo
COPY /scripts/startup_script.sh /usr/local/bin
RUN chmod +x /usr/local/bin/startup_script.sh

CMD ["/usr/local/bin/startup_script.sh"]


启动脚本:

#!/bin/bash

#Download secrets
mkdir -p secrets
gcloud secrets versions access "latest" --secret=google_workspace_credentials --out-file=secrets/credentials.json
gcloud secrets versions access "latest" --secret=credentials_webapp --out-file=secrets/credentials_webapp

#Copy over the google workspace credentials
cp "$HOME"/secrets/credentials.json auth/credentials.json
cp "$HOME"/secrets/credentials_webapp auth/credentials_web.json

#Acquire SSL Certificate
...don't know what to do here

#Setup the runtime packages
pip install -r requirements.txt

#Run the programs
python3 app.py

我所尝试/考虑的

1.将证书复制到我的本地机器上,并使用它来构建docker镜像这不起作用,因为我需要一个密码来从VM复制证书,但我没有sudo的密码(我从来没有设置过,VM是由Google Compute Engine预构建的)。所以我被卡住了。我也认为将密钥存储在镜像本身可能有风险。
2.我读到过可以在容器本身上运行certbot,作为每次设置新SSL证书的设置脚本的一部分但这似乎是一个坏主意,因为1.如果它不成功,你永远不会知道2.你直接添加证书密钥到图像,这似乎是粗略的,3. LetsEncrypt(其他CA服务有速率限制)。然而,这个解决方案似乎很方便,因为它意味着我不必处理VM中的密钥,并且可以在任何主机上启动我的容器,而无需关心SSL证书。
3.使用docker run时将证书文件挂载到docker我读到过这个堆栈溢出response。如果我理解正确的话,该方法在使用docker run path/to/certs的VM中运行容器时挂载证书文件。我有点担心这不会工作,因为证书是密码保护的。但我还没有尝试过,因为我还不了解这个解决方案,它是如何工作的。
**4.我可能读到过一种方法,可以在容器上打开一个端口来监听主机传递证书。**我不知道如何做到这一点,但这似乎是出于安全目的的理想选择。

问题

我应该采取什么方法,以及实现它的步骤是什么(如果可能的话,我是一个新的开发者,请提供示例代码)!
编辑:
我正在使用Traefik,但我需要帮助仔细检查我的Docker compose设置。目前它已经定义了traefik服务,我的webapp使用了证书。我还在运行时CMD复制证书,因为我不会从具有证书的VM构建此映像(我在本地构建它)。

services:
  traefik:
    image: traefik:v2.5
    command:
      - sh
      - -c
      - |
        mkdir -p /certs
        cp /etc/letsencrypt/live/dreamdai.io /certs/
        traefik
        --api.insecure=true
        --providers.docker=true
        --providers.docker.exposedbydefault=false
        --entrypoints.web.address=:80
        --entrypoints.websecure.address=:443
    ports:
      - "80:80"
      - "8080:8080"
      - "443:443"

  webapp:
    image: webapp
    build:
      context: .
      dockerfile: docker/webapp.dockerfile
    labels:
      - "traefik.http.routers.webapp.rule=Host(`dreamdai.io`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls=true"
      - "traefik.http.routers.webapp.tls.certresolver=myresolver"


我无法让traefik服务构建镜像。我正在运行docker compose build traefik,日志显示“[+] Building 0.0s(0/0)”,但之后立即退出。

b91juud3

b91juud31#

使用Traefik作为您的swarm的入口路由器。配置Traefik直接从LetsEncrypt获取证书,作为其ssl卸载设置的一部分。
现在你已经设置了一个容器,不必自己管理证书,并且有了tls对无数基于docker的服务的支持。

相关问题