基础环境
关闭防火墙
关闭防火墙,selinux
systemctl stop firewalld && systemctl disable firewalld
关闭elinux
setenforce 0
sed -i s/SELINUX=enforcing/SELINUX=disabled/ /etc/selinux/config
关闭swap分区
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
问题:k8s集群安装为什么需要关闭swap分区?
swap必须关,否则kubelet起不来,进而导致k8s集群起不来;
可能kublet考虑到用swap做数据交换的话,对性能影响比较大;
配置dns解析
cat >> /etc/hosts << EOF
172.29.9.51 master1
172.29.9.52 node1
172.29.9.53 node2
EOF
问题:k8s集群安装时节点是否需要配置dns解析?
就是后面的kubectl如果需要连接运行在node上面的容器的话,它是通过kubectl get node出来的名称去连接的,所以那个的话,我们需要在宿主机上能够解析到它。如果它解析不到的话,那么他就可能连不上;
安装 ipvs
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack # 4.19内核将nf_conntrack_ipv4更名为nf_conntrack
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack
yum install ipset -y
yum install ipvsadm -y
说明:
- 上面脚本创建了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。使用 lsmod | grep -e ip_vs -e nf_conntrack 命令查看是否已经正确加载所需的内核模块;
- 要确保各个节点上已经安装了 ipset 软件包,因此需要:yum install ipset -y;
- 为了便于查看 ipvs 的代理规则,最好安装一下管理工具 ipvsadm:yum install ipvsadm -y
ipset
ip set 是linux内核的一个内部框架, 可由ipset工具管理,ip set 可以分为以下几种类型:ip地址, 网路地址(网段),tcp/udp 端口号, mac地址, 网卡名称。或者是上述类型的组合,并保证快速的匹配。
ipset 适用于以下几种场景:
(1)一次性存储大量的ip或者端口,用以iptables匹配
(2)在不影响性能的前提下,动态更新iptables规则(针对ip或者端口)
(3)期望使用ipset的告诉匹配,或者在一条iptables规则中表达复杂的 ip/端口规则
同步服务器时间
yum install chrony -y
systemctl enable chronyd --now
chronyc sources
Containerd
配置内核参数
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# Setup required sysctl params, these persist across reboots.
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
# Apply sysctl params without reboot
sudo sysctl --system
安装
卸载之前的版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装 yum-utils
sudo yum install -y yum-utils
安装 containerd
yum install containerd.io
配置
如果 /etc/containerd/ 中没有配置文件,需要创建
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
将 containerd 的 cgroup driver 配置为 systemd
对于使用 systemd 作为 init system 的 Linux 的发行版,使用 systemd 作为容器的 cgroup driver 可以确保节点在资源紧张的情况更加稳定,所以推荐将 containerd 的 cgroup driver 配置为 systemd。
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
配置 sandbox_image
特别注意:containerd 中 sandbox_image pause 镜像版本会覆盖 pause 镜像版本
/etc/containerd/config.toml
sandbox_image = "k8s.gcr.io/pause:3.2" ==> 3.6 # 设置成 kubeadm 需要的 pause 镜像版本
配置代理
无法下载 k8s.gcr.io 中的精选,需要设置代理。containerd 不像 docker 那样支持使用 systemd 方式配置代理。但是可以通过配置全局代理,让 containerd 可以通过代理下载镜像。
vim ~/.bashrc
export HTTP_PROXY="http://<user>:<password>@<proxy_server>:<port>"
export HTTPS_PROXY="http://<user>:<password>@<proxy_server>:<port>"
然后应用配置
source ~/.bashrc
启动
systemctl daemon-reload
systemctl enable --now containerd.service
验证
$ ctr version
Client:
Version: 1.4.12
Revision: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
Go version: go1.16.10
Server:
Version: 1.4.12
Revision: 7b11cfaabd73bb80907dd23182b9347b4245eb5d
UUID: d1df458b-b13c-4a65-9579-4c914abf0e00
$ rictl version
Version: 0.1.0
RuntimeName: containerd
RuntimeVersion: 1.4.12
RuntimeApiVersion: v1alpha2
kubeadm
配置内核参数
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
注意:将桥接的IPv4流量传递到iptables的链
由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块:
modprobe br_netfilter
bridge-nf 使得 netfilter 可以对 Linux 网桥上的 IPv4/ARP/IPv6 包过滤。比如,设置net.bridge.bridge-nf-call-iptables=1后,二层的网桥在转发包时也会被 iptables的 FORWARD 规则所过滤。常用的选项包括:
- net.bridge.bridge-nf-call-arptables:是否在 arptables 的 FORWARD 中过滤网桥的 ARP 包
- net.bridge.bridge-nf-call-ip6tables:是否在 ip6tables 链中过滤 IPv6 包
- net.bridge.bridge-nf-call-iptables:是否在 iptables 链中过滤 IPv4 包
- net.bridge.bridge-nf-filter-vlan-tagged:是否在 iptables/arptables 中过滤打了 vlan 标签的包。
配置 yum 源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.cloud.tencent.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
exclude=kubelet kubeadm kubectl
EOF
关闭 SELinux
# Set SELinux in permissive mode (effectively disabling it)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
安装
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
sudo systemctl enable --now kubelet
说明:--disableexcludes 禁掉除了kubernetes之外的别的仓库
初始化集群
master节点配置
然后我们可以通过下面的命令在 master 节点上输出集群初始化默认使用的配置:
# 生成默认配置
kubeadm config print init-defaults --component-configs KubeletConfiguration > kubeadm.yaml
# 生成KubeletConfiguration示例文件
kubeadm config print init-defaults --component-configs KubeletConfiguration
# 生成KubeProxyConfiguration示例文件
kubeadm config print init-defaults --component-configs KubeProxyConfiguration
cat kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.0.24.16 # master 节点的 IP
bindPort: 6443
nodeRegistration:
criSocket: /run/containerd/containerd.sock # 修改成 containerd.sock
imagePullPolicy: IfNotPresent
name: master 修改成 master 节点 hostname
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
external: # 配置外部 etcd 集群
endpoints:
- https://172.21.16.14:2379
- https://172.21.16.6:2379
- https://172.21.16.13:2379
caFile: /root/kubeadm-init/ssl/ca.pem
certFile: /root/kubeadm-init/ssl/client.pem
keyFile: /root/kubeadm-init/ssl/client-key.pem
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: 1.22.4 # 修改 kubernetes 集群版本
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/16 # 修改 service IP 段
podSubnet: 10.97.0.0/16 # 修改 pod IP 段
scheduler: {}
---
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
cgroupDriver: systemd # 配置 cgroup driver
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
cpuManagerReconcilePeriod: 0s
evictionPressureTransitionPeriod: 0s
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimumGCAge: 0s
kind: KubeletConfiguration
logging: {}
memorySwap: {}
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
rotateCertificates: true
runtimeRequestTimeout: 0s
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
网络配置
kubeadm配置文件中podSubnet 和 flannel 配置文件中 Network 需要一致
kubeadm.yaml
podSubnet: 10.97.0.0/16
flannel.yaml
net-conf.json: |
{
"Network": "10.97.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
然后根据我们自己的需求修改配置,比如修改 imageRepository 指定集群初始化时拉取 Kubernetes 所需镜像的地址,kube-proxy 的模式为 ipvs,另外需要注意的是我们这里是准备安装 flannel 网络插件的,需要将 networking.podSubnet 设置为10.244.0.0/16:
拉取 k8s 容器镜像
查看镜像
kubeadm config images list
I1211 19:12:18.444683 199744 version.go:255] remote version is much newer: v1.23.0; falling back to: stable-1.22
k8s.gcr.io/kube-apiserver:v1.22.4
k8s.gcr.io/kube-controller-manager:v1.22.4
k8s.gcr.io/kube-scheduler:v1.22.4
k8s.gcr.io/kube-proxy:v1.22.4
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4
kubeadm config images list --config kubeadm.yaml
k8s.gcr.io/kube-apiserver:v1.22.4
k8s.gcr.io/kube-controller-manager:v1.22.4
k8s.gcr.io/kube-scheduler:v1.22.4
k8s.gcr.io/kube-proxy:v1.22.4
k8s.gcr.io/pause:3.5
k8s.gcr.io/coredns/coredns:v1.8.4
下载镜像
配置文件准备好过后,可以使用如下命令先将相关镜像 pull 下面:
kubeadm config images pull --config kubeadm.yaml
worker 节点配置
# 加入集群
kubeadm join 192.168.31.139:6443 --token --discovery-token-ca-cert-hash XXX sha256:XXX
# 生成用于添加节点的kubeadm-config.yaml文件
kubeadm config print join-defaults > kubeadm-config.yaml
# 添加节点:
kubeadm join --config kubeadm-config.yaml
网络配置
flannel 安装
# For Kubernetes v1.17+
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
修改网络配置:kube-flannel.yml
net-conf.json: |
{
"Network": "10.97.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
安装配置
kubectl apply -f kube-flannel.yml
nfs 插件安装
安装 helm
# 下载
https://github.com/helm/helm/releases
# 解压
tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
# 添加执行权限
chmod +x helm
# 在解压目中找到helm程序,移动到需要的目录中
mv helm /usr/local/bin/
安装 nfs
github 地址
https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
$ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--set nfs.server=x.x.x.x \
--set nfs.path=/exported/path
所需要的镜像
k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2