系统环境:
Ubuntu 22.04 LTS
containerd 1.6.20
k8s-mater:192.168.60.160
k8s-node1:192.168.60.161
k8s-node2:192.168.60.162
主机基础优化(所有节点):
cat /etc/sysctl.conf
net.ipv4.ip_forward=1
vm.max_map_count=262144
kernel.pid_max=4194303
fs.file-max=1000000
net.ipv4.tcp_max_tw_buckets=6000
net.netfilter.nf_conntrack_max=2097152
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness=0
net.ipv4.ip_forward=1: 启用IP转发功能,用于将接收到的网络数据包转发到另一个网络接口,有助于实现路由、防火墙等网络功能。
vm.max_map_count=262144:设置进程可以拥有的内存区域数量上限,通常应该大于或等于 Elasticsearch 和 Solr 需要的最低数量。
kernel.pid_max=4194303:设置进程 ID 的上限,即最大 PID。这个值越大,允许的进程数也就越多。
fs.file-max=1000000:设置系统可以同时打开的文件句柄数上限,这个值的大小决定了系统能够同时运行的应用程序数量。
net.ipv4.tcp_max_tw_buckets=6000:设置本地核心分配的 TIME_WAIT sockets 的最大数量,这决定了可以生成的TCP连接数量。
net.netfilter.nf_conntrack_max=2097152:设置Netfilter连接跟踪状态表大小的上限,跟踪表缓存容量的大小设置会影响到连接跟踪的引擎,上限防止服务器中规模较大的回话跟踪出现阻塞网络流量情况而设置。
net.bridge.bridge-nf-call-ip6tables = 1:如果启用了 net.ipv4.ip_forward 参数,需要将该参数设置为1。这样可以确保内核能够在 Linux 虚拟网桥桥接 IPv6 数据流时自动应用 iptables 规则。
net.bridge.bridge-nf-call-iptables = 1:开启系统 IPVS 时,如果启用了 net.ipv4.ip_forward
,还需将该参数设置为1,以确保内核在 Linux 虚拟网桥桥接 IPv4 数据流时自动应用 iptables 规则。
vm.swappiness=0:控制系统进行分页交换(swap)的倾向,值为0表示操作系统只在极端情况下才会进行交换(尽可能少)。
内核模块开机挂载(所有节点):
cat <<EOF >/etc/modules-load.d/modules.conf
ip_vs
ip_vs_lc
ip_vs_lblc
ip_vs_lblcr
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_dh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
ip_tables
ip_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
xt_set
br_netfilter
nf_conntrack
overlay
EOF
关闭swap(所有节点):
临时关闭:
sudo swapoff -a
永久关闭swap:
编辑/etc/fstab文件
root@k8s-master:~# cat /etc/fstab
# /etc/fstab: static file system information.
:#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/ubuntu-vg/ubuntu-lv during curtin installation
/dev/disk/by-id/dm-uuid-LVM-B3JMt5tYZ6wr0jJ9KKyrqy9Wrkh0YnhH55zotzNSKjdq7mjFQ739NvDv5HIV5UP8 / ext4 defaults 0 1
# /boot was on /dev/sda2 during curtin installation
/dev/disk/by-uuid/39a04650-f093-4cde-ae62-1a6c36fa2b63 /boot ext4 defaults 0 1
#/swap.img none swap sw 0 0
注释掉所有swap分区的行或者删除swap分区的行
重启系统
sudo reboot
重启后验证内核模块与内存参数:
lsmod | grep br_netfilter
br_netfilter 32768 0
bridge 307200 1 br_netfilter
sysctl -a | grep bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 1
安装containerd(所有节点):
wget https://shackles.cn/Software/runtime-docker20.10.19-containerd1.6.20-binary-install.tar.gz
tar xvf runtime-docker20.10.19-containerd1.6.20-binary-install.tar.gz
bash runtime-install.sh containerd
更换软件仓库镜像:
cat <<EOF >/etc/apt/sources.list
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
EOF
各节点安装kubeadm、 kubectl、 kubelet:
apt-get update && apt-get install -y apt-transport-https -y
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
apt-get update && apt-cache madison kubeadm
apt-get install -y kubeadm=1.27.2-00 kubectl=1.27.2-00 kubelet=1.27.2-00
下载kubenetes镜像:
kubeadm config images list --kubernetes-version v1.27.2
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.27.2
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controllermanager:v1.27.2
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.27.2
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.27.2
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.7-0
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1
#master节点所需image
cat <<EOF >/root/images-master-down.sh
#!/bin/bash
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controllermanager:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.7-0
EOF
#node节点所需image
cat <<EOF >/root/images-node-down.sh
#!/bin/bash
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1
EOF
使用配置文件进行初始化master:
kubeadm config print init-defaults > kubeadm-init.yaml
vim kubeadm-init.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s #加入集群需要的token有效时常默认24小时
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.60.160 # master主机的IP地址也是API Server的监听地址
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock #可ls此文件查看是否存在
imagePullPolicy: IfNotPresent
name: k8s-master #当前主机名
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki #证书路径
clusterName: kubernetes
#controlPlaneEndpoint: 192.168.60.160:6443 #公有云中负载均衡器的内网地址
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers #修改为国内image仓库
kind: ClusterConfiguration
kubernetesVersion: 1.27.2 #和当前版本对应
networking:
dnsDomain: cluster.local
podSubnet: 10.200.0.0/16 #Pod的IP段
serviceSubnet: 10.100.0.0/16 #SVC的IP段
scheduler: {}
--- #指定kubelet使⽤systemd
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
--- #指定KubeProxy使⽤ipvs
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
初始化:
kubeadm init --config kubeadm-init.yaml
初始化成功后会打印如下信息:
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.60.160:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:4e645a1f0d5d377f79d87139232e35e5972ebe86dbca1df808a54e818be3ec58
根据提示执行指令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
这三条命令的作用是将 Kubernetes 集群的 admin.conf 配置文件拷贝到当前用户的 $HOME/.kube/config 文件中,并修改其拥有者为当前用户,以便可以通过 kubectl 命令管理 Kubernetes 集群。
添加Node节点:
kubeadm join 192.168.60.160:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:4e645a1f0d5d377f79d87139232e35e5972ebe86dbca1df808a54e818be3ec58
检查node节点是否加入成功:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane 20h v1.27.2
k8s-node1 NotReady <none> 16h v1.27.2
k8s-node2 NotReady <none> 16h v1.27.2
如上图所示nodes又两台已经加入成功,STATUS为NotReady是因为没有配置CNI。
部署⽹络组件flannel:
cat <<EOF > 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
- apiGroups:
- networking.k8s.io
resources:
- clustercidrs
verbs:
- list
- watch
---
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.200.0.0/16",
"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.22.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.1.2
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.22.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
EOF
配置中"Network": "10.200.0.0/16",要和初始化时指定的podSubnet对应。
kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
serviceaccount/flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
验证flannel是否部署成功:
root@k8s-master:~# kubectl get pods -n kube-flannel
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-57hbz 1/1 Running 0 15h
kube-flannel-ds-hg48m 1/1 Running 0 15h
kube-flannel-ds-w5dsj 1/1 Running 0 15h
验证node节点状态:
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 20h v1.27.2
k8s-node1 Ready <none> 16h v1.27.2
k8s-node2 Ready <none> 16h v1.27.2
后期添加master节点:
kubeadm init phase upload-certs --upload-certs
I0414 16:21:59.283672 14673 version.go:256] remote version is much newer: v1.27.0;
falling back to: stable-1.26
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system"
Namespace
[upload-certs] Using certificate key:
e4226754e61e5cbcec412db6693597e2489ccf62187137357bd40a50b6c9b313
root@k8s-master2:~# kubeadm join 192.168.60.160:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash
sha256:5e36ce948f5f2ef7af33d61664d6572a4818239c4ec593d4fb0ee66eda17dfea \
--control-plane --certificate-key
e4226754e61e5cbcec412db6693597e2489ccf62187137357bd40a50b6c9b313
仅登录用户可评论,点击 登录