Kubernetes 集群大致分为两类:一主多从和多主多从。
为了测试方便,本次搭建的是一主多从类型的集群。
Kubernetes 有多种部署方式,目前主流的方式有 kubeadm 、minikube 、二进制包。
① minikube:一个用于快速搭建单节点的 Kubernetes 工具。
② kubeadm:一个用于快速搭建Kubernetes 集群的工具(可以用于生产环境)。
③ 二进制包:从官网上下载每个组件的二进制包,依次去安装(建议生产环境使用)。
角色 | IP地址 | 操作系统 | 配置 | hostname |
---|---|---|---|---|
Master | 192.168.68.100 | CentOS 7.9,基础设施服务器 | 2核CPU,4G内存,50G硬盘 | k8s-master |
Node1 | 192.168.68.101 | CentOS 7.9,基础设施服务器 | 2核CPU,4G内存,50G硬盘 | k8s-node1 |
Node2 | 192.168.68.102 | CentOS 7.9,基础设施服务器 | 2核CPU,4G内存,50G硬盘 | k8s-node2 |
① 准备 3 台机器,要求网络互通(如果是云服务器,要求私网互通;如果是虚拟机,要求网络互通)。
② 在 3 台机器上安装 Docker 容器化环境。
③ 安装 Kubernetes :
示例版本:v1.21
如果是虚拟机则需要让三台机器互通,最简单的做法就是关闭防火墙。
systemctl stop firewalld # 停止运行
systemctl disable firewalld # 禁用,禁止开机启动
systemctl status firewalld # 查看状态
如果是云厂商提供的云服务器则需要让三台机器的私有 IP 互通,不懂的,请查看《云平台操作》,而且还需要设置安全组策略放行指定的端口。
3.1 升级系统内核
cat /etc/redhat-release
uname -sr
yum install -y grub2-pc
grub2-editenv list
# 查看可用内核版本及启动顺序
sudo awk -F\' '$1=="menuentry " {print i++ " : " $2}' /boot/grub2/grub.cfg
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
温馨提示:可以替换为清华源:
sed -i "s/mirrorlist=/#mirrorlist=/g" /etc/yum.repos.d/elrepo.repo
、sed -i "s#elrepo.org/linux#mirrors.tuna.tsinghua.edu.cn/elrepo#g" /etc/yum.repos.d/elrepo.repo
。
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
yum -y --enablerepo=elrepo-kernel install kernel-lt
vim /etc/default/grub
修改如下:
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=0 # 修改此处,原来是 saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
温馨提示:也可以使用这个命令 sed -i 's/^GRUB_DEFAULT=saved$/GRUB_DEFAULT=0/' /etc/default/grub
。
重新创建内核配置
grub2-mkconfig -o /boot/grub2/grub.cfg
重启系统:
reboot
3.2 设置主机名
命令:
hostnamectl set-hostname <hostname>
示例:
# 192.168.65.100
hostnamectl set-hostname k8s-master
# 192.168.65.101
hostnamectl set-hostname k8s-node1
# 192.168.65.102
hostnamectl set-hostname k8s-node2
3.3 主机名解析
为了方便后面集群节点间的直接调用,需要配置一下主机名解析,企业中推荐使用内部的 DNS 服务器。
cat >> /etc/hosts << EOF
127.0.0.1 $(hostname)
192.168.65.100 k8s-master
192.168.65.101 k8s-node1
192.168.65.102 k8s-node2
EOF
3.4 时间同步
Kubernetes 要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步:
yum install ntpdate -y
ntpdate time.windows.com
3.5 关闭 SELinux
getenforce
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0
3.6 关闭 swap 分区
sed -ri 's/.*swap.*/#&/' /etc/fstab
swapoff -a
3.7 将桥接的 IPv4 流量传递到 iptables 的链
# 如果有配置,则修改
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
# 可能没有,追加
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
modprobe br_netfilter
sysctl -p
3.8 开启 ipvs
在 Kubernetes 中 service 有两种代理模型,一种是基于 iptables ,另一种是基于 ipvs 的。ipvs 的性能要高于 iptables 的,但是如果要使用它,需要手动载入 ipvs 模块。
在三台机器安装 ipset 和 ipvsadm
yum -y install ipset ipvsadm
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
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
3.9 重启
reboot
3.10 Docker 安装
三台机器上都安装 Docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
yum -y install gcc
yum -y install gcc-c++
yum -y install yum-utils
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum list docker-ce --showduplicates | sort -r
yum -y install docker-ce-3:20.10.8-3.el7.x86_64 docker-ce-cli-1:20.10.8-3.el7.x86_64 containerd.io
# 启动 Docker
systemctl start docker
# 开启自动启动
systemctl enable docker
docker version
sudo mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://du3ia00u.mirror.aliyuncs.com",
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://docker.nju.edu.cn",
"https://docker.mirrors.sjtug.sjtu.edu.cn"
],
"live-restore": true,
"log-driver":"json-file",
"log-opts": {"max-size":"500m", "max-file":"3"},
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 5,
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.11 添加阿里云的 Kubernetes 的 YUM 源
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
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
3.12 安装 kubelet 、kubeadm 和 kubectl
yum install -y kubelet-1.21.10 kubeadm-1.21.10 kubectl-1.21.10
/etc/sysconfig/kubelet
文件的内容:vim /etc/sysconfig/kubelet
# 修改
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
systemctl enable kubelet
kubeadm config images list
技巧:有大佬已经将墙外的 Docker 镜像同步到 DockerHub 中,地址在这里:https://github.com/x-mirrors/gcr.io ,大家可以去看看。
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.21.10
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.4.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.13-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.8.0 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
kubeadm config images pull --kubernetes-version=v1.21.10 \
--image-repository registry.aliyuncs.com/google_containers
# 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
kubeadm init \
--apiserver-advertise-address=192.168.65.100 \
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers \
--kubernetes-version=v1.21.10 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=10.244.0.0/16
注意:
apiserver-advertise-address 一定要是主机的 IP 地址。
apiserver-advertise-address 、service-cidr 和 pod-network-cidr 不能在同一个网络范围内。
不要使用 172.17.0.1/16 网段范围,因为这是 Docker 默认使用的。
日志如下:
Your Kubernetes control-plane has initialized successfully!
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
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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.65.100:6443 --token tluojk.1n43p0wemwehcmmh \
--discovery-token-ca-cert-hash sha256:c50b25a5e00e1a06cef46fa5d885265598b51303f1154f4b582e0df21abfa7cb
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 如果是 root 用户,还可以执行如下命令
export KUBECONFIG=/etc/kubernetes/admin.conf
kubeadm token create --print-join-command
# 生成一个永不过期的token
kubeadm token create --ttl 0 --print-join-command
kubeadm join 192.168.65.100:6443 --token tluojk.1n43p0wemwehcmmh \
--discovery-token-ca-cert-hash sha256:c50b25a5e00e1a06cef46fa5d885265598b51303f1154f4b582e0df21abfa7cb
官网。
Kubernetes 支持多种网络插件,比如 flannel、calico、canal 等,任选一种即可,本次选择 calico(在 192.168.65.100 节点上执行,网络不行,请点这里 calico.yaml)。
calico 和 k8s 的版本对应 。
kubectl apply -f https://projectcalico.docs.tigera.io/v3.19/manifests/calico.yaml
备注:为什么使用 3.19 , 原因在这里 。
kubectl get pods -n kube-system
watch kubectl get pods -n kube-system
kubectl get nodes
kubectl edit cm kube-proxy -n kube-system
apiVersion: v1
data:
config.conf: |-
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
bindAddressHardFail: false
clientConnection:
acceptContentTypes: ""
burst: 0
contentType: ""
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
qps: 0
clusterCIDR: 10.244.0.0/16
configSyncPeriod: 0s
conntrack:
maxPerCore: null
min: null
tcpCloseWaitTimeout: null
tcpEstablishedTimeout: null
detectLocalMode: ""
enableProfiling: false
healthzBindAddress: ""
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: null
minSyncPeriod: 0s
syncPeriod: 0s
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
strictARP: false
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kind: KubeProxyConfiguration
metricsBindAddress: ""
mode: ""
nodePortAddresses: null
minSyncPeriod: 0s
syncPeriod: 0s
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
strictARP: false
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kind: KubeProxyConfiguration
metricsBindAddress: ""
mode: "ipvs" # 修改此处
...
kubectl delete pod -l k8s-app=kube-proxy -n kube-system
# 192.168.65.101 和 192.168.65.102
mkdir -pv ~/.kube
touch ~/.kube/config
# 192.168.65.100
scp /etc/kubernetes/admin.conf [email protected]:~/.kube/config
# 192.168.65.100
scp /etc/kubernetes/admin.conf [email protected]:~/.kube/config
kubectl create deployment nginx --image=nginx:1.14-alpine
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pods,svc
# 安装
yum -y install bash-completion
# 自动补全
echo 'source <(kubectl completion bash)' >>~/.bashrc
kubectl completion bash >/etc/bash_completion.d/kubectl
# 全局
kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null
source /usr/share/bash-completion/bash_completion