另辟蹊径打入kubernetes网络内访问服务

Posted 爪哇小汉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了另辟蹊径打入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实现比较麻烦,端口多的时候无法招架。

image

 

image

 

        场景二:我们想知道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

 

 

image

 

image

 

效果如下:

image

 

先讲场景二:可以直接在这里ping服务名,如果要跨namespace访问,就可以通过k8s的访问规则去尝试访问,如果访问不了,就证明该服务有问题。

 

image

场景一:接下来就是要把这个192.168.109.125的流量代理出来,这样就可以像把电脑搬到k8s内部网络里访问服务了。下图是通过xshell的隧道方式实现socks代理,当然大家可以使用其它工具。

image

IE代理设置,使用socks5(套节字),当然你可以使用chrome,chrome需要安装插件。

image

 

 

我们来试试如果访问,其它服务这里就不列举了:

直接访问k8s内部IP:如访问Kunsul

image

image

 

 

通过navicat查询或导入导出数据

 

 

 

 

 

 

 

以上是关于另辟蹊径打入kubernetes网络内访问服务的主要内容,如果未能解决你的问题,请参考以下文章

《Kubernetes网络权威指南》读书笔记 | 找到你并不容易:从集群内访问服务

服务发布

Docker Kubernetes Service 网络服务代理模式详解

如何访问k8s集群内部署的mysql服务

在kubernetes 集群内访问k8s API服务

Kubernetes网络自学系列 | 你的名字:通过域名访问服务