Назад к вопросам
Middle
68
questionbank

Как мы можем получить доступ к контейнеру Kubernetes, в котором запущено приложение, из внешней сети?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Существует несколько основных способов получить доступ к контейнеру Kubernetes из внешней сети:

  1. Service типа LoadBalancer:

    • Облачные провайдеры (AWS, GCP, Azure) создают внешний балансировщик нагрузки, который направляет трафик на поды вашего приложения.
    • Присваивается внешний IP-адрес.
    • Самый простой способ в облачной среде.
  2. Service типа NodePort:

    • Открывает порт на каждом узле в кластере.
    • Этот порт перенаправляет трафик на сервис вашего приложения.
    • Доступ осуществляется по IP-адресу любого узла и номеру NodePort.
    • Менее масштабируемый и безопасный, чем LoadBalancer.
  3. Service типа ClusterIP совместно с Ingress:

    • ClusterIP - сервис, доступный только внутри кластера.
    • Ingress - API-объект, управляющий внешним доступом к сервисам в кластере.
    • Ingress-контроллер (например, Nginx Ingress Controller, Traefik) слушает внешний трафик и маршрутизирует его на подходящий ClusterIP Service.
    • Позволяет централизованно управлять маршрутизацией, SSL-терминацией, балансировкой нагрузки.
    • Гибкий и масштабируемый подход.
  4. Service типа ExternalName:

    • Создает псевдоним для внешнего домена. Не предоставляет прямого доступа к контейнеру через этот сервис, но позволяет использовать DNS-имя внутри кластера для обращения к внешнему ресурсу. Не подходит для прямого доступа к контейнеру извне.
  5. Прямой доступ к NodePort/HostPort на Pod:

    • Можно указать hostPort в спецификации пода, чтобы открыть порт на узле, где запущен под. Крайне не рекомендуется для продакшен-среды из-за низкой управляемости и потенциальных конфликтов портов.
    • Аналогично, nodePort можно указать в Service типа NodePort.

Примеры конфигураций:

  • LoadBalancer Service:

    // service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: my-app-service
    spec:
      selector:
        app: my-app
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
      type: LoadBalancer
    
  • NodePort Service:

    // service-nodeport.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: my-app-service-np
    spec:
      selector:
        app: my-app
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
          nodePort: 30000 # optional, Kubernetes will assign if not specified
      type: NodePort
    
  • Ingress (c ClusterIP service):

    // service-clusterip.yaml (предполагается, что он уже существует)
    apiVersion: v1
    kind: Service
    metadata:
      name: my-app-service-ci
    spec:
      selector:
        app: my-app
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
      type: ClusterIP
    
    // ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-app-ingress
    spec:
      rules:
        - host: myapp.example.com
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: my-app-service-ci
                    port:
                      number: 80
    

Выбор метода зависит от требований к масштабированию, безопасности, среде развертывания (облако или он-премис) и необходимости централизованного управления доступом. Ingress является предпочтительным решением для продакшен-систем.