249 lines
8.0 KiB
YAML
249 lines
8.0 KiB
YAML
apiVersion: apps/v1
|
|
kind: StatefulSet
|
|
metadata:
|
|
name: {{.ObjectMeta.Name}}
|
|
namespace: {{.ObjectMeta.Namespace}}
|
|
labels:
|
|
app: {{.ObjectMeta.Name}}
|
|
devstar-resource-type: devstar-devcontainer
|
|
spec:
|
|
podManagementPolicy: OrderedReady
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: {{.ObjectMeta.Name}}
|
|
devstar-resource-type: devstar-devcontainer
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: {{.ObjectMeta.Name}}
|
|
devstar-resource-type: devstar-devcontainer
|
|
spec:
|
|
# 安全策略,禁止挂载 ServiceAccount Token
|
|
automountServiceAccountToken: false
|
|
volumes:
|
|
# 添加 ttyd 共享卷
|
|
- name: ttyd-shared
|
|
emptyDir: {}
|
|
initContainers:
|
|
# 用户配置初始化
|
|
- name: init-user-config
|
|
image: {{.Spec.StatefulSet.Image}}
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
echo "=== Checking /target-root directory ==="
|
|
ls -la /target-root/ 2>/dev/null || echo "Directory not found"
|
|
|
|
# 检查是否为空目录或首次初始化
|
|
file_count=$(find /target-root -maxdepth 1 \( -type f -o -type d \) ! -name '.' ! -name '..' 2>/dev/null | wc -l)
|
|
echo "Found $file_count items in /target-root"
|
|
|
|
if [ "$file_count" -lt 2 ]; then
|
|
echo "Empty or minimal directory detected - initializing user home..."
|
|
cp -a /root/. /target-root/
|
|
echo "User config initialized from image defaults"
|
|
else
|
|
echo "User config already exists - skipping initialization to preserve user data"
|
|
echo "Current contents:"
|
|
ls -la /target-root/
|
|
fi
|
|
volumeMounts:
|
|
- name: pvc-devcontainer
|
|
mountPath: /target-root
|
|
subPath: user-home
|
|
|
|
# SSH 配置和公钥初始化
|
|
- name: init-root-ssh-dir
|
|
image: devstar.cn/public/busybox:27a71e19c956
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
# 确保目录存在
|
|
mkdir -p /root/.ssh
|
|
mkdir -p /etc/ssh
|
|
|
|
# 创建标准的 sshd_config 文件(如果不存在)
|
|
if [ ! -f /etc/ssh/sshd_config ]; then
|
|
cat > /etc/ssh/sshd_config << 'EOF'
|
|
# OpenSSH Server Configuration
|
|
Port 22
|
|
AddressFamily any
|
|
ListenAddress 0.0.0.0
|
|
|
|
# Host Keys
|
|
HostKey /etc/ssh/ssh_host_rsa_key
|
|
HostKey /etc/ssh/ssh_host_ecdsa_key
|
|
HostKey /etc/ssh/ssh_host_ed25519_key
|
|
|
|
# Logging
|
|
SyslogFacility AUTH
|
|
LogLevel INFO
|
|
|
|
# Authentication
|
|
LoginGraceTime 2m
|
|
PermitRootLogin yes
|
|
StrictModes yes
|
|
MaxAuthTries 6
|
|
MaxSessions 10
|
|
|
|
PubkeyAuthentication yes
|
|
AuthorizedKeysFile .ssh/authorized_keys
|
|
|
|
PasswordAuthentication no
|
|
PermitEmptyPasswords no
|
|
ChallengeResponseAuthentication no
|
|
|
|
# Forwarding
|
|
X11Forwarding yes
|
|
X11DisplayOffset 10
|
|
PrintMotd no
|
|
PrintLastLog yes
|
|
TCPKeepAlive yes
|
|
|
|
# Environment
|
|
AcceptEnv LANG LC_*
|
|
|
|
# Subsystem
|
|
Subsystem sftp /usr/lib/openssh/sftp-server
|
|
|
|
# PAM
|
|
UsePAM yes
|
|
EOF
|
|
echo "Created sshd_config"
|
|
fi
|
|
|
|
# 导入 SSH 公钥(如果不存在)
|
|
{{range .Spec.StatefulSet.SSHPublicKeyList}}
|
|
if ! grep -q "{{.}}" /root/.ssh/authorized_keys 2>/dev/null; then
|
|
echo "{{.}}" >> /root/.ssh/authorized_keys
|
|
fi
|
|
{{end}}
|
|
|
|
# 设置正确的权限
|
|
chmod 755 /root
|
|
chmod 700 /root/.ssh/
|
|
chmod 600 /root/.ssh/authorized_keys 2>/dev/null || true
|
|
chmod 644 /etc/ssh/sshd_config 2>/dev/null || true
|
|
|
|
# 确保文件所有者正确
|
|
chown -R root:root /root/.ssh/
|
|
|
|
echo 'SSH configuration and keys initialized.'
|
|
volumeMounts:
|
|
- name: pvc-devcontainer
|
|
mountPath: /root
|
|
subPath: user-home
|
|
- name: pvc-devcontainer
|
|
mountPath: /etc/ssh
|
|
subPath: ssh-host-keys
|
|
|
|
- name: init-git-repo-dir
|
|
image: {{.Spec.StatefulSet.Image}}
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- if [ ! -d '/data/workspace' ]; then git clone {{.Spec.StatefulSet.GitRepositoryURL}} /data/workspace && echo "Git Repository cloned."; else echo "Folder already exists."; fi
|
|
volumeMounts:
|
|
- name: pvc-devcontainer
|
|
mountPath: /data
|
|
subPath: user-data
|
|
|
|
# ttyd 二进制文件复制
|
|
- name: init-ttyd
|
|
image: tsl0922/ttyd:latest
|
|
imagePullPolicy: IfNotPresent
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
echo "Copying ttyd binary to shared volume..."
|
|
cp /usr/bin/ttyd /ttyd-shared/ttyd
|
|
chmod +x /ttyd-shared/ttyd
|
|
echo "ttyd binary copied successfully"
|
|
ls -la /ttyd-shared/ttyd
|
|
volumeMounts:
|
|
- name: ttyd-shared
|
|
mountPath: /ttyd-shared
|
|
|
|
containers:
|
|
- name: {{.ObjectMeta.Name}}
|
|
image: {{.Spec.StatefulSet.Image}}
|
|
command:
|
|
{{range .Spec.StatefulSet.Command}}
|
|
- {{.}}
|
|
{{end}}
|
|
imagePullPolicy: IfNotPresent
|
|
# securityContext: TODO: 设置 DevContainer 安全策略
|
|
ports:
|
|
- name: ssh-port
|
|
protocol: TCP
|
|
containerPort: {{.Spec.StatefulSet.ContainerPort}}
|
|
{{- range .Spec.Service.ExtraPorts }}
|
|
- name: {{ .Name | default (printf "port-%d" .ContainerPort) }}
|
|
protocol: TCP
|
|
containerPort: {{ .ContainerPort }}
|
|
{{- end }}
|
|
volumeMounts:
|
|
- name: pvc-devcontainer
|
|
mountPath: /data
|
|
subPath: user-data
|
|
- name: pvc-devcontainer
|
|
mountPath: /root
|
|
subPath: user-home
|
|
- name: pvc-devcontainer
|
|
mountPath: /etc/ssh
|
|
subPath: ssh-host-keys
|
|
# 挂载 ttyd 共享卷
|
|
- name: ttyd-shared
|
|
mountPath: /ttyd-shared
|
|
# 其他配置保持不变...
|
|
livenessProbe:
|
|
exec:
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- exec ls ~
|
|
failureThreshold: 6
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
successThreshold: 1
|
|
timeoutSeconds: 5
|
|
readinessProbe:
|
|
exec:
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- exec cat /etc/ssh/ssh_host*.pub
|
|
failureThreshold: 6
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
successThreshold: 1
|
|
timeoutSeconds: 5
|
|
resources:
|
|
limits:
|
|
cpu: 300m
|
|
ephemeral-storage: 8Gi
|
|
memory: 512Mi
|
|
requests:
|
|
cpu: 100m
|
|
ephemeral-storage: 50Mi
|
|
memory: 128Mi
|
|
volumeClaimTemplates:
|
|
- apiVersion: v1
|
|
kind: PersistentVolumeClaim
|
|
metadata:
|
|
name: pvc-devcontainer
|
|
spec:
|
|
storageClassName: openebs-hostpath
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
resources:
|
|
requests:
|
|
storage: 10Gi
|