在挎斗容器中启用 TLS 终结点Enable a TLS endpoint in a sidecar container

本文介绍如何使用一个应用程序容器以及一个运行 TLS/SSL 提供程序的挎斗容器创建容器组This article shows how to create a container group with an application container and a sidecar container running a TLS/SSL provider. 使用单独的 TLS 终结点设置容器组,可为应用程序启用 TLS 连接,而无需更改应用程序代码。By setting up a container group with a separate TLS endpoint, you enable TLS connections for your application without changing your application code.

设置包含两个容器的示例容器组:You set up an example container group consisting of two containers:

  • 一个运行简单 Web 应用且使用公共 Microsoft aci-helloworld 映像的应用程序容器。An application container that runs a simple web app using the public Microsoft aci-helloworld image.

  • 一个运行公共 Nginx 映像且配置为使用 TLS 的挎斗容器。A sidecar container running the public Nginx image, configured to use TLS.

在此示例中,容器组仅使用其公共 IP 地址公开 Nginx 的端口 443。In this example, the container group only exposes port 443 for Nginx with its public IP address. Nginx 将 HTTPS 请求路由到伴侣 Web 应用,后者在内部侦听端口 80。Nginx routes HTTPS requests to the companion web app, which listens internally on port 80. 可以改编侦听其他端口的容器应用示例。You can adapt the example for container apps that listen on other ports.

有关在容器组中启用 TLS 的其他方法,请参阅后续步骤See Next steps for other approaches to enabling TLS in a container group.

备注

在 Azure China 中使用 Azure CLI 2.0 之前,请首先运行 az cloud set -n AzureChinaCloud 更改云环境。Before you can use Azure CLI 2.0 in Azure China, please run az cloud set -n AzureChinaCloud first to change the cloud environment. 如果要切换回全局 Azure,请再次运行 az cloud set -n AzureCloudIf you want to switch back to Global Azure, run az cloud set -n AzureCloud again.

可以使用本地安装的 Azure CLI 来完成本文。You can use the local installation of the Azure CLI to complete this article. 如果想要在本地使用它,建议使用 2.0.55 版或更高版本。If you'd like to use it locally, version 2.0.55 or later is recommended. 运行 az --version 即可查找版本。Run az --version to find the version. 如果需要进行安装或升级,请参阅安装 Azure CLIIf you need to install or upgrade, see Install Azure CLI.

创建自签名证书Create a self-signed certificate

若要将 Nginx 设置为 TLS 提供程序,需要一个 TLS/SSL 证书。To set up Nginx as a TLS provider, you need a TLS/SSL certificate. 本文介绍如何创建和设置自签名的 TLS/SSL 证书。This article shows how to create and set up a self-signed TLS/SSL certificate. 对于生产方案,应从证书颁发机构获取证书。For production scenarios, you should obtain a certificate from a certificate authority.

若要创建自签名的 TLS/SSL 证书,请使用 Azure 本地 Shell 以及许多 Linux 分发版中提供的 OpenSSL 工具,或使用操作系统中的类似客户端工具。To create a self-signed TLS/SSL certificate, use the OpenSSL tool available in Azure local Shell and many Linux distributions, or use a comparable client tool in your operating system.

首先在本地工作目录中创建证书请求(.csr 文件):First create a certificate request (.csr file) in a local working directory:

openssl req -new -newkey rsa:2048 -nodes -keyout ssl.key -out ssl.csr

按提示添加标识信息。Follow the prompts to add the identification information. 对于“公用名”,请输入与证书关联的主机名。For Common Name, enter the hostname associated with the certificate. 当系统提示输入密码时,请直接按 Enter 而不要键入任何内容,以跳过添加密码的步骤。When prompted for a password, press Enter without typing, to skip adding a password.

运行以下命令,基于证书请求创建自签名证书(.crt 文件)。Run the following command to create the self-signed certificate (.crt file) from the certificate request. 例如:For example:

openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt

现在,该目录中应会出现三个文件:证书请求 (ssl.csr)、私钥 (ssl.key) 和自签名证书 (ssl.crt)。You should now see three files in the directory: the certificate request (ssl.csr), the private key (ssl.key), and the self-signed certificate (ssl.crt). 在后续步骤中将使用 ssl.keyssl.crtYou use ssl.key and ssl.crt in later steps.

