搭建的基础
- Linux: CentOS-7-x86_64-DVD-1810.iso
- Docker: docker-ce-18.03.1.ce
- kubernetes: kubernetes v1.16.7
参考博文:
kubernetes---CentOS7安装kubernetes1.11.2图文完整版
Centos7.6部署k8s v1.16.4高可用集群(主备模式)
kubeadm安装kubernetes1.13集群
k8s和docker还有linux系统有版本对应关系,具体的可以在github上面看
链接地址:https://github.com/kubernetes/kubernetes/releases
在CHANGELOG里面有,大概在这个位置,这里选择kubernetes v1.16.7
注意:Kubernetes 是google的东西,几乎所有的安装组件和 Docker 镜像都放在 goolge 自己的网站上,要么克服网络问题,要么使用国内的镜像,例如阿里云的镜像。
安装方式
Kubernetes 的安装方式大体有三种,这里搭建选择的第三种
- yum安装,好处是简单,坏处是需要google更新yum源才能获得最新版本的软件,而且所有软件的依赖不能自己指定
- 二进制安装,好处是可以安装任意版本的kubernetes,坏处是配置繁琐
- kubeadm安装,好处是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,坏处是屏蔽了很多细节,如果需要完全深度自己diy,没法弄。
准备工作
k8s至少需要一个master和一个node才能组成一个可用集群,这里我们按照高可用最低的配置,准备3台服务器
主机名 | ip | 备注 |
---|---|---|
master | 10.211.55.9 | master节点 |
node | 10.211.55.8 | node节点 |
node | 10.211.55.11 | node节点 |
安装docker
3台服务器安装了docker, 每台服务器docker安装好了,设置docker开机启动,然后进行下面的配置
安装docker的步骤这里就不赘述了,如果不会可以参考这篇博文:CentOS7 从零开始搭建一个jdk+tomcat的docker环境
关闭服务器防火墙和selinux
这里只是为了方便安装,把防火墙关闭了,如果是生产环境,可以去查询下具体需要开哪些端口
关闭防火墙
# 查看防火墙状态
firewall-cmd --state
# 关闭防火墙
systemctl stop firewalld.service
# 禁止防火墙开机启动
systemctl disable firewalld.service
禁用SELINUX
SELinux 主要由美国国家安全局开发。2.6 及以上版本的 Linux 内核都已经集成了 SELinux 模块。SELinux 的结构及配置非常复杂,而且有大量概念性的东西,要学精难度较大。所以我们这里把它关闭了。
# 查看selinux状态
/usr/sbin/sestatus -v | grep SELinux
# 临时关闭
setenforce 0
# 修改sulinux配置文件后重启,永久关闭,SELINUX=disabled
vi /etc/selinux/config
创建k8s网络配置文件
这里k8s网络使用flannel,网络需要设置内核参数bridge-nf-call-iptables=1,需要系统有br_netfilter模块
# 查看服务器有无lsmod |grep br_netfilter,没有就要加一个,有就忽略
lsmod |grep br_netfilter
# 临时新增一个,重启后会失效
modprobe br_netfilter
永久添加方法
在/etc/新建rc.sysinit 文件
#!/bin/bash
for file in /etc/sysconfig/modules/*.modules ; do
[ -x $file ] && $file
done
在/etc/sysconfig/modules/目录下新建文件如下
cat /etc/sysconfig/modules/br_netfilter.modules modprobe br_netfilter
配置脚本权限
chmod 755 br_netfilter.modules
创建网络配置文件
# 创建k8s配置文件
vi /etc/sysctl.d/k8s.conf
在k8s.conf中写入如下配置
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
加载配置文件
sysctl -p /etc/sysctl.d/k8s.conf
设置kubernetes源
创建yum配置文件
# 创建kubernetes源文件
vi /etc/yum.repos.d/kubernetes.repo
在文件中添加如下内容,阿里镜像使用第一个,google镜像使用第二个
[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
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
注意空格,换行
更新缓存策略
yum clean all
yum -y makecache
安装命令补全增强软件包 bash-completion
如果服务器已经有了可以忽略
yum -y install bash-completion
source /etc/profile.d/bash_completion.sh
配置docker镜像加速
前面有提到Docker Hub的服务器在国外,下载镜像会比较慢,这里配置阿里云
常用的加速地址:Docker官方提供的中国registry mirror、阿里云加速器、DaoCloud 加速器
vi /etc/docker/daemon.json
在文件中加入如下内容
{
"registry-mirrors": ["https://v16stybc.mirror.aliyuncs.com"]
}
重启动docker
systemctl daemon-reload
systemctl restart docker
可以验证下速度,非必须
docker run hello-world
到此,服务器准备工作全部完成
安装k8s
查看k8s版本,找到我们要的版本
yum list kubelet --showduplicates | sort -r
安装kubelet,kubeadm,kubectl
yum install -y kubelet-1.16.7 kubeadm-1.16.7 kubectl-1.16.7
- kubelet 运行在集群所有节点上,用于启动Pod和容器等对象的工具
- kubeadm 用于初始化集群,启动集群的命令工具
- kubectl 用于和集群通信的命令行,通过kubectl可以部署和管理应用,查看各种资源,创建、删除和更新各种组件
Cgroup Driver 修改
查看docker驱动,kubelet的启动环境变量要与docker的cgroup-driver驱动一样
docker info | grep -i cgroup
查看下kubelet启动的配置文件位置,不同的版本位置不一样
systemctl status kubelet
找到这个文件看下里面有没有cgroup-driver
cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf|grep "cgroup-driver"
如果没有,不执行Cgroup Driver 修改步骤
Cgroup Driver 修改
vi /etc/docker/daemon.json
在文件中追加
"exec-opts": ["native.cgroupdriver=systemd"]
有的版本,k8s是systemd,docker是cgroupfs,把docker的和k8s改成一样的
重启动docker
systemctl daemon-reload
systemctl restart docker
处理swap
Kubernetes 1.8开始要求关闭系统的Swap,如果不关闭,默认配置下kubelet将无法启动。
修改配置文件
vim /etc/sysconfig/kubelet
加入如下内容
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
设置开机自动启动
systemctl enable kubelet.service
注意现在要启动kubelet如果启动了,可能会报错下面的异常
遇到的异常情况
发现未启动成功,检查了Swap已经设置fail-swap-on=false,SELinux已经被disabled,firewalld也已经被disabled,cgroup也已经和docker设置成一样
查看systemd日志
journalctl -xefu kubelet
发现报错为
error: open /var/lib/kubelet/config.yaml: no such file or directory
这里可以先忽略,是因为我们在还没有init的时候启动了,先把kubelet停止了
# 启动kubelet
systemctl start kubelet.service
# 停止kubelet
systemctl stop kubelet.service
# 查看kubelet启动状态
systemctl status kubelet
查看下需要安装的镜像
kubeadm config images list --kubernetes-version=v1.16.7
发现报错如下
could not convert cfg to an internal cfg: nodeRegistration.name: Invalid value: "k8s_masterandnode_ecs": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')
这个是因为主机名不能带下划线,只能带中划线,修改一些hostname
hostnamectl set-hostname k8s-master-ecs
修改后再次执行命令无异常
一个拉取镜像的shell脚本,使用亚马逊镜像,url为亚马逊镜像仓库地址,version为安装的kubernetes版本。如果拉取亚马逊镜像失败,可以自己去找一下国内能拉取到的镜像仓库,例如阿里云的,或者克服网络去拉取官方地址的镜像,也可以找人下载好的镜像的tar,docker load进去
#!/bin/bash
# @description: docker 使用亚马逊中国镜像地址拉取kubernetes镜像
# @author: wangzhh
# @date: 2020/3/15
url=gcr.azk8s.cn/google-containers
version=v1.16.7
images=(`kubeadm config images list --kubernetes-version=$version|awk -F '/' '{print $2}'`)
for imagename in ${images[@]} ; do
docker pull $url/$imagename
docker tag $url/$imagename k8s.gcr.io/$imagename
docker rmi -f $url/$imagename
done
上传shell脚本到服务器,并执行
# 赋予脚本执行权限
chmod 777 pullImag.sh
# 执行脚本
./pullImag.sh
# 查看拉取回来的镜像
docker images
kubeadm init初始化集群master节点
启动kubelet
# 启动kubelet
systemctl start kubelet.service
此步骤只在主节点执行,规划的master10.211.55.9
kubeadm init --kubernetes-version=v1.16.7 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.211.55.9 --token-ttl 0
- --kubernetes-version 安装的kubernetes版本
- --pod-network-cidr=10.244.0.0/16 配置子网范围将被分解并发送给每个 node
- --apiserver-advertise-address是apiserver的通信地址,master的ip地址
- --token-ttl 0默认token的有效期为24小时,当过期之后,该token就不可用了,需要重新生成token,会比较麻烦,这里–token-ttl设置为0表示永不过期
如果遇到报错
[init] Using Kubernetes version: v1.16.7
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[WARNING SystemVerification]: this Docker version is not on the list of validated versions: 18.03.1-ce. Latest validated version: 18.09
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR Swap]: running with swap on is not supported. Please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher
修改一下初始化命令
kubeadm init --kubernetes-version=v1.16.7 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.211.55.9 --token-ttl 0 --ignore-preflight-errors 'Swap'
如果构建失败,根据失败信息处理后重置,然后再次初始化
# 重置命令
kubeadm reset
构建成功后控制台会输出token需要记录下来,后面加入集群要用
kubeadm join 10.211.55.9:6443 --token i0o01w.bfneabofx7i3p4gb \
--discovery-token-ca-cert-hash sha256:ab7158441d2dc84dc32ec4a8251bd1b9a2daf8d49345fae9a473d727e8f26325
加载环境变量
kubectl命令默认从$HOME/.kube/config这个位置读取配置。配置文件中包含apiserver的地址,证书,用户名等
echo "source <(kubectl completion bash)" >> ~/.bash_profile
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
master节点加入集群
kubeadm join 10.211.55.9:6443 --token i0o01w.bfneabofx7i3p4gb --discovery-token-ca-cert-hash sha256:ab7158441d2dc84dc32ec4a8251bd1b9a2daf8d49345fae9a473d727e8f26325 --ignore-preflight-errors=all
用kubeadm初始化的集群,出于安全考虑默认Pod不会被调度到Master Node上,也就是说Master Node不参与工作负载。如果需要master节点加入pod调用:
# 允许master部署pod
kubectl taint nodes --all node-role.kubernetes.io/master-
# 禁止master部署pod
kubectl taint nodes centos-master-1 node-role.kubernetes.io/master=true:NoSchedule
查看一下节点状态,此时NotReady 是正常的,因为还没有安装网络
kubectl get nodes
安装Flannel 网络插件
选用Flannel网络插件:https://github.com/coreos/flannel/tree/v0.10.0,如果直接安装失败,可以下载到本地再apply,这里对网络有要求,下载flannel的镜像,需要自己想办法或者用国内源手工拉取
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
下载本地执行
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
手工拉取
# 手工拉取
docker pull quay-mirror.qiniu.com/coreos/flannel:v0.12.0-amd64
# 改名
docker tag quay-mirror.qiniu.com/coreos/flannel:v0.12.0-amd64 quay.io/coreos/flannel:v0.12.0-amd64
完成后查看下所有镜像,如要有如下镜像(除了打马赛克那个)
docker images
执行成功后,Master并不能马上变成Ready状态,需要稍等一会,就可以看到所有状态都正常了
kubectl get nodes
kubectl get pods --all-namespaces
如果不是running状态,就说明出错了,通过查看描述kubectl describe pod kube-scheduler-master.hanli.com -n kube-system
和日志 kubectl logs kube-scheduler-master.hanli.com -n kube-system
来排错。
node节点加入集群
node节点服务器也需要安装好docker,处理swap,然后下载了上面步骤的k8s镜像
安装Flannel 网络插件
选用Flannel网络插件:https://github.com/coreos/flannel/tree/v0.10.0,如果直接安装失败,可以下载到本地再apply
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
下载本地执行
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
执行apply的时候可能报错连接不通,占时没发现什么影响,后面的博文会把工程实际部署到各个节点,如果影响,处理方式会更新
node节点加入集群,执行我们上面的kubeadm join
kubeadm join 10.211.55.9:6443 --token i0o01w.bfneabofx7i3p4gb --discovery-token-ca-cert-hash sha256:ab7158441d2dc84dc32ec4a8251bd1b9a2daf8d49345fae9a473d727e8f26325 --ignore-preflight-errors=all
如果加入后显示NotReady,可以重置一下再加入
systemctl stop kubelet.service
kubeadm reset
kubeadm join 10.211.55.9:6443 --token i0o01w.bfneabofx7i3p4gb --discovery-token-ca-cert-hash sha256:ab7158441d2dc84dc32ec4a8251bd1b9a2daf8d49345fae9a473d727e8f26325 --ignore-preflight-errors=all
如果还是不行,检查下是否缺少镜像没有拉下来,可以手工拉取一下,例如缺少flannel:v0.12.0-amd64
# 手工拉取
docker pull quay-mirror.qiniu.com/coreos/flannel:v0.12.0-amd64
# 改名
docker tag quay-mirror.qiniu.com/coreos/flannel:v0.12.0-amd64 quay.io/coreos/flannel:v0.12.0-amd64
node2节点采用导入node节点下载的镜像的方式,不执行pullImag.sh 脚本拉取镜像,也不安装Flannel 网络插件
,master如果有全套的images文件,也可以如此配置
首先使用命令导出镜像文件
docker save -o tar包的名字 镜像名
导出如下镜像
docker save -o flannel.tar quay.io/coreos/flannel
docker save -o kube-apiserver.tar k8s.gcr.io/kube-apiserver
docker save -o kube-proxy.tar k8s.gcr.io/kube-proxy
docker save -o kube-controller-manager.tar k8s.gcr.io/kube-controller-manager
docker save -o kube-scheduler.tar k8s.gcr.io/kube-scheduler
docker save -o etcd.tar k8s.gcr.io/etcd
docker save -o coredns.tar k8s.gcr.io/coredns
docker save -o pause.tar k8s.gcr.io/pause
在node2节点导入全部镜像
docker load -i coredns.tar
docker load -i etcd.tar
docker load -i flannel.tar
docker load -i kube-apiserver.tar
docker load -i kube-controller-manager.tar
docker load -i kube-proxy.tar
docker load -i kube-scheduler.tar
docker load -i pause.tar
加入集群
kubeadm join 10.211.55.9:6443 --token i0o01w.bfneabofx7i3p4gb --discovery-token-ca-cert-hash sha256:ab7158441d2dc84dc32ec4a8251bd1b9a2daf8d49345fae9a473d727e8f26325 --ignore-preflight-errors=all
在master执行命令查看,加入节点成功
在把剩下的node节点加入集群,到此,搭建k8s基本环境完成
简单测试一下
简单测试一下,后面的博文会继续添加部署实际的工程
关闭node1节点服务器
在master上看下节点状态
重新启动node2节点服务器,发现正常加入集群