# Kubernetes 集群配置

本指南面向使用 containerd 的 Kubernetes 集群。目标是让节点通过 SparkCR 拉取镜像，并让需要认证的 workload 使用 SparkCR Access Token。

## 节点运行时配置

在每个节点为 Docker Hub 配置 containerd mirror：

```bash
sudo mkdir -p /etc/containerd/certs.d/docker.io
sudo tee /etc/containerd/certs.d/docker.io/hosts.toml >/dev/null <<'EOF'
server = "https://docker.io"

[host."https://sparkcr.cn/docker.io"]
  capabilities = ["pull", "resolve"]
EOF
sudo systemctl restart containerd
```

如果使用别名入口：

```toml
server = "https://docker.io"

[host."https://docker.sparkcr.cn"]
  capabilities = ["pull", "resolve"]
```

## 多上游配置

为 `registry.k8s.io` 增加 mirror：

```bash
sudo mkdir -p /etc/containerd/certs.d/registry.k8s.io
sudo tee /etc/containerd/certs.d/registry.k8s.io/hosts.toml >/dev/null <<'EOF'
server = "https://registry.k8s.io"

[host."https://sparkcr.cn/registry.k8s.io"]
  capabilities = ["pull", "resolve"]
EOF
sudo systemctl restart containerd
```

使用别名入口时，把 host 改为 `k8s.sparkcr.cn`。

## 配置 imagePullSecret

需要认证拉取时，在 namespace 中创建 Secret：

```bash
kubectl create secret docker-registry sparkcr-registry \
  --docker-server=sparkcr.cn \
  --docker-username=<email> \
  --docker-password=<access-token>
```

使用别名入口时，`--docker-server` 使用对应上游 host：

```bash
kubectl create secret docker-registry sparkcr-docker \
  --docker-server=docker.sparkcr.cn \
  --docker-username=<email> \
  --docker-password=<access-token>
```

在 workload 中引用：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:
  restartPolicy: Never
  imagePullSecrets:
    - name: sparkcr-registry
  containers:
    - name: hello-world
      image: sparkcr.cn/docker.io/library/hello-world:latest
```

如果节点已经配置 Docker Hub mirror，也可以保持原始镜像引用：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello-world-native-ref
spec:
  restartPolicy: Never
  imagePullSecrets:
    - name: sparkcr-registry
  containers:
    - name: hello-world
      image: docker.io/library/hello-world:latest
```

## 批量下发节点配置

小规模集群可以通过 SSH 批量分发 `hosts.toml`：

```bash
while read -r node; do
  [ -n "$node" ] || continue
  scp hosts.toml "$node:/tmp/sparkcr-docker-hosts.toml"
  ssh "$node" 'sudo mkdir -p /etc/containerd/certs.d/docker.io && sudo mv /tmp/sparkcr-docker-hosts.toml /etc/containerd/certs.d/docker.io/hosts.toml && sudo systemctl restart containerd'
done < nodes.txt
```

如果集群允许特权 DaemonSet，也可以用一次性 DaemonSet 写入配置。生产环境建议由节点镜像、cloud-init、Ansible 或其他配置管理系统持久化。

## 验证

创建一次临时 Pod：

```bash
kubectl run sparkcr-test \
  --image=sparkcr.cn/docker.io/library/hello-world:latest \
  --restart=Never
```

查看事件：

```bash
kubectl describe pod sparkcr-test
```

SparkCR 控制台的 [History](/history) 中应能看到对应镜像、上游、字节数和状态。

## 回滚

删除节点 mirror 配置并重启 containerd：

```bash
sudo rm -f /etc/containerd/certs.d/docker.io/hosts.toml
sudo systemctl restart containerd
```

删除 Kubernetes Secret：

```bash
kubectl delete secret sparkcr-registry --namespace default
```

如果出现 `ImagePullBackOff`，优先检查节点 containerd 配置、Secret 所在 namespace 和镜像路径。
