Ожидается внешний IP-адрес службы Kubernetes


144

Я пытаюсь развернуть nginx на kubernetes, версия kubernetes - v1.5.2, я развернул nginx с 3 репликами, файл YAML находится ниже,

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment-example
spec:
  replicas: 3
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.10
        ports:
        - containerPort: 80

и теперь я хочу открыть его порт 80 на порту 30062 узла, для этого я создал службу ниже,

kind: Service
apiVersion: v1
metadata:
  name: nginx-ils-service
spec:
  ports:
    - name: http
      port: 80
      nodePort: 30062
  selector:
    app: nginx
  type: LoadBalancer

этот сервис работает нормально, но он отображается как ожидающий не только на панели инструментов kubernetes, но и на терминале. Терминальный выходСтатус панели управления

поэтому, пожалуйста, помогите мне решить эту проблему. Спасибо ...

Ответы:


177

Похоже , что вы используете пользовательские Kubernetes кластера (используя minikube, kubeadmили тому подобное). В этом случае нет интегрированного LoadBalancer (в отличие от AWS или Google Cloud). С этой настройкой по умолчанию вы можете использовать только NodePortили Ingress Controller.

С помощью Ingress Controller вы можете настроить доменное имя, которое соответствует вашему поду; вам не нужно указывать LoadBalancerтип своей службы, если вы используете Ingress Controller.


Большое спасибо @javier, это действительно полезно. Я решил свою проблему из документа выше.
Панкадж Джексон

10
Это действительно не отвечает на вопрос? Пользователь использует LoadBalancerв качестве типа службы допустимый тип службы. NodePortи ingressесть ли другие способы сделать это, но не решить проблему, верно?
Raptor

2
Это допустимый тип службы, но он используется на несовместимой платформе (по крайней мере, по умолчанию). Чтобы использовать LoadBalancer, у вас должна быть платформа, которая может предоставлять внешние IP-адреса модулям, что и делают Google Cloud или AWS.
Хавьер Салмерон

2
Я использую kubeadm на AWS. Могу я еще LoadBalancer?
jiashenC

3
Если вы используете миникубе, запустите «туннель миникубе». Теперь проверьте свои службы, вы получите общедоступный IP. Вот документ для получения дополнительной информации minikube.sigs.k8s.io/docs/tasks/loadbalancer
Рави

75

Если вы используете Minikube, есть волшебная команда!

$ minikube tunnel

Надеюсь, кто-то сможет сэкономить на этом несколько минут.

Ссылка для справки https://minikube.sigs.k8s.io/docs/handbook/accessing/#using-minikube-tunnel


Я попробовал, minikube tunnelи это действительно решаетpending проблему, но затем новый внешний IP-адрес не работает: я получаю ошибку тайм-аута ...
a.barbieri

@ a.barbieri убедитесь, что вы используете IP-адрес туннеля вместо IP-адреса minikube. «Патчинг ingress-nginx с IP 10.106.102.98»
Питер Чжоу

2
да, спасибо, Питер. Попытаюсь. В любом случае, переключившись на рабочий стол Docker, я смог решить эту проблему с помощью стандартной настройки, которая работает непосредственно на localhost.
a.barbieri

3
Отличный совет по экономии времени для демонстрации!
jgitter

50

Если вы не используете GCE или EKS (вы использовали kubeadm ), вы можете добавить externalIPsспецификацию к YAML вашей службы. Вы можете использовать IP-адрес, связанный с основным интерфейсом вашего узла, например eth0. Затем вы можете получить доступ к сервису извне, используя внешний IP-адрес узла.

...
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.0.10

2
Должна быть недостающая информация: «внешние IP-адреса не управляются Kubernetes и находятся в ведении администратора кластера». ( kubernetes.io/docs/concepts/services-networking/service ). Есть ли какой-то «контроллер», который мне нужно установить?
Дэниел Алдер

Я следую учебнику Kubernetes ( kubernetes.io/docs/tutorials/stateless-application/guestbook ), и он отлично работал с kubeadm
Эдуардо

Спасибо - молодец, сработало как положено. Я предоставил Service для узлов сети IP IP, который теперь доступен за пределами кластера
Влад Гулин


21

Я создал одноузловой кластер k8s с помощью kubeadm. Когда я попробовал PortForward и прокси kubectl , он показал внешний IP-адрес как ожидающий.

$ kubectl get svc -n argocd argocd-server
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
argocd-server   LoadBalancer   10.107.37.153   <pending>     80:30047/TCP,443:31307/TCP   110s

В моем случае я исправил сервис следующим образом:

kubectl patch svc <svc-name> -n <namespace> -p '{"spec": {"type": "LoadBalancer", "externalIPs":["172.31.71.218"]}}'

После этого он начал работать по общедоступному IP.

$ kubectl get svc argo-ui -n argo
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
argo-ui   LoadBalancer   10.103.219.8   172.31.71.218   80:30981/TCP   7m50s

11
Возможно, вам стоит упомянуть, откуда взялось "172.31.71.218"?
EuRBamarth

Наконец, ответ, в котором рассказывается, как исправить. Спасибо, что поделился.
Srikant

5

Если вы работаете на minikube , не забудьте указать пространство имен, если вы не используете default.

служба minikube << имя_службы >> --url --namespace = << имя_пространства имен >>


4

Если вы используете minikube, запустите приведенные ниже команды с терминала,

$ minikube ip
$ 172.17.0.2 // then 
$ curl http://172.17.0.2:31245
or simply
$ curl http://$(minikube ip):31245

2

та же проблема:

os> kubectl получить svc right-sabertooth-wordpress

ИМЯ ТИП КЛАСТЕР-IP ВНЕШНИЙ IP-ПОРТ ( )
right-sabertooth-wordpress LoadBalancer 10.97.130.7 "ожидающий" 80: 30454 / TCP, 443: 30427 / TCP

