kubeadm部署k8s(v1.18.13)
目录
一、环境准备
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 # 设置master节点IP地址
$ export APISERVER_NAME=apiserver.demo # apiserver的名称可自定义
$ export POD_SUBNET=10.100.0.1/16 # K8s容器组所在的网段,该网段安装完成后,由 k8s创建
$ 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 # node节点全部处于Ready状态
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 # 确保pod都是Running的状态
$ 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
*************** 当你发现自己的才华撑不起野心时,就请安静下来学习吧!***************