将 Nginx 配置为使用 TLSConfigure Nginx to use TLS

创建 Nginx 配置文件Create Nginx configuration file

在本部分,你将为 Nginx 创建配置文件以使用 TLS。In this section, you create a configuration file for Nginx to use TLS. 首先,将以下文本复制到名为 nginx.conf 的新文件中。Start by copying the following text into a new file named nginx.conf. 在 Azure 本地 Shell 中,可以使用 Visual Studio Code 在工作目录中创建该文件:In Azure local Shell, you can use Visual Studio Code to create the file in your working directory:

code nginx.conf

location 中,请务必将 proxy_pass 设置为应用的正确端口。In location, be sure to set proxy_pass with the correct port for your app. 本示例为 aci-helloworld 容器设置了端口 80。In this example, we set port 80 for the aci-helloworld container.

# nginx Configuration File
# https://wiki.nginx.org/Configuration

# Run as a less privileged user for security reasons.
user nginx;

worker_processes auto;

events {
  worker_connections 1024;
}

pid        /var/run/nginx.pid;

http {

    #Redirect to https, using 307 instead of 301 to preserve post data

    server {
        listen [::]:443 ssl;
        listen 443 ssl;

        server_name localhost;

        # Protect against the BEAST attack by not using SSLv3 at all. If you need to support older browsers (IE6) you may need to add
        # SSLv3 to the list of protocols below.
        ssl_protocols              TLSv1.2;

        # Ciphers set to best allow protection from Beast, while providing forwarding secrecy, as defined by Mozilla - https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx
        ssl_ciphers                ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;
        ssl_prefer_server_ciphers  on;

        # Optimize TLS/SSL by caching session parameters for 10 minutes. This cuts down on the number of expensive TLS/SSL handshakes.
        # The handshake is the most CPU-intensive operation, and by default it is re-negotiated on every new/parallel connection.
        # By enabling a cache (of type "shared between all Nginx workers"), we tell the client to re-use the already negotiated state.
        # Further optimization can be achieved by raising keepalive_timeout, but that shouldn't be done unless you serve primarily HTTPS.
        ssl_session_cache    shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
        ssl_session_timeout  24h;

        # Use a higher keepalive timeout to reduce the need for repeated handshakes
        keepalive_timeout 300; # up from 75 secs default

        # remember the certificate for a year and automatically connect to HTTPS
        add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';

        ssl_certificate      /etc/nginx/ssl.crt;
        ssl_certificate_key  /etc/nginx/ssl.key;

        location / {
            proxy_pass http://localhost:80; # TODO: replace port if app listens on port other than 80

            proxy_set_header Connection "";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
}

对机密和配置文件进行 Base64 编码Base64-encode secrets and configuration file

对 Nginx 配置文件、TLS/SSL 证书和 TLS 密钥进行 Base64 编码。Base64-encode the Nginx configuration file, the TLS/SSL certificate, and the TLS key. 在下一部分,你将在用于部署容器组的 YAML 文件中输入编码的内容。In the next section, you enter the encoded contents in a YAML file used to deploy the container group.

cat nginx.conf | base64 > base64-nginx.conf
cat ssl.crt | base64 > base64-ssl.crt
cat ssl.key | base64 > base64-ssl.key

部署容器组Deploy container group

现在,通过在 YAML 文件中指定容器配置来部署容器组。Now deploy the container group by specifying the container configurations in a YAML file.

创建 YAML 文件Create YAML file

将以下 YAML 复制到名为 deploy-aci.yaml 的新文件中。Copy the following YAML into a new file named deploy-aci.yaml. 在 Azure 本地 Shell 中,可以使用 Visual Studio Code 在工作目录中创建该文件:In Azure local Shell, you can use Visual Studio Code to create the file in your working directory:

code deploy-aci.yaml

输入 base64 编码文件的内容(在 secret 下指示)。Enter the contents of the base64-encoded files where indicated under secret. 例如,对每个 base64 编码的文件运行 cat 以查看其内容。For example, cat each of the base64-encoded files to see its contents. 在部署期间,这些文件将添加到容器组中的机密卷During deployment, these files are added to a secret volume in the container group. 在本示例中,机密卷已装载到 Nginx 容器。In this example, the secret volume is mounted to the Nginx container.

api-version: 2018-10-01
location: chinanorth2
name: app-with-ssl
properties:
  containers:
  - name: nginx-with-ssl
    properties:
      image: nginx
      ports:
      - port: 443
        protocol: TCP
      resources:
        requests:
          cpu: 1.0
          memoryInGB: 1.5
      volumeMounts:
      - name: nginx-config
        mountPath: /etc/nginx
  - name: my-app
    properties:
      image: mcr.microsoft.com/azuredocs/aci-helloworld
      ports:
      - port: 80
        protocol: TCP
      resources:
        requests:
          cpu: 1.0
          memoryInGB: 1.5
  volumes:
  - secret:
      ssl.crt: <Enter contents of base64-ssl.crt here>
      ssl.key: <Enter contents of base64-ssl.key here>
      nginx.conf: <Enter contents of base64-nginx.conf here>
    name: nginx-config
  ipAddress:
    ports:
    - port: 443
      protocol: TCP
    type: Public
  osType: Linux
tags: null
type: Microsoft.ContainerInstance/containerGroups

部署容器组Deploy the container group

使用 az group create 命令创建资源组:Create a resource group with the az group create command:

az group create --name myResourceGroup --location chinanorth2

使用 az container create 命令部署容器组并传递 YAML 文件作为参数。Deploy the container group with the az container create command, passing the YAML file as an argument.

az container create --resource-group <myResourceGroup> --file deploy-aci.yaml

查看部署状态View deployment state

若要查看部署状态,请运行以下 az container show 命令:To view the state of the deployment, use the following az container show command:

az container show --resource-group <myResourceGroup> --name app-with-ssl --output table

如果部署成功,输出将如下所示:For a successful deployment, output is similar to the following:

Name          ResourceGroup    Status    Image                                                    IP:ports             Network    CPU/Memory       OsType    Location
------------  ---------------  --------  -------------------------------------------------------  -------------------  ---------  ---------------  --------  ----------
app-with-ssl  myresourcegroup  Running   nginx, mcr.microsoft.com/azuredocs/aci-helloworld        52.157.22.76:443     Public     1.0 core/1.5 gb  Linux     chinanorth2

验证 TLS 连接Verify TLS connection

使用浏览器导航到容器组的公共 IP 地址。Use your browser to navigate to the public IP address of the container group. 本示例中显示的 IP 地址是 52.157.22.76,因此 URL 是 https://52.157.22.76。The IP address shown in this example is 52.157.22.76, so the URL is https://52.157.22.76. 由于 Nginx 服务器配置的原因,必须使用 HTTPS 查看正在运行的应用程序。You must use HTTPS to see the running application, because of the Nginx server configuration. 尝试通过 HTTP 连接失败。Attempts to connect over HTTP fail.

浏览器屏幕截图,显示应用程序在 Azure 容器实例中运行

备注

由于本示例使用自签名证书而不是证书颁发机构提供的证书,因此,在通过 HTTPS 连接站点时,浏览器会显示安全警告。Because this example uses a self-signed certificate and not one from a certificate authority, the browser displays a security warning when connecting to the site over HTTPS. 你可能需要接受警告或调整浏览器或证书设置才能继续进入页面。You might need to accept the warning or adjust browser or certificate settings to proceed to the page. 这是预期的行为。This behavior is expected.

后续步骤Next steps

本文介绍了如何设置 Nginx 容器,以便与容器组中运行的 Web 应用建立 TLS 连接。This article showed you how to set up an Nginx container to enable TLS connections to a web app running in the container group. 对于侦听端口 80 以外的端口的应用,可以改编此示例。You can adapt this example for apps that listen on ports other than port 80. 还可以更新 Nginx 配置文件来自动重定向端口 80 (HTTP) 上的服务器连接,以使用 HTTPS。You can also update the Nginx configuration file to automatically redirect server connections on port 80 (HTTP) to use HTTPS.

尽管本文在挎斗中使用 Nginx,但你可以使用另一个 TLS 提供程序,例如 CaddyWhile this article uses Nginx in the sidecar, you can use another TLS provider such as Caddy.