web-dev-qa-db-ja.com

Google Kubernetes Engineでのhttp-> httpsリダイレクト

からすべてのトラフィックをリダイレクトしようとしています

http://example.com -> https://example.com ほぼすべてのWebサイトと同じです。

私はこのリンクを見ましたが、成功しませんでした: Google Container EngineでのKubernetes HTTPS Ingress

そして、私のingress.yamlファイルで次のアノテーションを試しました。

nginx.ingress.kubernetes.io/configuration-snippet: |
  if ($http_x_forwarded_proto != 'https') {
    return 301 https://$Host$request_uri;
  }
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.allow-http: "false"

すべて成功せず。明確にするために、エラーなく https://example.com および http://example.com にアクセスできます。httpsにリダイレクトするには、http呼び出しが必要です。

ありがとう

10
Daniel Lee

それだけの価値があるため、NGINXでリバースプロキシを使用することになりました。

  1. シークレットを作成してコンテナに同期する必要があります
  2. Nginx構成と、この追加の構成ファイルを参照するデフォルト構成を使用して、nginxに構成マップを作成する必要があります。

これが私の設定です:

worker_processes  1;

events {
    worker_connections  1024;
}


http {

default_type  application/octet-stream;

# Logging Configs
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

sendfile        on;
keepalive_timeout  65;

# Puntdoctor Proxy Config
include /path/to/config-file.conf;

# PubSub allows 10MB Files. lets allow 11 to give some space
client_max_body_size 11M;

}

次に、config.conf

server {
listen 80;
server_name example.com;
return 301 https://$Host$request_uri;
}

server {

listen 443;
server_name example.com;

ssl_certificate           /certs/tls.crt;
ssl_certificate_key       /certs/tls.key;

ssl on;
ssl_session_cache  builtin:1000  shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:AES128-GCM-SHA256:HIGH:!RC4:!MD5:!aNULL:!EDH:!CAMELLIA;
ssl_prefer_server_ciphers on;

location / {

  proxy_set_header        Host $Host;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Proto $scheme;
  proxy_set_header        X-Forwarded-Host $http_Host;

  # Fix the “It appears that your reverse proxy set up is broken" error.
  proxy_pass          http://deployment-name:8080/;
  proxy_read_timeout  90;

  proxy_redirect      http://deployment-name:8080/ https://example.com/;
}
}
  1. デプロイを作成します。

これが.yamlファイルです

---
apiVersion: v1
kind: Service
metadata:
  name: puntdoctor-lb
spec:
   ports:
    - name: https
      port: 443
      targetPort: 443
     - name: http
      port: 80
      targetPort: 80
  selector:
    app: puntdoctor-nginx-deployment
  type: LoadBalancer
  loadBalancerIP: 35.195.214.7
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: puntdoctor-nginx-deployment
spec:
   replicas: 2
  template:
    metadata:
      labels:
        app: puntdoctor-nginx-deployment
    spec:
       containers:
       - name: adcelerate-nginx-proxy
        image: nginx:1.13
         volumeMounts:
        - name: certs
          mountPath: /certs/
        - name: site-config
          mountPath: /etc/site-config/
        - name: default-config
          mountPath: /etc/nginx/
        ports:
        - containerPort: 80
          name: http
        - containerPort: 443
          name: https
      volumes:
      - name: certs
        secret:
          secretName: nginxsecret
      - name: site-config
        configMap:
          name: nginx-config
       - name: default-config
        configMap:
         name: default

これが誰かがこの問題を解決するのに役立つことを願っています。他の2つの回答のおかげで、どちらも私に貴重な洞察を与えてくれました。

2
Daniel Lee

現在、これを適切に行う方法(注釈、SSL/HTTPS、ヘルスチェックなど)のドキュメントは非常に欠けており、非常に長い間使用されてきました。 App Engineを使用する方が好まれるのではないかと思います。これは魔法のようですが、非常に高価です。 GKEの場合、2つのオプションがあります。

  • アプリ/サイトの前に、Googleが管理するSSL証明書と追加のNGINXサーバー構成を使用した上り
  • 自己管理/サードパーティのSSL証明書を備えたNGINX入力コントローラー

以下は、前者を使用して動作するセットアップへのステップです。

1アプリへの扉

nginx.conf:(省略記号は、関連のない、強制されないその他の設定を表します)

user  nginx;
worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    ...

    keepalive_timeout  620s;

    ## Logging ##
    ...
    ## MIME Types ##
    ...
    ## Caching ##
    ...
    ## Security Headers ##
    ...
    ## Compression ##
    ....

    server {
        listen 80;

        ## HTTP Redirect ##
        if ($http_x_forwarded_proto = "http") {
            return 301 https://[YOUR DOMAIN]$request_uri;
        }

        location /health/liveness {
            access_log off;
            default_type text/plain;
            return 200 'Server is LIVE!';
        }

        location /health/readiness {
            access_log off;
            default_type text/plain;
            return 200 'Server is READY!';
        }

        root /usr/src/app/www;
        index index.html index.htm;
        server_name [YOUR DOMAIN] www.[YOUR DOMAIN];

        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}

注:1つのサービングポートのみ。グローバル転送ルールは、通過するすべてのトラフィックに http_x_forwarded_proto ヘッダーを追加します。ドメインへのすべてのトラフィックがこのルールを通過するため(コンテナーの1つのポート、サービス、および入力を忘れないでください)、このヘッダーは(決定的に!)常に設定されます。上記の確認とリダイレクトに注意してください。ヘッダーの値が「https」の場合にのみ配信が続行されます。ルート、インデックス、ロケーションの値はプロジェクトによって異なります(これはangularプロジェクトです)。keepalive_timeoutは値 googleが推奨 に設定されています。メインのnginx.confファイルですが、ほとんどの人はcustom.confファイルを/etc/nginx/conf.dに追加します。これを行う場合は、ファイルをメインのnginx.conf httpブロックにインポートすることを確認してくださいincludesステートメント。コメントは、gzip/brotli、セキュリティヘッダー、ログの保存場所など、すべてが機能しているときに追加したい他の設定の場所を強調しています。

