mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-12-24 11:51:13 +08:00
376 lines
13 KiB
Markdown
376 lines
13 KiB
Markdown
# KubeVPN
|
|
|
|
[English](README.md) | [中文](README_ZH.md) | [维基](https://github.com/wencaiwulue/kubevpn/wiki/%E6%9E%B6%E6%9E%84)
|
|
|
|
KubeVPN 是一个云原生开发工具, 可以在本地连接云端 kubernetes 网络的工具,可以在本地直接访问远端集群的服务。也可以在远端集群访问到本地服务,便于调试及开发。同时还可以使用开发模式,直接在本地使用 Docker
|
|
将远程容器运行在本地。
|
|
|
|
## 快速开始
|
|
|
|
#### 从 Github release 下载编译好的二进制文件
|
|
|
|
[链接](https://github.com/wencaiwulue/kubevpn/releases/latest)
|
|
|
|
#### 从 自定义 Krew 仓库安装
|
|
|
|
```shell
|
|
(
|
|
kubectl krew index add kubevpn https://github.com/wencaiwulue/kubevpn.git && \
|
|
kubectl krew install kubevpn/kubevpn && kubectl kubevpn
|
|
)
|
|
```
|
|
|
|
#### 自己构建二进制文件
|
|
|
|
```shell
|
|
(
|
|
git clone https://github.com/wencaiwulue/kubevpn.git && \
|
|
cd kubevpn && make kubevpn && ./bin/kubevpn
|
|
)
|
|
|
|
```
|
|
|
|
#### 安装 bookinfo 作为 demo 应用
|
|
|
|
```shell
|
|
kubectl apply -f https://raw.githubusercontent.com/wencaiwulue/kubevpn/master/samples/bookinfo.yaml
|
|
```
|
|
|
|
## 功能
|
|
|
|
### 链接到集群网络
|
|
|
|
```shell
|
|
➜ ~ kubevpn connect
|
|
get cidr from cluster info...
|
|
get cidr from cluster info ok
|
|
get cidr from cni...
|
|
get cidr from svc...
|
|
get cidr from svc ok
|
|
traffic manager not exist, try to create it...
|
|
pod [kubevpn-traffic-manager] status is Pending
|
|
Container Reason Message
|
|
|
|
pod [kubevpn-traffic-manager] status is Pending
|
|
Container Reason Message
|
|
control-plane ContainerCreating
|
|
vpn ContainerCreating
|
|
webhook ContainerCreating
|
|
|
|
pod [kubevpn-traffic-manager] status is Running
|
|
Container Reason Message
|
|
control-plane ContainerRunning
|
|
vpn ContainerRunning
|
|
webhook ContainerRunning
|
|
|
|
update ref count successfully
|
|
port forward ready
|
|
your ip is 223.254.0.101
|
|
tunnel connected
|
|
dns service ok
|
|
|
|
---------------------------------------------------------------------------
|
|
Now you can access resources in the kubernetes cluster, enjoy it :)
|
|
---------------------------------------------------------------------------
|
|
|
|
```
|
|
|
|
**有这个提示出来后, 当前 terminal 不要关闭,新打开一个 terminal, 执行新的操作**
|
|
|
|
```shell
|
|
➜ ~ kubectl get pods -o wide
|
|
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
|
|
details-7db5668668-mq9qr 1/1 Running 0 7m 172.27.0.199 172.30.0.14 <none> <none>
|
|
kubevpn-traffic-manager-99f8c8d77-x9xjt 1/1 Running 0 74s 172.27.0.207 172.30.0.14 <none> <none>
|
|
productpage-8f9d86644-z8snh 1/1 Running 0 6m59s 172.27.0.206 172.30.0.14 <none> <none>
|
|
ratings-859b96848d-68d7n 1/1 Running 0 6m59s 172.27.0.201 172.30.0.14 <none> <none>
|
|
reviews-dcf754f9d-46l4j 1/1 Running 0 6m59s 172.27.0.202 172.30.0.14 <none> <none>
|
|
```
|
|
|
|
```shell
|
|
➜ ~ ping 172.27.0.206
|
|
PING 172.27.0.206 (172.27.0.206): 56 data bytes
|
|
64 bytes from 172.27.0.206: icmp_seq=0 ttl=63 time=49.563 ms
|
|
64 bytes from 172.27.0.206: icmp_seq=1 ttl=63 time=43.014 ms
|
|
64 bytes from 172.27.0.206: icmp_seq=2 ttl=63 time=43.841 ms
|
|
64 bytes from 172.27.0.206: icmp_seq=3 ttl=63 time=44.004 ms
|
|
64 bytes from 172.27.0.206: icmp_seq=4 ttl=63 time=43.484 ms
|
|
^C
|
|
--- 172.27.0.206 ping statistics ---
|
|
5 packets transmitted, 5 packets received, 0.0% packet loss
|
|
round-trip min/avg/max/stddev = 43.014/44.781/49.563/2.415 ms
|
|
```
|
|
|
|
```shell
|
|
➜ ~ kubectl get services -o wide
|
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
|
|
details ClusterIP 172.27.255.92 <none> 9080/TCP 9m7s app=details
|
|
productpage ClusterIP 172.27.255.48 <none> 9080/TCP 9m6s app=productpage
|
|
ratings ClusterIP 172.27.255.154 <none> 9080/TCP 9m7s app=ratings
|
|
reviews ClusterIP 172.27.255.155 <none> 9080/TCP 9m6s app=reviews
|
|
```
|
|
|
|
```shell
|
|
➜ ~ curl 172.27.255.48:9080
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Simple Bookstore App</title>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
```
|
|
|
|
### 域名解析功能
|
|
|
|
```shell
|
|
➜ ~ curl productpage.default.svc.cluster.local:9080
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Simple Bookstore App</title>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
```
|
|
|
|
### 短域名解析功能
|
|
|
|
```shell
|
|
➜ ~ curl productpage:9080
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Simple Bookstore App</title>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
...
|
|
```
|
|
|
|
### 反向代理
|
|
|
|
```shell
|
|
➜ ~ kubevpn connect --workloads deployment/productpage
|
|
got cidr from cache
|
|
traffic manager not exist, try to create it...
|
|
pod [kubevpn-traffic-manager] status is Running
|
|
Container Reason Message
|
|
control-plane ContainerRunning
|
|
vpn ContainerRunning
|
|
webhook ContainerRunning
|
|
|
|
update ref count successfully
|
|
Waiting for deployment "productpage" rollout to finish: 1 out of 2 new replicas have been updated...
|
|
Waiting for deployment "productpage" rollout to finish: 1 out of 2 new replicas have been updated...
|
|
Waiting for deployment "productpage" rollout to finish: 1 out of 2 new replicas have been updated...
|
|
Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination...
|
|
Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination...
|
|
deployment "productpage" successfully rolled out
|
|
port forward ready
|
|
your ip is 223.254.0.101
|
|
tunnel connected
|
|
dns service ok
|
|
|
|
---------------------------------------------------------------------------
|
|
Now you can access resources in the kubernetes cluster, enjoy it :)
|
|
---------------------------------------------------------------------------
|
|
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
)
|
|
|
|
func main() {
|
|
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
|
|
_, _ = io.WriteString(writer, "Hello world!")
|
|
})
|
|
_ = http.ListenAndServe(":9080", nil)
|
|
}
|
|
```
|
|
|
|
```shell
|
|
➜ ~ curl productpage:9080
|
|
Hello world!%
|
|
➜ ~ curl productpage.default.svc.cluster.local:9080
|
|
Hello world!%
|
|
```
|
|
|
|
### 反向代理支持 service mesh
|
|
|
|
支持 HTTP, GRPC 和 WebSocket 等, 携带了指定 header `"a: 1"` 的流量,将会路由到本地
|
|
|
|
```shell
|
|
➜ ~ kubevpn connect --workloads=deployment/productpage --headers a=1
|
|
got cidr from cache
|
|
traffic manager not exist, try to create it...
|
|
pod [kubevpn-traffic-manager] status is Running
|
|
Container Reason Message
|
|
control-plane ContainerRunning
|
|
vpn ContainerRunning
|
|
webhook ContainerRunning
|
|
|
|
update ref count successfully
|
|
Waiting for deployment "productpage" rollout to finish: 1 out of 2 new replicas have been updated...
|
|
Waiting for deployment "productpage" rollout to finish: 1 out of 2 new replicas have been updated...
|
|
Waiting for deployment "productpage" rollout to finish: 1 out of 2 new replicas have been updated...
|
|
Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination...
|
|
Waiting for deployment "productpage" rollout to finish: 1 old replicas are pending termination...
|
|
deployment "productpage" successfully rolled out
|
|
port forward ready
|
|
your ip is 223.254.0.101
|
|
tunnel connected
|
|
dns service ok
|
|
|
|
---------------------------------------------------------------------------
|
|
Now you can access resources in the kubernetes cluster, enjoy it :)
|
|
---------------------------------------------------------------------------
|
|
|
|
```
|
|
|
|
```shell
|
|
➜ ~ curl productpage:9080
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Simple Bookstore App</title>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
...
|
|
```
|
|
|
|
```shell
|
|
➜ ~ curl productpage:9080 -H "a: 1"
|
|
Hello world!%
|
|
```
|
|
|
|
### 本地进入开发模式
|
|
|
|
将 Kubernetes pod 运行在本地的 Docker 容器中,同时配合 service mesh, 拦截带有制定 header 的流量到本地,或者所有的流量到本地
|
|
|
|
```shell
|
|
➜ ~ kubevpn dev deployment/authors -n kube-system --headers a=1 -p 9080:9080 -p 80:80
|
|
got cidr from cache
|
|
update ref count successfully
|
|
traffic manager already exist, reuse it
|
|
Waiting for deployment "authors" rollout to finish: 1 old replicas are pending termination...
|
|
Waiting for deployment "authors" rollout to finish: 1 old replicas are pending termination...
|
|
deployment "authors" successfully rolled out
|
|
port forward ready
|
|
tunnel connected
|
|
dns service ok
|
|
tar: removing leading '/' from member names
|
|
/var/folders/4_/wt19r8113kq_mfws8sb_w1z00000gn/T/3264799524258261475:/var/run/secrets/kubernetes.io/serviceaccount
|
|
tar: Removing leading `/' from member names
|
|
tar: Removing leading `/' from hard link targets
|
|
/var/folders/4_/wt19r8113kq_mfws8sb_w1z00000gn/T/4472770436329940969:/var/run/secrets/kubernetes.io/serviceaccount
|
|
tar: Removing leading `/' from member names
|
|
tar: Removing leading `/' from hard link targets
|
|
/var/folders/4_/wt19r8113kq_mfws8sb_w1z00000gn/T/359584695576599326:/var/run/secrets/kubernetes.io/serviceaccount
|
|
Created container: authors_kube-system_kubevpn_a7d82
|
|
Wait container authors_kube-system_kubevpn_a7d82 to be running...
|
|
Container authors_kube-system_kubevpn_a7d82 is running on port 9080/tcp:32771 now
|
|
Created container: nginx_kube-system_kubevpn_a7d82
|
|
Wait container nginx_kube-system_kubevpn_a7d82 to be running...
|
|
Container nginx_kube-system_kubevpn_a7d82 is running now
|
|
/opt/microservices # ls
|
|
app
|
|
/opt/microservices # ps -ef
|
|
PID USER TIME COMMAND
|
|
1 root 0:00 ./app
|
|
10 root 0:00 nginx: master process nginx -g daemon off;
|
|
32 root 0:00 /bin/sh
|
|
44 101 0:00 nginx: worker process
|
|
45 101 0:00 nginx: worker process
|
|
46 101 0:00 nginx: worker process
|
|
47 101 0:00 nginx: worker process
|
|
49 root 0:00 ps -ef
|
|
/opt/microservices # apk add curl
|
|
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
|
|
fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
|
|
(1/4) Installing brotli-libs (1.0.9-r5)
|
|
(2/4) Installing nghttp2-libs (1.43.0-r0)
|
|
(3/4) Installing libcurl (7.79.1-r5)
|
|
(4/4) Installing curl (7.79.1-r5)
|
|
Executing busybox-1.33.1-r3.trigger
|
|
OK: 8 MiB in 19 packages
|
|
/opt/microservices # curl localhost:9080
|
|
404 page not found
|
|
/opt/microservices # curl localhost:9080/health
|
|
{"status":"Authors is healthy"}/opt/microservices # exit
|
|
prepare to exit, cleaning up
|
|
update ref count successfully
|
|
clean up successful
|
|
```
|
|
|
|
此时本地会启动两个 container, 对应 pod 容器中的两个 container, 并且共享端口, 可以直接使用 localhost:port 的形式直接访问另一个 container,
|
|
并且, 所有的环境变量、挂载卷、网络条件都和 pod 一样, 真正做到与 kubernetes 运行环境一致。
|
|
|
|
```shell
|
|
➜ ~ docker ps
|
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
|
de9e2f8ab57d nginx:latest "/docker-entrypoint.…" 5 seconds ago Up 5 seconds nginx_kube-system_kubevpn_e21d8
|
|
28aa30e8929e naison/authors:latest "./app" 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:9080->9080/tcp authors_kube-system_kubevpn_e21d8
|
|
➜ ~
|
|
```
|
|
|
|
### 支持多种协议
|
|
|
|
- TCP
|
|
- UDP
|
|
- ICMP
|
|
- GRPC
|
|
- WebSocket
|
|
- HTTP
|
|
- ...
|
|
|
|
### 支持三大平台
|
|
|
|
- macOS
|
|
- Linux
|
|
- Windows
|
|
|
|
Windows
|
|
下需要安装 [PowerShell](https://docs.microsoft.com/zh-cn/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.2)
|
|
|
|
## 问答
|
|
|
|
- 依赖的镜像拉不下来,或者内网环境无法访问 docker.io 怎么办?
|
|
- 答:在可以访问 docker.io 的网络中,将命令 `kubevpn version` 中的 image 镜像, 转存到自己的私有镜像仓库,然后启动命令的时候,加上 `--image 新镜像` 即可。
|
|
例如:
|
|
|
|
``` shell
|
|
➜ ~ kubevpn version
|
|
KubeVPN: CLI
|
|
Version: v1.1.14
|
|
Image: docker.io/naison/kubevpn:v1.1.14
|
|
Branch: master
|
|
Git commit: 87dac42dad3d8f472a9dcdfc2c6cd801551f23d1
|
|
Built time: 2023-01-15 04:19:45
|
|
Built OS/Arch: linux/amd64
|
|
Built Go version: go1.18.10
|
|
➜ ~
|
|
```
|
|
|
|
镜像是 `docker.io/naison/kubevpn:v1.1.14`,将此镜像转存到自己的镜像仓库。
|
|
|
|
```text
|
|
docker pull docker.io/naison/kubevpn:v1.1.14
|
|
docker tag docker.io/naison/kubevpn:v1.1.14 [镜像仓库地址]/[命名空间]/[镜像仓库]:[镜像版本号]
|
|
docker push [镜像仓库地址]/[命名空间]/[镜像仓库]:[镜像版本号]
|
|
```
|
|
|
|
然后就可以使用这个镜像了,如下:
|
|
|
|
```text
|
|
➜ ~ kubevpn connect --image docker.io/naison/kubevpn:v1.1.14
|
|
got cidr from cache
|
|
traffic manager not exist, try to create it...
|
|
pod [kubevpn-traffic-manager] status is Running
|
|
...
|
|
``` |