1

内部に次のサービスを含む Kubernetes クラスターを構築しようとしています。

  • Docker-registry (これには私の django Docker イメージが含まれます)
  • ポート80と443の両方でリッスンするNginx
  • PostgreSQL
  • gunicorn で提供されるいくつかの django アプリケーション
  • 署名付き SSL 証明書を生成して自動的に更新するletencryptコンテナ

私の問題は、クラスターの作成中に発生するニワトリと卵の問題です。

私の SSL 証明書は、letsencrypt コンテナーによって生成されるシークレット ボリュームに保存されます。証明書を生成できるようにするには、ドメイン名の所有者であることを示す必要があります。これは、サーバー名からファイルにアクセスできることを検証することによって行われます (基本的に、これはポート 80 経由で静的ファイルを提供できる Nginx で構成されます)。

ここで最初の問題が発生します。letsencrypt が必要とする静的ファイルを提供するには、nginx を起動する必要があります。シークレットがマウントされていない場合、nginx の SSL 部分を開始できず、暗号化が成功した場合にのみシークレットが生成されます...

したがって、簡単な解決策は、2 つの Nginx コンテナーを用意することです。1 つはポート 80 でのみリッスンし、最初に開始されます。次に、letsencrypt を開始し、ポート 443 でリッスンする 2 つ目の Nginx コンテナーを開始します。

->私の意見では、この種のリソースの無駄のように見えますが、そうではありません.

2 つの nginx コンテナーがあると仮定すると、https 経由で Docker レジストリーにアクセスできるようにする必要があります。

したがって、私のnginx構成では、 docker-registry.conf ファイルは次のようになります。

upstream docker-registry {
  server registry:5000;
}

server {
  listen 443;
  server_name docker.thedivernetwork.net;

  # SSL
  ssl on;
  ssl_certificate /etc/nginx/conf.d/cacert.pem;
  ssl_certificate_key /etc/nginx/conf.d/privkey.pem;

  # disable any limits to avoid HTTP 413 for large image uploads
  client_max_body_size 0;

  # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
  chunked_transfer_encoding on;

  location /v2/ {
    # Do not allow connections from docker 1.5 and earlier
    # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
    if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
      return 404;
    }

    # To add basic authentication to v2 use auth_basic setting plus add_header
    auth_basic "registry.localhost";
    auth_basic_user_file /etc/nginx/conf.d/registry.password;
    add_header 'Docker-Distribution-Api-Version' 'registry/2.0' always;

    proxy_pass                          http://docker-registry;
    proxy_set_header  Host              $http_host;   # required for docker client's sake
    proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_read_timeout                  900;
  }
}

重要な部分は、レジストリ コンテナーにリダイレクトする proxy_pass です。

私が直面している問題は、私の Django Gunicorn サーバーの構成ファイルも同じフォルダー django.conf にあることです。

upstream django {
    server django:5000;
}

server {
    listen 443 ssl;
    server_name example.com;
    charset     utf-8;

    ssl on;
    ssl_certificate /etc/nginx/conf.d/cacert.pem;
    ssl_certificate_key /etc/nginx/conf.d/privkey.pem;

    ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers          HIGH:!aNULL:!MD5;
    client_max_body_size 20M;

    location / {
        # checks for static file, if not found proxy to app
        try_files $uri @proxy_to_django;
    }

    location @proxy_to_django {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        #proxy_pass_header Server;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 65;
        proxy_read_timeout 65;

        proxy_pass   http://django;
    }

}

したがって、nginx は次の 3 つの条件でのみ正常に起動します。

  • シークレットがマウントされている (これは、Nginx を 2 つの別個のコンテナーに分割することで対処できます)
  • レジストリ サービスが開始されました
  • djangoサービスが開始されました

問題は、django イメージがそのイメージをレジストリ サービスから取得しているため、再びデッドロック状態になることです。

私はそれについて言及しませんでしたが、レジストリとdjangoの両方でServerNameが異なるため、nginxは両方を提供できます

私がそれについて考えた解決策(しかし、それはかなり汚いです!)は、より多くの構成でnginxを数回リロードすることです:

  • docker レジストリ サービスを開始します
  • 私はregistry.confだけでNginxを起動します
  • django rc とサービスを作成します
  • registry.conf と django.conf の両方で nginx をリロードします

失敗した構成を無視してnginxを開始させる方法があれば、おそらく私の問題も解決するでしょう。

このセットアップをきれいに達成するにはどうすればよいですか?

ご協力いただきありがとうございます

ティボー

4

1 に答える 1

1

アプリケーションにKubernetesサービスを使用していますか?

各 Pod への Service を使用すると、Pod のプロキシを使用できます。ポッドが開始されていなくても、サービスが開始されている限り、サービスには IP が割り当てられているため、nginx は検索時にそれを見つけます。

したがって、サービスを開始してから、nginx と必要な Pod を必要な順序で開始します。

于 2016-01-20T23:35:14.910 に答える