Dockerfile:

...
COPY nginx.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off;"]

注:最後の2行のみ。 EXPOSEポートの指定は不要です。 COPYは、デフォルトのnginx.confを変更されたものに置き換えます。 CMDはライトサーバーを起動します。

2配置マニフェストを作成して適用/作成する

deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: uber-dp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: uber
  template:
    metadata:
      labels:
        app: uber
    spec:
      containers:
        - name: uber-ctr
          image: gcr.io/uber/beta:v1 // or some other registry
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 60
            httpGet:
              path: /health/liveness
              port: 80
              scheme: HTTP
          readinessProbe:
            failureThreshold: 3
            initialDelaySeconds: 30
            httpGet:
              path: /health/readiness
              port: 80
              scheme: HTTP
          ports:
            - containerPort: 80
          imagePullPolicy: Always

注:すべての(HTTPおよびHTTPS)トラフィックをそのポートにポイントするため、指定するポートは1つだけ必要です。簡単にするために、活性度プローブと準備度プローブには同じパスを使用しています。これらのチェックはNGINXサーバーで処理されますが、アプリ自体の正常性をプローブするチェックを追加できます(正常であれば200を返す専用ページなど)。準備プローブもGCEによってピックアップされます。デフォルトでは、独自の削除不可能なヘルスチェックがあります。

3サービスマニフェストを作成して適用/作成

service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: uber-svc
  labels:
    app: uber
spec:
  ports:
    - name: default-port
      port: 80
  selector:
    app: uber
  sessionAffinity: None
  type: NodePort

注:default-portは、コンテナのポート80を指定します。

4静的IPアドレスを取得する

GCPのハンバーガーメニュー:VPCネットワーク->外部IPアドレス。自動生成されたエフェメラルIPを変換するか、新しいものを作成します。名前と住所を書き留めます。

5 SSL証明書の作成 およびデフォルトゾーン

ハンバーガーメニュー:ネットワークサービス->負荷分散-> [詳細メニュー]-> [証明書]-> [SSL証明書の作成]をクリックします。指示に従い、証明書を作成またはアップロードし、名前を書き留めます。次に、メニューから:Cloud DNS-> Create Zone。手順に従って、ドメインの デフォルトゾーンを作成 します。 DNS名としてwww、正規名としてドメインを含むCNAMEレコードを追加します。空のDNS名の値と静的IPを持つAレコードをIPV4として追加します。保存する。

6入力マニフェストを作成して適用/作成

ingress.yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mypt-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: [NAME OF YOUR STATIC IP ADDRESS]
    kubernetes.io/ingress.allow-http: "true"
    ingress.gcp.kubernetes.io/pre-shared-cert: [NAME OF YOUR GOOGLE-MANAGED SSL]
spec:
  backend:
    serviceName: mypt-svc
    servicePort: 80

注:バックエンドプロパティは、サーバーによって「保護された」アプリを含むコンテナーを指すサービスを指します。アノテーションはアプリをSSLに接続し、ヘルスチェックのためにhttpを強制的に許可します。サービスと入力を組み合わせて、 G7ロードバランサー を構成します(グローバル転送ルール、バックエンドとフロントエンドの「サービス」、SSL証明書、ターゲットプロキシなどを組み合わせたもの)。

7お茶か何かを作る

すべての設定に約10分かかります。キャッシュをクリアして、さまざまなブラウザー(Tor、Opera、Safari、IEなど)でドメインをテストします。すべてがhttpsで機能します。

NGINX Ingress Controllerについてはどうですか?安価/リソース使用量が少なく、柔軟性が高いため、より優れているとの議論がありました。安くはありません。追加のデプロイ/ワークロードとサービス(GCE L4)が必要です。そして、より多くの設定を行う必要があります。より柔軟ですか?はい。しかし、ほとんどの作業を処理する場合、最初のオプションは、より重要な種類の柔軟性を提供します。

5
Jai

GKEはGCE L7を使用します。例で参照したルールはサポートされておらず、HTTPからHTTPSへのリダイレクトはアプリケーションレベルで制御する必要があります。

L7はx-forwarded-protoヘッダー。フロントエンドトラフィックがHTTPまたはHTTPSのどちらを使用して送信されたかを理解するために使用できます。ここを見てください: HTTPSへのHTTPのリダイレクト

Nginxのリンクの例もあります(便宜上コピーされています)。

# Replace '_' with your hostname.
server_name _;
if ($http_x_forwarded_proto = "http") {
    return 301 https://$Host$request_uri;
}

GKEは、httpsの強制をサポートしない独自のIngress Controllerを使用します。

そのため、NGINX Ingress Controllerを自分で管理する必要があります。

GKEでそれを行う方法については この投稿 を参照してください。

それが役に立てば幸い。

4

私のように月に1回程度この質問を検索するすべての人のために、Googleはリクエストに応答し、ロードバランサーでHTTP-> HTTPS SSLリダイレクトをテストしています。 最新の回答 2020年1月末までにアルファ版になる予定であると述べた。

彼らのコメント:

この問題についてお待ちいただき、ありがとうございます。この機能は現在テスト段階にあり、1月末までにアルファ段階に入る予定です。 PMチームは、アルファ版のリリースが近づくと、詳細をお知らせします。

2
Josh