【问题标题】:Kubernetes 1.4 SSL Termination on AWSAWS 上的 Kubernetes 1.4 SSL 终止
【发布时间】:2017-04-06 08:47:01
【问题描述】:

我有 6 个 HTTP 微服务。目前,它们在疯狂的 bash/自定义部署工具设置(dokku、mup)中运行。

我将它们 docker 化并移至 AWS 上的 kubernetes(使用 kop 设置)。最后一部分是转换我的 nginx 配置。

我愿意

  1. 所有 6 个都具有 SSL 终止(不在 docker 映像中)
  2. 4 需要 websockets 和客户端 IP 会话亲和性(Meteor、Socket.io)
  3. 5需要http->https转发
  4. 1 在 http 和 https 上提供相同的内容

我做了 1. SSL 终止将服务类型设置为 LoadBalancer 和 using AWS specific annotations。这创建了 AWS 负载均衡器,但这看起来像 dead end for the other requirements

我查看了 Ingress,但不知道如何在 AWS 上执行此操作。这个Ingress Controller 可以在 AWS 上工作吗?

每个 pod 中都需要一个 nginx 控制器吗? This 看起来很有趣,但我不确定它有多新/相关。

我不确定从哪个方向开始。什么会起作用?

迈克

【问题讨论】:

  • 为什么不使用 nginx k8s 服务来充当其他服务的网关?然后为 http/websockets 配置 SSL/重定向?
  • @iamnat 我知道你的意思,但不知道该怎么做。如何在没有硬编码的情况下将服务信息放入 nginx 配置中?例子?
  • 硬编码是指不添加k8s svc dns标签?或者您是否可以在 nginx.conf 中使用 proxy_pass my-service.default:8080 之类的规则?

标签: amazon-web-services ssl nginx kubernetes


【解决方案1】:

您应该可以使用nginx ingress controller 来完成此操作。

  1. SSL termination
  2. Websocket support
  3. http->https
  4. 关闭 http->https 重定向,如上面链接中所述

README 将引导您完成设置,examples 有很多。

完成这项工作所需的基本部分是:

  • 当没有匹配的 Ingress 规则时,default backend 将响应 404
  • nginx ingress controller 将监控您的入口规则并在它们发生变化时重写/重新加载 nginx.conf。
  • 一个或多个 ingress rules,描述应如何将流量路由到您的服务。

最终结果是您将拥有一个与您的 nginx 入口控制器服务相对应的 ELB,该控制器反过来负责根据指定的入口规则路由到您的各个服务。

【讨论】:

  • 好的,所以这个答案基本上是 RTFM,而且 FM 的语法在 kubernetes 中无法编译。
  • @MichaelCole 你能扩展一下吗?
  • 所以这不是你的错。没有创建 ELB。 This Ingress 不会因为语法错误而“应用”。我认为 Ingress 有多种实现,这很令人困惑。
  • 好的@pixel我有一个工作配置(见答案)。感谢您的链接!如果我删除 nginx 容器,它会移动到另一个节点,从而破坏 DNS。是否有关于如何管理 Ingress 的 DNS 的最佳实践?另外,this 是否意味着我可以删除服务,因为它们什么都不做?
  • 你有用于 nginx 控制器的 LoadBalancer 类型的服务吗?这应该会为您提供一个始终指向正确节点端口的 ELB,因此您不必担心如果 pod 由于重新启动而移动,事情会中断。 Ingress 用于进入集群的外部流量。如果您有任何不通过 Ingress 的直接服务到服务通信,那么您希望保留它们。
【解决方案2】:

可能有更好的方法来做到这一点。我写这个答案是因为我问了这个问题。这是我能想到的最好的像素大象doclinksabove

default-http-backend 对于调试非常有用。 +1

入口

  • 这会在节点的 IP 地址上创建一个端点,该端点可能会根据 Ingress Container 的运行位置而改变
  • 注意底部的配置图。根据环境配置。

