另辟蹊径打入kubernetes网络内访问服务
我们知道kubernetes外部访问服务只有四种:port-forward、Ingress、LoadBalancer、NodePort,那有没有一种直接进入到集群内访问服务?当然有,这里为大家提供一个思路及一个方法,大家可以尝试做做,该方法可以为你的工作提效。
我们知道kubernetes外部访问服务只有四种:port-forward、Ingress、LoadBalancer、NodePort,那有没有一种直接进入到集群内访问服务?当然有,这里为大家提供一个思路及一个方法,大家可以尝试玩玩,该方法可以为你的工作提效。
场景一:大家在k8s中是不是遇到,想到群集的应用导入数据时,发该服务没有暴露端口,想要导数据得先将服务暴露出来,这时需要先在k8s里创建LoadBalancer或NodePort,或者将原来ClusterIP改为LoadBalancer或NodePort才可以外部访问,或者使用port-forward。ingress这时更不好实现,ingress本身就是一个LoadBalancer,对TCP和UDP实现比较麻烦,端口多的时候无法招架。
场景二:我们想知道k8s集群内部各容器是否互访及内部域名是否互通,通常的做法是进入pod里面去ping、curl等操作,比较麻烦。
说明一下:场景一是外部访问问题,场景二是集群内部之间访问问题。
这种场景我是怎么解决的呢,思路很简单,就是将集群的流量代理出来,如http、vpn、socks等,这里举一个非常实用且简单的方法:跑一个能连sshd的pod就可以了。注意:使用sshd代理上网可能会遇到证书问题,所以大家不要用来代理上网。
ssh.yaml
1 apiVersion: apps/v1 2 kind: Deployment 3 metadata: 4 name: ssh 5 namespace: javalittleman 6 # labels: 7 # app: ssh 8 spec: 9 replicas: 1 10 template: 11 metadata: 12 labels: 13 app: ssh 14 spec: 15 containers: 16 - name: ssh 17 image: panubo/sshd 18 env: 19 - name: SSH_ENABLE_ROOT 20 value: "true" 21 - name: SSH_ENABLE_PASSWORD_AUTH 22 value: "true" 23 - name: MOTD 24 value: "欢迎登录" 25 # - name: DISABLE_SFTP 26 # value: "false" 27 - name: SSH_USERS 28 value: "userr:1000:1000,admin:48:48,root" 29 - name: GATEWAY_PORTS 30 value: "true" 31 - name: TCP_FORWARDING 32 value: "true" 33 # - name: SFTP_MODE 34 # value: "true" 35 # - name: SFTP_CHROOT 36 # value: "/data" 37 # - name: SCP_MODE 38 # value: "true" 39 # - name: RSYNC_MODE 40 # value: "true" 41 ports: 42 - containerPort: 22 43 protocol: TCP 44 # tty: true 45 volumeMounts: 46 - mountPath: /etc/entrypoint.d/ 47 name: ssh-storage 48 subPath: entrypoint.d 49 - mountPath: /root/.ssh/ 50 name: ssh-storage 51 subPath: .ssh 52 # - mountPath: /etc/ssh/keys 53 # name: ssh-storage 54 # subPath: keys 55 - mountPath: /data 56 name: ssh-storage 57 subPath: data 58 - mountPath: /etc/ssh/ 59 name: ssh-storage 60 subPath: ssh 61 volumes: 62 - name: ssh-storage 63 persistentVolumeClaim: 64 claimName: ssh-pvc 65 selector: 66 matchLabels: 67 app: ssh 68 --- 69 apiVersion: v1 70 kind: Service 71 metadata: 72 namespace: javalittleman 73 name: ssh 74 labels: 75 app: ssh 76 spec: 77 type: LoadBalancer 78 ports: 79 - port: 22 80 targetPort: 22 81 protocol: TCP 82 selector: 83 app: ssh 84 85 --- 86 apiVersion: v1 87 kind: PersistentVolumeClaim 88 metadata: 89 name: ssh-pvc 90 namespace: javalittleman 91 spec: 92 # storageClassName: nfs-client-provisioner1 93 accessModes: 94 - ReadWriteMany 95 resources: 96 requests: 97 storage: 1Mi
以上yaml自己根据自己的情况去配置,我这里使用了存储、LoadBalancer,这些先要准备好
这个脚本我加了一个对xshell兼容的代码,至于用户密码你可以选择密文或者明文都可以了,这个脚本是放在/etc/entrypoint.d/下的,需要对此加可执行权限chmod。
setpasswd.sh
1 #!/usr/bin/env bash 2 3 set -e 4 #docker run --rm -it --entrypoint /usr/bin/env docker.io/panubo/sshd:1.3.0 mkpasswd 5 #echo 'root:$6$1yzDg4xFmQMecjlV$ddBMEcWZaHGkyki1aJ67ZavSOJaPVXj8v03PQc5n08Pb6ilplthzrBr/prmcEJ5uplaIvgtMpzDF0pijtCEi01' | chpasswd --encrypted 6 7 # Or if you don't pre-hash the password remove the line above and uncomment the line below. 8 echo "userr:userrpassword" | chpasswd 9 echo "admin:adminpassword" | chpasswd 10 11 # 解决xshell报错:服务器发送了一个意外的数据包。received:3,expected:20 12 13 sshd_config=/etc/ssh/sshd_config 14 findstr='KexAlgorithms1' 15 16 if [ `grep -c $findstr $sshd_config` -eq '0' ]; then 17 echo "KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha1" >> /etc/ssh/sshd_config 18 else 19 echo "已经存在" 20 fi
效果如下:
先讲场景二:可以直接在这里ping服务名,如果要跨namespace访问,就可以通过k8s的访问规则去尝试访问,如果访问不了,就证明该服务有问题。
场景一:接下来就是要把这个192.168.109.125的流量代理出来,这样就可以像把电脑搬到k8s内部网络里访问服务了。下图是通过xshell的隧道方式实现socks代理,当然大家可以使用其它工具。
IE代理设置,使用socks5(套节字),当然你可以使用chrome,chrome需要安装插件。
我们来试试如果访问,其它服务这里就不列举了:
直接访问k8s内部IP:如访问Kunsul
通过navicat查询或导入导出数据