Kubernetes(K8s)笔记Day02:安装与配置全流程
概述
本实现基于openEuler 22.03 LTS系统下的 Kubernetes 1.26 集群安装。
安装方法
| 方法 | 复杂度 | 说明 |
|---|---|---|
| Kubeadm | 简单 | 官方推荐,自动化程度高 |
| 二进制安装 | 复杂 | 手动部署每个组件,适合深入学习 |
Kubernetes 组件架构
Kubernetes 集群由控制节点和工作节点组成,核心组件包括:
(master)主节点组件:
- apiserver:集群的统一入口,提供 REST API
- controller-manager:控制器管理器,维护集群状态
- scheduler:调度器,将 Pod 分配到合适节点
- etcd:分布式键值存储,保存集群数据
- kubelet:管理控制平面的静态 Pod(apiserver、etcd 等),确保控制平面组件正常运行
- kube-proxy:在主节点上配置网络规则,保证控制平面组件的 Service 访问和网络通信
(node)工作节点组件:
- kubelet:节点代理,管理 Pod 生命周期
- kube-proxy:网络代理,实现 Service 负载均衡
容器运行时:运行容器的底层引擎(如 Docker、containerd,k8s在v1.24版本之前默认容器运行时是Docker-ce,v1.24版本之后默认是containerd), 是工作节点上的一个基础软件组件,它负责创建、运行和管理容器,它是容器得以存在的前提条件。
网络插件:
- Calico:提供 Pod 网络通信和网络策略
环境规划
注意,要使用纯净的环境进行配置,避免干扰(建议恢复到仅配置好网络的阶段)
| K8S 集群角色 | IP 地址 | 主机名 | 安装的主要组件 |
|---|---|---|---|
| 控制节点 | 192.168.1.11 | hd1 | apiserver、controller-manager、scheduler、kubelet、etcd、kube-proxy、容器运行时、calico、coredns |
| 工作节点 | 192.168.1.12 | hd2 | kubelet、kube-proxy、calico、coredns、容器运行时 |
| 工作节点 | 192.168.1.13 | hd3 | kubelet、kube-proxy、calico、coredns、容器运行时 |
一、环境准备
1.1 更新系统(所有节点)
# 只是更新系统软件,不更新内核yum update-y1.2 安装基础软件包(所有节点)
yuminstall-ydevice-mapper-persistent-data lvm2wgetnet-tools nfs-utils lrzsz gcc gcc-c++makecmake libxml2-devel openssl-develcurlcurl-develunzipsudontp libaio-develwgetvimncurses-devel autoconf automake zlib-devel openssh-server socat ipvsadm conntrack telnet ipvsadm1.3 关闭 SELinux(所有节点,需重启)
# 修改 SELinux 配置文件,重启后永久生效sed-i's/SELINUX=enforcing/SELINUX=disabled/g'/etc/selinux/configreboot# 查看是否关闭getenforce#输出为Disabled即是成功1.4 配置主机名
加上&& bash可以让主机名修改立即在前台生效
# 在 192.168.1.11 上执行hostnamectl set-hostname hd1&&bash# 在 192.168.1.12 上执行hostnamectl set-hostname hd2&&bash# 在 192.168.1.13 上执行hostnamectl set-hostname hd3&&bash1.5 配置 hosts 文件(所有节点)
cat>>/etc/hosts<<EOF 192.168.1.11 hd1 192.168.1.12 hd2 192.168.1.13 hd3 EOF1.6 配置 SSH 免密登录(在 hd1 上执行)
因为我们要将hd1作为控制主机,所以只在hd1做免密即可
# 生成密钥对(一路回车,不输入密码)[root@hd1 ~]# ssh-keygen# 把公钥拷贝到远程主机[root@hd1 ~]# ssh-copy-id hd2[root@hd1 ~]# ssh-copy-id hd31.7 关闭交换分区 Swap(所有节点)
Kubernetes 要求关闭 Swap 以提升性能。
# 永久关闭:注释 swap 挂载行[root@hd1 ~]# vim /etc/fstab# /dev/mapper/centos-swap swap swap defaults 0 0 # 注释掉这一行# 临时关闭[root@hd1 ~]# swapoff -a[root@hd2 ~]# swapoff -a[root@hd3 ~]# swapoff -a#注意,这两步都要做1.8 修改内核参数(所有节点)
加载内核模块并配置网络参数,使 Kubernetes 能够正确处理网络流量。
# 加载 br_netfilter 内核模块modprobe br_netfilter# 创建内核参数配置文件cat>/etc/sysctl.d/k8s.conf<<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF# 重新加载内核参数sysctl-p/etc/sysctl.d/k8s.conf1.9 关闭 Firewalld 防火墙(所有节点)
[root@hd1 ~]# systemctl stop firewalld && systemctl disable firewalld[root@hd2 ~]# systemctl stop firewalld && systemctl disable firewalld[root@hd3 ~]# systemctl stop firewalld && systemctl disable firewalld1.10 配置 YUM 源(所有节点)
Docker CE 源(华为云):
cat>/etc/yum.repos.d/docker-ce.repo<<EOF [docker-ce-stable] name=Docker CE Stable - \$basearchbaseurl=https://mirrors.huaweicloud.com/docker-ce/linux/rhel/8.8/x86_64/stable/ enabled=1 gpgcheck=0 EOFKubernetes 源(阿里云):
cat>/etc/yum.repos.d/kubernetes.repo<<EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=0 EOF1.11 配置时间同步(所有节点)
# 安装 ntpdateyuminstallntpdate-y# 同步网络时间ntpdate ntp.aliyun.com# 添加计划任务(每分钟同步一次)crontab-e* * * * * /usr/sbin/ntpdate ntp.aliyun.com# 重启 crond 服务servicecrond restart二、Docker 相关软件安装
2.1 安装 Docker CE(所有节点)
yuminstalldocker-ce-ysystemctlenabledocker--now2.2 安装 cri-dockerd(所有节点)
背景知识
在k8s中docker是默认的容器运行时,k8s早期版本在kubelet程序中开发了一个名字为dockershim的代理程序,负责kubelet和docker之间的通信。从Kubernetes 1.20版本开始宣布,将在1.24版本中移除 dockershim。
Docker 官方为解决此问题,开发了cri-dockerd代理程序,替代原来的 dockershim 功能。
容器运行时调用链对比:
| 容器运行时 | 调用链 |
|---|---|
| Docker | kubelet → cri-dockerd → dockerd → containerd → container |
| containerd | kubelet → containerd → container |
Docker 方式比 containerd 方式多了一层调用链。虽然containerd会更加轻便,但目前Docker的市场占有率更高。所以未来想追求极致性能,可以考虑切换到 containerd,但目前依旧是以Docker为主
安装 cri-dockerd
从 GitHub 下载 cri-dockerd RPM 包:
https://github.com/Mirantis/cri-dockerd/releases
[root@hd1 ~]# rpm -ivh cri-dockerd-0.3.25-3.fc36.x86_64.rpm[root@hd2 ~]# rpm -ivh cri-dockerd-0.3.25-3.fc36.x86_64.rpm[root@hd3 ~]# rpm -ivh cri-dockerd-0.3.25-3.fc36.x86_64.rpm修改 cri-docker 服务配置(hd1实施,分发到hd2,hd3)
将 pause 镜像地址指定为阿里云镜像源,避免因网络问题拉取失败。
# 修改 /usr/lib/systemd/system/cri-docker.service[root@hd1 ~]# cat /usr/lib/systemd/system/cri-docker.service#只修改[Service]这个模块[Service]Type=notifyExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9# 同步到 hd2 和 hd3[root@hd1 ~]# scp /usr/lib/systemd/system/cri-docker.service hd2:/usr/lib/systemd/system/[root@hd1 ~]# scp /usr/lib/systemd/system/cri-docker.service hd3:/usr/lib/systemd/system/# 重启并启用服务(所有节点)systemctl daemon-reload&&systemctl start cri-docker.service&&systemctlenablecri-docker.service2.3 配置 Docker 镜像加速器(所有节点)
vim/etc/docker/daemon.json{"registry-mirrors":["https://docker.m.daocloud.io","https://docker.1ms.run","https://docker.xuanyuan.me"]}# 重启 Dockersystemctl restartdocker三、初始化 Kubernetes 集群
3.1 安装 Kubeadm、Kubelet、Kubectl(所有节点)
所有节点安装Kubeadm、Kubelet、Kubectl,是为了让他们具备运行 Kubernetes 的环境
| 软件包 | 作用 |
|---|---|
| kubeadm | 集群初始化工具,用于初始化 Kubernetes 集群 |
| kubelet | 安装在集群所有节点上,用于启停 Pod |
| kubectl | 管理工具,可部署和管理应用、查看资源、创建/删除/更新组件 |
# 安装指定版本(1.26.0)[root@hd1 ~]# yum install -y kubelet-1.26.0 kubeadm-1.26.0 kubectl-1.26.0# 设置 kubelet 启动与开机自启(此时尚未启动,需等到集群初始化后才真正运行)[root@hd1 ~]# systemctl start kubelet[root@hd1 ~]# systemctl enable kubelet3.2 初始化集群(仅在 Master 节点 hd1 执行)
#查看可能要下载的镜像版本[root@hd1 ~]# kubeadm config images list --image-repository=registry.aliyuncs.com/google_containers#命令显示如下结果:registry.aliyuncs.com/google_containers/kube-apiserver:v1.26.15 registry.aliyuncs.com/google_containers/kube-controller-manager:v1.26.15 registry.aliyuncs.com/google_containers/kube-scheduler:v1.26.15 registry.aliyuncs.com/google_containers/kube-proxy:v1.26.15 registry.aliyuncs.com/google_containers/pause:3.9 registry.aliyuncs.com/google_containers/etcd:3.5.6-0 registry.aliyuncs.com/google_containers/coredns:v1.9.3#查看kubelet的版本号,k8s的版本号和kubelet保持一致[root@hd1 ~]# rpm -qa | grep kubeletkubelet-1.26.0-0.x86_64#切记!这里的kubernetes-version的版本一定要和要下载的k8s组件镜像一致,否则报错![root@h1 ~]# kubeadm init --image-repository=registry.aliyuncs.com/google_containers --control-plane-endpoint 192.168.1.100:80 --upload-certs --token-ttl=0 --kubernetes-version=v1.26.15 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock参数说明(了解):
由于参数过多过于复杂,目前仅了解大致作用即可
| 参数 | 说明 |
|---|---|
--apiserver-advertise-address | API Server 监听地址(Master 节点 IP) |
--image-repository | 镜像仓库地址(使用阿里云加速) |
--token-ttl | 共享令牌(token)的过期时长,默认为24小时,0表示永不过期 |
--kubernetes-version | K8s 版本号 |
--pod-network-cidr | Pod 网络 CIDR(需与网络插件一致) |
--service-cidr | Service 网络 CIDR |
--cri-socket | CRI 套接字路径(使用 cri-dockerd) |
补充内容(了解):
- –cri-socket是v1.24版之后指定连接cri的socket文件路径,不同的CRI连接文件是不同的
- 如果是CRI是containerd,则使用–cri-socket unix:///run/containerd/containerd.sock
k8s-1.24后版本此值是默认值 - 如果是CRI是docker,则使用–cri-socket unix:///var/run/cri-dockerd.sock
- 如果是CRI是CRI-o,则使用–cri-socket unix:///var/run/crio/crio.sock
- 如果是CRI是containerd,则使用–cri-socket unix:///run/containerd/containerd.sock
保存初始化信息
初始化成功后,会输出类似如下 Join 命令。要保存好,用于后续添加工作节点:
kubeadmjoin192.168.1.11:6443--tokeneyzo6e.bihj65mqdimn1ktq\--discovery-token-ca-cert-hash sha256:1679ed21f376c6a5a997d13d1016d3e88e380dcffadd1096e297d68b767b48da3.3 踩坑记录
先是在安装软件时报错,然后尝试重置kubeadm环境
kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock结果报错:
显示重置环境没有清理干净
# 删除 CNI 网络配置(必须)[root@hd1 ~]# rm -rf /etc/cni/net.d#删除 kubeconfig 文件(必须)[root@hd1 ~]# rm -rf $HOME/.kube/config#清理 iptables 规则(建议,如果有的话)[root@hd1 ~]# iptables -F && iptables -t nat -F && iptables -t mangle -F#如果使用过 IPVS,清理 IPVS 表(可选)[root@hd1 ~]# ipvsadm --clear 2>/dev/null#确认 swap 已禁用(必须)[root@hd1 ~]# free -h | grep SwapSwap: 0B 0B 0B# 如果显示不为 0,执行:swapoff-ased-i'/swap/s/^/#/'/etc/fstab#查看是否残留容器(包括已经停止的)[root@hd1 ~]# docker ps -a# 如果有残留,可以批量删除[root@hd1 ~]# docker rm -f $(docker ps -aq) 2>/dev/null再次尝试,依旧报错
经过解读发现,是因为我下载的kubeadm 版本与目标 Kubernetes 版本不匹配。我原先使用的下载命令中指定的是v1.28.2版本:
kubeadm init --image-repository=registry.aliyuncs.com/google_containers --control-plane-endpoint192.168.1.100:80 --upload-certs --token-ttl=0--kubernetes-version=v1.28.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock我们把要下载的kubeadm的版本改成1.26.15:
[root@h1 ~]# kubeadm init --image-repository=registry.aliyuncs.com/google_containers --control-plane-endpoint 192.168.1.100:80 --upload-certs --token-ttl=0 --kubernetes-version=v1.26.15 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/16 --cri-socket=unix:///var/run/cri-dockerd.sock就可以正常下载了。为此,我增加了查看可能要下载的镜像版本的步骤
3.4 配置 Kubectl(仅在 Master 节点 hd1 执行)
配置 kubectl 的配置文件config,相当于对 kubectl 进行授权,使其能够管理 Kubernetes 集群。
#kubectl 默认会在 $HOME/.kube/config 路径下查找配置文件[root@hd1 ~]# mkdir -p $HOME/.kube#把管理员凭证文件复制到 kubectl 的默认读取位置[root@hd1 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config#把配置文件的拥有权交给当前用户,确保 kubectl 能正常读取[root@hd1 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config验证集群状态:
[root@hd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 NotReady control-plane 2m25s v1.26.0此时节点状态为
NotReady,因为尚未安装网络插件(CNI)。
四、集群扩容(添加工作节点)
4.1 将 hd2、hd3 加入集群
在 hd2 和 hd3 上执行 kubeadm init 输出的 join 命令,注意需要用到 步骤 3.2 的初始化信息
# hd2 加入集群[root@hd2 ~]# kubeadm join 192.168.1.11:6443 --token eyzo6e.bihj65mqdimn1ktq \--discovery-token-ca-cert-hash sha256:1679ed21f376c6a5a997d13d1016d3e88e380dcffadd1096e297d68b767b48da\--cri-socket=unix:///var/run/cri-dockerd.sock# hd3 加入集群[root@hd3 ~]# kubeadm join 192.168.1.11:6443 --token eyzo6e.bihj65mqdimn1ktq \--discovery-token-ca-cert-hash sha256:1679ed21f376c6a5a997d13d1016d3e88e380dcffadd1096e297d68b767b48da\--cri-socket=unix:///var/run/cri-dockerd.sock4.2 查看集群节点状态(在 hd1 执行)
[root@hd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 NotReady control-plane 49m v1.26.0 hd2 NotReady<none>39s v1.26.0 hd3 NotReady<none>39s v1.26.04.3 给节点打标签(可选)
为工作节点添加角色标签work,便于识别和管理。
[root@hd1 ~]# kubectl label nodes hd2 node-role.kubernetes.io/work=work[root@hd1 ~]# kubectl label nodes hd3 node-role.kubernetes.io/work=work# 再次查看节点状态[root@hd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 NotReady control-plane 10m v1.26.0 hd2 NotReady work 27s v1.26.0 hd3 NotReady work 27s v1.26.0五、网络组件 Calico
在 K8s 1.26 集群中安装 Calico,主要就是为了实现这两点功能:
- 打通网络:让集群中所有 Pod 能够通过 IP 直接互相访问,为服务发现和负载均衡等更高级的功能打下基础。
- 保障安全:提供实施网络策略的能力,实现 Pod 间的访问控制与隔离。
5.1 加载 Calico 镜像(所有节点)
上传七个 Calico 镜像包(直接拉到root目录执行)和**calico.yaml(用于部署和启动Calico服务)**到各节点,然后加载:
dockerload-icalico-cni.tardockerload-icalico-dikastes.tardockerload-icalico-flannel-migration-controller.tardockerload-icalico-kube-controllers.tardockerload-icalico-node.tardockerload-icalico-pod2daemon.tardockerload-icalico-typha.tar下载 Calico 配置文件的地址是:https://docs.projectcalico.org/manifests/calico.yaml
5.2 部署 Calico 网络插件(在 hd1 执行)
[root@hd1 ~]# kubectl apply -f calico.yaml5.3 验证节点状态(hd1)
等待 Calico 部署完成后,节点状态变为Ready:
[root@hd1 ~]# kubectl get nodesNAME STATUS ROLES AGE VERSION hd1 Ready control-plane 41m v1.26.0 hd2 Ready work 21m v1.26.0 hd3 Ready work 21m v1.26.05.4 测试 Pod 网络连通性
把busybox-1-28.tar.gz上传到hd2、hd3节点,并在 hd2、hd3 上加载 busybox 镜像:
[root@hd2 ~]# docker load -i busybox-1-28.tar.gz[root@hd3 ~]# docker load -i busybox-1-28.tar.gz在 hd1 上创建测试 Pod 并验证网络:
[root@hd1 ~]# kubectl run busybox --image docker.io/library/busybox:1.28 \--image-pull-policy=IfNotPresent\--restart=Never\--rm-itbusybox --sh# --rm:容器退出后自动删除If you don't see acommandprompt, try pressing enter.# ping www.baidu.com,验证网络插件已经正常安装/# ping www.baidu.comPING www.baidu.com(36.152.44.132):56data bytes64bytes from36.152.44.132:seq=0ttl=127time=78.099ms64bytes from36.152.44.132:seq=1ttl=127time=57.193ms....../# exitpod"busybox"deleted#查看pod,没有pod存在。因为之前创建制定了--rm,退出pod会自动删除[root@hd1 ~]# kubectl get podsNo resources foundindefault namespace.
--image-pull-policy=IfNotPresent:如果本地已有镜像,则不拉取;如果不存在,则从远程仓库拉取。这样在有离线包的情况下可以加速部署。
六、补充配置
6.1 配置 Kubectl 命令自动补全(即tap补齐,在hd1 执行)
# 安装 bash-completionyum-yinstallbash-completion# 加载 bash-completionsource/usr/share/bash-completion/bash_completion# 配置 kubectl 自动补全kubectl completionbash|sudotee/etc/bash_completion.d/kubectl>/dev/nullsudochmoda+r /etc/bash_completion.d/kubectl# 加载配置source/etc/bash_completion.d/kubectl# 测试 Tab 补全[root@hd1 ~]# kubectl get deployments.apps6.2 集群重置
如果集群搭建失败需要重置,可在各节点执行:
[root@hd1 ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock这会清除集群配置,恢复到初始化前的状态,以便重新初始化。
如果报错显示没有清理干净,就进行更深一步的清理:
# 删除 CNI 网络配置(必须)[root@hd1 ~]# rm -rf /etc/cni/net.d#删除 kubeconfig 文件(必须)[root@hd1 ~]# rm -rf $HOME/.kube/config#清理 iptables 规则(建议,如果有的话)[root@hd1 ~]# iptables -F && iptables -t nat -F && iptables -t mangle -F#如果使用过 IPVS,清理 IPVS 表(可选)[root@hd1 ~]# ipvsadm --clear 2>/dev/null#确认 swap 已禁用(必须)[root@hd1 ~]# free -h | grep SwapSwap: 0B 0B 0B# 如果显示不为 0,执行:swapoff-ased-i'/swap/s/^/#/'/etc/fstab#查看是否残留容器(包括已经停止的)[root@hd1 ~]# docker ps -a# 如果有残留,可以批量删除[root@hd1 ~]# docker rm -f $(docker ps -aq) 2>/dev/null核心知识点总结
Kubernetes 核心组件
| 组件 | 作用 | 部署位置 |
|---|---|---|
| kube-apiserver | 集群统一 API 入口 | Master |
| etcd | 分布式键值存储,保存集群状态 | Master |
| kube-scheduler | Pod 调度 | Master |
| kube-controller-manager | 控制器管理,维护集群状态 | Master |
| kubelet | 节点代理,管理 Pod | All |
| kube-proxy | 网络代理,实现 Service 负载均衡 | All |
| 容器运行时 | 运行容器的底层引擎 | All |
| CNI 插件(Calico) | Pod 网络通信 | All |
Kubeadm 安装流程
1. 环境准备(主机名、hosts、免密、swap、内核参数、防火墙、时间同步) ↓ 2. 安装 Docker + cri-dockerd ↓ 3. 安装 kubeadm/kubelet/kubectl ↓ 4. kubeadm init 初始化 Master 节点 ↓ 5. 配置 kubectl ↓ 6. kubeadm join 添加 Worker 节点 ↓ 7. 安装 CNI 网络插件(Calico) ↓ 8. 验证集群状态关键命令速查
| 命令 | 作用 |
|---|---|
kubeadm init | 初始化集群 |
kubeadm join | 将节点加入集群 |
kubeadm reset | 重置集群 |
kubectl get nodes | 查看节点状态 |
kubectl label nodes | 给节点打标签 |
kubectl apply -f calico.yaml | 部署网络插件 |
kubectl run | 创建测试 Pod |
注意事项
- SELinux 必须关闭:Kubernetes 与 SELinux 存在兼容性问题。
- Swap 必须关闭:kubelet 要求禁用 Swap。
- 网络插件必须在集群初始化后立即安装:否则节点状态为
NotReady。 - cri-dockerd 必须指定正确的 socket 路径:
--cri-socket=unix:///var/run/cri-dockerd.sock。 - Pod 网络 CIDR 必须与网络插件配置一致:此处为
10.244.0.0/16。
