Ожидается внешний 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.