Входной контроллер Kubernetes nginx в Azure недоступен

Я очень новичок в Azure, Kubernetes, даже в самом Docker, и играю с системой, чтобы изучить и оценить возможное развертывание позже. До сих пор я докеризовал свои сервисы и успешно развернул их, а также сделал веб-интерфейс общедоступным, используя сервис с типом: LoadBalancer.

Теперь я хотел бы добавить завершение TLS и узнал, что для этого я должен настроить контроллер входа, наиболее часто упоминаемым из которых является nginx-ingress-controller.

Строго изучив примеры, а затем попытавшись прочитать документы, я пришел к установке, которая выглядит интересно, но не работает. Может быть, какая-нибудь добрая душа укажет на мои ошибки и/или подскажет, как это отлаживать и где подробнее об этом прочитать.

У меня kubectl применил следующий файл:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: default-http-backend-deployment
  namespace: kube-system
spec:
  template:
    metadata:
      labels:
        app: default-http-backend
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: default-http-backend
          image: gcr.io/google_containers/defaultbackend:1.0
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: default-http-backend-service
  namespace: kube-system
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80  
  selector:
    app: default-http-backend
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-controller-conf
  namespace: kube-system
data:
  # enable-vts-status: 'true'
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller-deployment
  namespace: kube-system
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx-ingress-controller
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - image: gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.13
          name: nginx-ingress-controller
          ports:
            - containerPort: 80
              hostPort: 80
            - containerPort: 443
              hostPort: 443
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          args:
            - /nginx-ingress-controller
            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
            - --configmap=$(POD_NAMESPACE)/nginx-ingress-controller-conf
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller-service
  namespace: kube-system
spec:
  ports:
    - name: https
      port: 443
      protocol: TCP
      targetPort: 443
    - name: http
      port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx-ingress-controller
  sessionAffinity: None
  type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: kube-system
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: 
      http:
        paths:
          - path: /
            backend:
              serviceName: default-http-backend-service
              servicePort: 80

Это дало мне два модуля:

c:\Projects\Release-Management\Azure>kubectl get pods --all-namespaces

NAMESPACE     NAME                                                   READY     STATUS    RESTARTS   AGE
<some lines removed>
kube-system   default-http-backend-deployment-3108185104-68xnk       1/1       Running   0          39m
<some lines removed>
kube-system   nginx-ingress-controller-deployment-4106313651-v7p03   1/1       Running   0          24s

Также две новые услуги. Обратите внимание, что я также настроил службу default-http-backend с типом: LoadBalancer, это только для отладки. Я включил свой веб-интерфейс, который называется webcms:

c:\Projects\Release-Management\Azure>kubectl get services --all-namespaces

NAMESPACE     NAME                               CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
<some lines removed>
default       webcms                             10.0.105.59    13.94.250.173   80:31400/TCP                 23h
<some lines removed>
kube-system   default-http-backend-service       10.0.106.233   13.80.68.38     80:31639/TCP                 41m
kube-system   nginx-ingress-controller-service   10.0.33.80     13.95.30.39     443:31444/TCP,80:31452/TCP   37m

И, наконец, вход:

c:\Projects\Release-Management\Azure>kubectl get ingress --all-namespaces

NAMESPACE     NAME            HOSTS     ADDRESS      PORTS     AGE
kube-system   nginx-ingress   *         10.240.0.5   80        39m

Нет ошибок, которые я могу сразу обнаружить. Затем я зашел на панель управления Azure и посмотрел на балансировщик нагрузки и его правила, и на мой (серьезно неподготовленный) взгляд это выглядит хорошо. Эти я не трогал, балансировщик нагрузки и правила были созданы системой. Здесь есть скриншот:

https://qvwx.de/tmp/azure-loadbalancer.png

Но, к сожалению, это не работает. Я могу свернуть свой webcms-сервис:

