Kubernetes集群搭建指南:高效优化与最佳实践
- [1. 准备工作](#1. 准备工作)
-
- [1.1 提前说明](#1.1 提前说明)
- [1.2 相关IP地址](#1.2 相关IP地址)
- [2. 配置和安装](#2. 配置和安装)
-
- [2.1 配置主机名](#2.1 配置主机名)
- [2.2 配置hosts](#2.2 配置hosts)
- [2.3 下载依赖](#2.3 下载依赖)
- [2.4 设置防火墙为 Iptables 并设置空规则](#2.4 设置防火墙为 Iptables 并设置空规则)
- [2.5 关闭 SELINUX](#2.5 关闭 SELINUX)
- [2.6 调整内核参数](#2.6 调整内核参数)
- [2.7 调整系统时区](#2.7 调整系统时区)
- [2.8 设置 rsyslogd 和 systemd journald](#2.8 设置 rsyslogd 和 systemd journald)
- [2.9 kube-proxy开启ipvs的前置条件](#2.9 kube-proxy开启ipvs的前置条件)
- [3. 集群安装](#3. 集群安装)
-
- [3.1 安装Docker](#3.1 安装Docker)
- [3.2 安装kubeadm,kubelet和kubectl](#3.2 安装kubeadm,kubelet和kubectl)
- [3.3 初始化 kubernetes](#3.3 初始化 kubernetes)
-
- [3.3.1 Master 初始化](#3.3.1 Master 初始化)
- [3.3.1 配置集群相关信息](#3.3.1 配置集群相关信息)
- [3.3.2 将Node节点加入到集群中](#3.3.2 将Node节点加入到集群中)
- [4. 配置网络插件](#4. 配置网络插件)
-
- [4.1 下载flannel](#4.1 下载flannel)
- [4.2 执行文件](#4.2 执行文件)
- [5. 调整 kube-proxy 性能模式](#5. 调整 kube-proxy 性能模式)
- 6、搭建成功
- 7、安装Rancher
-
- [7.1 安装环境](#7.1 安装环境)
- [7.2 查看密码](#7.2 查看密码)
- [7.3 登录平台](#7.3 登录平台)
提示:
如果沒有安装虚拟机,可以参考《使用 VMware 在 Windows 上搭建 Linux 系统的完整指南》
1. 准备工作
1.1 提前说明
注意:
在特定节点执行命令时,请使用节点名称指定。例如,在执行命令时,只需在名为master的服务器上执行,无需在其他服务器(如node节点)上执行命令。
1.2 相关IP地址
IP地址 | 节点名称 | 备注 |
---|---|---|
192.168.40.128 | master | 配置2核CPU |
192.168.40.129 | node1 | 工作节点 |
192.168.40.130 | node2 | 工作节点 |
192.168.40.131 | rancher | rancher平台(此文章不介绍搭建流程) |
2. 配置和安装
2.1 配置主机名
shell
# master节点
hostnamectl set-hostname master
# node1节点
hostnamectl set-hostname node1
# node2节点
hostnamectl set-hostname node2
# rancher节点
hostnamectl set-hostname rancher
2.2 配置hosts
shell
# master 、 node 、rancher 节点执行该命令
cat <<EOF>> /etc/hosts
192.168.40.128 master
192.168.40.129 node1
192.168.40.130 node2
192.168.40.131 rancher
EOF
2.3 下载依赖
Master和所有Node节点执行该shell命令
shell
yum install -y conntrack ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git
2.4 设置防火墙为 Iptables 并设置空规则
Master和所有Node节点执行该shell命令
shell
# Master和所有Node节点执行该命令
systemctl stop firewalld && systemctl disable firewalld
# Master和所有Node节点执行该命令
yum -y install iptables-services && systemctl start iptables && systemctl enable iptables && iptables -F && service iptables save
2.5 关闭 SELINUX
Master和所有Node节点执行该shell命令
shell
# Master和所有Node节点执行该命令
swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# Master和所有Node节点执行该命令
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
2.6 调整内核参数
Master和所有Node节点执行该shell命令
shell
# Master和所有Node节点执行该命令
modprobe br_netfilter
# Master和所有Node节点执行该命令
cat <<EOF> kubernetes.conf
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
# Master和所有Node节点执行该命令
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
# Master和所有Node节点执行该命令
sysctl -p /etc/sysctl.d/kubernetes.conf
2.7 调整系统时区
Master和所有Node节点执行该shell命令
shell
# 设置系统时区为 中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart crond
2.8 设置 rsyslogd 和 systemd journald
Master和所有Node节点执行该shell命令
shell
# 持久化保存日志的目录
mkdir /var/log/journal
mkdir /etc/systemd/journald.conf.d
Master和所有Node节点执行该shell命令
shell
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
Master和所有Node节点执行该shell命令
shell
systemctl restart systemd-journald
2.9 kube-proxy开启ipvs的前置条件
Master和所有Node节点执行该shell命令
shell
cat <<EOF> /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
Master和所有Node节点执行该shell命令
shell
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
3. 集群安装
3.1 安装Docker
Master、Rancher和所有Node节点执行该shell命令
shell
# 安装工具
yum install -y yum-utils device-mapper-persistent-data lvm2
shell
# 添加镜像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
shell
# 列出版本
yum list docker-ce.x86_64 --showduplicates |sort
## 建议安装 19.03版本
yum -y install docker-ce-19.03.15-3.el8 docker-ce-cli-19.03.15-3.el8
shell
## 创建 /etc/docker 目录
mkdir /etc/docker
shell
# 写入内容
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://gqs7xcfd.mirror.aliyuncs.com","https://hub-mirror.c.163.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
shell
# 启动且配置docker服务
systemctl daemon-reload && systemctl enable docker && systemctl start docker
3.2 安装kubeadm,kubelet和kubectl
Master和所有Node节点执行该shell命令
shell
# 写入文件
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=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
shell
### 列出所有版本 建议安装 1.18.8
yum list kubelet --showduplicates
# 安装
yum install -y kubelet-1.18.8 kubeadm-1.18.8 kubectl-1.18.8
# 自启动
systemctl enable kubelet
3.3 初始化 kubernetes
3.3.1 Master 初始化
Master节点执行该shell命令
- 执行命令
shell
kubeadm init \
--kubernetes-version 1.18.8 \
--apiserver-advertise-address=192.168.40.128 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers
解释一下每个参数的含义
:
- kubernetes-version 1.18.8:指定所需的 Kubernetes 版本为 1.18.8。
- apiserver-advertise-address=192.168.40.128:设置 Kubernetes API 服务器的广告地址为 192.168.40.128,这将用于与其他节点通信。
- service-cidr=10.96.0.0/16:设置服务网络 CIDR,该 CIDR 范围内的 IP 地址将用于 Kubernetes 服务。
- pod-network-cidr=10.244.0.0/16:设置 Pod 网络 CIDR,该 CIDR 范围内的 IP 地址将用于容器之间的通信。
- image-repository registry.aliyuncs.com/google_containers:指定容器镜像仓库地址,此处使用阿里云的镜像仓库以加速拉取。
请注意,这只是一个示例命令,您可以根据自己的需求进行调整和修改
- 输出的重要内容(截取了部分)
shell
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
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.126.128:6443 --token 7asz9u.eba42givcg6n1pe7 \
--discovery-token-ca-cert-hash sha256:e59a83424968d10e71c330df6d4d91cc183428b0131b9fb456c19da5a251b010
3.3.1 配置集群相关信息
Master节点执行该shell命令
(该命令由上方生成)
shell
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 查看节点
shell
kubectl get nodes
# 输出
NAME STATUS ROLES AGE VERSION
master NotReady master 17m v1.18.8
3.3.2 将Node节点加入到集群中
所有Node节点执行该shell命令
(该命令由上方生成)
shell
kubeadm join 192.168.126.128:6443 --token 7asz9u.eba42givcg6n1pe7 \
--discovery-token-ca-cert-hash sha256:e59a83424968d10e71c330df6d4d91cc183428b0131b9fb456c19da5a251b010
- 查看节点信息
shell
kubectl get nodes
# 输出错误信息
!!! !!! The connection to the server localhost:8080 was refused - did you specify the right host or port?
- 解决问题
出现这个问题的原因是kubectl命令需要使用
kubernetes-admin
来运行,解决方法如下,将Master主节点中的/etc/kubernetes/
这个目录下的.conf
文件拷贝到所有Node节点
相同目录下,然后配置环境变量:export KUBECONFIG=/etc/kubernetes/kubelet.conf
就可以了.如果node 上 /etc/kubernetes/ 目录下有kubelet.conf,只设置对应的环境变量即可(下面命令二选一)
shell
## 临时命令行
export KUBECONFIG=/etc/kubernetes/kubelet.conf
或
shell
## 写入环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
4. 配置网络插件
4.1 下载flannel
shell
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
- 也可以直接复制
kube-flannel.yml配置文件
yml
---
kind: Namespace
apiVersion: v1
metadata:
name: kube-flannel
labels:
pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-flannel
labels:
tier: node
app: flannel
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.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-flannel
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
hostNetwork: true
priorityClassName: system-node-critical
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni-plugin
#image: flannelcni/flannel-cni-plugin:v1.1.0 for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0
command:
- cp
args:
- -f
- /flannel
- /opt/cni/bin/flannel
volumeMounts:
- name: cni-plugin
mountPath: /opt/cni/bin
- name: install-cni
#image: flannelcni/flannel:v0.19.1 for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel:v0.19.1
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
#image: flannelcni/flannel:v0.19.1 for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel:v0.19.1
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN", "NET_RAW"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: EVENT_QUEUE_DEPTH
value: "5000"
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
- name: xtables-lock
mountPath: /run/xtables.lock
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni-plugin
hostPath:
path: /opt/cni/bin
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
- name: xtables-lock
hostPath:
path: /run/xtables.lock
type: FileOrCreate
4.2 执行文件
shell
# 执行命令
kubectl apply -f kube-flannel.yml
# 查看服务状态
kubectl -n kube-system get pods -o wide
# 查看节点
kubectl get nodes
5. 调整 kube-proxy 性能模式
此模式必须安装ipvs内核模块,否则会降级为iptables
shell
# 先查看当前状态
kubectl get pod -n kube-system --show-labels
ipvsadm -Ln
# 开启ipvs
# 修改mode: "ipvs"
kubectl edit cm kube-proxy -n kube-system
# 执行命令
kubectl delete pod -l k8s-app=kube-proxy -n kube-system
# 查看
ipvsadm -Ln
kube-proxy 是 Kubernetes 中的一个网络代理组件,用于将网络流量转发到正确的目标 Pod。它在每个节点上运行,并为 Pod 提供了一个虚拟 IP 地址和负载均衡功能。
kube-proxy 主要有三种模式:
Userspace Proxy(用户空间代理):在该模式下,kube-proxy 使用 Linux 的 userspace 网络堆栈来处理网络流量。它通过创建一组虚拟 IP 地址和 iptables
规则来实现服务的负载均衡。这种模式的好处是简单易用,但性能较低,特别是在大规模集群中。
IPtables Proxy(IPtables 代理):在该模式下,kube-proxy 使用 Linux 的 iptables 功能来处理网络流量。它通过 iptables 规则对流量进行转发和负载均衡。相对于 Userspace Proxy 模式,IPtables
Proxy 模式在性能方面更优,特别适用于中等规模的集群。
IPVS Proxy(IPVS 代理):在该模式下,kube-proxy 使用 Linux 的 IPVS(IP Virtual Server)功能来处理网络流量。IPVS 是 Linux 内核提供的一种高性能的负载均衡技术,它能够有效地分发流量并提供更高的性能和可靠性。IPVS Proxy, 模式适用于大规模集群以及对性能和可靠性有更高要求的场景。
可以根据集群规模和性能要求选择适合的 kube-proxy 模式。默认情况下,Kubernetes 使用 IPtables Proxy 模式,但您可以通过修改 kube-proxy 的配置来选择其他模式。
6、搭建成功
shell
[root@master /]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 47h v1.18.8
node1 Ready <none> 46h v1.18.8
node2 Ready <none> 46h v1.18.8
7、安装Rancher
注意:
确保rancher已经安装了Docker环境,若没有安装可以参考3.1章节的内容
7.1 安装环境
shell
docker run -d --name=rancher --restart=unless-stopped \
-p 80:80 -p 443:443 \
--privileged \
-v /data/rancher:/var/lib/rancher \
rancher/rancher:v2.5.15
解释一下每个参数的含义:
- -d:以后台守护进程(detached)模式运行容器。
--name=rancher:为该容器指定一个名称,此处为 "rancher"。
--restart=unless-stopped:设置容器在退出时自动重新启动,除非手动停止容器。- -p 80:80 -p 443:443:将主机的 80 端口映射到容器的 80 端口,将主机的 443 端口映射到容器的 443 端口。这样可以通过主机的 IP 地址访问 Rancher 的 Web 界面。
--privileged:提供容器内部的特权访问,以便 Rancher 可以与主机进行通信。- -v /data/rancher:/var/lib/rancher:将主机上的 /data/rancher 目录挂载到容器内的 /var/lib/rancher 目录,用于持久化存储 Rancher 的数据。
rancher/rancher:v2.5.15:指定要运行的 Rancher 容器的镜像及版本。
7.2 查看密码
shell
docker logs 容器id 2>&1 | grep "Bootstrap Password:"
7.3 登录平台
IP地址:
IP+Port(8443)