Я пока работаю над настройкой кластера Kubernetes. Моя установка состоит из двух узлов и одного мастера. Все три машины работают в кластере Proxmox и имеют 2 виртуальных сетевых интерфейса. Один из интерфейсов (перечисленных ниже) находится в мостовой сети с другими машинами. Другой открыт для внутренней сети.
Настройка сети для мостовых интерфейсов выглядит следующим образом:
Network: 10.10.0.0
Broadcast: 10.10.255.255
Netmask: 255.255.0.0
kubernetes-master IP: 10.10.0.1
kubernetes-worker01 IP: 10.10.0.2
kubernetes-worker02 IP: 10.10.0.3
Все серверы могут без проблем разговаривать друг с другом. Я еще не настраивал брандмауэр.
root@kubernetes-master:~/manifests# kubectl get nodes
NAME STATUS AGE
10.10.0.2 Ready 5d
10.10.0.3 Ready 5d
У меня есть приложение hello world nodeJS, которое предоставляет HTTP-сервер на порт 8080 и отображает «Hello world» при запросе. Это настроено так:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-node-deployment
spec:
replicas: 4
template:
metadata:
labels:
app: hello-node
spec:
containers:
- name: hello-node
image: kubernetes-master:5000/hello-node:v1
ports:
- containerPort: 8080
Затем я создал новую службу, которая должна предоставлять развертывание через NodePort.
apiVersion: v1
kind: Service
metadata:
name: hello-node-service
labels:
app: hello-node
spec:
ports:
- port: 8080
protocol: TCP
selector:
app: hello-node
type: NodePort
После запуска службы и развертывания:
root@kubernetes-master:~/manifests# kubectl describe service hello-node-service
Name: hello-node-service
Namespace: default
Labels: app=hello-node
Selector: app=hello-node
Type: NodePort
IP: 10.100.0.88
Port: <unset> 8080/TCP
NodePort: <unset> 30862/TCP
Endpoints: 192.168.0.22:8080,192.168.0.23:8080,192.168.0.89:8080 + 1 more...
Session Affinity: None
No events.
root@kubernetes-master:~/manifests# kubectl get pods --selector="app=hello-node" --output=wide
NAME READY STATUS RESTARTS AGE IP NODE
hello-node-deployment-815057587-0w896 1/1 Running 0 24m 192.168.0.89 10.10.0.2
hello-node-deployment-815057587-62d2b 1/1 Running 0 24m 192.168.0.23 10.10.0.3
hello-node-deployment-815057587-d6t4z 1/1 Running 0 24m 192.168.0.90 10.10.0.2
hello-node-deployment-815057587-k7qcx 1/1 Running 0 24m 192.168.0.22 10.10.0.3
После этого мастер не может связаться ни с одним из узлов на предоставленном порту узла (10.10.0.2:30862, 10.10.0.2:30862). Соединение зависает и не удается.
Если я подключаюсь к узлу через ssh, я могу успешно запросить службу, напрямую поговорив с модулем:
root@kubernetes-worker02:~# curl http://192.168.0.22:8080
Hello World!
Я что-то упустил? Это ожидаемое поведение или мои настройки нарушены?
Kubernetes требует больше, чем просто возможность общения узлов друг с другом. Также требуется сеть (или таблица маршрутизации), чтобы модули могли общаться друг с другом. По сути, это другая сеть только для модулей (часто называемая сетью наложения / основы), которая позволяет модулю на nodeA взаимодействовать с модулями на nodeB.
Судя по всему, у вас не настроена сеть модулей. Вы можете реализовать наложение сети множеством способов (что является одной из причин, по которой это так сбивает с толку). Узнать больше о сетевых требованиях Вот.
Имея всего 2 узла, я бы порекомендовал вам настроить то, что я называю «no SDN Kubernetes», и просто вручную добавлять маршруты модулей к каждому узлу. Это потребует от вас сделать 2 вещи.
У меня есть подробности, как это сделать на моем сообщение в блоге, которое я написал на эту тему.
К сожалению, настройка сети модулей поможет вам добиться этого только наполовину. Чтобы реализовать автоматические службы NodePort, вам также необходимо установить kube-proxy. Задача kube-proxy - следить за тем, на каком порту запускается служба, и затем направлять этот порт в нужную службу / модуль внутри кластера. Это делается через IP-таблицы и в основном происходит автоматически.
Мне не удалось найти очень хороший пример развертывания kube-proxy вручную (обычно это выполняется с помощью вашего инструмента развертывания). Вот пример DaemonSet в Кубеадм Инструмент должен автоматически создать для запуска kube-proxy на каждом узле кластера.
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
generation: 1
labels:
component: kube-proxy
k8s-app: kube-proxy
kubernetes.io/cluster-service: "true"
name: kube-proxy
tier: node
name: kube-proxy
namespace: kube-system
spec:
selector:
matchLabels:
component: kube-proxy
k8s-app: kube-proxy
kubernetes.io/cluster-service: "true"
name: kube-proxy
tier: node
template:
metadata:
labels:
component: kube-proxy
k8s-app: kube-proxy
kubernetes.io/cluster-service: "true"
name: kube-proxy
tier: node
spec:
containers:
- command:
- kube-proxy
- --kubeconfig=/run/kubeconfig
image: gcr.io/google_containers/kube-proxy-amd64:v1.5.2
imagePullPolicy: IfNotPresent
name: kube-proxy
securityContext:
privileged: true
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /var/run/dbus
name: dbus
- mountPath: /run/kubeconfig
name: kubeconfig
dnsPolicy: ClusterFirst
hostNetwork: true
restartPolicy: Always
terminationGracePeriodSeconds: 30
volumes:
- hostPath:
path: /etc/kubernetes/kubelet.conf
name: kubeconfig
- hostPath:
path: /var/run/dbus
name: dbus
Еще один ресурс, который может оказаться полезным: Kubernetes: трудный путь. Это напрямую не применимо к запуску в виртуальных машинах на proxmox (предполагается, что GCE или AWS), но показывает минимальные шаги и ресурсы, необходимые для запуска работающего кластера Kubernetes.