将ArchLinux作为节点加入EKS UnmanagedNode
添加一个自管理的节点
添加这个自管理的节点是直接添加进入集群的, 并未使用EKS节点组的概念, 所以这个节点是可以被重启, 或者健康检查失败的, 并不具有任何的扩展或者弹性管理的能力。
创建集群,启动一个新的 EC2, 登录到已经启动的 EKS 优化 OS 内,准备复制一些脚本过来。
添加EC2的标签: kubernetes.io/cluster/clusterName owned
配置EC2的Instance Profile
控制台获取 Kubernetes APIServer的Endpoint URL
获取 apiserver b64 CA :
cat ~/.kube/config这个文件里面可以找到 ,或者是通过EKS的控制台上面, 找到 Base64 的 CA。编辑 userdata, 或者 ssh 登录到ec2上面创建一个bash脚本用来调用 bootstrap.sh
1
2
3
4
5
6
7
8
9
10mkdir ~/eks; touch ~/eks/start.sh
---
#!/bin/bash
set -ex
B64_CLUSTER_CA=
API_SERVER_URL=
K8S_CLUSTER_DNS_IP=10.100.0.10
/etc/eks/bootstrap.sh ${ClusterName} --b64-cluster-ca ${B64_CLUSTER_CA} --apiserver-endpoint ${API_SERVER_URL}集群里面没有节点组 , 也不会创建aws-auth configmap 所以节点无法正常的加入集群, 需要手动创建。
1
2
3
4
5
6
7
8
9
10
11
12
13
14apiVersion: v1
data:
mapRoles: |
- groups:
- system:bootstrappers
- system:nodes
rolearn: [CLUSTER_ROLE]
username: system:node:{{EC2PrivateDNSName}}
mapUsers: |
[]
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
需要复制的文件
1 | sudo pacman -S containerd # 安装Containerd |
Bootstrap 脚本内容分析
记录一下脚本自动配置的内容, 大概就是 获取变量, aws的服务地址, ec2 元数据地址, 替换模板中的变量生成Kubelet配置文件 和 Containerd 的配置文件(这个替换是一次性的, 也就是说, bootstrap只能变更模板中的变量一次, 第二次执行只会生成刷新一次集群的信息, 以及重启服务)。
- 读取bootstrap后面给出的参数,设置变量, 例如: ClusterName etc.
- 查看Kubelet的版本, 决定Runtime, containerd | dockerd, 判断条件是 kubelet 版本 大于 1.24
1
2
3
4
5
6++ kubelet --version
++ grep -Eo '[0-9]\.[0-9]+\.[0-9]+'
+ KUBELET_VERSION=1.24.9
---
+ IS_124_OR_GREATER=true
+ DEFAULT_CONTAINER_RUNTIME=containerd - 设置ECR以及Pause容器地址
1
2
3
4
5
6
7
8
9
10# 获取region以及aws service domain
+ AWS_DEFAULT_REGION=cn-north-1
+ AWS_SERVICES_DOMAIN=amazonaws.com.cn
# 调用脚本 /etc/eks/get-ecr-uri.sh cn-north-1 amazonaws.com.cn ''
+ ECR_URI=918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn
+ PAUSE_CONTAINER_IMAGE=918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause
+ PAUSE_CONTAINER=918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5
+ CA_CERTIFICATE_DIRECTORY=/etc/kubernetes/pki
+ CA_CERTIFICATE_FILE_PATH=/etc/kubernetes/pki/ca.crt - 创建证书目录:
1
2
3
4+ mkdir -p /etc/kubernetes/pki
+ sed -i s,MASTER_ENDPOINT,https://CE0253A94B6B14215AE3282580CFA5E3.yl4.cn-north-1.eks.amazonaws.com.cn,g /var/lib/kubelet/kubeconfig
+ sed -i s,AWS_REGION,cn-north-1,g /var/lib/kubelet/kubeconfig
+ sed -i s,CLUSTER_NAME,NewClusterForManualJoin,g /var/lib/kubelet/kubeconfig - 获取 VPC CIDR
1
2
3
4# imds shell script help to get metadata.
imds: /usr/bin/imds
++ imds latest/meta-data/local-ipv4
++ imds latest/meta-data/network/interfaces/macs/02:66:06:2e:48:08/vpc-ipv4-cidr-blocks - 创建kubelet 配置, 计算预留的资源 和 MaxPod 等等参数的数值。
1
2
3
4
5/etc/kubernetes/kubelet/kubelet-config.json
+ mkdir -p /etc/systemd/system/kubelet.service.d
+ sudo mkdir -p /etc/containerd
+ sudo mkdir -p /etc/cni/net.d
+ sudo mkdir -p /etc/systemd/system/containerd.service.d - 创建containerd 配置文件
1
2
3+ printf '[Service]\nSlice=runtime.slice\n'
+ sudo tee /etc/systemd/system/containerd.service.d/00-runtime-slice.conf
+ sudo sed -i s,SANDBOX_IMAGE,918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5,g /etc/eks/containerd/containerd-config.toml - kubelet配置和启动。
1
2
3
4
5+ sudo cp -v /etc/eks/containerd/kubelet-containerd.service /etc/systemd/system/kubelet.service
+ sudo chown root:root /etc/systemd/system/kubelet.service
+ sudo containerd config dump
+ systemctl enable kubelet
+ systemctl start kubelet
制作 NodeTemplate AMI
如果使用已经加入过集群的实例直接制作AMI, 节点会无法加入, kubelet报错是APIserver拒绝这个节点的加入。
1
2023-04-19T15:10:13Z kubelet-eks.daemon[11577]: E0419 15:10:13.325154 11577 event.go:267] Server rejected event '&v1.Event{TypeMeta:v1.TypeMeta{Kind:"", APIVersion:""}, ObjectMeta:v1.ObjectMeta{Name:"ip-10-0-1-249.cn-northwest-1.compute.internal.17575e9c08aefd8d", GenerateName:"", Namespace:"default", SelfLink:"", UID:"", ResourceVersion:"", Generation:0, CreationTimestamp:time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), DeletionTimestamp:<nil>, DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string(nil), ZZZ_DeprecatedClusterName:"", ManagedFields:[]v1.ManagedFieldsEntry(nil)}, InvolvedObject:v1.ObjectReference{Kind:"Node", Namespace:"", Name:"ip-10-0-1-249.cn-northwest-1.compute.internal", UID:"ip-10-0-1-249.cn-northwest-1.compute.internal", APIVersion:"", ResourceVersion:"", FieldPath:""}, Reason:"NodeHasNoDiskPressure", Message:"Node ip-10-0-1-249.cn-northwest-1.compute.internal status is now: NodeHasNoDiskPressure", Source:v1.EventSource{Component:"kubelet", Host:"ip-10-0-1-249.cn-northwest-1.compute.internal"}, FirstTimestamp:time.Date(2023, time.April, 19, 15, 10, 10, 99764621, time.Local), LastTimestamp:time.Date(2023, time.April, 19, 15, 10, 13, 272025156, time.Local), Count:6, Type:"Normal", EventTime:time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), Series:(*v1.EventSeries)(nil), Action:"", Related:(*v1.ObjectReference)(nil), ReportingController:"", ReportingInstance:""}': 'Unauthorized' (will not retry!)
排查所有的地方之后,权限都是正确的, 依旧没发现到底哪里的权限有问题。
发生问题的原因是 已经启动的节点, 有些配置文件已经被更改过了, 写入了固定的信息, 例如apiserver的ca证书, 以及节点的Endpoint地址, 这些文件需要被删除 或者 重新配置,其中最主要的影响 是 /var/lib/kubelet/config 这个配置文件中已经被替换的变量, 还有控制平面错误的CA证书以及信息。
所需处理的文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19root@ip-10-0-1-249:/var/lib/kubelet# ll /var/lib/kubelet/
total 44
drwxr-xr-x 8 root root 4096 Apr 19 15:41 ./
drwxr-xr-x 38 root root 4096 Apr 19 15:40 ../
-rw------- 1 root root 62 Apr 19 15:41 cpu_manager_state
drwxr-xr-x 2 root root 4096 Apr 19 15:50 device-plugins/
-rw-r--r-- 1 root root 575 Apr 19 15:41 kubeconfig # 这个目录中唯一存在的一个文件,里面应该是为配置的变量,不能被替换为确定的值。
-rw------- 1 root root 61 Apr 19 15:41 memory_manager_state
drwxr-xr-x 2 root root 4096 Apr 19 15:41 pki/
drwxr-x--- 2 root root 4096 Apr 19 15:41 plugins/
drwxr-x--- 2 root root 4096 Apr 19 15:41 plugins_registry/
drwxr-x--- 2 root root 4096 Apr 19 15:41 pod-resources/
drwxr-x--- 8 root root 4096 Apr 19 15:50 pods/
root@ip-10-0-1-249:/etc/kubernetes/pki# ll /etc/kubernetes/pki/
total 12
drwxr-xr-x 2 root root 4096 Apr 19 15:38 ./
drwxr-xr-x 4 root root 4096 Apr 19 15:33 ../
-rw-r--r-- 1 root root 1099 Apr 19 15:41 ca.crt删除上面目录中的所有文件, 并创建一个新的空文件
touch /var/lib/kubelet/kubeconfig, 写入内容如下, 保留其中的变量值, 这个部分的变量会在bootstrap的时候替换掉:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: /etc/kubernetes/pki/ca.crt
server: MASTER_ENDPOINT
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubelet
name: kubelet
current-context: kubelet
users:
- name: kubelet
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: /usr/bin/aws-iam-authenticator
args:
- "token"
- "-i"
- "CLUSTER_NAME"
- --region
- "AWS_REGION"将上面的步骤做完之后关闭实例, 并创建一个新的AMI即可。
当AMI被创建为实例, 并完成运行Bootstrap脚本之后, 所有的节点信息会被重新配置, 这样节点才能正确的加入集群中。


