Tips:
a.原文可参考https://kuboard.cn/install/install-k8s.html,真的是非常详细的一个关于学习kubernetes的地方,新大陆!
b.另外在搜索资料的时候发现了github上的一个kubeasz项目,项目的目标是致力于提供快速部署高可用k8s集群的工具, 同时也努力成为k8s实践、使用的参考书。我还没有尝试过,各位大佬可以吃个瓜先。
c.此次部署使用kubeadmin和calico的方式部署,k8s的另外覆盖网络的方式flannel请参考:https://www.cnblogs.com/Liuxz/p/13254617.html 进行部署。
d.对于初学者来说或,有很多新的概念,容易混淆。可以通过Deployment和DaemonSet、calico与flannel对比一些资料更好的帮助自己去了解概念的差异。
e.使用YUM配合flannel部署K8S的案例可参考利用Centos7 YUM 快速搭建Kubernetes集群,部署完成但是没有实际跑容器进行测试,各位大佬可以完善一下。
1. 部署架构
角色 | IP | 服务 | VCPU | 内存 |
---|---|---|---|---|
master | 192.168.199.30 | etcd、kube-apiserver、kube-scheduler、kube-controller-manager、kube-proxy、calico-node | 4 | 4 |
node1 | 192.168.199.31 | kube-proxy、calico-node | 4 | 4 |
2. 设置主机名及相关环境准备
(1) 在两台主机上执行以下操作
- 编辑
/etc/hostname
文件,将其中主机名修改为master和node1,并编辑/etc/hosts
文件,修改内容为:
192.168.199.31 node1
192.168.199.30 master
192.168.199.30 etcd
192.168.199.30 apiserver.k8s
- 关闭防火墙
[root@master yum.repos.d]# systemctl stop firewalld
[root@master yum.repos.d]# systemctl disable firewalld
- 关闭swap
swap,这个当内存不足时,linux会自动使用swap,将部分内存数据存放到磁盘中,这个这样会使性能下降,为了性能考虑推荐关掉
[root@master yum.repos.d]# swapoff -a
- 关闭selinux
vi /etc/selinux/config
,关闭SELINUX
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
- 配置yum源,此处配置的是阿里的Centos 7的yum源和kubernetes源
Tips:可以在配置之前将/etc/yum.repos.d/ 下的文件都备份到bak目录下
[root@master ~]# cd /etc/yum.repos.d/ && curl -O http://mirrors.aliyun.com/repo/Centos-7.repo
[root@master yum.repos.d]# vi kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
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"
[root@master yum.repos.d]yum clean all
[root@master yum.repos.d]#yum makecache
-
reboot
重启操作系统,使hostname、SELINUX配置生效
3. 安装docker及kubelet(每个节点都需要安装,本案例即master和node1)
命令安装(效果等同于手动脚本安装)
# 在 master 节点和 worker 节点都要执行
# 最后一个参数 1.19.2 用于指定 kubenetes 版本,支持所有 1.19.x 版本的安装
# 腾讯云 docker hub 镜像
# export REGISTRY_MIRROR="https://mirror.ccs.tencentyun.com"
# DaoCloud 镜像
# export REGISTRY_MIRROR="http://f1361db2.m.daocloud.io"
# 华为云镜像
# export REGISTRY_MIRROR="https://05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.com"
# 阿里云 docker hub 镜像
export REGISTRY_MIRROR=https://5xcgs6ii.mirror.aliyuncs.com
curl -sSL https://kuboard.cn/install-script/v1.19.x/install_kubelet.sh | sh -s 1.19.2
手动脚本安装
也可以选择手动安装部署,将install_kubelet.sh下载到本地之后,修改其中的${1}为将要安装的kubernetes版本,本案例修改为1.19.2 。注意在手动运行脚本之前先声明变量REGISTRY_MIRROR。 修改好的脚本内容:
#!/bin/bash
# 在 master 节点和 worker 节点都要执行
export REGISTRY_MIRROR=https://5xcgs6ii.mirror.aliyuncs.com
# 安装 docker
# 参考文档如下
# https://docs.docker.com/install/linux/docker-ce/centos/
# https://docs.docker.com/install/linux/linux-postinstall/
# 卸载旧版本
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
# 设置 yum repository
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装并启动 docker
yum install -y docker-ce-19.03.11 docker-ce-cli-19.03.11 containerd.io-1.2.13
mkdir /etc/docker || true
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["${REGISTRY_MIRROR}"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# Restart Docker
systemctl daemon-reload
systemctl enable docker
systemctl restart docker
# 安装 nfs-utils
# 必须先安装 nfs-utils 才能挂载 nfs 网络存储
yum install -y nfs-utils
yum install -y wget
# 关闭 防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭 SeLinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 关闭 swap
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab
# 修改 /etc/sysctl.conf
# 如果有配置,则修改
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
# 执行命令以应用
sysctl -p
# 配置K8S的yum源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[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
# 卸载旧版本
yum remove -y kubelet kubeadm kubectl
# 安装kubelet、kubeadm、kubectl
# 将 ${1} 替换为 kubernetes 版本号,例如 1.19.2
yum install -y kubelet-1.19.2 kubeadm-1.19.2 kubectl-1.19.2
# 重启 docker,并启动 kubelet
systemctl daemon-reload
systemctl restart docker
systemctl enable kubelet && systemctl start kubelet
docker version
Tips:
如果此时执行 systemctl status kubelet 命令,将得到 kubelet 启动失败的错误提示,请忽略此错误,因为必须完成后续步骤中 kubeadm init 的操作,kubelet 才能正常启动
4. 初始化 master 节点
Tips:
关于初始化时用到的环境变量
- APISERVER_NAME 不能是 master 的 hostname
- APISERVER_NAME 必须全为小写字母、数字、小数点,不能包含减号
- POD_SUBNET 所使用的网段不能与 master节点/worker节点 所在的网段重叠。该字段的取值为一个 CIDR 值,如果您对 CIDR 这个概念还不熟悉,请仍然执行 export POD_SUBNET=10.100.0.1/16 命令,不做修改.
命令行初始化(效果等同手动脚本初始化)
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点实际 IP(请使用内网 IP)
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP=x.x.x.x
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=10.100.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
curl -sSL https://kuboard.cn/install-script/v1.19.x/init_master.sh | sh -s 1.19.2
手动脚本初始化
将init_master.sh下载到本地之后,修改其中的${1}为将要安装的kubernetes版本,本案例修改为1.19.2 。 修改好的脚本内容:
#!/bin/bash
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点的内网IP
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP=x.x.x.x
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=10.100.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
# 脚本出错时终止执行
set -e
if [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; then
echo -e "\033[31;1m请确保您已经设置了环境变量 POD_SUBNET 和 APISERVER_NAME \033[0m"
echo 当前POD_SUBNET=$POD_SUBNET
echo 当前APISERVER_NAME=$APISERVER_NAME
exit 1
fi
# 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
rm -f ./kubeadm-config.yaml
cat <<EOF > ./kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.19.2
imageRepository: registry.aliyuncs.com/k8sxio
controlPlaneEndpoint: "${APISERVER_NAME}:6443"
networking:
serviceSubnet: "10.96.0.0/16"
podSubnet: "${POD_SUBNET}"
dnsDomain: "cluster.local"
EOF
# kubeadm init
# 根据您服务器网速的情况,您需要等候 3 - 10 分钟
kubeadm init --config=kubeadm-config.yaml --upload-certs
# 配置 kubectl
rm -rf /root/.kube/
mkdir /root/.kube/
cp -i /etc/kubernetes/admin.conf /root/.kube/config
# 安装 calico 网络插件
# 参考文档 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises
echo "安装calico-3.13.1"
rm -f calico-3.13.1.yaml
wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml
kubectl apply -f calico-3.13.1.yaml
检查master初始化结果
# 只在 master 节点执行
# 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
watch kubectl get pod -n kube-system -o wide
# 查看 master 节点初始化结果
kubectl get nodes -o wide
Tips:如果 watch kubectl get pod -n kube-system -o wide
的输出结果中出现 ImagePullBackoff 或者长时间处于 Pending 的情况,可以参考 查看镜像抓取进度。其中很大几率的原因是在pull calico的时候去Registry上拉取calico/cni:v3.13.1
、calico/pod2daemon-flexvol:v3.13.1
、calico/node:v3.13.1
、calico/kube-controllers:v3.13.1
四个镜像出了问题。我虽然在之前安装的时候都做了国内docker镜像仓库加速,但是在实验的时候还是卡在这个步骤。可以尝试以下几种解决办法:
- 修改为仓库加速路径为:
imageRepository: gcr.azk8s.cn/google-containers
[root@master ~]kubectl delete -f calico-3.13.1.yaml [root@master ~]watch kubectl get pods -n kube-system -o wide # 确保所有的calico pod都删除之后继续运行以下命令 [root@master ~]docker pull calico/cni:v3.13.1 [root@master ~]docker pull calico/pod2daemon-flexvol:v3.13.1 [root@master ~]docker pull calico/node:v3.13.1 [root@master ~]docker pull calico/kube-controllers:v3.13.1 [root@master ~]rm -f calico-3.13.1.yaml [root@master ~]wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml [root@master ~]kubectl apply -f calico-3.13.1.yaml
5. 初始化 worker节点
Tips:如果之前在init master的步骤的时候没有记录加入的token和命令,那么可以执行以下命令获取加入集群的命令
在 master 节点上执行
# 只在 master 节点执行
kubeadm token create --print-join-command
可获取kubeadm join 命令及参数,如下所示:
kubeadm join apiserver.k8s:6443 --token s5161o.c2e5k40x9ho0g92z --discovery-token-ca-cert-hash sha256:bada8ae90761ce9427d5331cce13d5d31106836489c9dd4c952f4fd49471dad5
Tips:有效时间
该 token 的有效时间为 2 个小时,2小时内,您可以使用此 token 初始化任意数量的 worker 节点
检查初始化结果
# 只在 master 节点执行
[root@master ~]# kubeadm token create --print-join-command
W1114 07:09:31.680441 26133 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
kubeadm join apiserver.k8s:6443 --token s5161o.c2e5k40x9ho0g92z --discovery-token-ca-cert-hash sha256:bada8ae90761ce9427d5331cce13d5d31106836489c9dd4c952f4fd49471dad5
[root@master ~]# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready master 7h1m v1.19.2 192.168.199.30 <none> CentOS Linux 7 (Core) 3.10.0-1127.el7.x86_64 docker://19.3.11
node1 Ready <none> 6h27m v1.19.2 192.168.199.31 <none> CentOS Linux 7 (Core) 3.10.0-1127.el7.x86_64 docker://19.3.11
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 7h2m v1.19.2
node1 Ready <none> 6h28m v1.19.2
[root@master ~]#
以上, 整个kubernetes的两台集群部署已经完成。下面我们可以用过部署kuboard来验证k8s的正常运行,并对整个k8s的集群状态进行监控和管理。
6. 部署kuboard
运行以下两条命令进行部署
kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml
kubectl apply -f https://addons.kuboard.cn/metrics-server/0.3.7/metrics-server.yaml
查看 Kuboard 运行状态:
[root@master ~]# kubectl get pods -l k8s.kuboard.cn/name=kuboard -n kube-system
NAME READY STATUS RESTARTS AGE
kuboard-74c645f5df-8b92n 1/1 Running 0 3h55m
[root@master ~]#
6.1 获取Token进行页面登陆
-
管理员用户
此Token拥有 ClusterAdmin 的权限,可以执行所有操作。
# 如果您参考 www.kuboard.cn 提供的文档安装 Kuberenetes,可在第一个 Master 节点上执行此命令
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)
- 只读用户
拥有的权限:
view 可查看名称空间的内容
system:node 可查看节点信息
system:persistent-volume-provisioner 可查看存储类和存储卷声明的信息
执行如下命令可以获得 只读用户 的 Token
# 如果您参考 www.kuboard.cn 提供的文档安装 Kuberenetes,可在第一个 Master 节点上执行此命令
echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-viewer | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)
6.2 访问Kuboard
Kuboard Service 使用了 NodePort 的方式暴露服务,NodePort 为 32567。可以按如下方式访问 Kuboard:
http://任意一个Worker节点的IP地址:32567/
输入前一步骤中获得的 token,可进入 Kuboard 集群概览页。
Tips:
详情可参考原文:https://kuboard.cn/install/install-dashboard.html