Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add_telemetry #249

Merged
merged 7 commits into from
Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/guide/install-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@
1. 执行卸载命令:
```
kubectl delete -f pkg/k8s/crd/install/shifu_install.yml
```
```

### 关于遥测
要了解更多信息,包括如何禁用内置遥测,请在[此处](telemetry.md)查看我们的指南
rhoninl marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions docs/guide/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
```
kubectl delete -f pkg/k8s/crd/install/shifu_install.yml
```

### About Telemetry
rhoninl marked this conversation as resolved.
Show resolved Hide resolved
To learn more including how to disable the built-in telemetry, checkout out our guide [here!](telemetry.md)
36 changes: 36 additions & 0 deletions docs/guide/telemetry-zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 遥测

安装 Shifu 时默认启用遥测,您可以在安装之前或之后禁用它。

## 我们收集的数据

- 外网IP
- 下载日期
- Kubernetes 版本
- Shifu 版本
- Kubernetes 集群规模
- Kubernetes Pod 名称
- Kubernetes Deployment 名称
- 操作系统的类型

## 关闭遥测

如果要关闭 telemetry,请手动删除 `pkg/k8s/crd/install/shifu_install.yaml` 上的 `--enable-telemetry`。
或者您也可以在安装后通过 `kubectl edit deployment -n shifu-crd-system shifu-crd-controller-manager` 进行编辑
rhoninl marked this conversation as resolved.
Show resolved Hide resolved

```yaml
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 1
selector:
matchLabels:
control-plane: controller-manager
template:
spec:
containers:
image: quay.io/brancz/kube-rbac-proxy:v0.12.0
name: kube-rbac-proxy
- args:
- --enable-telemetry ## delete on demand
rhoninl marked this conversation as resolved.
Show resolved Hide resolved
```
36 changes: 36 additions & 0 deletions docs/guide/telemetry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Telemetry
rhoninl marked this conversation as resolved.
Show resolved Hide resolved

Telemetry is enabled by default when you install Shifu, while you also have the option to disable it either before or after the installation.

## Data we collect

- External network IP
- Download date
- Kubernetes version
- Shifu version
- Kubernetes cluster size
- Kubernetes Pod Name
- Kubernetes Deployment Name
- The type of the operating system

## To turn-off Telemetry

If you want to turn off temeletry, please delete `--enable-telemetry` on `pkg/k8s/crd/install/shifu_install.yaml` manually.
rhoninl marked this conversation as resolved.
Show resolved Hide resolved
Or you can also edit via `kubectl edit deployment -n shifu-crd-system shifu-crd-controller-manager` after installation
rhoninl marked this conversation as resolved.
Show resolved Hide resolved

```yaml
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 1
selector:
matchLabels:
control-plane: controller-manager
template:
spec:
containers:
image: quay.io/brancz/kube-rbac-proxy:v0.12.0
name: kube-rbac-proxy
- args:
- --enable-telemetry ## delete on demand
```
1 change: 1 addition & 0 deletions pkg/k8s/crd/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RUN go mod download

# Copy the go source
COPY pkg/k8s/crd/main.go main.go
COPY pkg/k8s/crd/telemetry pkg/k8s/crd/telemetry
COPY pkg/k8s/api pkg/k8s/api
COPY pkg/k8s/controllers pkg/k8s/controllers

Expand Down
1 change: 1 addition & 0 deletions pkg/k8s/crd/config/default/manager_auth_proxy_patch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ spec:
- "--health-probe-bind-address=:8081"
- "--metrics-bind-address=127.0.0.1:8080"
- "--leader-elect"
- "--enable-telemetry"
1 change: 1 addition & 0 deletions pkg/k8s/crd/config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ spec:
- /manager
args:
- --leader-elect
- --enable-telemetry
image: controller:latest
name: manager
securityContext:
Expand Down
14 changes: 14 additions & 0 deletions pkg/k8s/crd/install/config_default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ spec:
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
- --leader-elect
- --enable-telemetry
command:
- /manager
image: edgehub/shifu-controller:v0.1.0
Expand Down Expand Up @@ -463,3 +464,16 @@ spec:
runAsNonRoot: true
serviceAccountName: shifu-crd-controller-manager
terminationGracePeriodSeconds: 10
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: default-view
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: shifu-crd-controller-manager
namespace: shifu-crd-system
14 changes: 14 additions & 0 deletions pkg/k8s/crd/install/shifu_install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ spec:
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
- --leader-elect
- --enable-telemetry
command:
- /manager
image: edgehub/shifu-controller:v0.1.0
Expand Down Expand Up @@ -527,3 +528,16 @@ subjects:
- kind: ServiceAccount
name: edgedevice-sa
namespace: deviceshifu
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: default-view
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: shifu-crd-controller-manager
namespace: shifu-crd-system
10 changes: 9 additions & 1 deletion pkg/k8s/crd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ package main

import (
"flag"
"os"

"github.com/edgenesis/shifu/pkg/k8s/api/v1alpha1"
"github.com/edgenesis/shifu/pkg/k8s/controllers"
"os"
"github.com/edgenesis/shifu/pkg/k8s/crd/telemetry"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
Expand Down Expand Up @@ -50,18 +52,24 @@ func init() {
func main() {
var metricsAddr string
var enableLeaderElection bool
var enableTelemetry bool
var probeAddr string
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.BoolVar(&enableTelemetry, "enable-telemetry", false, "Collect telemetry")
opts := zap.Options{
Development: true,
}
opts.BindFlags(flag.CommandLine)
flag.Parse()

if enableTelemetry {
go telemetry.StartTelemetry()
}

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Expand Down
87 changes: 87 additions & 0 deletions pkg/k8s/crd/telemetry/telemetry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package telemetry

import (
"context"
"log"
"time"

"github.com/edgenesis/shifu/pkg/k8s/crd/telemetry/types"
"github.com/edgenesis/shifu/pkg/k8s/crd/telemetry/utils"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

func StartTelemetry() {
for {
publicIP, err := utils.GetPublicIPAddr(utils.URL_EXTERNAL_IP)
if err != nil {
log.Printf("issue getting Public IP")
publicIP = utils.URL_DEFAULT_PUBLIC_IP
}

log.Printf("Public IP is %v\n", publicIP)
config, err := rest.InClusterConfig()
if err != nil {
log.Println("error when get cluster Config,error: ", err)
continue
}

clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Println("cannot get ClusterInfo,errors: ", err)
continue
}

kVersion, err := clientset.ServerVersion()
if err != nil {
log.Println("cannot get Kubernetes Server Info,errors: ", err)
continue
}
log.Printf("%#v", kVersion)
pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Println("cannot get Pod Info,errors: ", err)
continue
}

deploy, err := clientset.AppsV1().Deployments("").List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Println("cannot get Deployment Info,errors: ", err)
continue
}

podList := make([]string, len(pods.Items))
deploymentList := make([]string, len(deploy.Items))
for index, item := range pods.Items {
podList[index] = item.Name
}

for index, item := range deploy.Items {
deploymentList[index] = item.Name
}

clusterInfoTelemetry := types.ClusterInfo{
NumPods: len(podList),
NumDeployments: len(deploymentList),
Pods: podList,
Deployments: deploymentList,
KubernetesVersion: kVersion.GitVersion,
Platform: kVersion.Platform,
}

controllerTelemetry := types.TelemetryResponse{
IP: publicIP,
Source: utils.SOURCE_SHIFU_CONTROLLER,
Task: utils.TASK_RUN_DEMO_KIND,
ClusterInfo: clusterInfoTelemetry,
}

if result := utils.SendTelemetry(controllerTelemetry); result == nil {
log.Println("telemetry done")
}

time.Sleep(utils.TELEMETRY_INTERVAL_IN_SECOND * time.Second)
}
}
17 changes: 17 additions & 0 deletions pkg/k8s/crd/telemetry/types/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package types

type TelemetryResponse struct {
IP string `json:"ip"`
Source string `json:"source"`
Task string `json:"task"`
ClusterInfo ClusterInfo `json:"cluster_info"`
}

type ClusterInfo struct {
KubernetesVersion string `json:"kubernetesVersion"`
Platform string `json:"platform"`
NumPods int `json:"num_pods"`
NumDeployments int `json:"num_deployments"`
Pods []string `json:"pods"`
Deployments []string `json:"deployments"`
}
70 changes: 70 additions & 0 deletions pkg/k8s/crd/telemetry/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package utils

import (
"bufio"
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"strings"

"github.com/edgenesis/shifu/pkg/k8s/crd/telemetry/types"
)

const (
URL_EXTERNAL_IP = "http://cip.cc"
URL_IP_LINE = "<pre>IP"
URL_SHIFU_TELEMETRY = "https://telemetry.shifu.run/shifu-telemetry/"
URL_DEFAULT_PUBLIC_IP = "0.0.0.0"
TASK_RUN_DEMO_KIND = "run_shifu_release"
SOURCE_SHIFU_CONTROLLER = "shifu_controller"
HTTP_CONTENT_TYPE_JSON = "application/json"
TELEMETRY_INTERVAL_IN_SECOND = 60
)

func GetPublicIPAddr(url string) (string, error) {
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("error getting public IP")
}

defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
log.Printf("Error getting response of IP query")
return "", err
}

responseText := string(bodyBytes)
scanner := bufio.NewScanner(strings.NewReader(responseText))
for scanner.Scan() {
if strings.Contains(scanner.Text(), URL_IP_LINE) {
ipString := strings.Split(scanner.Text(), ": ")
return ipString[len(ipString)-1], nil
}
}

}
return "", errors.New("Did not find IP in return query")
}

func SendTelemetry(telemetry types.TelemetryResponse) error {
postBodyJson, err := json.Marshal(telemetry)
if err != nil {
log.Printf("Error marshaling telemetry")
return err
}

resp, err := http.Post(URL_SHIFU_TELEMETRY, HTTP_CONTENT_TYPE_JSON, bytes.NewBuffer(postBodyJson))
if err != nil {
log.Println("error posting telemetry, errors: ", err)
return err
}

defer resp.Body.Close()
return nil
}