Kubernetes 最新版安装部署
介绍
Kubernetes(k8s)
Kubernetes是一个开源的容器编排管理系统,主要功能包括:
- 应用部署
k8s可以快速部署容器化的应用和服务,通过编写YAML格式的配置文件定义部署状态,包括副本数、网络配置、存储等。主要对象类型有:
- Deployment:部署无状态应用
- StatefulSet:部署有状态应用
- DaemonSet:在集群每台机器上运行一个Pod
- Job/CronJob:运行批处理任务
- 服务发现和负载均衡
k8s通过Service资源把一组Pod暴露成一个统一的入口,并提供负载均衡。Service可以给Pod提供固定IP和DNS名称,客户端只需要访问Service就可以流量分发到后端Pod。
常用的Service类型有ClusterIP、NodePort、LoadBalancer。
- 水平扩展/缩减
可以通过更改Deployment的副本数来实现应用扩缩容,k8s会准确控制Pod数目。HPA可以根据CPU使用率自动扩缩容。
- 滚动更新
Deployment支持自动的滚动更新,可以编辑Pod模板来更新镜像版本,k8s以控制台的速率替换旧版本Pod。
- 存储编排
可以用PersistentVolume(PV)和PersistentVolumeClaim(PVC)提供存储卷给Pod挂载,实现状态存储。并支持多种存储系统,如本地、网络存储。
- 配置管理
ConfigMap用于保存配置数据,Pod可以将其挂载为文件或环境变量。Secret可以保存敏感信息。
- 调度
k8s会根据资源使用情况、硬件亲和性、抗亲和性等调度Pod到集群节点。
- 自我修复
k8s会重启或重调度故障的容器,还可以用ReplicaSet确保副本数目,实现高可用。
- 日志与监控
k8s提供日志收集、指标收集等功能,可以集成到监控系统。
主要组件包括kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy等。
Kubernetes版本与推荐Docker版本的对应表(2022年12月)
Kubernetes版本 | Docker版本 |
---|---|
1.24 - 1.25 | 20.10+ |
1.23 | 20.10+ |
1.22 | 20.10+ |
1.21 | 19.03+ |
1.20 | 19.03+ |
1.19 | 18.09+ |
1.18 | 18.09+ |
1.17 | 18.06+ |
1.16 | 18.06+ |
1.15 | 18.06+ |
1.14 | 18.06+ |
1.13 | 17.03+ |
1.12 | 17.03+ |
1.11 | 1.13+ |
1.10 | 1.13+ |
几点说明:
Kubernetes 1.24+ 版本已经去除了对Docker的直接接口支持,需要通过containerd + docker CRI使用Docker。
对于老版本Kubernetes,需要Docker版本不低于对应版本才能保证功能和稳定性。
Docker 18.09版本加入了对Kubernetes CRI的支持。
最低支持的Docker版本随Kubernetes版本的升级而不断提高。
一般建议使用最新稳定版本的Docker,可以获得更完备的特性和兼容性。
所以在部署Kubernetes集群时,需要注意配置正确版本的Docker或者containerd运行时。
Kubernetes最新版本(v1.24+)移除了对Docker作为容器运行时的原生支持,但这并不意味着完全不支持Docker。
Kubernetes仍然支持使用Docker镜像。所有现有的Docker镜像可以直接用在k8s集群中,不需要修改。
Kubernetes已经全面拥抱容器运行时接口(CRI)。最新版本的kubelet将通过CRI管理容器,而不是直接通过Docker API。
用户可以继续使用Docker作为CRI运行时。只需要安装并配置Docker的CRI插件,即docker-containerd插件,kubelet就可以通过CRI控制Docker。
推荐的容器运行时是containerd。它功能丰富,性能好,资源消耗少。docker-containerd确保它可以与Docker镜像兼容。
切换到containerd后,节点上仍可以同时运行Docker引擎,用于构建镜像等场景。
Kubernetes移除Docker的依赖可以使其支持更多类型的容器运行时,提高其可移植性。
最新k8s版本只是去掉了直接通过Docker API管理容器的方式,但通过添加CRI层,用户仍可以继续使用Docker及其镜像。这带来更多可选择性及未来兼容性。
k8s组件包括Kube-apiserver、kube-scheduler、kube-controller-manager、kubelet、kube-proxy等。使用k8s能够进行自动化容器部署、弹性伸缩、应用监控等,从而减轻干系人员的运维工作量。
内核版本要求
Kubernetes 1.23+ 需要内核3.10.0-1160及以上,否则无法安装和运行。
这是因为最新的Kubernetes启用了新的内核特性,需要相应版本的内核支持。
对于CentOS 7,其默认内核版本为3.10.x,比较老旧,无法满足新版本Kubernetes的需求。
---
所有主机操作
Kubernetes集群环境准备
IP | docker version | cri-dockerd | k8s(Kubernetes) | 内核 | centos | CPU/内存 | hostname |
---|---|---|---|---|---|---|---|
192.168.9.9 | 24.0.5 | v0.3.4 | v1.28.0 | 6.4.11-1.el7.elrepo.x86_64 | 7.9 | 2 核 / 4GB | master |
192.168.9.99 | 24.0.5 | v0.3.4 | v1.28.0 | 6.4.11-1.el7.elrepo.x86_64 | 7.9 | 2 核 / 4GB | node1 |
- 至少2台CentOS 7以上服务器,一主多从,主要用于运行master和node组件。
#集群中所有主机设置主机名
#并添加到/etc/hosts里
192.168.9.9:
hostnamectl set-hostname master
bash
#vim /etc/hosts
192.168.9.9 master
192.168.9.99 node1
---
#192.168.9.99:
hostnamectl set-hostname node1
bash
#vim /etc/hosts
192.168.9.9 master
192.168.9.99 node1
#集群中的所有主机做ssh互信
ssh-keygen -t rsa
for i in 192.168.9.9 192.168.9.99 ; do ssh-copy-id $i; done
关闭swap
临时加永久
临时
swapoff -a
永久
vim进入fstab把这行加井号注释掉
vim /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0
关闭防火墙 Selinux
#临时加永久
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
配置NTP时间同步服务
yum -y install ntp
#安装ntp软件包。
systemctl enable ntpd
#设置ntp服务开机自启。
systemctl start ntpd
#启动ntp服务。
ntpdate -u cn.pool.ntp.org
#从公共ntp服务器同步一次时间。
hwclock --systohc
#将系统时间同步到硬件时钟。
timedatectl set-timezone Asia/Shanghai
#设置系统时区为上海。
内核升级(最新)
不指定版本默认就是当前最新版本
#CentOS 7 上安装最新版本 kernel-ml 内核的过程:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
#导入 elrepo 源的 GPG 公钥,用于验证软件包的签名。
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
#安装 elrepo 源的 rpm 包,添加 elrepo 源。
yum --enablerepo=elrepo-kernel install kernel-ml -y
#启用 elrepo 源,并安装 kernel-ml 内核包。
sed -i s/saved/0/g /etc/default/grub
#编辑 /etc/default/grub 文件,设置开机从新内核启动。
grub2-mkconfig -o /boot/grub2/grub.cfg
#更新 grub 配置。
reboot
#重启系统,以使用新的内核启动。
#总结:
#该命令的作用是添加 elrepo 源、安装最新的 kernel-ml 内核包,并更新 grub 引导来使用该内核,从而升级系统的 Linux 内核。
docker安装
不指定版本默认就是当前最新版本
#CentOS 7 系统的 yum 源替换为阿里云的镜像源。
#yum update 来更新系统,-y 自动确认。
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum -y update
#首先卸载已安装的Docker
#如果你的操作系统没有安装过Docker就不需要执行卸载命令
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#建立仓库
## 安装Docker所需要的一些工具包
sudo yum install -y yum-utils
## 建立Docker yum仓库
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
#使用yum安装了最新版本的Docker CE社区版、命令行工具包及containerd.io容器运行时,完成了Docker CE的安装。
sudo yum -y install docker-ce docker-ce-cli containerd.io
#配置加速器
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://pho7vcn8.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://reg-mirror.qiniu.com"
]
}
EOF
#重新加载系统管理守护进程,从而读取新的配置文件。
sudo systemctl daemon-reload
#开机自启并启动Docker
sudo systemctl enable docker --now
#测试 Docker 是否安装正常
sudo docker run hello-world
安装cri-dockerd
最新版本
#到GitHub自行手动下载并上传到服务器
https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.4/cri-dockerd-0.3.4-3.el7.x86_64.rpm
#用rpm安装
rpm -ivh cri-dockerd-0.3.4-3.el7.x86_64.rpm
#重载系统守护进程→设置cri-dockerd自启动→启动cri-dockerd
systemctl daemon-reload
systemctl enable cri-docker.socket cri-docker --now
安装Kubernetes(k8s)
不指定版本默认就是当前最新版本
#安装kubectl
#kubectl是kubernetes的命令行工具,是操作、检查集群的重要组件。这里通过 curl 方式来安装 kubectl最新发行版
#通过命令行下载
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
#下载校验文件,验证 kubectl 的可执行文件。
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
#安装 kubectl
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
#测试安装是否成功和安装的版本,安装成功会返回一个WARNING,这是正常的,只要版本输出是正确的就说明kubectl安装成功
kubectl version --client
#安装kubeadm
#安装 kubeadm、kubelet 和 kubectl,配置yum文件,因为国内无法直接访问google,这里需要将官网中的google的源改为国内源,以阿里云为例:
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=1
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF
#执行安装
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
#设置kubelet自启动
systemctl enable kubelet --now
搭建Kubernetes集群
#这里作者用到了两台一台主master,一台node节点
#检查hostname,node节点则对应修改为相应名称以及hosts文件
192.168.9.40 master
192.168.9.50 node1
下载runc
#安装runc,这是Kubernetes必须要的运行环境。
#到GitHub自行手动下载并上传到服务器
https://github.com/opencontainers/runc/releases/download/v1.1.9/runc.amd64
#安装runc,检查是否安装成功
sudo install -m 755 runc.amd64 /usr/local/bin/runc
runc -v
#runc是符合OCI(开放容器 Initiative)标准的容器运行时,也可以看作是docker容器运行时的内核组件。runc提供了直接使用操作系统接口创建和运行容器的功能。
#runc的主要特征包括:
#- 它是轻量级的,只负责运行容器中的进程,不包括镜像管理、容器网络等高级功能。
#- 它可以直接通过OCI标准接口管理容器,不依赖于docker daemon。
#- 它主要用于嵌入到其他系统中,为其提供容器运行能力,如Docker、Kubernetes。
#- runc直接调用Linux内核namespace、cgroup、capabilities等接口创建容器。
#- runc可以跨平台工作,支持主流操作系统。
#- runc允许您自定义容器的配置并直接运行容器,适合自动化的容器处理。
#- runc的设计简单和专注,有利于安全审计和理解。
#总结而言,runc可以看作是实现OCI标准的简单而专注的容器运行时内核,它为其他容器系统提供了直接操作容器的基础工具。Docker和Kubernetes都使用了runc来运行容器实例。
修改配置文件
# vim到/usr/lib/systemd/system/cri-docker.service里修改 找到第10行ExecStart=
vim /usr/lib/systemd/system/cri-docker.service
ExecStart=/usr/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7
#这段配置是修改 cri-docker 系统服务的启动参数,主要作用是:
#设置 Kubernetes 使用的容器网络插件为 CNI (Container Network Interface)
#通过 --network-plugin=cni 参数指定网络插件类型为 CNI。这是 Kubernetes 默认的网络模型,需要安装额外的 CNI 插件比如 Calico、Flannel 等来提供 Pod 网络。
#设置 pause 镜像
#通过 --pod-infra-container-image 指定 pause 镜像,这个镜像用来提供 Pod 内部共享的网络和文件空间。
#默认是 k8s.gcr.io/pause,这里修改为了国内阿里云的镜像,加速获取镜像。
#修改 cri-docker 服务的启动参数
#Kubernetes 通过 docker CRI (Container Runtime Interface) 来管理容器,cri-docker 这个系统服务就是 docker 的 CRI 实现。
#通过修改服务启动参数,可以自定义 Kubernetes 使用 docker 时的网络和镜像配置。
#总结一下,这组配置主要是设置了 CNI 网络插件类型和自定义了 pause 镜像,方便后续 Kubernetes 集群使用。
重启
# 重启Docker组件
systemctl daemon-reload && systemctl restart docker cri-docker.socket cri-docker
# 检查Docker组件状态
systemctl status docker cir-docker.socket cri-docker
启用模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
#启用了overlay和br_netfilter两个对Kubernetes重要的内核模块。
#这是准备Kubernetes节点的必要步骤之一,需要在所有节点上执行完成。
设置所需的 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
lsmod | grep br_netfilter
lsmod | grep overlay
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
---
master操作
Master初始化
#执行初始化命令,这一步只在主节点master执行
kubeadm init --node-name=master --image-repository=registry.aliyuncs.com/google_containers --cri-socket=unix:///var/run/cri-dockerd.sock --apiserver-advertise-address=192.168.9.9 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12
初始化命令注释
# 将下载容器镜像源替换为阿里云,否则因为网络原因会导致镜像拉不下来,一定会执行不成功。
--image-repository=registry.aliyuncs.com/google_containers
# 这是指定容器运行时,因为containerd也是Docker的组件之一,下载Docker会一并将containerd下载下来,在执行初始化时当Kubernetes检测到有多个容器运行时环境,就必须要手动选择一个。这里也可以看出containerd实际上比Docker更轻量得多。
--cri-socket=unix:///var/run/cri-dockerd.sock
# 为API server设置广播地址,这里选择本机的ipv4地址,这里不希望API SERVER设置在其他node上的话就不要改为其他地址。
--apiserver-advertise-address=192.168.9.40
# 指明 pod 网络可以使用的 IP 地址段
--pod-network-cidr=10.244.0.0/16
# 为服务的虚拟 IP 地址另外指定 IP 地址段
--service-cidr=10.96.0.0/12
初始化成功会有以下提示
将kubeadm join那一段用一个文本文档记下,后面node节点执行加入就是依靠这一条指令
mkdir -p $HOME/.kube
#在当前用户的HOME目录下创建.kube配置目录。
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
#将默认的admin.conf文件拷贝到.kube/config文件,这个admin.conf文件包含了管理集群的凭证和相关配置。
sudo chown {
mathJaxContainer[0]}(id -g) $HOME/.kube/config
#将.kube/config文件的ownership修改为当前用户,否则可能因为权限问题无法访问集群。
完成这些步骤后,当前用户就可以通过kubectl工具管理该Kubernetes集群了。
这是Kubernetes集群安装完成后,在master节点上配置kubectl命令行工具访问集群的常用方法。
需要注意kubeconfig文件包含权限敏感信息,要确保其文件权限只对当前用户可读可写。
# 永久生效,执行kubeadm reset后再次init也无需再次执行这条命令
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
# 执行永久生效命令之后需要source一下使其生效
source ~/.bash_profile
# 检测配置是否生效
echo $KUBECONFIG
/etc/kubernetes/admin.conf
#这两条命令的作用是设置KUBECONFIG环境变量,以配置kubectl命令行工具访问Kubernetes集群。
#1. echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
#这行将export KUBECONFIG的配置命令追加到当前用户的bash profile文件中。这里将KUBECONFIG变量指定为admin.conf的路径。
#2. source ~/.bash_profile
#运行source命令重新加载bash profile,以立即生效其对环境变量的更改。
#这样就设置了KUBECONFIG变量指向admin.conf文件,kubectl将会使用这个配置文件访问Kubernetes集群。
#admin.conf文件包含访问Kubernetes集群所需的认证信息,是在master初始化时生成的,通常位于/etc/kubernetes/目录下。
#将其路径 export到KUBECONFIG变量是一个简单的方式,来配置kubectl与指定集群的连接。
#将这些命令添加到profile文件中,可以使设置持久化,方便长期使用。
flannel
#安装配置网络插件——这里使用flannel,将kube-flannel.yml文件下载并上传到server上。
#到GitHub自行手动下载并上传到服务器
https://github.com/flannel-io/flannel/releases/download/v0.22.2/kube-flannel.yml
#apply kube-flannel.yml文件,为Kubernetes配置flannel网络插件
kubectl apply -f kube-flannel.yml
cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
#执行完kubectl apply -f kube-flannel.yml这条命令之后,等待一会,才可以查看cat /run/flannel/subnet.env这个文件
node操作
Node节点加入Master
#Node节点加入Master
#在执行join指令前还需要将master节点上的/etc/kubernetes/admin.conf拷贝到node节点上,在局域网状态下,可以使用scp命令快速高效地完成两个节点之间的文件传输。
scp /etc/kubernetes/admin.conf 192.168.9.99:/etc/kubernetes/
#到node节点检查admin.conf文件是否传输完成
cd /etc/kubernetes
ls
# 不要忘记将admin.conf加入环境变量,这里直接使用永久生效
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
#执行join指令加入Master,在前面初始化Master时有让将kubeadm join那一段用一个文本文档记下
#执行join指令加入Master时,在指令末尾添加参数 --cri-socket unix:///var/run/cri-dockerd.sock
kubeadm join 192.168.9.9:6443 --token nudpa2.psn5wxya9fn34gbd \
--discovery-token-ca-cert-hash sha256:784e9aae7272644b33822350adb3c42ea8aca9f3a2ac6be2fcfe974c0c9ce5ee /
--cri-socket unix:///var/run/cri-dockerd.sock
#在任意节点执行 kubectl get nodes。如果节点都是ready的话说明整个集群状态是正常的。
kubectl get nodes
#
source <(kubectl completion bash)
kubectl completion bash >>~/.bashrc
#这两条命令的作用是为kubectl启用bash自动补全功能。
#source <(kubectl completion bash)
#这条命令会立即激活kubectl的bash补全功能。
#kubectl completion bash >>~/.bashrc
#这条命令会将启用补全功能的代码追加到当前用户的~/.bashrc文件中。
#这样就可以在当前shell以及未来新启动的shell中都默认启用kubectl的补全功能。
#补全功能可以减少很多输入命令时的打字工作,提高使用kubectl管理集群的效率。
#例如输入 "kubectl get p" 后按Tab键,就会自动补全为 "kubectl get pods"。
#对于经常通过命令行与Kubernetes交互管理集群的情况,启用这个补全功能可以明显感受到操作效率的提升。
#所以在配置好kubectl后启用bash补全是一个很有价值的设置,可以推荐给所有kubectl用户启用。
---
---
问题
Found multiple CRI endpoints on the host. Please define which one do you wish to use by setting the 'criSocket' field in the kubeadm configuration file: unix:///var/run/containerd/containerd.sock, unix:///var/run/cri-dockerd.sock
To see the stack trace of this error execute with --v=5 or higher
解决办法,在命令后面加上以下选项
--cri-socket unix:///var/run/cri-dockerd.sock