Развертывание NFS-сервера в K8S и раскрытие его извне
Я нахожусь в процессе настройки сервера NFS на моем кластере K8S. Я хочу, чтобы он действовал как NFS-сервер для внешних объектов, т.е. клиент будет находиться за пределами кластера K8S, такого как виртуальные машины.
Требования к порту для образа Docker:
==================================================================
SERVER STARTUP COMPLETE
==================================================================
----> list of enabled NFS protocol versions: 4.2, 4.1, 4
----> list of container exports:
----> /exports *(rw,no_subtree_check)
----> list of container ports that should be exposed:
----> 111 (TCP and UDP)
----> 2049 (TCP and UDP)
----> 32765 (TCP and UDP)
----> 32767 (TCP and UDP)
Итак, я создал образ докера Debian Stretch. Когда я запускаю его, используя docker run
Я могу успешно выставить /exports
и смонтировать его из других систем.
docker run -v /data:/exports -v /tmp/exports.txt:/etc/exports:ro \
--cap-add SYS_ADMIN -p 2049:2049 -p 111:111 -p 32765:32765 \
-p 32767:32767 8113b6abeac
Приведенная выше команда раскручивает мой док-контейнер, и когда я делаю
mount.nfs4 <DOKCER_HOST_IP>:/exports /mount/
с другой виртуальной машины я могу успешно смонтировать том.
Так что все до тех пор, пока здесь все в порядке!
Теперь задача состоит в том, чтобы развернуть это в K8S.
Мое определение набора состояний:
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: nfs-provisioner
spec:
selector:
matchLabels:
app: nfs-provisioner
serviceName: "nfs-provisioner"
replicas: 1
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccount: nfs-provisioner
terminationGracePeriodSeconds: 10
imagePullSecrets:
- name: artifactory
containers:
- name: nfs-provisioner
image: repository.hybris.com:5005/test/nfs/nfs-server:1.2
ports:
- name: nfs
containerPort: 2049
- name: mountd
containerPort: 20048
- name: rpcbind
containerPort: 111
- name: rpcbind-udp
containerPort: 111
protocol: UDP
- name: filenet
containerPort: 32767
- name: filenet-udp
containerPort: 32767
protocol: UDP
- name: unknown
containerPort: 32765
- name: unknown-udp
containerPort: 32765
protocol: UDP
securityContext:
privileged: true
env:
- name: SERVICE_NAME
value: nfs-provisioner
- name: NFS_EXPORT_0
value: '/exports *(rw,no_subtree_check)'
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: export-volume
mountPath: /exports
volumes:
- name: export-volume
hostPath:
path: /var/tmp
Как видите, я указал все порты (как TCP, так и UDP)
А теперь, чтобы показать это внешнему миру, а не только внутри кластера, мой service.yaml
замедление файла:
kind: Service
apiVersion: v1
metadata:
name: nfs-provisioner
labels:
app: nfs-provisioner
spec:
type: NodePort
ports:
- name: nfs
port: 2049
- name: mountd
port: 20048
- name: rpcbind
port: 111
- name: rpcbind-udp
port: 111
protocol: UDP
- name: filenet
port: 32767
- name: filenet-udp
port: 32767
protocol: UDP
- name: unknown
port: 32765
- name: unknown-udp
port: 32765
protocol: UDP
selector:
app: nfs-provisioner
Это приводит к
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nfs-provisioner NodePort 10.233.43.135 <none> 2049:30382/TCP,20048:31316/TCP,111:32720/TCP,111:32720/UDP,32767:30173/TCP,32767:30173/UDP,32765:31215/TCP,32765:31215/UDP 32m
Сейчас пытаюсь смонтировать /exports
с другого узла / виртуальной машины, которая является внешней по отношению к кластеру K8S.
я пробовал
mount.nfs4 <K8S_Node_IP>:/exports /mount/
и я попробовал
mount.nfs4 -o port=<NodePort> <K8S_Node_IP>:/exports /mount/
Я пробовал каждый NodePort по одному. Но никто из них не работает. Я получаю ошибку:
mount.nfs4 -o port=31316 <K8S_Node_IP>:/exports /mount/
mount.nfs4: mount to NFS server '<K8S_Node_IP>:/exports' failed: RPC Error: Unable to receive
Я не уверен, в чем может быть проблема здесь. Это то, что мне нужно указать все nodePorts? Если так, как я могу это сделать?
1 ответ
Проблема здесь в том, что все NodePorts отличаются от внешнего вида от:
----> 111 (TCP and UDP)
----> 2049 (TCP and UDP)
----> 32765 (TCP and UDP)
----> 32767 (TCP and UDP)
Вы можете попробовать балансировщик нагрузки L4, который выставляет именно эти порты на заданный IP-адрес (внутренний или внешний) и перенаправляет их на порты узла (что type=LoadBalancer
тоже)
Другой вариант - жестко закодировать NodePorts в ваших сервисах так, чтобы они точно соответствовали контейнерам:
kind: Service
apiVersion: v1
metadata:
name: nfs-provisioner
labels:
app: nfs-provisioner
spec:
type: NodePort
ports:
- name: nfs
port: 2049
nodePort: 2049
- name: mountd
port: 20048
nodePort: 20048
- name: rpcbind
port: 111
nodePort: 111
- name: rpcbind-udp
port: 111
nodePort: 111
protocol: UDP
- name: filenet
port: 32767
nodePort: 32767
- name: filenet-udp
port: 32767
nodePort: 32767
protocol: UDP
- name: unknown
port: 32765
nodePort: 32765
- name: unknown-udp
port: 32765
nodePort: 32765
protocol: UDP
selector:
app: nfs-provisioner
Вам придется изменить диапазон nodePort ( --service-node-port-range
) на кубеле, хотя. Это так, что вы можете использовать 2049
а также 111
,
Вы также можете изменить порты, которые прослушивает ваш NFS-сервер 2049
(NFS) и 111
(portmapper), например, таким образом, вам не нужно менять --service-node-port-range