sshpiper 在 Kubernetes 上的应用

这篇具有很好参考价值的文章主要介绍了sshpiper 在 Kubernetes 上的应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

sshpiper 在 Kubernetes 上的应用

介绍

GitHub Repo

一个反向代理目标服务器的 proxy,客户端想请求某个 ssh 服务器,直接请求的是 sshpiper 服务,再经由 sshpiper 服务转发到对应的 ssh 服务器,相当于一个中间人。

一开始并不理解这种组件的用处,但实际用了之后感觉还是蛮有意思的。

设想有这样一种场景,你有多个 ssh 服务器,你可能要不停切换 ssh 服务器,这过程中有可能使用不同的 ssh 秘钥来连接。而且如果是想从公司外网连进来,ssh 服务器的端口要对外网开放,会有很大的安全隐患。

ssh 可以通过密码、秘钥两种方式鉴权连接,密码方式相对简单,我也主要是使用秘钥模式连接的,这里主要介绍秘钥连接。

原理

完成整个连接过程,需要有两套秘钥(即两套公钥私钥),我们这里分别称为 PublicKey_X,PrivateKey_X,PublicKey_Y,PrivateKey_Y,其中:

  • PrivateKey_X 由客户端持有
  • PublicKey_X 由 sshpiper 持有(在 k8s 中由集群保存)
  • PrivateKey_Y 由 sshpiper 持有(在 k8s 中由集群保存)
  • PublicKey_Y 由 ssh 服务器持有 (写入 .ssh/authorized_keys 中)

客户端持 PrivateKey_X ssh 请求 sshpiper,sshpiper 使用 PublicKey_X 进行校验,校验之后 sshpiper 持 PrivateKey_Y 请求服务器,服务器持 PublicKey_Y 进行校验。

此处提及的 ssh 密钥,公钥均为 ssh-rsa XXXXXX 形式,私钥均为 pem 形式,即类似:-----BEGIN PRIVATE KEY----- 开头,-----END PRIVATE KEY----- 结尾

优点(个人总结)

  • ssh 服务器均可以不暴露外网端口,所有外网请求由 sshpiper 代理即可。
  • 可以使用同一套 PrivateKey_XPublicKey_X 登录多台服务器。
  • 可以利用 PublicKey_X, PrivateKey_X 更好地控制 ssh 访问服务器的权限。

Kubernetes 上的应用

目标:运行一个可以通过 sshpiper 访问的 pod。

安装

在 kubernetes Pod 中使用 sshpiper,先按照此处文档在集群中安装和部署 sshpiper 服务:

https://github.com/tg123/sshpiper/tree/master/plugin/kubernetes

我使用了手动安装,共两步:

  1. 安装 CRD
  2. 启动 sshpiper 服务

启动 sshpiper 服务时,使用如下 yaml 配置:

# sshpiper service
---
apiVersion: v1
kind: Service
metadata:
  name: sshpiper
spec:
  selector:
    app: sshpiper
  ports:
    - protocol: TCP
      port: 2222
      targetPort: 2222
      nodePort: 30022
  type: NodePort
---
apiVersion: v1
data:
  server_key: | # 此配置暂时没发现用处,直接使用官方提供的样例中的值即可
    LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNCWUhWV01lNzVDZ3Rzdm5rOWlTekJFU3hSdjdMb3U3K0tVbndmb3VnNzcxZ0FBQUpEQnArS0d3YWZpCmhnQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDQllIVldNZTc1Q2d0c3ZuazlpU3pCRVN4UnY3TG91NytLVW53Zm91Zzc3MWcKQUFBRUJKSDU3eTFaRTUxbVo2a2VsWUR0eDQ1ajBhZGdsUk5CY0pZOE94YTY4TEJWZ2RWWXg3dmtLQzJ5K2VUMkpMTUVSTApGRy9zdWk3djRwU2ZCK2k2RHZ2V0FBQUFEV0p2YkdsaGJrQjFZblZ1ZEhVPQotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K
