一、环境准备
OS |
IP |
hostname |
Centos 7.6 |
192.168.99.151 |
k8s-master |
Centos 7.6 |
192.168.99.152 |
k8s-node01 |
Centos 7.6 |
192.168.99.153 |
k8s-node02 |
如果没有特殊说明,均在所有节点上执行!
二、调整系统其他配置
| $ yum install -y nfs-utils wget |
| # 安装常用工具 |
| $ systemctl stop firewalld && systemctl disable firewalld |
| # 关闭防火墙 |
| $ setenforce 0 |
| $ sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config |
| # 禁用SELinux |
| $ swapoff -a |
| $ sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab |
| $ mount -a |
| # 禁用交换分区 |
| |
| # 注意,修改内核参数,如果文件中有相应内容执行该操作修改 |
| $ sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf |
| $ sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf |
| $ sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf |
| $ sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g" /etc/sysctl.conf |
| $ sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g" /etc/sysctl.conf |
| $ sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g" /etc/sysctl.conf |
| $ sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g" /etc/sysctl.conf |
| |
| # 修改内核参数,如果是纯净的系统,应执行该操作添加内核参数 |
| $ cat >> /etc/sysctl.conf <<EOF |
| net.ipv4.ip_forward = 1 |
| net.bridge.bridge-nf-call-ip6tables = 1 |
| net.bridge.bridge-nf-call-iptables = 1 |
| net.ipv6.conf.all.disable_ipv6 = 1 |
| net.ipv6.conf.default.disable_ipv6 = 1 |
| net.ipv6.conf.lo.disable_ipv6 = 1 |
| net.ipv6.conf.all.forwarding = 1 |
| EOF |
| # 修改内核参数,二选一即可 |
| |
| $ sysctl -p # 使内核参数生效 |
三、升级系统内核
由于这次安装的k8s 1.18.13,建议将内核升级至最新版本,否则可能会出现意想不到的错误!
| $ uname -r |
| 3.10.0-957.el7.x86_64 |
| $ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org |
| # 载入公钥 |
| $ yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm |
| # 安装elrepo最新版本 |
| $ yum list available --disablerepo=* --enablerepo=elrepo-kernel |
| # 列出可以使用的 kernel 包版本 |
| $ yum -y install kernel-lt --enablerepo=elrepo-kernel |
| # 如果不指定版本信息,默认安装最新的,如果需要安装指定版本可以使用以下方式 |
| $ yum -y install kernel-lt-5.4.128-1.el7.elrepo --enablerepo=elrepo-kernel |
| # 二选一即可! |
| $ awk -F \' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg |
| # 查看当前系统可用内核版本 |
| 0 : CentOS Linux (5.4.128-1.el7.elrepo.x86_64) 7 (Core) |
| 1 : CentOS Linux (3.10.0-957.el7.x86_64) 7 (Core) |
| 2 : CentOS Linux (0-rescue-f36646e20ef14cf7b7c3d921839dd2b5) 7 (Core) |
| $ grub2-set-default 'CentOS Linux (5.4.128-1.el7.elrepo.x86_64) 7 (Core)' |
| # 设置系统启动默认加载的内核 |
| $ grub2-editenv list # 查看系统默认加载的内核 |
| saved_entry=CentOS Linux (5.4.128-1.el7.elrepo.x86_64) 7 (Core) |
| $ reboot # 重启系统加载内核 |
| $ uname -r # 确认系统已经加载了新的内核 |
| 5.4.128-1.el7.elrepo.x86_64 |
四、修改主机名,配置hosts
| $ hostnamectl set-hostname k8s-master |
| $ ssh-keygen |
| $ for i in 192.168.99.15{1..3};do ssh-copy-id ${i};done |
| $ cat >> /etc/hosts << EOF |
| 192.168.99.151 k8s-master |
| 192.168.99.152 k8s-node01 |
| 192.168.99.153 k8s-node02 |
| EOF |
| $ for i in 192.168.99.15{1..3};do scp /etc/hosts ${i}:/etc/;done |
五、安装docker 19.03
| $ yum remove -y docker \ |
| docker-client \ |
| docker-client-latest \ |
| docker-ce-cli \ |
| docker-common \ |
| docker-latest \ |
| docker-latest-logrotate \ |
| docker-logrotate \ |
| docker-selinux \ |
| docker-engine-selinux \ |
| docker-engine |
| # 卸载旧版本docker |
| $ yum install -y yum-utils \ |
| device-mapper-persistent-data \ |
| lvm2 |
| # 安装docker所需依赖 |
| $ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo |
| # 添加阿里云docker repo仓库 |
| $ yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8 containerd.io |
| # 安装指定版本的docker |
| $ [ -d /etc/docker ] || mkdir /etc/docker |
| $ tee /etc/docker/daemon.json <<EOF |
| { |
| "registry-mirrors" : [ |
| "https://nrbewqda.mirror.aliyuncs.com", |
| "https://dmmxhzvq.mirror.aliyuncs.com", |
| "https://8xpk5wnt.mirror.aliyuncs.com", |
| "https://registry.docker-cn.com" |
| ] |
| } |
| EOF |
| # 修改docker镜像下载仓库地址 |
| $ systemctl daemon-reload |
| $ systemctl start docker && systemctl enable docker |
| # 启动docker |
| $ docker version | grep 'Version' | head -1 |
| Version: 19.03.8 |
| $ docker info | grep -A1 'Registry Mirrors' # A1表示显示匹配行及匹配行后一行内容 |
| # 确认docker版本及镜像仓库地址 |
六、初始化kubernetes准备工作
| $ cat > /etc/yum.repos.d/kubernetes.repo <<EOF |
| [kubernetes] |
| name=Kubernetes |
| baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 |
| enabled=1 |
| gpgcheck=0 |
| repo_gpgcheck=0 |
| gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg |
| http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg |
| EOF |
| # 添加K8s yum源 |
| $ yum remove -y kubelet kubeadm kubectl |
| # 卸载旧版本的k8s工具(如果是纯净的系统,可省略该操作) |
| $ yum install -y kubelet-1.18.13 kubeadm-1.18.13 kubectl-1.18.13 |
| # 安装k8s常用工具 |
| $ sed -i "s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g" /usr/lib/systemd/system/docker.service |
| # 修改docker Cgroup Driver为systemd,如果不修改在添加work节点时,会出现错误 |
| $ systemctl enable kubelet |
| # 设置为开机启动即可,如果此时启动会报错,因为k8s master节点并没有完成初始化 |
七、初始化master节点
该步骤的操作仅在master节点执行即可!
| $ export MASTER_IP=192.168.99.151 |
| $ export APISERVER_NAME=apiserver.demo |
| $ export POD_SUBNET=10.100.0.1/16 |
| $ echo "$MASTER_IP $APISERVER_NAME" >> /etc/hosts |
| $ mkdir k8s_deploy && cd k8s_deploy |
| $ cat > kubeadm-config.yaml <<EOF |
| apiVersion: kubeadm.k8s.io/v1beta2 |
| kind: ClusterConfiguration |
| kubernetesVersion: v1.18.13 |
| imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers |
| controlPlaneEndpoint: "${APISERVER_NAME}:6443" |
| networking: |
| serviceSubnet: "10.96.0.0/16" |
| podSubnet: "${POD_SUBNET}" |
| dnsDomain: "cluster.local" |
| EOF |
| # 准备kubeadm初始化集群所需文件 |
| $ kubeadm init --config=kubeadm-config.yaml --upload-certs |
| # 初始化k8s集群 |
八、配置kubectl
| $ rm -rf /root/.kube/ |
| $ mkdir /root/.kube/ |
| $ cp -i /etc/kubernetes/admin.conf /root/.kube/config |
| # 配置kubectl的认证文件(管理员身份) |
| $ for i in 192.168.99.15{1..3};do scp -r ~/.kube ${i}:;done |
| # 为了方便起见,配置node节点的kubectl认证文件(管理员身份) |
| $ yum -y install bash-completion |
| $ source /usr/share/bash-completion/bash_completion |
| $ source <(kubectl completion bash) |
| $ echo "source <(kubectl completion bash)" >> ~/.bashrc |
| # 设置kubectl指令支持补全功能 |
如果初始化失败,请检查以下节点:
- 环境变量 MASTER_IP 的值应该为 master 节点的 内网IP,如果不是,请重新 export
- APISERVER_NAME 不能是 master 的 hostname
- APISERVER_NAME 必须全为小写字母、数字、小数点,不能包含减号
- POD_SUBNET 所使用的网段不能与 master节点/worker节点 所在的网段重叠。该字段的取值为一个 CIDR 值,如果对 CIDR 这个概念还不熟悉,请仍然执行 export POD_SUBNET=10.100.0.1/16 命令,不做修改
- 然后重新初始化master节点,重新初始化前,请先执行
kubeadm reset -f
操作。
九、安装calico网络插件
| $ wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml |
| # 这是kuboard官方提供的yml文件,如果失效了,请替换为官方的地址:https://docs.projectcalico.org/manifests/calico.yaml |
| $ kubectl apply -f calico-3.13.1.yaml |
| $ kubectl get pod -n kube-system -o wide |
| # 确保所有容器是Running状态 |
十、初始化work节点
master节点获取join命令参数
| $ kubeadm token create --print-join-command |
| |
| kubeadm join apiserver.demo:6443 --token xhicdc.3jwmcz2yipbo8z3d --discovery-token-ca-cert-hash sha256:79d68a2776fb3ec1cf41f7efb8bfc8ae1f8df06b9eab2cbb7319c69ff0b6d2a7 |
| # 返回的最后一条信息就是work节点加入master节点的所需的指令(包括token) |
work节点执行
| $ export MASTER_IP=192.168.99.151 |
| $ export APISERVER_NAME=apiserver.demo |
| $ echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts |
| $ kubeadm join apiserver.demo:6443 --token xhicdc.3jwmcz2yipbo8z3d --discovery-token-ca-cert-hash sha256:79d68a2776fb3ec1cf41f7efb8bfc8ae1f8df06b9eab2cbb7319c69ff0b6d2a7 |
| # 该命令就是master获取join命令的返回结果 |
master节点确认
| $ kubectl get nodes |
| NAME STATUS ROLES AGE VERSION |
| k8s-master Ready master 3m v1.18.13 |
| k8s-node01 Ready <none> 4m v1.18.13 |
| k8s-node02 Ready <none> 4m v1.18.13 |
| $ kubectl get pods -n kube-system |
| |
| $ kubectl taint node k8s-master node-role.kubernetes.io/master:NoSchedule- |
| # 去除master节点的污点 |
十一、work节点join失败
如果遇到worker节点不能成功的join到k8s集群,那么请按照以下思路来解决问题。
11.1 在worker节点执行以下语句可验证worker节点是否能访问 apiserver
| $ curl -ik https://apiserver.demo:6443 |
如果不能,请在 master 节点上验证
| $ curl -ik https://apiserver.demo:6443 |
正常输出结果如下:
| HTTP/1.1 403 Forbidden |
| Cache-Control: no-cache, private |
| Content-Type: application/json |
| X-Content-Type-Options: nosniff |
| Date: Sat, 13 Jun 2020 19:44:58 GMT |
| Content-Length: 233 |
| |
| { |
| "kind": "Status", |
| "apiVersion": "v1", |
| "metadata": { |
| |
| }, |
| "status": "Failure", |
| "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"", |
| "reason": "Forbidden", |
| "details": { |
| |
| }, |
| "code": 403 |
11.2 可能原因
- 如果 master 节点能够访问 apiserver、而 worker 节点不能,则请检查自己的网络设置
- /etc/hosts 是否正确设置?
- 是否有安全组或防火墙的限制?
- worker 节点默认网卡
- Kubelet使用的 IP 地址 与 master 节点可互通(无需 NAT 映射),且没有防火墙、安全组隔离,如果你使用 vmware 或 virtualbox 创建虚拟机用于 K8S 学习,可以尝试 NAT 模式的网络,而不是桥接模式的网络。
11.3 解决方法
11.3.1 移除worker节点并重试
注:正常情况下,无需移除 worker 节点,如果添加到集群出错,可以移除 worker 节点,再重新尝试添加。
11.3.2 在准备移除的 worker 节点上执行
| $ kubeadm reset -f |
| # worker 节点执行 |
在 master 节点上执行
| $ kubectl get nodes -o wide |
| # master节点执行,获取worker列表 |
| $ kubectl delete node demo-worker-x-x |
| # master节点执行,将demo-worker-x-x替换为你要移除的节点 |
十二、部署kuboard
| $ kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml |
| $ kubectl apply -f https://addons.kuboard.cn/metrics-server/0.3.6/metrics-server.yaml |
| $ kubectl get pods -l k8s.kuboard.cn/name=kuboard -n kube-system |
| NAME READY STATUS RESTARTS AGE |
| kuboard-7bb89b4cc4-hq46h 1/1 Running 0 5m |
| # 确保容器是正常的状态 |
| $ kubectl get svc -n kube-system | grep kuboard |
| kuboard NodePort 10.96.196.64 <none> 80:32567/TCP 5m |
| # 查看kuboard对应的svc暴露的端口 |
| $echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d) |
| # 获取管理员的token信息 |
浏览器访问:

十三、解决重启之后kubelet异常
**修改kubelet的Cgroup Driver**
修改/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
文件,增加--cgroup-driver=systemd
| $ vim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf |
| ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --cgroup-driver=systemd |
| |
| $ systemctl daemon-reload && systemctl restart kubelet |
| $ systemctl status kubelet |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律