1. 准备
相关软件:
- kubeas:https://github.com/easzlab/kubeasz,官方文档很详细,以下是iji实际操作的记录
使用Ansible来安装k8s集群.
- Kubeadm:https://blog.frognew.com/2018/08/kubeadm-install-kubernetes-1.11.html
1.1. 集群需求
软硬件需求:
- 4台:1核2G(资源实在不足就用1.5g),推荐2核4g
- node至少1核2G
- master也是至少1核2G
- 更新,全部1.5g问题不大.刚好内存全部使用完毕
- CentOS7内核版本3.10以上
- docker1.9以上
- etcd2.0以上
高可用集群所需节点规划:
- 部署节点——x1 : 运行这份 ansible 脚本的节点
- etcd节点——x3 : 注意etcd集群必须是1,3,5,7…奇数个节点,目测也是为了方便选举
- master节点—-x2 : 根据实际集群规模可以增加节点数,需要额外规划一个master VIP(虚地址)
- lb节点——–x2 : 负载均衡节点两个,安装 haproxy(负载均衡)+keepalived(高可用)
- node节点——x2 : 真正应用负载的节点,根据需要提升机器配置和增加节点数
具体机器规划:5个IP,4台机器,本机总共8G内存,凑或一下,以下是最大内存,如果运行不起来,稍微再改大一点
- 192.168.137.30:主机名:madao-master1(1.5G)
- deploy:ansible
- master1
- lb1
- etcd
- 192.168.137.31:主机名:madao-node1(2G)
- etcd
- node
- 192.168.137.32:主机名:madao-node2(2G)
- etcd
- node
- 192.168.137.33:主机名:madao-master2(1.5G)
- master2
- lb2
- 192.168.137.34
- vip
1.2. 4台机器通用
sudo yum install -y epel-release
sudo yum update && sudo yum upgrade -y
sudo yum install -y python
sudo systemctl stop firewalld && sudo systemctl disable firewalld
sudo hostnamectl set-hostname 对应的hostname
sudo vi /etc/selinux/config
# disabled
# 重启
# 如果需要使用python3
sudo yum install https://centos7.iuscommunity.org/ius-release.rpm -y
# 然后建立一个python的软连接即可
2. 在master1上用ansible部署
# 按装ansible
sudo yum install -y python-pip git
sudo pip install pip --upgrade -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
# 升级为阿里的源
sudo pip install --no-cache-dir ansible -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
# 使用pip安装ansible
# deploy节点配置免密码登录
sudo su -
ssh-keygen
# 如果使用-f /home/madao/test
# 最好每个机器该一下sshd中的默认key名
# 复制到各个节点
for ip in 30 31 32 33;
do
sudo ssh-copy-id 192.168.137.$ip;
# 把pub分别复制到几台机器上
# 如果上面直接ssh-keygen ,这里可以不用-i选项 -i /home/madao/test
# 分别,yes输入密码登录就ok
done;
# 使用kubeasz
git clone https://github.com/gjmzj/kubeasz.git
sudo mkdir -p /etc/ansible
sudo mv kubeasz/* /etc/ansible/
sudo chown root:root -R /etc/ansible
# 下载二进制文件
#从百度云网盘下载二进制文件 https://pan.baidu.com/s/1c4RFaA
# 最新的1-14-2
# 复制到虚拟机上,并解压
sudo tar zxvf k8s.1-14-2.tar.gz
sudo mv bin/* /etc/ansible/bin/
# 配置集群参数
cd /etc/ansible/
sudo cp example/hosts.m-masters.example hosts
sudo vim hosts
# 根据实际情况修改IP地址
# 集群部署节点:一般为运行ansible 脚本的节点
# 变量 NTP_ENABLED (=yes/no) 设置集群是否安装 chrony 时间同步
[deploy]
192.168.137.30 NTP_ENABLED=no
# etcd集群请提供如下NODE_NAME,注意etcd集群必须是1,3,5,7...奇数个节点
[etcd]
192.168.137.30 NODE_NAME=etcd1
192.168.137.31 NODE_NAME=etcd2
192.168.137.32 NODE_NAME=etcd3
[kube-master]
192.168.137.30
192.168.137.33
[kube-node]
192.168.137.31
192.168.137.32
# 参数 NEW_INSTALL:yes表示新建,no表示使用已有harbor服务器
# 如果不使用域名,可以设置 HARBOR_DOMAIN=""
[harbor]
#192.168.1.8 HARBOR_DOMAIN="harbor.yourdomain.com" NEW_INSTALL=no
# 灯会手动配置
# 负载均衡(目前已支持多于2节点,一般2节点就够了) 安装 haproxy+keepalived
[lb]
192.168.137.30 LB_IF="ens33" LB_ROLE=master # 注意根据实际使用网卡设置 LB_IF变量
192.168.137.33 LB_IF="ens33" LB_ROLE=backup
# 对哪个网卡来配置虚拟IP
# 30上的服务有点多,可能需要2G内存
#[可选]外部负载均衡,用于自有环境负载转发 NodePort 暴露的服务等
[ex-lb]
#192.168.1.6 LB_ROLE=backup EX_VIP=192.168.1.250
#192.168.1.7 LB_ROLE=master EX_VIP=192.168.1.250
[all:vars]
# ---------集群主要参数---------------
#集群部署模式:allinone, single-master, multi-master
DEPLOY_MODE=multi-master
# 集群 MASTER IP即 LB节点VIP地址,为区别与默认apiserver端口,设置VIP监听的服务端口8443
# 公有云上请使用云负载均衡内网地址和监听端口
MASTER_IP="192.168.137.34"
KUBE_APISERVER="https://{{ MASTER_IP }}:8443"
# 下面的不需要改动
# 开始安装
cd /etc/ansible/
# 直接一步到位
sudo ansible-playbook 90.setup.yml
# 全部在roles目录下
# 大概需要10分钟不等
# 分步安装
# 1.创建整数并准备安装
sudo ansible-playbook 01.prepare.yml
# 2.安装etcd集群
sudo ansible-playbook 02.etcd.yml
# 2.1.检查etcd节点健康状况:
sudo su
for ip in 30 31 32 ;
do
ETCDCTL_API=3 etcdctl --endpoints=https://192.168.137.$ip:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem endpoint healt;
# etcdctl命令只有root能用
done
# 输出: https://192.168.137.30:2379 is healthy: successfully committed proposal: took = 2.95722ms
# 3.安装docker
sudo ansible-playbook 03.docker.yml
# 另外一个文件是03.containerd.yml.两个一模一样
# 第一次运行,在启动docker时,报错,冲ixnyunxing一遍,好了??,不知道原因
# 4.安装master节点
sudo ansible-playbook 04.kube-master.yml
sudo su
kubectl get componentstatus
# 查看集群状态NAME STATUS MESSAGE ERROR
# 需要把kubectl加入$PATH
# 5.安装node节点
sudo ansible-playbook 05.kube-node.yml
kubectl get nodes
#查看node节点
# 6.部署集群网络
sudo ansible-playbook 06.network.yml
kubectl get pod -n kube-system
# 查看kube-system namespace上的pod,从中可以看到flannel相关的pod
# flannel也是一个镜像
# 7.安装集群插件(dns, dashboard)
sudo ansible-playbook 07.cluster-addon.yml
# 查看kube-system namespace下的服务
kubectl get svc -n kube-system
# 如果不加 -n 只会显示default namespace
#查看集群信息:
kubectl cluster-info
#查看node/pod使用资源情况:
kubectl top node
# 默认按照CPU使用率排序
kubectl top pod --all-namespaces
2.1. 测试dns
# 创建nginx service
kubectl run nginx --image=nginx --expose --port=80 --generator=run-pod/v1
# 默认的generator是deployment/apps.v1 现在被弃用了
# 是default namespace
kubectl describe pod nginx-755464dd6c-fktz7
# message相当于log
kubectl get svc --all-namespaces
# 主要是dns和nginx的
# 创建busybox 测试pod
kubectl run busybox --rm -it --image=busybox /bin/sh --generator=run-pod/v1
# 进入到busybox内部,退出时,直接删除
nslookup nginx.default.svc.cluster.local
# 结果如果和kubectl get svc中ip一样即可
ping nginx
3. 集群管理
3.1. 增加node节点
现在版本:
# 添加免密登录
easzctl add-node 192.168.137.50
# 验证
kubectl get node
kubectl get pod -n kube-system -o wide
以前的版本:(1-11)
# deploy节点免密码登录node: ssh-copy-id 新node ip
# 修改/etc/ansible/hosts
[new-node]
192.168.137.50
# 执行安装脚本
ansible-playbook /etc/ansible/20.addnode.yml
# 验证
kubectl get node
kubectl get pod -n kube-system -o wide
# 后续工作
# 修改/etc/ansible/hosts,将new-node里面的所有ip全部移动到kube-node组里去
3.2. 增加master节点
现在的版本:
# 添加免密登录
easzctl add-master 192.168.137.70
# 验证
# 在新节点master 服务状态
systemctl status kube-apiserver
systemctl status kube-controller-manager
systemctl status kube-scheduler
# 查看新master的服务日志
journalctl -u kube-apiserver -f
3.3. 升级集群(k8s)
现在的版本:
# 备份etcd
ETCDCTL_API=3 etcdctl snapshot save backup.db
# 查看备份文件信息
ETCDCTL_API=3 etcdctl --write-out=table snapshot status backup.db
# 到本项目的根目录kubeasz
cd /dir/to/kubeasz
# 拉取最新的代码
git pull origin master
# 下载升级目标版本的kubernetes二进制包(百度网盘 https://pan.baidu.com/s/1c4RFaA)====>替换全部
# 或者去 https://dl.k8s.io/v1.14.2/kubernetes-server-linux-amd64.tar.gz ====>替换kube开头的文件
# 解压,并替换/etc/ansible/bin/下的二进制文件,
#如果使用 easzctl 命令行,可按如下执行:
#首先确认待升级的集群(如果有多集群的话)
easzctl checkout <cluster_name>
# 执行升级
easzctl upgrade
# 升级docker(现在版本):
# 除非特别需要,否则不建议频繁升级docker
# 如果可以接受短暂业务中断,执行
ansible-playbook -t upgrade_docker 03.docker.yml
# 如果要求零中断升级,执行
ansible-playbook -t download_docker 03.docker.yml
# 然后手动执行如下
# 待升级节点,先应用
kubectl cordon
kubectl drain
# 迁移业务pod
#待升级节点执行
systemctl restart docker
# 恢复节点可调度
kubectl uncordon
# 升级docker(以前版本)
# 如果接受业务中断,执行:
ansible-playbook -t upgrade_k8s,restart_dockerd 22.upgrade.yml
# 不能接受短暂中断
ansible-playbook -t upgrade_k8s 22.upgrade.yml
#到所有node上逐一:
kubectl cordon
kubectl drain
# 迁移业务pod
systemctl restart docker
kubectl uncordon
# 恢复pod
4. 集群备份和恢复
主要就是备份和恢复配置文件,比如etcd,ca证书,hosts等
4.1. 备份
# 再创建一个pod,mysql,资源有限无法启动
kubectl run mysql --image=mysql:5.5 --expose --port=3306 --generator=run-pod/v1 --env="MYSQL_ALLOW_EMPTY_PASSWORD=true"
# 如果出问题,排查
kubectl describe pod mysql
kubectl logs mysql
sudo mkdir -p /backup/k8s
# 创建备份目录
sudo su
ETCDCTL_API=3 etcdctl snapshot save /backup/k8s/snapshot.db
# 备份etcd数据
mkdir -p /backup/k8s/ssl/
cp /etc/kubernetes/ssl/ca* /backup/k8s
# 备份ca证书
# 模拟集群崩溃,deploy节点执行
ansible-playbook /etc/ansible/99.clean.yml
4.2. 恢复
手动恢复:
# 恢复步骤如下(在deploy节点):
# a)恢复ca证书
mkdir -p /etc/kubernetes/ssl
\cp -rf /backup/k8s/* /etc/kubernetes/ssl/
# \cp可以不使用别名
# b)重建集群
cd /etc/ansible
ansible-playbook 01.prepare.yml
ansible-playbook 02.etcd.yml
ansible-playbook 03.docker.yml
ansible-playbook 04.kube-master.yml
ansible-playbook 05.kube-node.yml
# 6.7的配置在etcd中
# c)恢复etcd数据
#停止服务
ansible etcd -m service -a 'name=etcd state=stopped'
#清空文件
ansible etcd -m file -a 'name=/var/lib/etcd/member/ state=absent'
# 登录所有的etcd节点
# 把backup目录复制过去(主要就是snapshot.db)
#,参照本etcd节点/etc/systemd/system/etcd.service的服务文件,替换如下{{}}中变量后执行
cd /backup/k8s
# cat /etc/systemd/system/etcd.service
# 可以参考一下
#ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
#--name {{节点名,etcd1,etcd2...}} \
#--initial-advertise-peer-urls https://{{本etcd的ip}}:2380 \
#--initial-cluster etcd1 {{https://etcd1的ip:2380,etcd2=https://etcd2的ip:2380,etcd3=https://etcd3的ip:2380}} \
#--initial-cluster-token etcd-cluster-0 \
# 比如:
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \
--name etcd1 \
--initial-advertise-peer-urls https://192.168.137.30:2380 \
--initial-cluster etcd1=https://192.168.137.30:2380,etcd2=https://192.168.137.31:2380,etcd3=https://192.168.137.32:2380 \
--initial-cluster-token etcd-cluster-0 \
#执行上面的步骤后,会生成{{ NODE_NAME }}.etcd目录
#复制每个节点都需要复制
cp -r etcd1.etcd/member /var/lib/etcd/
# 2,3
systemctl restart etcd
# 分别重启,1,2,3
kubectl get pods
# nginx 和mysql就出现了
# d)在deploy节点重建网络
# 可以提前下载flannel镜像
ansible-playbook /etc/ansible/tools/change_k8s_network.yml
# 清理kubeproxy产生的optables会报错,影响不大.
4.3. 一键备份恢复
不想手动恢复,可以用ansible自动恢复
# 需要一键备份
ansible-playbook /etc/ansible/23.backup.yml
#检查/etc/ansible/roles/cluster-backup/files目录下是否有文件
tree /etc/ansible/roles/cluster-backup/files/
# 如下
├-- ca # 集群CA 相关备份
│ ├-- ca-config.json
│ ├-- ca.csr
│ ├-- ca-csr.json
│ ├-- ca-key.pem
│ └-- ca.pem
├-- hosts # ansible hosts备份
│ ├-- hosts # 最近的备份
│ └-- hosts-201807231642
├-- readme.md
└-- snapshot # etcd 数据备份
├-- snapshot-201807231642.db
└-- snapshot.db # 最近的备份
# 模拟故障:
ansible-playbook /etc/ansible/99.clean.yml
#修改文件/etc/ansible/roles/cluster-restore/defaults/main.yml,指定要恢复的etcd快照备份
# 如果不修改就是最新的一次
# 恢复操作:
ansible-playbook /etc/ansible/24.restore.yml
ansible-playbook /etc/ansible/tools/change_k8s_network.yml