mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-12-24 11:51:13 +08:00
feat: add options netstack to helm charts (#509)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
1. Connect to cluster network by running these commands:
|
1. Connect to cluster network by running these commands:
|
||||||
kubevpn connect --namespace {{ .Release.Namespace }}
|
kubevpn connect --namespace {{ include "kubevpn.namespace" . }}
|
||||||
export POD_IP=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "kubevpn.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].status.podIP}")
|
export POD_IP=$(kubectl get pods --namespace {{ include "kubevpn.namespace" . }} -l "app.kubernetes.io/name={{ include "kubevpn.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].status.podIP}")
|
||||||
ping $POD_IP
|
ping $POD_IP
|
||||||
|
|||||||
@@ -61,3 +61,22 @@ Create the name of the service account to use
|
|||||||
{{- default "default" .Values.serviceAccount.name }}
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Namespace
|
||||||
|
1. special by -n
|
||||||
|
2. use default namespace kubevpn
|
||||||
|
*/}}
|
||||||
|
{{- define "kubevpn.namespace" -}}
|
||||||
|
{{- if .Release.Namespace }}
|
||||||
|
{{- if eq .Release.Namespace "default" }}
|
||||||
|
{{- .Values.namespace }}
|
||||||
|
{{- else }}
|
||||||
|
{{- .Release.Namespace }}
|
||||||
|
{{- end }}
|
||||||
|
{{- else if .Values.namespace }}
|
||||||
|
{{- .Values.namespace }}
|
||||||
|
{{- else }}
|
||||||
|
{{- .Values.namespace }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -2,6 +2,7 @@ apiVersion: v1
|
|||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
data:
|
data:
|
||||||
DHCP: ""
|
DHCP: ""
|
||||||
DHCP6: ""
|
DHCP6: ""
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "kubevpn.labels" . | nindent 4 }}
|
{{- include "kubevpn.labels" . | nindent 4 }}
|
||||||
spec:
|
spec:
|
||||||
@@ -32,8 +33,8 @@ spec:
|
|||||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||||
containers:
|
containers:
|
||||||
- args:
|
- args:
|
||||||
- |2-
|
{{- if eq .Values.netstack "system" }}
|
||||||
|
- |
|
||||||
sysctl -w net.ipv4.ip_forward=1
|
sysctl -w net.ipv4.ip_forward=1
|
||||||
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
||||||
sysctl -w net.ipv6.conf.all.forwarding=1
|
sysctl -w net.ipv6.conf.all.forwarding=1
|
||||||
@@ -47,6 +48,9 @@ spec:
|
|||||||
iptables -t nat -A POSTROUTING -s ${CIDR4} -o eth0 -j MASQUERADE
|
iptables -t nat -A POSTROUTING -s ${CIDR4} -o eth0 -j MASQUERADE
|
||||||
ip6tables -t nat -A POSTROUTING -s ${CIDR6} -o eth0 -j MASQUERADE
|
ip6tables -t nat -A POSTROUTING -s ${CIDR6} -o eth0 -j MASQUERADE
|
||||||
kubevpn serve -L "tcp://:10800" -L "tun://:8422?net=${TunIPv4}" -L "gtcp://:10801" -L "gudp://:10802" --debug=true
|
kubevpn serve -L "tcp://:10800" -L "tun://:8422?net=${TunIPv4}" -L "gtcp://:10801" -L "gudp://:10802" --debug=true
|
||||||
|
{{- else }}
|
||||||
|
- kubevpn serve -L "tcp://:10800" -L "gtcp://:10801" -L "gudp://:10802" --debug=true
|
||||||
|
{{- end }}
|
||||||
command:
|
command:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
- -c
|
- -c
|
||||||
@@ -74,12 +78,10 @@ spec:
|
|||||||
protocol: TCP
|
protocol: TCP
|
||||||
resources:
|
resources:
|
||||||
{{- toYaml .Values.resources | nindent 12 }}
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
{{- if eq .Values.netstack "system" }}
|
||||||
securityContext:
|
securityContext:
|
||||||
capabilities:
|
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||||
add:
|
{{- end }}
|
||||||
- NET_ADMIN
|
|
||||||
privileged: true
|
|
||||||
runAsUser: 0
|
|
||||||
- args:
|
- args:
|
||||||
- control-plane
|
- control-plane
|
||||||
- --watchDirectoryFilename
|
- --watchDirectoryFilename
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ apiVersion: autoscaling/v2
|
|||||||
kind: HorizontalPodAutoscaler
|
kind: HorizontalPodAutoscaler
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "kubevpn.labels" . | nindent 4 }}
|
{{- include "kubevpn.labels" . | nindent 4 }}
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ apiVersion: batch/v1
|
|||||||
kind: Job
|
kind: Job
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "kubevpn.labels" . | nindent 4 }}
|
{{- include "kubevpn.labels" . | nindent 4 }}
|
||||||
annotations:
|
annotations:
|
||||||
@@ -36,34 +37,34 @@ spec:
|
|||||||
args:
|
args:
|
||||||
- |2-
|
- |2-
|
||||||
|
|
||||||
echo "Label namespace {{ .Release.Namespace }}"
|
echo "Label namespace {{ include "kubevpn.namespace" . }}"
|
||||||
kubectl label ns {{ .Release.Namespace }} ns={{ .Release.Namespace }}
|
kubectl label ns {{ include "kubevpn.namespace" . }} ns={{ include "kubevpn.namespace" . }}
|
||||||
|
|
||||||
echo "Generating https certificate"
|
echo "Generating https certificate"
|
||||||
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -subj "/CN={{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}.svc" -addext "subjectAltName=DNS:{{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local,DNS:{{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}.svc" -keyout server.key -out server.crt
|
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -subj "/CN={{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}.svc" -addext "subjectAltName=DNS:{{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}.svc.cluster.local,DNS:{{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}.svc" -keyout server.key -out server.crt
|
||||||
|
|
||||||
export TLS_CRT=$(cat server.crt | base64 | tr -d '\n')
|
export TLS_CRT=$(cat server.crt | base64 | tr -d '\n')
|
||||||
echo "Patch mutatingwebhookconfigurations {{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}"
|
echo "Patch mutatingwebhookconfigurations {{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}"
|
||||||
kubectl patch mutatingwebhookconfigurations {{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }} -p "{\"webhooks\":[{\"name\":\"{{ include "kubevpn.fullname" . }}.naison.io\",\"sideEffects\":\"None\",\"admissionReviewVersions\":[\"v1\", \"v1beta1\"],\"clientConfig\":{\"service\":{\"namespace\":\"{{ .Release.Namespace }}\",\"name\":\"{{ include "kubevpn.fullname" . }}\"},\"caBundle\":\"$TLS_CRT\"}}]}"
|
kubectl patch mutatingwebhookconfigurations {{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }} -p "{\"webhooks\":[{\"name\":\"{{ include "kubevpn.fullname" . }}.naison.io\",\"sideEffects\":\"None\",\"admissionReviewVersions\":[\"v1\", \"v1beta1\"],\"clientConfig\":{\"service\":{\"namespace\":\"{{ include "kubevpn.namespace" . }}\",\"name\":\"{{ include "kubevpn.fullname" . }}\"},\"caBundle\":\"$TLS_CRT\"}}]}"
|
||||||
|
|
||||||
export TLS_KEY=$(cat server.key | base64 | tr -d '\n')
|
export TLS_KEY=$(cat server.key | base64 | tr -d '\n')
|
||||||
echo "Patch secret {{ include "kubevpn.fullname" . }}"
|
echo "Patch secret {{ include "kubevpn.fullname" . }}"
|
||||||
kubectl patch secret {{ include "kubevpn.fullname" . }} -n {{ .Release.Namespace }} -p "{\"data\":{\"tls_key\":\"$TLS_KEY\",\"tls_crt\":\"$TLS_CRT\"}}"
|
kubectl patch secret {{ include "kubevpn.fullname" . }} -n {{ include "kubevpn.namespace" . }} -p "{\"data\":{\"tls_key\":\"$TLS_KEY\",\"tls_crt\":\"$TLS_CRT\"}}"
|
||||||
|
|
||||||
echo "Restart the pods..."
|
echo "Restart the pods..."
|
||||||
kubectl scale -n {{ .Release.Namespace }} --replicas=0 deployment/{{ include "kubevpn.fullname" . }}
|
kubectl scale -n {{ include "kubevpn.namespace" . }} --replicas=0 deployment/{{ include "kubevpn.fullname" . }}
|
||||||
kubectl scale -n {{ .Release.Namespace }} --replicas=1 deployment/{{ include "kubevpn.fullname" . }}
|
kubectl scale -n {{ include "kubevpn.namespace" . }} --replicas=1 deployment/{{ include "kubevpn.fullname" . }}
|
||||||
|
|
||||||
export POOLS=$(kubectl get cm {{ include "kubevpn.fullname" . }} -n {{ .Release.Namespace }} -o jsonpath='{.data.IPv4_POOLS}')
|
export POOLS=$(kubectl get cm {{ include "kubevpn.fullname" . }} -n {{ include "kubevpn.namespace" . }} -o jsonpath='{.data.IPv4_POOLS}')
|
||||||
if [[ -z "${POOLS// }" ]];then
|
if [[ -z "${POOLS// }" ]];then
|
||||||
echo "Cidr is empty"
|
echo "Cidr is empty"
|
||||||
echo "Get pod cidr..."
|
echo "Get pod cidr..."
|
||||||
export POD_CIDR=$(kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' | tr -s '\n' ' ')
|
export POD_CIDR=$(kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' | tr -s '\n' ' ')
|
||||||
echo "Get service cidr..."
|
echo "Get service cidr..."
|
||||||
export SVC_CIDR=$(echo '{"apiVersion":"v1","kind":"Service","metadata":{"name":"kubevpn-get-svc-cidr-{{ .Release.Namespace }}", "namespace": "{{ .Release.Namespace }}"},"spec":{"clusterIP":"1.1.1.1","ports":[{"port":443}]}}' | kubectl apply -f - 2>&1 | sed 's/.*valid IPs is //')
|
export SVC_CIDR=$(echo '{"apiVersion":"v1","kind":"Service","metadata":{"name":"kubevpn-get-svc-cidr-{{ include "kubevpn.namespace" . }}", "namespace": "{{ include "kubevpn.namespace" . }}"},"spec":{"clusterIP":"1.1.1.1","ports":[{"port":443}]}}' | kubectl apply -f - 2>&1 | sed 's/.*valid IPs is //')
|
||||||
echo "Pod cidr: $POD_CIDR, service cidr: $SVC_CIDR"
|
echo "Pod cidr: $POD_CIDR, service cidr: $SVC_CIDR"
|
||||||
echo "Patch configmap {{ include "kubevpn.fullname" . }}"
|
echo "Patch configmap {{ include "kubevpn.fullname" . }}"
|
||||||
kubectl patch configmap {{ include "kubevpn.fullname" . }} -n {{ .Release.Namespace }} -p "{\"data\":{\"IPv4_POOLS\":\"$POD_CIDR $SVC_CIDR\"}}"
|
kubectl patch configmap {{ include "kubevpn.fullname" . }} -n {{ include "kubevpn.namespace" . }} -p "{\"data\":{\"IPv4_POOLS\":\"$POD_CIDR $SVC_CIDR\"}}"
|
||||||
else
|
else
|
||||||
echo "Cidr is NOT empty"
|
echo "Cidr is NOT empty"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
apiVersion: admissionregistration.k8s.io/v1
|
apiVersion: admissionregistration.k8s.io/v1
|
||||||
kind: MutatingWebhookConfiguration
|
kind: MutatingWebhookConfiguration
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}
|
name: {{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
webhooks:
|
webhooks:
|
||||||
- admissionReviewVersions:
|
- admissionReviewVersions:
|
||||||
- v1
|
- v1
|
||||||
@@ -10,7 +11,7 @@ webhooks:
|
|||||||
caBundle: {{ .Values.tls.crt }}
|
caBundle: {{ .Values.tls.crt }}
|
||||||
service:
|
service:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
namespace: {{ .Release.Namespace }}
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
path: /pods
|
path: /pods
|
||||||
port: 80
|
port: 80
|
||||||
failurePolicy: Ignore
|
failurePolicy: Ignore
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
|||||||
kind: Role
|
kind: Role
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
rules:
|
rules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
@@ -20,7 +21,7 @@ rules:
|
|||||||
- delete
|
- delete
|
||||||
- apiGroups: [ "" ]
|
- apiGroups: [ "" ]
|
||||||
resources: [ "namespaces" ]
|
resources: [ "namespaces" ]
|
||||||
resourceNames: [{{ .Release.Namespace }}]
|
resourceNames: ["{{ include "kubevpn.namespace" . }}"]
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- patch
|
- patch
|
||||||
@@ -47,14 +48,14 @@ rules:
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}
|
name: {{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}
|
||||||
rules:
|
rules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- admissionregistration.k8s.io
|
- admissionregistration.k8s.io
|
||||||
resources:
|
resources:
|
||||||
- mutatingwebhookconfigurations
|
- mutatingwebhookconfigurations
|
||||||
resourceNames:
|
resourceNames:
|
||||||
- {{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}
|
- {{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- list
|
- list
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
|||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
roleRef:
|
roleRef:
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
kind: Role
|
kind: Role
|
||||||
@@ -9,18 +10,18 @@ roleRef:
|
|||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
namespace: {{ .Release.Namespace }}
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
|
|
||||||
---
|
---
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRoleBinding
|
kind: ClusterRoleBinding
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}
|
name: {{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
namespace: {{ .Release.Namespace }}
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
name: {{ include "kubevpn.fullname" . }}.{{ .Release.Namespace }}
|
name: {{ include "kubevpn.fullname" . }}.{{ include "kubevpn.namespace" . }}
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
data:
|
|
||||||
tls_crt: {{ .Values.tls.crt }}
|
|
||||||
tls_key: {{ .Values.tls.key }}
|
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
type: Opaque
|
type: Opaque
|
||||||
|
data:
|
||||||
|
tls_crt: {{ .Values.tls.crt }}
|
||||||
|
tls_key: {{ .Values.tls.key }}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ apiVersion: v1
|
|||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.fullname" . }}
|
name: {{ include "kubevpn.fullname" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "kubevpn.labels" . | nindent 4 }}
|
{{- include "kubevpn.labels" . | nindent 4 }}
|
||||||
spec:
|
spec:
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ apiVersion: v1
|
|||||||
kind: ServiceAccount
|
kind: ServiceAccount
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "kubevpn.serviceAccountName" . }}
|
name: {{ include "kubevpn.serviceAccountName" . }}
|
||||||
|
namespace: {{ include "kubevpn.namespace" . }}
|
||||||
labels:
|
labels:
|
||||||
{{- include "kubevpn.labels" . | nindent 4 }}
|
{{- include "kubevpn.labels" . | nindent 4 }}
|
||||||
{{- with .Values.serviceAccount.annotations }}
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
# This is a YAML-formatted file.
|
# This is a YAML-formatted file.
|
||||||
# Declare variables to be passed into your templates.
|
# Declare variables to be passed into your templates.
|
||||||
|
|
||||||
|
# default namespace
|
||||||
|
namespace: kubevpn
|
||||||
|
# default is system mode, available ["system", "gvisor"]
|
||||||
|
# system: needs privilege permission and cap NET_ADMIN (Best experience)
|
||||||
|
# gvisor: no needs any additional permission (Best compatibility)
|
||||||
|
netstack: system
|
||||||
|
|
||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
|
|
||||||
image:
|
image:
|
||||||
@@ -40,14 +47,13 @@ podLabels:
|
|||||||
|
|
||||||
podSecurityContext: { }
|
podSecurityContext: { }
|
||||||
# fsGroup: 2000
|
# fsGroup: 2000
|
||||||
|
securityContext:
|
||||||
securityContext: { }
|
capabilities:
|
||||||
# capabilities:
|
add:
|
||||||
# drop:
|
- NET_ADMIN
|
||||||
# - ALL
|
privileged: true
|
||||||
# readOnlyRootFilesystem: true
|
runAsUser: 0
|
||||||
# runAsNonRoot: true
|
runAsGroup: 0
|
||||||
# runAsUser: 1000
|
|
||||||
|
|
||||||
service:
|
service:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
|
|||||||
Reference in New Issue
Block a user