Renamed ControlAgent to NodeControl

This commit is contained in:
2026-04-25 04:38:23 +08:00
parent 1354e83813
commit 8fae920fc8
20 changed files with 404 additions and 73 deletions

278
clitools/pkg/render/sshd.go Normal file
View File

@@ -0,0 +1,278 @@
package render
import (
"bytes"
"fmt"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/util/intstr"
monov1alpha1 "example.com/monok8s/pkg/apis/monok8s/v1alpha1"
"example.com/monok8s/pkg/templates"
)
const (
sshdName = "sshd"
sshdConfigName = "sshd-authorized-keys"
sshdNodePort = int32(30022)
)
func RenderSSHDDeployments(namespace, authKeys string) (string, error) {
vals := templates.LoadTemplateValuesFromEnv()
labels := map[string]string{
"app.kubernetes.io/name": sshdName,
"app.kubernetes.io/component": "host-access",
"app.kubernetes.io/part-of": "monok8s",
"app.kubernetes.io/managed-by": monov1alpha1.NodeControlName,
}
objs := []runtime.Object{
buildSSHDConfigMap(authKeys, namespace, labels),
buildSSHDService(vals, namespace, labels),
buildSSHDDeployment(vals, namespace, labels),
}
s := runtime.NewScheme()
_ = corev1.AddToScheme(s)
_ = rbacv1.AddToScheme(s)
_ = appsv1.AddToScheme(s)
serializer := json.NewYAMLSerializer(json.DefaultMetaFactory, s, s)
var buf bytes.Buffer
for i, obj := range objs {
if i > 0 {
if _, err := fmt.Fprintln(&buf, "---"); err != nil {
return "", err
}
}
if err := serializer.Encode(obj, &buf); err != nil {
return "", err
}
}
return buf.String(), nil
}
func buildSSHDConfigMap(
authorizedKeys string,
namespace string,
labels map[string]string,
) *corev1.ConfigMap {
return &corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "ConfigMap",
},
ObjectMeta: metav1.ObjectMeta{
Name: sshdConfigName,
Namespace: namespace,
Labels: labels,
},
Data: map[string]string{
"authorized_keys": authorizedKeys,
},
}
}
func buildSSHDService(
tVals templates.TemplateValues,
namespace string,
labels map[string]string,
) *corev1.Service {
selectorLabels := map[string]string{
monov1alpha1.NodeControlKey: "true",
"kubernetes.io/hostname": tVals.NodeName,
}
return &corev1.Service{
TypeMeta: metav1.TypeMeta{
APIVersion: "v1",
Kind: "Service",
},
ObjectMeta: metav1.ObjectMeta{
Name: sshdName,
Namespace: namespace,
Labels: labels,
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeNodePort,
Selector: selectorLabels,
Ports: []corev1.ServicePort{
{
Name: "ssh",
Protocol: corev1.ProtocolTCP,
Port: 22,
TargetPort: intstr.FromInt32(22),
NodePort: sshdNodePort,
},
},
},
}
}
func buildSSHDDeployment(
tVals templates.TemplateValues,
namespace string,
labels map[string]string,
) *appsv1.Deployment {
replicas := int32(1)
selectorLabels := map[string]string{
monov1alpha1.NodeControlKey: "true",
"kubernetes.io/hostname": tVals.NodeName,
}
podLabels := mergeStringMaps(labels, selectorLabels)
runAsUser := int64(0)
runAsNonRoot := false
privileged := true
allowPrivilegeEscalation := true
readOnlyRootFilesystem := false
return &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
APIVersion: "apps/v1",
Kind: "Deployment",
},
ObjectMeta: metav1.ObjectMeta{
Name: sshdName,
Namespace: namespace,
Labels: labels,
},
Spec: appsv1.DeploymentSpec{
Replicas: &replicas,
Selector: &metav1.LabelSelector{
MatchLabels: selectorLabels,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: podLabels,
},
Spec: corev1.PodSpec{
NodeSelector: selectorLabels,
Containers: []corev1.Container{
{
Name: sshdName,
Image: "alpine:latest",
Command: []string{
"/bin/sh",
"-ceu",
`
apk add --no-cache openssh-server
mkdir -p /run/sshd
mkdir -p /root/.ssh
cp /authorized-keys/authorized_keys /root/.ssh/authorized_keys
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
ssh-keygen -A
exec /usr/sbin/sshd \
-D \
-e \
-p 22 \
-o PermitRootLogin=prohibit-password \
-o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no \
-o PubkeyAuthentication=yes \
-o AuthorizedKeysFile=/root/.ssh/authorized_keys
`,
},
Ports: []corev1.ContainerPort{
{
Name: "ssh",
ContainerPort: 22,
Protocol: corev1.ProtocolTCP,
},
},
SecurityContext: &corev1.SecurityContext{
RunAsUser: &runAsUser,
RunAsNonRoot: &runAsNonRoot,
Privileged: &privileged,
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
},
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("10m"),
corev1.ResourceMemory: resource.MustParse("32Mi"),
},
Limits: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("200m"),
corev1.ResourceMemory: resource.MustParse("128Mi"),
},
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "authorized-keys",
MountPath: "/authorized-keys",
ReadOnly: true,
},
{
Name: "host-etc",
MountPath: "/host/etc",
},
{
Name: "host-var",
MountPath: "/host/var",
},
},
},
},
Volumes: []corev1.Volume{
{
Name: "authorized-keys",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: sshdConfigName,
},
DefaultMode: ptrInt32(0600),
},
},
},
{
Name: "host-etc",
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc",
Type: ptrHostPathType(corev1.HostPathDirectory),
},
},
},
{
Name: "host-var",
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/var",
Type: ptrHostPathType(corev1.HostPathDirectory),
},
},
},
},
},
},
},
}
}
func ptrInt32(v int32) *int32 {
return &v
}
func ptrHostPathType(v corev1.HostPathType) *corev1.HostPathType {
return &v
}