new: add kubetail addon (#20345)

Signed-off-by: Andres Morey <andresmarcel@gmail.com>
pull/20831/head
Andres Morey 2025-06-05 20:39:36 +03:00 committed by GitHub
parent 945b43609c
commit 60212f165f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 752 additions and 0 deletions

View File

@ -178,4 +178,8 @@ var (
// YakdAssets assets for yakd addon // YakdAssets assets for yakd addon
//go:embed yakd/*.yaml yakd/*.tmpl //go:embed yakd/*.yaml yakd/*.tmpl
YakdAssets embed.FS YakdAssets embed.FS
// Kubetail assets for kubetail addon
//go:embed kubetail/*.yaml kubetail/*.tmpl
KubetailAssets embed.FS
) )

View File

@ -0,0 +1,54 @@
kind: ServiceAccount
apiVersion: v1
metadata:
name: kubetail-cli
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cli
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubetail-cli
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cli
rules:
- apiGroups: [""]
resources: [nodes]
verbs: [get, list, watch]
- apiGroups: ["", apps, batch]
resources: [cronjobs, daemonsets, deployments, jobs, pods, replicasets, statefulsets]
verbs: [get, list, watch]
- apiGroups: [""]
resources: [pods/log]
verbs: [list, watch]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubetail-cli
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cli
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubetail-cli
subjects:
- kind: ServiceAccount
name: kubetail-cli
namespace: kubetail-system

View File

@ -0,0 +1,175 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: kubetail-cluster-agent
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
data:
config.yaml: |
cluster-agent:
addr: :50051
logging:
enabled: true
format: json
level: info
tls:
cert-file: null
enabled: false
key-file: null
---
kind: ServiceAccount
apiVersion: v1
automountServiceAccountToken: true
metadata:
name: kubetail-cluster-agent
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: kubetail-cluster-agent
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
spec:
selector:
matchLabels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
template:
metadata:
labels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
spec:
automountServiceAccountToken: true
serviceAccountName: kubetail-cluster-agent
securityContext:
fsGroup: 0
containers:
- name: kubetail-cluster-agent
image: {{.CustomRegistries.Kubetail | default .ImageRepository | default .Registries.Kubetail }}{{.Images.KubetailClusterAgent}}
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- DAC_READ_SEARCH
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 1000
runAsUser: 1000
imagePullPolicy: IfNotPresent
args:
- --config=/etc/kubetail/config.yaml
ports:
- name: grpc
protocol: TCP
containerPort: 50051
livenessProbe:
grpc:
port: 50051
initialDelaySeconds: 5
timeoutSeconds: 30
periodSeconds: 3
failureThreshold: 3
readinessProbe:
grpc:
port: 50051
initialDelaySeconds: 5
timeoutSeconds: 30
periodSeconds: 3
failureThreshold: 3
volumeMounts:
- name: config
mountPath: /etc/kubetail
readOnly: true
- name: varlog
mountPath: /var/log
readOnly: true
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: config
configMap:
name: kubetail-cluster-agent
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
operator: Exists
- effect: NoSchedule
key: node-role.kubernetes.io/control-plane
operator: Exists
---
kind: Service
apiVersion: v1
metadata:
name: kubetail-cluster-agent
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
spec:
clusterIP: None
selector:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: kubetail-cluster-agent
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-agent
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api

View File