c:\Projects\Release-Management\Azure>curl -v http://13.94.250.173
* Rebuilt URL to: http://13.94.250.173/
*   Trying 13.94.250.173...
* TCP_NODELAY set
* Connected to 13.94.250.173 (13.94.250.173) port 80 (#0)
<more lines removed, success>

Но ни default-http-backend, ни вход не работают:

c:\Projects\Release-Management\Azure>curl -v http://13.80.68.38
* Rebuilt URL to: http://13.80.68.38/
*   Trying 13.80.68.38...
* TCP_NODELAY set
* connect to 13.80.68.38 port 80 failed: Timed out
* Failed to connect to 13.80.68.38 port 80: Timed out
* Closing connection 0
curl: (7) Failed to connect to 13.80.68.38 port 80: Timed out

(вход дает то же самое с другим IP)

Если вы дочитали до этого места: Спасибо за ваше время, и я был бы признателен за любые подсказки.

Мариан


person Marian Aldenhövel    schedule 11.09.2017    source источник


Ответы (1)


Вроде тривиальная вещь, но она сэкономит вам $$$: default-http-backend не предназначена для лицевой стороны, и поэтому не должна иметь type: LoadBalancer -- это просто предназначен для 404, поэтому контроллер Ingress может универсальный /dev/null трафик для сервисов без Pod.


Немного поднимемся по лестнице тривиальности и для предельной ясности: я не думаю, что то, что у вас есть, неправильное, но я хотел предложить вам кое-что, чтобы решить, хотите ли вы измениться. Обычно контракт для контейнера пода заключается в том, чтобы дать порту идеальное имя на естественном языке («http», «https», «prometheus» и т. д.), которое сопоставляется с портом базового образа. Затем установите targetPort: в сервисе на это имя, а не на номер, что дает контейнеру возможность переместить номер порта, не нарушая контракт между сервисом и подом. Вход nginx Контейнер развертывания: порты: согласен со мной в этом.


Теперь давайте перейдем к частям, которые могут способствовать тому, что ваша система ведет себя не так, как вы хотите.

Я не могу это доказать прямо сейчас, но наличие container:hostPort: подозрительно без hostNetwork: верно. Я искренне удивлен, что kubectl не ныл, потому что эти комбинации конфигураций немного странные.

Я предполагаю, что шаг устранения неполадок будет состоять в том, чтобы получить доступ к Node (то есть к чему-то в кластере, который не является подом — вы можете сделать это с отдельной виртуальной машиной в той же подсети, что и ваш Node, если хотите) и затем перейдите к порту 31452 Node, на котором работает nginx-ingress-controller Pod.

kubectl get nodes перечислит все доступные Nodes, и

kubectl get -o json pod nginx-ingress-controller-deployment-4106313651-v7p03 | jq -r '.items[0].status.hostIP' должен предоставить IP-адрес конкретной виртуальной машины, если вы его еще не знаете. Э-э, я только что понял из вашей подсказки, что у вас, вероятно, нет jq, но я недостаточно хорошо знаю PowerShell, чтобы знать его синтаксис запросов JSON.

Потом из любого Node: curl -v http://${that_host_IP_value}:31452 и посмотрим, что материализуется. Может быть что-то, а может быть то самое "что?!" которые дает вам LoadBalancer.


Что касается ресурса Ingress, опять же, default-http-backend не должен иметь ресурс Ingress — я не знаю, вредит ли это чему-либо, потому что я никогда не пробовал, но я также готов поспорить на 1 доллар, что это не так. помощь в вашей ситуации.

Поскольку у вас уже есть известный работающий Service с default:webcms, я бы порекомендовал создать ресурс Ingress в пространстве имен default практически с тем же, что и ваш текущий ресурс Ingress, но указав на webcms вместо default-http-backend. Таким образом, ваш контроллер Ingress на самом деле будет иметь цель, которая не является серверной частью по умолчанию.

Если вы еще этого не видели, добавление --v=2 приведет к тому, что под будет выдавать фактический diff изменения конфигурации nginx, что может быть невероятно полезным для отслеживания недопонимания конфигурации.


Мне очень жаль, что вам приходится сражаться с Azure, контроллерами Ingress и грубой документацией для вашего первого контакта с Kubernetes. Это действительно удивительно, когда вы все правильно настроили, но это, конечно, довольно сложный механизм.

person mdaniel    schedule 17.09.2017
comment
Спасибо за ваш отзыв, он был очень кстати и мне очень помог. Я добился прогресса и заставил вещь работать очень хорошо. Для справки, я думаю, что моя проблема была не столько в показанной конфигурации, сколько в разрешении DNS, я просто вообще запутался. Состояние, которое в последнее время стало намного лучше. Меня не нужно жалеть, я нахожу документацию от core-Kubernetes, контроллера nginx ingress и даже Microsoft для Azure-интеграции весьма полезной. Просто многое нужно понять. Еще раз спасибо за очень полезный ответ. - person Marian Aldenhövel; 24.09.2017