Kubernetes集群搭建

Prerequisites
硬件资源
目前登录使用的是机房内的一台机器(192.168.40.50) 连接已经配好的虚拟机地址 虚拟机硬件资源如下: os版本:Ubuntu 24.04 LTS (GNU/Linux 6.8.0-31-generic x86_64) k8s版本:Kubernetes v1.30.6

将会使用kubeadm进行安装
安装前要求检测
一台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令。
每台机器 2 GB 或更多的 RAM(如果少于这个数字将会影响你应用的运行内存)。
控制平面机器需要 CPU 2 核心或更多。
集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)。
节点之中不可以有重复的主机名、MAC 地址或 product_uuid。请参见这里了解更多详细信息。
开启机器上的某些端口。请参见这里了解更多详细信息。
交换分区的配置。kubelet 的默认行为是在节点上检测到交换内存时无法启动。更多细节参阅交换内存管理。
如果 kubelet 未被正确配置使用交换分区,则你必须禁用交换分区。例如,
sudo swapoff -a将暂时禁用交换分区。要使此更改在重启后保持不变,请确保在如/etc/fstab、systemd.swap等配置文件中禁用交换分区,具体取决于你的系统如何配置。
Install Steps
配置必要插件以及网络参数
k8s 需要通过ipv4来进行不同pod之间的通信
# 安装两个必要内核插件,overlay 和 br_netfilter
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# 动态加载这两个模块
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# 应用 sysctl 参数而不重新启动
sudo sysctl --system
# 使用以下命令验证 net.ipv4.ip_forward 是否设置为 1
sudo sysctl net.ipv4.ip_forward
下载containerd service 选择 container runtime
这里选择containerd而不是docker(kubernetes新版本已将默认容器编排切换为containerd)
## 1、containerd
# 下载包
wget https://github.com/containerd/containerd/releases/download/v1.7.22/containerd-1.7.22-linux-amd64.tar.gz
# 将下载的包解压到/usr/local下
tar Cxzvf /usr/local containerd-1.7.22-linux-amd64.tar.gz
# 下载服务启动文件
wget -O /etc/systemd/system/containerd.service https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
# 文件内容如下,下载不下来直接复制
cat /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
# 启动containerd
systemctl daemon-reload
systemctl enable --now containerd
## 2、Installing runc
wget https://github.com/opencontainers/runc/releases/download/v1.2.0-rc.3/runc.amd64
TODO:worker1
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
containerd也可以通过apt来下载:
`sudo apt-get install containerd.io`
修改containerd配置文件 (!important)
containerd 相关配置
# 创建containerd目录
sudo mkdir /etc/containerd
# 恢复默认配置文件
sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
# 切换为国内源
sed -i 's/registry.k8s.io/registry.aliyuncs.com\/google_containers/' /etc/containerd/config.toml
# 修改SystemCgroup为true
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
# 重启服务
sudo systemctl daemon-reload
sudo systemctl restart containerd
设置cgroup
sudo sed -i 's/SystemdCgroup = true/SystemdCgroup = false/' /etc/containerd/config.toml
为什么还需要在config中设置镜像源
使用kubeadm init 并指定image-repository 后仍需要在 containerd 的 config.toml 文件中指定镜像源的原因,主要是由于这两个配置的生命周期不同:
kubeadm init 配置镜像源仅用于初始化过程加速必要的相关组件:如
kube-apiserver、kube-controller-manager、kube-scheduler等)containerd自身的配置不受kubeadm影响 。Kubernetes 组件启动后,由containerd负责持续管理容器和镜像的生命周期。当containerd需要重新拉取镜像(例如镜像更新或节点重启后),它将遵循自己的config.toml配置文件,而不是kubeadm的参数。未在containerd中配置镜像源时,它会默认访问官方的k8s.gcr.io源,而这一源在中国大陆访问通常较慢或受限。
设置完成后保存、重新加载containerd配置、重启containerd服务、验证配置是否生效
sudo systemctl daemon-reload
sudo systemctl restart containerd
sudo systemctl status containerd
下载kubeadm以及相关组件
sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
初始化master节点
命令行部署
国内如果不指定image源,在拉取sandbox的时候会出现异常 sudo kubeadm init --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr=10.128.0.0/16
yaml部署(推荐)
首先执行kubeadm config print init-defaults 输出kubeadm默认配置
之后需要在kubeadm-config.yaml这个文件中修改以下几个地方:
hostname 修改name为自己的主机名称,上下文: nodeRegistration: criSocket: unix:///run/containerd/containerd.sock imagePullPolicy: IfNotPresent imagePullSerial: true name: k8s-master taints: null
podSubnet 追加podSubnet podSubnet: 10.244.0.0/16 上下文: networking: dnsDomain: cluster.local serviceSubnet: 10.96.0.0/12 podSubnet: 10.244.0.0/16
KubeletConfiguration 文件最后追加 KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd
之后,可以根据yaml文件初始化master节点:kubeadm init --config=kubeadm-config.yaml
master初始化完成
初始化完成后显示示例:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.40.140:6443 --token wssf4y.fikow8fj6w1f2oar \
--discovery-token-ca-cert-hash sha256:f942ac3be4f63eff7ff780145bf2937bd10656e7a361daf2da002fe2ece6a76e
注意:export KUBECONFIG=$HOME/.kube/config 这里需要设置环境变量,当使用普通用户非root的时候,如果没有上述操作,可能会默认读取/etc下的config文件
初始化flannel网络插件
下载配置文件
wget https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
如果连接失败可参考文件:
apiVersion: v1
kind: Namespace
metadata:
labels:
k8s-app: flannel
pod-security.kubernetes.io/enforce: privileged
name: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: flannel
name: flannel
namespace: kube-flannel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: flannel
name: flannel
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: flannel
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-flannel
---
apiVersion: v1
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"EnableNFTables": false,
"Backend": {
"Type": "vxlan"
}
}
kind: ConfigMap
metadata:
labels:
app: flannel
k8s-app: flannel
tier: node
name: kube-flannel-cfg
namespace: kube-flannel
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: flannel
k8s-app: flannel
tier: node
name: kube-flannel-ds
namespace: kube-flannel
spec:
selector:
matchLabels:
app: flannel
k8s-app: flannel
template:
metadata:
labels:
app: flannel
k8s-app: flannel
tier: node
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
containers:
- args:
- --ip-masq
- --kube-subnet-mgr
command:
- /opt/bin/flanneld
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: EVENT_QUEUE_DEPTH
value: "5000"
image: docker.io/flannel/flannel:v0.26.0
name: kube-flannel
resources:
requests:
cpu: 100m
memory: 50Mi
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
privileged: false
volumeMounts:
- mountPath: /run/flannel
name: run
- mountPath: /etc/kube-flannel/
name: flannel-cfg
- mountPath: /run/xtables.lock
name: xtables-lock
hostNetwork: true
initContainers:
- args:
- -f
- /flannel
- /opt/cni/bin/flannel
command:
- cp
image: docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel2
name: install-cni-plugin
volumeMounts:
- mountPath: /opt/cni/bin
name: cni-plugin
- args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
command:
- cp
image: docker.io/flannel/flannel:v0.26.0
name: install-cni
volumeMounts:
- mountPath: /etc/cni/net.d
name: cni
- mountPath: /etc/kube-flannel/
name: flannel-cfg
priorityClassName: system-node-critical
serviceAccountName: flannel
tolerations:
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /run/flannel
name: run
- hostPath:
path: /opt/cni/bin
name: cni-plugin
- hostPath:
path: /etc/cni/net.d
name: cni
- configMap:
name: kube-flannel-cfg
name: flannel-cfg
- hostPath:
path: /run/xtables.lock
type: FileOrCreate
name: xtables-lock
设置镜像源
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."[docker.io](http://docker.io)"]
endpoint = ["[https://docker.1panel.live(https://docker.1panel.live)","[https://docker.agsv.top](https://docker.agsv.top)","[https://docker.agsvpt.work](https://docker.agsvpt.work)"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."[k8s.gcr.io](http://k8s.gcr.io)"]
endpoint = ["[registry.aliyuncs.com/google_containers](http://registry.aliyuncs.com/google_containers)"]
目前境内一些好用的镜像源:
https://docker.1panel.live ✅网友自建
地址 https://docker.agsv.top ✅网友自建
备用 https://docker.agsvpt.work ✅网友自建
地址①:https://dockerpull.com ✅网友自建
地址②:https://dockerproxy.cn ✅网友自建
配置完成后进行应用 kubectl apply -f kube-flannel.yml
kubectl get pods --all-namespaces 可以检查看dns和flannel相关pod有没有正常启动,
初始化工作节点
工作节点前置任务完成后(安装containerd&安装kubeadm)
kubeadm join <master-ip>:<port> --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:<discovery-token-ca-cert-hash>
主节点的 IP 和端口:
主节点的 IP 地址可以通过在主节点上运行 ip addr show 或 ifconfig 命令来获取。
端口通常是 6443,这是 Kubernetes API 服务器默认使用的端口。
加入令牌(Token):
当你使用 kubeadm init 初始化主节点时,命令会输出一个加入令牌。这个令牌用于工作节点加入集群时的身份验证。
如果你丢失了这个令牌,可以通过以下命令在主节点上重新获取:
kubeadm token list
这将列出所有可用的令牌及其过期时间。你可以选择一个合适的令牌用于 kubeadm join 命令。
发现令牌的 CA 证书哈希:
发现令牌的 CA 证书哈希是用于验证集群信息的证书的哈希值。这个哈希值也可以在主节点上通过以下命令获取:
kubeadm token create --print-join-command
这个命令会输出一个完整的 kubeadm join 命令,包括所需的 CA 证书哈希。你可以直接复制这个命令中的哈希值。
# 可以在master节点生成新的加入令牌
kubeadm token create --print-join-command
初始化完成后可以跳到主节点,kubectl get nodes 查看是否加入成功
工作节点不需要进行flannel配置,工作节点加入集群后会自动进行同步
初始化节点失败后回退方法
重置 Kubernetes 节点,使其恢复到初始化前的状态 sudo kubeadm reset -f
手动清除配置文件: sudo rm -rf /etc/kubernetes /var/lib/etcd /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes
查看是否有端口占用,如果有kill一下 sudo lsof -i :10250


![[Learn With Agent] JSX & React Components](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fstock%2Funsplash%2FUYsBCu9RP3Y%2Fupload%2F532d6d51855d3424a2ec49f01ddcf4c1.jpeg&w=3840&q=75)
