简介
基本概念
- Master:Master 节点是 Kubernetes 集群的控制节点,负责整个集群的管理和控制。Master 节点上包含以下组件:
- kube-apiserver:集群控制的入口,提供 HTTP REST 服务
- kube-controller-manager:Kubernetes 集群中所有资源对象的自动化控制中心
- kube-scheduler:负责 Pod 的调度
- Node:Node 节点是 Kubernetes 集群中的工作节点,Node 上的工作负载由 Master 节点分配,工作负载主要是运行容器应用。Node 节点上包含以下组件:
- kubelet:负责 Pod 的创建、启动、监控、重启、销毁等工作,同时与 Master 节点协作,实现集群管理的基本功能。
- kube-proxy:实现 Kubernetes Service 的通信和负载均衡
- 运行容器化(Pod)应用
- Pod: Pod 是 Kubernetes 最基本的部署调度单元。每个 Pod 可以由一个或多个业务容器和一个根容器(Pause 容器)组成。一个 Pod 表示某个应用的一个实例
- ReplicaSet:是 Pod 副本的抽象,用于解决 Pod 的扩容和伸缩
- Deployment:Deployment 表示部署,在内部使用ReplicaSet 来实现。可以通过 Deployment 来生成相应的 ReplicaSet 完成 Pod 副本的创建
- Service:Service 是 Kubernetes 最重要的资源对象。Kubernetes 中的 Service 对象可以对应微服务架构中的微服务。Service 定义了服务的访问入口,服务的调用者通过这个地址访问 Service 后端的 Pod 副本实例。Service 通过 Label Selector 同后端的 Pod 副本建立关系,Deployment 保证后端Pod 副本的数量,也就是保证服务的伸缩性。
Kubernetes 主要由以下几个核心组件组成:
- etcd 保存了整个集群的状态,就是一个数据库;
- apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
- controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
- kubelet 负责维护容器的生命周期,同时也负责 Volume(CSI)和网络(CNI)的管理;
- Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
- kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡;
除了上面的这些核心组件,还有一些推荐的插件:
- CoreDNS 负责为整个集群提供 DNS 服务
- Ingress Controller 为服务提供外网入口
- 提供资源监控
- Dashboard 提供 GUI
环境准备
主机名 | IP地址 | 角色 | 配置 |
---|---|---|---|
master | 192.168.80.100 | master节点 | 4H4G 50G |
node1 | 192.168.80.201 | node节点 | 4H4G 50G |
node2 | 192.168.10.202 | node节点 | 4H4G 50G |
版本信息
信息 | 备注 |
---|---|
系统版本 | Ubuntu 22.04 |
CRI | containerd 1.7.2 |
k8s版本 | 1.28.2 |
pod网段 | 10.244.0.0/16 |
serverice网段 | 10.96.0.0/12 |
基本配置
- 以下配置信息在所有节点通用,因此只列出一台机器的
- ssh互信要保证集群中的每台节点都可以访问集群中的任意节点
修改主机名
# master节点
hostnamectl set-hostname master
# node1节点
hostnamectl set-hostname node1
# node2节点
hostnamectl set-hostname node2
配置hosts文件解析
cat > /etc/hosts <<EOF
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.80.100 master master.example.com kubeapi.example.com
192.168.80.201 node1
192.168.80.202 node2
关闭swap分区
# 临时关闭
swapoff -a && sysctl -w vm.swappiness=0
# 修改配置文件,永久关闭
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
# 测试环境请禁止ufw防火墙
systemctl stop ufw
systemctl disable ufw
# 注意:生产环境中请开放对应的端口
master节点
api-server 6443
kubelet 10250
kube-schduler 10251
kube-controller-manager 10252
node节点
kubelet 10250
nodeport servicest 30000~32767
NTP时间同步
方法一:自己安装ntp服务
# 集群中一台服务器配置ntpd时间服务器,其他节点同步时间即可
yum -y install ntp ntpdate
# 编辑文件 "/etc/ntp.conf",根据情况修改文件内容为:
driftfile /var/lib/ntp/drift
pidfile /var/run/ntpd.pid
logfile /var/log/ntp.log
restrict default kod nomodify notrap nopeer noquery
restrict -6 default kod nomodify notrap nopeer noquery
restrict 127.0.0.1
server 127.127.1.0
fudge 127.127.1.0 stratum 10
server ntp.aliyun.com iburst minpoll 4 maxpoll 10
restrict ntp.aliyun.com nomodify notrap nopeer noquery
# 启动服务
systemctl start ntpd
systemctl enable ntpd
# 各节点同步时间
ntpdate ntp.exa
方法二:各节点同步公有云NTP服务,并配置定时任务同步时间
# 安装ntpdate
apt -y install ntpdate
# 同步阿里云NTP时间
[root@master ~]# ntpdate ntp.aliyun.com
21 Dec 14:59:27 ntpdate[1019335]: adjust time server 203.107.6.88 offset -0.013022 sec
# 配置计划任务
[root@master ~]# crontab -e
*/1 * * * * ntpdate ntp.aliyun.com > /dev/null 2>&1
内核配置
# 所有节点安装ipvsadm
yum install ipvsadm ipset sysstat conntrack libseccomp -y
# 内核参数优化,所有节点配置
[root@master ~]# cat > /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
fs.file-max=1000000
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
vm.max_map_count=262144
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
net.netfilter.nf_conntrack_max=2097152
kernel.pid_max=4194303
EOF
# 应用上面的配置
sysctl --system
内核模块开机挂载
[root@master01 ~]# vim /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
安装containerd
# 通过apt/yum源安装containerd
apt install container
# 修改配置文件
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
修改containerd使用SystemdCgroup /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
配置Containerd使用国内Mirror站点上的pause镜像及指定的版本 /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"
配置Containerd使用国内的Image加速服务,以加速Image获取
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://docker.mirrors.ustc.edu.cn", "https://registry.docker-cn.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
endpoint = ["https://registry.aliyuncs.com/google_containers"]
配置crictl运⾏时环境 /etc/crictl.yaml
# vim /etc/crictl.yaml
runtime-endpoint: "unix:///run/containerd/containerd.sock"
image-endpoint: "unix:///run/containerd/containerd.sock"
timeout: 10
debug: false
安装containerd客户端⼯具
GitHub地址:https://github.com/containerd/nerdctl
root@master:~# wget https://github.com/containerd/nerdctl/releases/download/v1.7.2/nerdctl-1.7.2-linux-amd64.tar.g
root@master:~# tar xvf nerdctl-1.7.2-linux-amd64.tar.gz -C /usr/local/bin/
nerdctl
containerd-rootless-setuptool.sh
containerd-rootless.sh
root@master:~# nerdctl version
WARN[0000] unable to determine buildctl version: exec: "buildctl": executable file not found in $PATH
Client:
Version: v1.7.2
OS/Arch: linux/amd64
Git commit: e32c4b023bf41e5c8325cfb893a53cefb5fc68ed
buildctl:
Version:
Server:
containerd:
Version: 1.7.2
GitCommit:
runc:
Version: 1.1.7-0ubuntu1~22.04.1
nerdctl配置文件
root@master:~# mkdir /etc/nerdctl/
root@master:~# vim /etc/nerdctl/nerdctl.toml
namespace = "k8s.io"
debug = false
debug_full = false
insecure_registry = true
配置Kubernetes源
# 配置阿里云的k8s源
apt-get update && apt-get install -y apt-transport-https
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
# 安装 kubelet kubeadm kubectl
apt-get update
apt-get install -y kubelet kubeadm kubectl
K8初始化
提前下载好k8s集群初始化需要的镜像,防止由于网络问题导致集群初始化失败
# 下载镜像
kubeadm config images pull --image-repository="registry.aliyuncs.com/google_containers" --kubernetes-version=v1.28.2
初始化集群
kubeadm init --kubernetes-version=v1.28.2 --control-plane-endpoint="kubeapi.example.com" --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --token-ttl=0 --image-repository=registry.aliyuncs.com/google_containers
# 参数说明:
--image-repository:指定要使用的镜像仓库,默认为registry.k8s.io;
--kubernetes-version:kubernetes程序组件的版本号,它必须要与安装的kubelet程序包的版本号相同;
--control-plane-endpoint:控制平面的固定访问端点,可以是IP地址或DNS名称,会被用于集群管理员及集群组件的kubeconfig配置文件的API Server的访问地址;单控制平面部署时可以不使用该选项;
--pod-network-cidr:Pod网络的地址范围,其值为CIDR格式的网络地址,通常,Flannel网络插件的默认为10.244.0.0/16,Project Calico插件的默认值为192.168.0.0/16;
--service-cidr:Service的网络地址范围,其值为CIDR格式的网络地址,默认为10.96.0.0/12;通常,仅Flannel一类的网络插件需要手动指定该地址;
--apiserver-advertise-address:apiserver通告给其他组件的IP地址,一般应该为Master节点的用于集群内部通信的IP地址,0.0.0.0表示节点上所有可用地址
--token-ttl:共享令牌(token)的过期时长,默认为24小时,0表示永不过期;为防止不安全存储等原因导致的令牌泄露危及集群安全,建议为其设定过期时长。未设定该选项时,在token过期后,若期望再向集群中加入其它节点,可以使用如下命令重新创建token,并生成节点加入命令。
看到如下输出,则证明集群初始化成功
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
# 配置kubectl认证信息
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/
You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:
kubeadm join kubeapi.example.com:6443 --token qqi5po.sbybgnyufwlmaosm \
--discovery-token-ca-cert-hash sha256:9e63db27b513958c00ffe152d32c5506b863f48f45a9ec7dd1ab79bf53d35ebe \
--control-plane
Then you can join any number of worker nodes by running the following on each as root:
# 其他节点加入k8s集群
kubeadm join kubeapi.example.com:6443 --token qqi5po.sbybgnyufwlmaosm \
--discovery-token-ca-cert-hash sha256:9e63db27b513958c00ffe152d32c5506b863f48f45a9ec7dd1ab79bf53d35ebe
安装网络组件
# flannel
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
# calico
curl https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/calico.yaml -O
kubectl apply -f calico.yaml
# 请注意:
# calico默认POD网络:192.168.0.0/16,若集群pod网络不是192.168.0.0/16则需要修改calico.yaml文件的默认地址
# flannel默认的pod网络为10.244.0.0/16
验证集群状态
oot@master:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 2d19h v1.28.2
node1 Ready <none> 2d19h v1.28.2
node2 Ready <none> 2d19h v1.28.2