(markdown 占位符因为没有```)

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
  name: all-ingress
spec:
  tls:
  - hosts:
    - admin-stage.example.io
    secretName: tls-secret
  rules:
  - host: admin-stage.example.io
    http:
      paths:
      - backend:
          serviceName: admin
          servicePort: http-port
        path: /
---
apiVersion: v1
data:
  enable-sticky-sessions: "true"
  proxy-read-timeout: "7200"
  proxy-send-imeout: "7200"
kind: ConfigMap
metadata:
  name: nginx-load-balancer-conf

应用服务和部署

  • 服务端口需要命名,否则你可能会得到“上游default-admin-80没有任何活动端点。使用默认后端”

(markdown 占位符因为没有```)

apiVersion: v1
kind: Service
metadata:
  name: admin
spec:
  ports:
  - name: http-port
    port: 80
    protocol: TCP
    targetPort: http-port
  selector:
    app: admin
  sessionAffinity: ClientIP
  type: ClusterIP
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: admin
spec:
  replicas: 1
  template:
    metadata:
      labels: 
        app: admin
      name: admin
    spec:
      containers:
      - image: example/admin:latest
        name: admin
        ports:
        - containerPort: 80
          name: http-port
        resources:
          requests:
            cpu: 500m
            memory: 1000Mi
        volumeMounts:
        - mountPath: /etc/env-volume
          name: config
          readOnly: true
      imagePullSecrets:
      - name: cloud.docker.com-pull
      volumes:
      - name: config
        secret:
          defaultMode: 420
          items:
          - key: admin.sh
            mode: 256
            path: env.sh
          - key: settings.json
            mode: 256
            path: settings.json
          secretName: env-secret

入口 Nginx Docker 镜像

  • 注意底部的 default-ssl-certificate
  • 日志记录很棒 -v 下面
  • 请注意,该服务将在 AWS 上创建一个 ELB,可用于配置 DNS。

(markdown 占位符因为没有```)

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-service
spec:
  ports:
  - name: http-port
    port: 80
    protocol: TCP
    targetPort: http-port
  - name: https-port
    port: 443
    protocol: TCP
    targetPort: https-port
  selector:
    app: nginx-ingress-service
  sessionAffinity: None
  type: LoadBalancer
---
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-ingress-controller
  labels:
    k8s-app: nginx-ingress-lb
spec:
  replicas: 1
  selector:
    k8s-app: nginx-ingress-lb
  template:
    metadata:
      labels:
        k8s-app: nginx-ingress-lb
        name: nginx-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - image: gcr.io/google_containers/nginx-ingress-controller:0.8.3
        name: nginx-ingress-lb
        imagePullPolicy: Always
        readinessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
        livenessProbe:
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          timeoutSeconds: 1
        # use downward API
        env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
        ports:
        - name: http-port
          containerPort: 80
          hostPort: 80
        - name: https-port
          containerPort: 443
          hostPort: 443
        # we expose 18080 to access nginx stats in url /nginx-status
        # this is optional
        - containerPort: 18080
          hostPort: 18080
        args:
        - /nginx-ingress-controller
        - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
        - --default-ssl-certificate=default/tls-secret
        - --nginx-configmap=$(POD_NAMESPACE)/nginx-load-balancer-conf
        - --v=2

默认后端(这是从 .yaml 文件复制/粘贴)

apiVersion: v1
kind: Service
metadata:
  name: default-http-backend
  labels:
    k8s-app: default-http-backend
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    k8s-app: default-http-backend
---
apiVersion: v1
kind: ReplicationController
metadata:
  name: default-http-backend
spec:
  replicas: 1
  selector:
    k8s-app: default-http-backend
  template:
    metadata:
      labels:
        k8s-app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: default-http-backend
        # Any image is permissable as long as:
        # 1. It serves a 404 page at /
        # 2. It serves 200 on a /healthz endpoint
        image: gcr.io/google_containers/defaultbackend:1.0
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          timeoutSeconds: 5
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi

此配置使用三个秘密:

  • tls-secret - 3 个文件:tls.key、tls.crt、dhparam.pem
  • env-secret - 2 个文件:admin.sh 和 settings.json。容器具有设置环境的启动脚本。
  • cloud.docker.com-pull

【讨论】:

    猜你喜欢
    • 2019-01-23
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 2021-11-28
    • 2021-02-03
    • 2017-11-09
    • 2019-10-07
    • 2018-12-04
    相关资源
    最近更新 更多