Как запустить SSH в Kubernetes?

#kubernetes #ssh #openssh #sshd

Вопрос:

Я пытаюсь запустить sshd в своем кластере Kubernetes, чтобы я мог настроить обратный туннель прокси/ngrok в соответствии с этим сообщением в блоге.

У меня работает nginx, но я не могу подключиться к SSH.

Вот полная конфигурация Kubernetes:

 apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: dev-example-ingress
  namespace: dev-example
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - dev.example.ca
      secretName: dev-example-tls
  rules:
    - host: dev.example.ca
      http:
        paths:
          - backend:
              serviceName: app-service
              servicePort: 80
          - backend:
              serviceName: app-service
              servicePort: 2222
---
apiVersion: v1
kind: Service
metadata:
  name: app-service
  namespace: dev-example
spec:
  selector:
    pod: my-pod-label
  ports:
    - name: http
      protocol: TCP
      port: 80
    - name: ssh-tcp
      protocol: TCP
      port: 2222
#    - name: ssh-udp
#      protocol: UDP
#      port: 2222
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
  namespace: dev-example
spec:
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      pod: my-pod-label
  template:
    metadata:
      labels:
        pod: my-pod-label
    spec:
      imagePullSecrets:
        - name: regcred
      containers:
        - name: nginx
          image: dreg.example.ca/example/dev.example.ca
          ports:
            - name: http
              containerPort: 80
        - name: sshd
          image: linuxserver/openssh-server
          ports:
            - name: ssh
              containerPort: 2222
          env:
            - name: PUID
              value: '1000'
            - name: PGID
              value: '1000'
            - name: TZ
              value: America/Los_Angeles
            - name: USER_NAME
              value: example
            - name: USER_PASSWORD
              value: test
 

Но когда я пытаюсь подключиться, он говорит «соединение отказано».:

 ❯ ssh -p 2222 example@dev.example.ca
ssh: connect to host dev.example.ca port 2222: Connection refused
 

Я не знаю, означает ли это, что я неправильно раскрыл порт или что.

Я почти уверен linuxserver/openssh-server , что он работает на порту 2222. Если я побегу ps -aux в этом контейнере, я получу:

 ^@root@app-deployment-5d9567dcc5-f5hq6:/# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0    200     4 ?        Ss   19:26   0:00 s6-svscan -t0 /var/run/s6/services
root        34  0.0  0.0    200     4 ?        S    19:26   0:00 s6-supervise s6-fdholderd
root       277  0.0  0.0    200     4 ?        S    19:26   0:00 s6-supervise openssh-server/log
root       278  0.0  0.0    200     4 ?        S    19:26   0:00 s6-supervise openssh-server
mpen       280  0.0  0.0    256     4 ?        Ss   19:26   0:00 s6-log n30 s10000000 S30000000 T !gzip -nq9 /config/logs/openssh
mpen       281  0.0  0.0   4384  3480 ?        Ss   19:26   0:00 sshd: /usr/sbin/sshd -D -e -p 2222 [listener] 0 of 10-100 startups
root       298  0.5  0.0   2580  2304 pts/0    Ss   19:32   0:00 bash
root       307  0.0  0.0   1640   868 pts/0    R    19:32   0:00 ps -aux
 

Что я упускаю?

Я открыт для использования других образов докеров ssh, если они работают лучше/проще. Это только для дэва.

Ответ №1:

Входная система работает только для HTTP (некоторые контроллеры входа поддерживают базовую маршрутизацию TCP в качестве пользовательского расширения, но вы просто используете основы). SSH не является протоколом на основе HTTP 🙂 Вместо этого вам нужна служба с типом LoadBalancer.

Комментарии:

1. Хмм. Поэтому я использую диаграмму nginx-ingress для своего балансировщика нагрузки. Я вижу, что там есть controller.service.customPorts опция , которую, как я полагаю, я могу использовать для добавления SSH/порта 22. Но что тогда? Могу ли я просто добавить свой сервис, как указано выше, и он найдет его?

2. Просто, просто добавьте type: LoadBalancer , и это должно сработать. Вы увидите общедоступный IP-адрес в информации об услуге.

Ответ №2:

Ресурс Kubernetes Ingress не предназначен для поддержки служб TCP или UDP. Тем не менее, некоторые Ingress реализации предоставляют механизмы для поддержки TCP или UDP на разных портах. Если вы используете входной контроллер NGINX, вы можете открыть порты TCP или UDP, изменив ConfigMaps их .

Чтобы настроить контроллер входа NGINX для их ConfigMaps использования, вам необходимо настроить их при развертывании контроллера с использованием аргументов --tcp-services-configmap и --udp-services-configmap . Каждый ConfigMap из них уже должен быть доступен до развертывания контроллера.

Затем вы можете определить свои пользовательские порты, определив карту портов для служб.

Например, если вы определяли входной контроллер NGINX с помощью файлов манифеста, вы должны настроить DaemonSet его для контроллера следующим образом:

 apiVersion: apps/v1
kind: DaemonSet
metadata:
  # metadata configuration...
spec:
  # spec configuration...
  containers:
    - image: k8s.gcr.io/ingress-nginx/controller:$TAG
      name: nginx-ingress-microk8s
      # container configuration...
      args:
        - /nginx-ingress-controller
        - --tcp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-tcp-services
        - --udp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-udp-services
        # other arguments...
 

Вот пример ConfigMap , взятый непосредственно из документов:

 apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  9000: "default/example-go:8080"
 

Вы можете определить любое количество портов, которые могут быть открыты с помощью этого механизма. Однако я никогда не использовал эту конфигурацию с SSH для предоставления портов системного журнала.