@ -0,0 +1,238 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: kubetail-cluster-api
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
data:
config.yaml: |
cluster-api:
addr: :8080
cluster-agent-dispatch-url: "kubernetes://kubetail-cluster-agent:50051"
base-path: /
csrf:
cookie:
domain: null
http-only: true
max-age: 43200
name: kubetail_cluster_api_csrf
path: /
same-site: strict
secure: false
enabled: true
field-name: csrf_token
secret: ${KUBETAIL_CLUSTER_API_CSRF_SECRET}
gin-mode: release
logging:
access-log:
enabled: true
hide-health-checks: true
enabled: true
format: json
level: info
tls:
cert-file: null
enabled: false
key-file: null
---
kind: ServiceAccount
apiVersion: v1
automountServiceAccountToken: true
metadata:
name: kubetail-cluster-api
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: "kubetail"
app.kubernetes.io/component: "cluster-api"
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubetail-cluster-api
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
rules:
- apiGroups: [""]
resources: [nodes]
verbs: [get, list, watch]
- apiGroups: ["", apps, batch]
resources: [cronjobs, daemonsets, deployments, jobs, pods, replicasets, statefulsets]
verbs: [get, list, watch]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubetail-cluster-api
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubetail-cluster-api
subjects:
- kind: ServiceAccount
name: kubetail-cluster-api
namespace: kubetail-system
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kubetail-system
name: kubetail-cluster-api
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
rules:
- apiGroups: [discovery.k8s.io]
resources: [endpointslices]
verbs: [list, watch]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kubetail-system
name: kubetail-cluster-api
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubetail-cluster-api
subjects:
- kind: ServiceAccount
name: kubetail-cluster-api
namespace: kubetail-system
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: kubetail-cluster-api
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
spec:
replicas: 1
revisionHistoryLimit: 5
selector:
matchLabels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
strategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
spec:
automountServiceAccountToken: true
serviceAccountName: kubetail-cluster-api
containers:
- name: kubetail-cluster-api
image: {{.CustomRegistries.Kubetail | default .ImageRepository | default .Registries.Kubetail }}{{.Images.KubetailClusterAPI}}
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 1000
runAsUser: 1000
imagePullPolicy: IfNotPresent
env:
- name: KUBETAIL_CLUSTER_API_CSRF_SECRET
value: "DUMMY"
args:
- --config=/etc/kubetail/config.yaml
ports:
- name: http
protocol: TCP
containerPort: 8080
livenessProbe:
httpGet:
scheme: HTTP
path: /healthz
port: http
initialDelaySeconds: 30
timeoutSeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
scheme: HTTP
path: /healthz
port: http
initialDelaySeconds: 30
timeoutSeconds: 30
periodSeconds: 10
failureThreshold: 3
volumeMounts:
- name: config
mountPath: /etc/kubetail
readOnly: true
volumes:
- name: config
configMap:
name: kubetail-cluster-api
---
kind: Service
apiVersion: v1
metadata:
name: kubetail-cluster-api
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: cluster-api
ports:
- name: http
protocol: TCP
port: 8080
targetPort: http
appProtocol: http

View File

@ -0,0 +1,254 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: kubetail-dashboard
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
data:
config.yaml: |
dashboard:
addr: :8080
auth-mode: auto
cluster-api-endpoint: "http://kubetail-cluster-api:8080"
environment: cluster
ui:
cluster-api-enabled: true
base-path: /
csrf:
cookie:
domain: null
http-only: true
max-age: 43200
name: kubetail_dashhboard_csrf
path: /
same-site: strict
secure: false
enabled: true
field-name: csrf_token
secret: ${KUBETAIL_DASHBOARD_CSRF_SECRET}
gin-mode: release
logging:
access-log:
enabled: true
hide-health-checks: true
enabled: true
format: json
level: info
session:
cookie:
domain: null
http-only: true
max-age: 1092000
name: kubetail_dashboard_session
path: /
same-site: lax
secure: false
secret: ${KUBETAIL_DASHBOARD_SESSION_SECRET}
tls:
cert-file: null
enabled: false
key-file: null
---
kind: ServiceAccount
apiVersion: v1
automountServiceAccountToken: true
metadata:
name: kubetail-dashboard
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubetail-dashboard
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
rules:
- apiGroups: [""]
resources: [namespaces, nodes]
verbs: [get, list, watch]
- apiGroups: ["", apps, batch]
resources: [cronjobs, daemonsets, deployments, jobs, pods, pods/log, replicasets, statefulsets]
verbs: [get, list, watch]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubetail-dashboard
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubetail-dashboard
subjects:
- kind: ServiceAccount
name: kubetail-dashboard
namespace: kubetail-system
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kubetail-system
name: kubetail-dashboard
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
rules:
- apiGroups: [discovery.k8s.io]
resources: [endpointslices]
verbs: [list, watch]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kubetail-system
name: kubetail-dashboard
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubetail-dashboard
subjects:
- kind: ServiceAccount
name: kubetail-dashboard
namespace: kubetail-system
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: kubetail-dashboard
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
spec:
replicas: 1
revisionHistoryLimit: 5
selector:
matchLabels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
strategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
spec:
automountServiceAccountToken: true
serviceAccountName: kubetail-dashboard
containers:
- name: kubetail-dashboard
image: {{.CustomRegistries.Kubetail | default .ImageRepository | default .Registries.Kubetail }}{{.Images.KubetailDashboard}}
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 1000
runAsUser: 1000
imagePullPolicy: IfNotPresent
env:
- name: KUBETAIL_DASHBOARD_CSRF_SECRET
value: "DUMMY"
- name: KUBETAIL_DASHBOARD_SESSION_SECRET
value: "DUMMY"
args:
- --config=/etc/kubetail/config.yaml
ports:
- name: http
protocol: TCP
containerPort: 8080
livenessProbe:
httpGet:
scheme: HTTP
path: /healthz
port: http
initialDelaySeconds: 30
timeoutSeconds: 30
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
scheme: HTTP
path: /healthz
port: http
initialDelaySeconds: 30
timeoutSeconds: 30
periodSeconds: 10
failureThreshold: 3
volumeMounts:
- name: config
mountPath: /etc/kubetail
readOnly: true
volumes:
- name: config
configMap:
name: kubetail-dashboard
---
kind: Service
apiVersion: v1
metadata:
name: kubetail-dashboard
namespace: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile
app.kubernetes.io/name: kubetail
app.kubernetes.io/version: "0.11.5"
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: kubetail
app.kubernetes.io/instance: kubetail
app.kubernetes.io/component: dashboard
ports:
- name: http
protocol: TCP
port: 8080
targetPort: http
appProtocol: http

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: kubetail-system
labels:
kubernetes.io/minikube-addons: kubetail
addonmanager.kubernetes.io/mode: Reconcile