os> список сервисов minikube

| ------------- | ---------------------------- | ------ -------------------------- |

| NAMESPACE | ИМЯ | URL |

| ------------- | ---------------------------- | ------ -------------------------- |

| по умолчанию | кубернетес | Нет порта узла |

| по умолчанию | правый-саблезубый-мариадб | Нет порта узла |

| по умолчанию | правый-саблезубый-wordpress | http://192.168.99.100:30454 |

| | | http://192.168.99.100:30427 |

| кубе-система | кубе-днс | Нет порта узла |

| кубе-система | мотоблок | Нет порта узла |

| ------------- | ---------------------------- | ------ -------------------------- |

Однако он доступен через http://192.168.99.100:30454 .


2

После ответа @Javier. Я решил пойти с «исправлением внешнего IP» для моего балансировщика нагрузки.

 $ kubectl patch service my-loadbalancer-service-name \
-n lb-service-namespace \
-p '{"spec": {"type": "LoadBalancer", "externalIPs":["192.168.39.25"]}}'

Это заменит этот «ожидающий» новый исправленный IP-адрес, который вы можете использовать для своего кластера.

Подробнее об этом. См. Сообщение karthik о поддержке LoadBalancer с помощью Minikube для Kubernetes.

Не самый чистый способ сделать это. Мне нужно было временное решение. Надеюсь, это кому-то поможет.


2

Используйте NodePort:

$ kubectl run user-login --replicas=2 --labels="run=user-login" --image=kingslayerr/teamproject:version2  --port=5000

$ kubectl expose deployment user-login --type=NodePort --name=user-login-service

$ kubectl describe services user-login-service

(Запишите порт)

$ kubectl cluster-info

(IP-> Получить IP-адрес, на котором работает мастер)

Ваш сервис доступен по адресу (IP) :( порт)


1

При использовании Minikube вы можете получить IP-адрес и порт, через которые вы можете получить доступ к службе, запустив службу minikube kubia-http.



1

LoadBalancer ServiceType будет работать только в том случае, если базовая инфраструктура поддерживает автоматическое создание балансировщиков нагрузки и имеет соответствующую поддержку в Kubernetes, как в случае с Google Cloud Platform и AWS. Если такая функция не настроена, поле IP-адреса LoadBalancer не заполняется и все еще находится в состоянии ожидания, и Служба будет работать так же, как Служба типа NodePort.


1

Вы можете исправить IP-адрес узла, на котором размещены поды (частный IP-адрес узла), это простой обходной путь.

Ссылаясь на приведенные выше сообщения, для меня сработало следующее:

kubectl patch service my-loadbalancer-service-name \ -n lb-service-namespace \ -p '{"spec": {"type": "LoadBalancer", "externalIPs": ["xxx.xxx.xxx.xxx Private IP физического сервера - узел - где выполняется развертывание "]}} '


0

удалить существующую службу и создать такую ​​же новую службу решила мои проблемы. Моя проблема в том, что Ip балансировки нагрузки, который я определяю, используется так, что внешняя конечная точка ожидает обработки. Когда я сменил новый IP-адрес для балансировки нагрузки, он все еще не работал. Наконец, удаление существующей службы и создание новой решило мою проблему.


0

Проверьте логи kube-controller. Мне удалось решить эту проблему, установив теги clusterID для экземпляра ec2, на котором я развернул кластер.


0

Если это ваш частный кластер k8s, MetalLB подойдет лучше. Ниже приведены шаги.

Шаг 1. Установите MetalLB в свой кластер

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yaml
# On first install only
kubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"

Шаг 2. Настройте его с помощью configmap

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 172.42.42.100-172.42.42.105 #Update this with your Nodes IP range 

Шаг 3: Создайте свою службу для получения внешнего IP (хотя это будет частный IP).

FYR:

Перед установкой MetalLB: введите описание изображения здесь

После установки MetalLB: введите описание изображения здесь

введите описание изображения здесь


0

Добавление решения для тех, кто столкнулся с этой ошибкой при работе на ,

Прежде всего запустите:

kubectl describe svc <service-name>

А затем просмотрите eventsполе в примере вывода ниже:

Name:                     some-service
Namespace:                default
Labels:                   <none>
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"some-service","namespace":"default"},"spec":{"ports":[{"port":80,...
Selector:                 app=some
Type:                     LoadBalancer
IP:                       10.100.91.19
Port:                     <unset>  80/TCP
TargetPort:               5000/TCP
NodePort:                 <unset>  31022/TCP
Endpoints:                <none>
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type     Reason                  Age        From                Message
  ----     ------                  ----       ----                -------
  Normal   EnsuringLoadBalancer    68s  service-controller  Ensuring load balancer
  Warning  SyncLoadBalancerFailed  67s  service-controller  Error syncing load balancer: failed to ensure load balancer: could not find any suitable subnets for creating the ELB

Просмотрите сообщение об ошибке:

Failed to ensure load balancer: could not find any suitable subnets for creating the ELB

В моем случае причиной отсутствия подходящих подсетей для создания ELB были:

1: Кластер EKS был развернут не в той группе подсетей - внутренние подсети, а не общедоступные.
(*) По умолчанию службы типа LoadBalancerсоздают общедоступные балансировщики нагрузки, если service.beta.kubernetes.io/aws-load-balancer-internal: "true"аннотация не была предоставлена).

2: подсети не были помечены в соответствии с указанными здесь требованиями .

Пометка VPC с помощью:

Key: kubernetes.io/cluster/yourEKSClusterName
Value: shared

Пометка общедоступных подсетей с помощью:

Key: kubernetes.io/role/elb
Value: 1
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.