kind: Secret
metadata:
  name: sshpiper-server-key
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sshpiper-deployment
  labels:
    app: sshpiper
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sshpiper
  template:
    metadata:
      labels:
        app: sshpiper
    spec:
      serviceAccountName: sshpiper-account
      containers:
      - name: sshpiper
        imagePullPolicy: IfNotPresent
        image: farmer1992/sshpiperd:latest
        ports:
        - containerPort: 2222
        env:
        - name: PLUGIN
          value: "kubernetes"
        - name: SSHPIPERD_SERVER_KEY
          value: "/serverkey/ssh_host_ed25519_key"
        - name: SSHPIPERD_LOG_LEVEL
          value: "trace"
        volumeMounts:
        - name: sshpiper-server-key
          mountPath: "/serverkey/"
          readOnly: true          
      volumes:
      - name: sshpiper-server-key
        secret:
          secretName: sshpiper-server-key
          items:
          - key: server_key
            path: ssh_host_ed25519_key
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: sshpiper-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
- apiGroups: ["sshpiper.com"]
  resources: ["pipes"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-sshpiper
subjects:
- kind: ServiceAccount
  name: sshpiper-account
roleRef:
  kind: Role
  name: sshpiper-reader
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sshpiper-account
  1. 官方样例这里 Service 使用了默认的 ClusterIP 类型,但如果要通过外网访问,需要使用 LoadBalancer 或 NodePort 类型。我使用了 NodePort 类型,并映射给了 30022 端口
  2. 官方样例设置了一个 Secret sshpiper-server-key, 但并没有说明其用处。不过这个似乎对使用 sshpiper 没有影响,直接填充官方给的默认值即可。默认值在 ReadMe 中没有给出,可以看上面给的 github 路径下的 sample.yaml 文件

启动成功后如下图:

sshpiper 在 Kubernetes 上的应用

镜像准备

由于需要访问 ssh 服务,所有业务 Pod 的基础镜像需要运行 ssh 服务并暴露 ssh 接口。还需要将 PublicKey_Y 写入目标容器的 .ssh/authorized_keys 文件中。

这里我用官方使用的 lscr.io/linuxserver/openssh-server:latest 镜像,它提供了 PUBLIC_KEY 环境变量,在启动时自动将其中配置的 public_key 写入 .ssh/authorized_keys 文件中。

除此之外,亦可以通过设置 ConfigMap,将 public_key 挂载进容器的路径下。

启动容器

apiVersion: apps/v1
kind: Deployment
metadata:
  name: host-publickey
spec:
  replicas: 3
  selector:
    matchLabels:
      app: host-publickey
  template:
    metadata:
      labels:
        app: host-publickey
    spec:
      containers:
      - name: host-publickey
        image: lscr.io/linuxserver/openssh-server:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 2222
        env:
        - name: USER_NAME
          value: "user"
        - name: PUBLIC_KEY
          value: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDgMF4AKRaRf3V2+6T7rluYW37t5TwuQDcdT966jKhKNHBkLHuT/YhBuWkpHuGR3Wh3S3zGAZ73vZ8zJHXsOPmBakkxPa9lqSHMj7Y0mN/0XvpcIHIdphzKUiEIP65N6OG2ZtYaZYti8wDNs1rW+V2Vx5IlOcT8IiNQ5FNvOozS9w=="
---
apiVersion: v1
kind: Service
metadata:
  name: host-publickey
spec:
  selector:
    app: host-publickey
  ports:
    - protocol: TCP
      port: 2222
  1. USER_NAME 字段会为你自动创建对应的用户。
  2. PUBLIC_KEY 字段填写的是 ssh 公钥明文,非 pem 形式。这里填入的就是上面所说的 PublicKey_Y

创建 pipe

pipe 就是第一步安装中安装的 CRD。它负责定义 from 和 to 的相关信息,以及保存前面提到的 PublicKey_XPrivateKey_Y

apiVersion: v1
data:
  ssh-privatekey: |
    LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlDWGdJQkFBS0JnUURnTUY0QUtSYVJmM1YyKzZUN3JsdVlXMzd0NVR3dVFEY2RUOTY2aktoS05IQmtMSHVUCi9ZaEJ1V2twSHVHUjNXaDNTM3pHQVo3M3ZaOHpKSFhzT1BtQmFra3hQYTlscVNITWo3WTBtTi8wWHZwY0lISWQKcGh6S1VpRUlQNjVONk9HMlp0WWFaWXRpOHdETnMxclcrVjJWeDVJbE9jVDhJaU5RNUZOdk9velM5d0lEQVFBQgpBb0dCQU5ZcG5rS3MvYUEwa0hQL1pOWUE5QU1SdEtseHlSR3R5bmkzNmQ5dnF2eG9KODJxS010dzhROUlIY3RvCmNyZXpPSzV0Y0Y1L0FldE1PNTdSZjgwUGlGaHNvenowWnJkU2dzNXNZa2N4aS9CQTNBa05UNXh4aVo0STQxOEoKRStVemZnVDFOT0Y5bnNzbWoxQWVnNlJ1d3RYbVJkWElRUm1wcEtVVjBNcENERGJoQWtFQStiTk0wQzhxaHFpeQpyVWg0VFpSUWhGc0FyRTMzL1NoVzNobU5pdUd0Qjc3QnVXSFBWVDlnaDFpV0Mwby9CV0FSZUlSR05WbUdhZGtTClUxZCswdk8wdVFKQkFPWFlUT1dLZEd6MWZKVGJNWDdnNUVsRmV0NVpEV3hwZFEzWWpiUEQzRDg2cDNaN1JrVHMKQ1RQdDd1VjVzZXpZZWJKK1B5SnI5WVEzOXBybm02S0xUUzhDUUhVZEpYL1hQMmpkSXNDblp0VnNKTCtQTnllWgpnaUNZbFBXaW9vSnJDbzdCWjNjZGF2TWV3SlY2ZFJWaWcyQndDSUd2K0lYNU1WUGYzZnA4NVJ6bjlQRUNRUURiClhvU1dHSDFpZVRLOGlEQkhYckhEMVJLZUlQU1U0bG9jS3ZHai8yMjQwMng5d3M2Z2ZYK1RGcWFLVW9vaytiKzkKUW8xVGR5TFBYUEo3aWs2YTVzVjFBa0VBN1FPc1lPZ0FXeFZzbCttdFBva3VkS3FUa2lYaDNVNFp5Si8zWDZ5YgpwVjVkQWtLQlRMdjVwMFdEQlcyVDB5UmpaMGNDME01ckkyMHI2ejdnWktCeFJnPT0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0=
kind: Secret
metadata:
  name: host-publickey-key
type: kubernetes.io/ssh-auth
---
apiVersion: sshpiper.com/v1beta1
kind: Pipe
metadata:
  name: pipe-publickey
  annotations:
    privatekey_field_name: ssh-privatekey # this is optional, default is ssh-privatekey
spec:
  from:
  - username: "test"
    authorized_keys_data: "c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCQVFERThzZnBiOXkweVNRMTRsaWpQNnc5QWg2UEF6SC9hdGdXVDB5c3NZL29aSGJONDlwUHk4OWt1NC9ndmUwWEZOcE5HMGN2aThOQ3J5aDdNNDBZWnN1KzlXY1BpR2RXRnVuVG4xMGhWWmVQaGhTQk5WUVByMU16dy9MNHpTb3U2amozdWh4aHI1a3pNdi9pbWY1WFFHT2U5WEVKaTBoK29lbVlPUkxybUNvKzhWUFkvb29SL2tIY3J5L3ZuVVdoek1GYzNXMC9Pck80Q2ZvUlBnc1VabGREVnZmU0toUnlQQllISkJhaHUza0xLWC9VRk9ZRnRzd2lZTWtMWHpwY0JjSmJnUDE0RHFaNGIxZEhmZHp5MGZCYThyTVJFWEI5NHErNlhnV1cvRDlKbUQzaURQd2pRengySVRTZXRCSUlhYjlvYWkzRWd0TTdDQk13ZE5tdk5mQXQgNzYwNzUyNTgwQHFxLmNvbQo="
  to:
    host: 10-244-3-30.default.pod.cluster.local:2222
    username: "user"
    private_key_secret:
      name: host-publickey-key
    ignore_hostkey: true

Piper 中所填写的 privateKey,

  1. Secret 中定义即为 PrivateKey_Y,经过 base64 编码,用于填写在 to 中,作为 sshpiper 与目标服务器之间的校验。
  2. Pipe.spec.from.username 是 ssh 请求 sshpiper 的 username,如: ssh username@sshpiper-ip -p 30022 -i private_key.pem。这里亦可以填写正则匹配,需要设置 Pipe.spec.from.username_regex_match: true
  3. Pipe.spec.from.authorized_keys_data 保存 PublicKey_Xbase64 编码,用于客户端发起请求时,sshpiper 会取的这个公钥与用户的 private_key.pem 进行验证
  4. Pipe.spec.to.host 是 k8s 集群中任何能路由到 Pod 的方式,可以直接是 Pod 的 ip,也可以是集群内部支持的域名,可以被集群 DNS 解析,也可以是 Pod 的 Service 对应的域名或路由。参考:https://kubernetes.io/zh-cn/docs/concepts/services-networking/dns-pod-service/#pod
  5. Pipe.spec.to.username 为登录到目标服务器上所用的用户名,这个用户名需要存在于目标服务器
  6. Pipe.spec.to.private_key_secret 指定了上面定义的 Secret,用于 sshpiper 与目标服务器之间的校验。

注意:

  • 如果 Pipe.spec.to.host 填写的是 Service 路由,那么每次 ssh 时,进入的 Pod 可能时 Service 管理下的任何一个 Pod。
  • 此处所填公钥私钥,均为其 base64 编码形式。

上面我使用 pod-ip-addres.namespace.pod.cluster-domain.example 方式作为 to.host 。创建 pipe 之后,通过命令 ssh test@sshpiperIP -p 30022 -i ~/.ssh/id_rsa

sshpiper 在 Kubernetes 上的应用文章来源地址https://www.toymoban.com/news/detail-569464.html

  • 如果 sshpiper Service 为 NodePort 类型,这里 sshpiperIP 即为 nodeIP,port 即为 nodePort
  • 如果真实的生产环境中,这里肯定要用上 LoadBalance,或者 nginx、ingress 等组件,以及配置域名解析等方式来代替明文 NodeIP。

应用场景和业务流程

  1. 有长期运行的 Pod,而且用户可能频繁进入 Pod 内部进行调试和开发工作。
  2. 此时用户相当于 client。
  3. 一般要搭配 ssh 管理模块使用。
    1. 创建 ssh 密钥,将私钥返回给用户,作为 client 的 PrivateKey_X,提醒用户妥善保管
    2. ssh 模块保存公钥,即 PublicKey_X,但不保存 PrivateKey_X,私钥一旦丢失,密钥将无法正常使用。
    3. 创建 Pod 时,列出已有 ssh 密钥,用户可选择自己手中已持有的密钥,也可以新创建一对 ssh 密钥。
    4. 点击确认,系统后台再生成一对 ssh 密钥,作为 PublicKey_YPrivateKey_Y
    5. PublicKey_Y 绑定入 Pod authorized_keys 中,同时使用 PublicKey_YPublicKey_X 创建 Pipe 资源
  4. 创建成功后,用户可使用所持 PrivateKey_X 成功登入 Pod 中。

到了这里,关于sshpiper 在 Kubernetes 上的应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 电能计量管理系统在煤矿上的应用

    摘要: 随着煤矿供电系统管、控一体化的发展需要,本文提出了一种基于矿井光纤网络构成的煤矿电参数计量系统,该系统具有实现变电所各类开关、动力设备的用电高精度计量;远程实时监测各路电参数;远程抄表;远程监控重点用电设备的运行状况等功能,提高了煤炭生

    2023年04月27日
    浏览(28)
  • 知识图谱实战应用17-推荐系统在婚恋交友项目上的实际应用

    大家好,我是微学AI, 今天给大家介绍一下知识图谱实战应用17-推荐系统在婚恋交友项目上的实际应用,推荐系统在婚恋交友项目中的应用可以大大提高用户的匹配效果和满意度。通过利用大数据和智能算法分析用户需求、行为和反馈,推荐系统能够为用户找到更符合他们期

    2024年02月15日
    浏览(63)
  • 机器视觉系统在汽车车轮毂检测上的应用

    将机器视觉用于轮毂检测,可以利用图像分析的方法来测量轮毂特征尺寸、判断轮毂形状,并获取其位置坐标等信息,从而能够辨识流水生产线上的各种款式和型号的汽车轮毂。   市面上对汽车车轮毂具体检测要求如下 : 1.为了分辨流水线上不同类型的轮毂,大约有30种不同

    2024年01月21日
    浏览(37)
  • Dagger2和它在SystemUI上的应用,附答案

    @Override public Application instantiateApplicationCompat( @NonNull ClassLoader cl, @NonNull String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = super.instantiateApplicationCompat(cl, className); if (app instanceof ContextInitializer) { // 注册Context成功取得的回调 ((ContextInitializer)

    2024年04月09日
    浏览(27)
  • 机器学习笔记 - 深度学习在网球运动分析上的应用

            观看网球比赛时,您可以根据中间或角落的发球次数、球的深度、向左或向右的偏好来自动丰富视图,具体取决于球员所处的位置。此类统计数据可以通过 Hawk-Eye、IBM Slamtracker 等工具提供。         Hawk-Eye 是一个复杂的系统,由多达 10 个高速摄像头组成,能

    2024年02月16日
    浏览(31)
  • 机器视觉检测在流水线上的技术应用

    机器视觉在流水线上的应用机器视觉系统的主要功能可以简单概括为:定位、识别、测量、缺陷检测等。相对于人工或传统机械方式而言,机器视觉系统具有速度快、精度高、准确性高等一系列优点。随着工业现代化发展,机器视觉已经广泛应用于各大领域。为企业及用户提

    2024年02月08日
    浏览(27)
  • 差分升级在物联网水表上的实现与应用(学习)

    当越来越多的物联网水表加入抄表系统后,实现了水表数据的信息化,并且当水表终端需要技术更新时,通过网络方式来升级产品可以高效修复设备面临的问题,减少用户损失,降低维护成本,但同时也对有限的网络资源形成负担。 当前终端的无线远程升级技术多采用单一的

    2024年02月13日
    浏览(35)
  • 数字化孪生技术在工业上的应用场景和案例分享

    编者按:数字化孪生是一个完整的生命周期概念,它从设计和制造开始,贯穿整个生产过程,直到产品退役。数字化孪生将现实世界和虚拟世界相结合,使企业能够更好地理解和优化物理系统的运行情况,从而提高生产效率,降低成本,并提高产品质量和客户满意度。在工业

    2024年02月04日
    浏览(36)
  • 通话降噪算法在手机和IOT设备上的应用和挑战

    随着电子产品的升级换代,用户对通话质量的要求也越来越高。通话降噪算法对通话质量起到了关键核心的作用。计算资源的提升使得深度学习模型在便携式的低功耗芯片上面跑起来了,器件成本降低让IoT设备开始使用骨导传感器,,那怎么样才能将深度学习和传统算法结合

    2024年02月14日
    浏览(33)
  • LLM在text2sql上的应用

    目前,大模型的一个热门应用方向text2sql它可以帮助用户快速生成想要查询的SQL语句。那对于用户来说,大部分简单的sql都是正确的,但对于一些复杂逻辑来说,需要用户在产出SQL的基础上进行简单修改,Text2SQL应用主要还是帮助用户去解决开发时间,减少开发成本。 Text to

    2024年02月08日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包