View File

@ -104,6 +104,11 @@ var Addons = []*Addon{
set: SetBool, set: SetBool,
callbacks: []setFn{EnableOrDisableAddon}, callbacks: []setFn{EnableOrDisableAddon},
}, },
{
name: "kubetail",
set: SetBool,
callbacks: []setFn{EnableOrDisableAddon},
},
{ {
name: "kubevirt", name: "kubevirt",
set: SetBool, set: SetBool,

View File

@ -798,6 +798,21 @@ var Addons = map[string]*Addon{
map[string]string{ map[string]string{
"Yakd": "docker.io", "Yakd": "docker.io",
}), }),
"kubetail": NewAddon([]*BinAsset{
MustBinAsset(addons.KubetailAssets, "kubetail/kubetail-namespace.yaml", vmpath.GuestAddonsDir, "kubetail-namespace.yaml", "0640"),
MustBinAsset(addons.KubetailAssets, "kubetail/kubetail-dashboard.yaml.tmpl", vmpath.GuestAddonsDir, "kubetail-dashboard.yaml", "0640"),
MustBinAsset(addons.KubetailAssets, "kubetail/kubetail-cluster-api.yaml.tmpl", vmpath.GuestAddonsDir, "kubetail-cluster-api.yaml", "0640"),
MustBinAsset(addons.KubetailAssets, "kubetail/kubetail-cluster-agent.yaml.tmpl", vmpath.GuestAddonsDir, "kubetail-cluster-agent.yaml", "0640"),
MustBinAsset(addons.KubetailAssets, "kubetail/kubetail-cli.yaml", vmpath.GuestAddonsDir, "kubetail-cli.yaml", "0640"),
}, false, "kubetail", "3rd party (kubetail.com)", "amorey", "https://minikube.sigs.k8s.io/docs/handbook/addons/kubetail/",
map[string]string{
"KubetailDashboard": "kubetail/kubetail-dashboard:0.6.0@sha256:fc8d01805c09f2ad3f5a2c94016e399ece4c03ff7275dc007a213281087490ac",
"KubetailClusterAPI": "kubetail/kubetail-cluster-api:0.4.0@sha256:fec3154c589a31493f14ca5ecbbc48d3ad7bab6b5e30dcddabc2457bd297dae7",
"KubetailClusterAgent": "kubetail/kubetail-cluster-agent:0.4.0@sha256:5363ca1a5394943aa6bf4c160860a8dc616c3e939d2006cfa902f8863e182bae",
},
map[string]string{
"Kubetail": "docker.io",
}),
} }
// parseMapString creates a map based on `str` which is encoded as <key1>=<value1>,<key2>=<value2>,... // parseMapString creates a map based on `str` which is encoded as <key1>=<value1>,<key2>=<value2>,...