简介

本文容最初记录于2020年1月,整理并发布于2021年10月

本文记录的和azure相关的服务已经失效

本版本主要变更:

  • 引入ceph,服务器的四个盘位均给ceph使用
  • 使用kubespray部署k8s集群,并使用ceph作为pv后端
  • 升级SSD容量,为VM提供系统盘存储

router

  • 本次未做更新
  • ssl证书除了系统设置里上传以外,还需要修改/etc/里的证书

ilo

  • 更新固件:exe在windows下运行,点提取,解压出bin文件,然后在ilo web端更新固件。
    • 更新中文语言包
  • https端口改回443

esxi

  • 升级6.7u3

  • 修改配置-高级,scheduler相关配置,修复安全漏洞

esxi虚拟机部署(centos7)

  • 使用dvd在图形界面下安装第一台系统,并进行适当初始化配置

    • 网卡配置vim /etc/sysconfig/network-scripts/ifcfg-ens192 :配置onboot、ipv4、dns1
    • 将mbp的ssh key导入~/.ssh/authorized_keys
    • 关闭防火墙systemctl stop firewalld.service systemctl disable firewalld.service
    • 更新包和内核yum update
    • 安装vimyum intall vim
    • vim /etc/sysctl.conf加入net.ipv4.ip_forward = 1
    • 内核的大版本需要再考虑,目前保持默认的不动
  • 下载vmware ovf tool,导出第一台的ovf模板,并在esxi从模板复制出另外几台虚拟机,然后做网络配置

    • 改ipvim /etc/sysconfig/network-scripts/ifcfg-ens192
    • 改hostnamehostnamectl set-hostname XXXXXXX
    • 为每台虚拟机设置init快照,方便反复尝试时快速恢复

esxi虚拟机部署(debian10)

  • 系统安装:用dvd1镜像安装,断网。
  • 用普通用户ssh,然后将秘钥加入root的可信证书,换root登陆,删除普通用户
  • 换apt源,中科大,然后apt update && apt upgrade
  • apt install vim
  • 导出ovf模板,复制另外三台
  • 改ip
  • 时区:pssh -H "10.0.0.21 10.0.0.22 10.0.0.23 10.0.0.24" -l root -i timedatectl set-timezone Asia/Shanghai
  • 创建虚拟机快照

ceph集群

集群部署

版本选择:debian10 安装会报错,找不到ceph包。所以用debian9安装,ceph-deploy自动选择的版本是ceph10,太过古老,和现在的文档不相符。所以用ubuntu安装。

节点公共初始化如下

#清华源,vim

#ip

#hostname

#hosts

#ntp

#时区

接下来是admin节点

#开发机
pip install ceph-deploy

#用pssh同时执行命令,完成ceph集群的preflight
pssh -H "ip1 ip2" -l root -i XXXXXX

接下来正式开始部署

ceph-deploy --username root new ceph1

ceph-deploy --username root install --repo-url http://mirrors.ustc.edu.cn/ceph/debian-mimic --gpg-url http://mirrors.ustc.edu.cn/ceph/keys/release.asc ceph1 ceph2 ceph3

ceph-deploy --username root mon create-initial

ceph-deploy --username root admin ceph1 ceph2 ceph3

ceph-deploy --username root mgr create ceph1

接下来插入硬盘,部署osd

# 4块2T硬盘,设置4个raid0单盘
fdisk -l
#/dev/sdb
ceph-deploy --username root osd create --data /dev/sdb ceph1
ceph-deploy --username root osd create --data /dev/sdb ceph2
ceph-deploy --username root osd create --data /dev/sdb ceph3

组件冗余部署

在完成上面的基础上,给其他的osd节点也部署上mon、mgr组件

ceph-deploy --username root mon add ceph2
ceph-deploy --username root mon add ceph3
# 此处可能报错,解决方案
#ceph.conf中加入这一行
public_network= 192.168.4.0/24
ceph-deploy --username root --overwrite-conf config push ceph1 ceph2 ceph3

ceph-deploy --username root mgr create ceph2 ceph3

#rgw暂时未部署

新加节点时

install
admin
osd
mon
mgr

PG计算

待仔细研究docs

cephfs初始化

ceph osd pool create cephfs.default.data 32
ceph osd pool create cephfs.default.meta 32
ceph fs new default cephfs.default.meta cephfs.default.data

# 调整副本数为2
ceph osd pool set cephfs.default.meta size 2
ceph osd pool set cephfs.default.data size 2

docs

rbd初始化

ceph osd pool create rbd 128
rbd pool init rbd

#下面是为k8s provisioner准备的
ceph osd pool create kube 128
ceph osd pool set kube size 2
ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=kube'
ceph auth get client.kube 2>&1 | grep "key = " | awk '{print  $3}' | xargs echo -n
ceph auth print-key client.kube

doc

dashboard

按照文档开启

注意事项,创建自签名证书是必须的,否则服务不会启动。但是后面可以禁用ssl即可使用http访问。

# 提示Module 'dashboard' has failed: No module named routes
# 用pssh在每个节点安装python-routes即可

preps for k8s

创建kube pool

#创建 kube用户
ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=kube'
ceph auth get client.kube 2>&1 | grep "key = " | awk '{print  $3}' | xargs echo -n

最后修改k8s里的admin和user的secret

使用kubespray安装生产级别的kubernetes集群

首先实现能够成功部署集群,后面再研究配置调整和优化,为了实现成功部署,主要需要解决的问题就是用到的组件被墙或服务器在国外速度过慢的问题。

#在部署机器进入kubespray项目根目录,我使用的是我自己的mac

git clone https://github.com/kubernetes-incubator/kubespray.git

# master分支不能用,必须到相应的release tag
git checkout v2.12.0

pip install -r requirements.txt

cp -rfp inventory/sample inventory/default

# 连续IP可以直接如下写,非连续IP参考readme定义ip数组
CONFIG_FILE=inventory/default/hosts.yaml python contrib/inventory_builder/inventory.py 10.0.0.201-10.0.0.204

修改docker安装镜像源

inventory/default/group_vars/k8s-cluster/k8s-cluster.yml中覆盖docker源

#红帽&centos7
docker_rh_repo_base_url: 'https://mirrors.aliyun.com/docker-ce/linux/centos/7/$basearch/stable'
docker_rh_repo_gpgkey: 'https://mirrors.aliyun.com/docker-ce/linux/centos/gpg'

dockerproject_rh_repo_base_url: 'http://mirror.azure.cn/docker-engine/yum/repo/main/centos/7/'
dockerproject_rh_repo_gpgkey: 'http://mirror.azure.cn/docker-engine/yum/gpg'

extras_rh_repo_base_url: "https://mirrors.aliyun.com/centos//$releasever/extras/$basearch/"
extras_rh_repo_gpgkey: "https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7"
#debian
docker_debian_repo_base_url: "https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian"
docker_debian_repo_gpgkey: 'https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/gpg'

dockerproject_apt_repo_base_url: 'http://mirror.azure.cn/docker-engine/apt/repo'
dockerproject_apt_repo_gpgkey: 'https://mirror.azure.cn/docker-engine/apt/gpg'

gcr.io和quay.io镜像配置

#同样在上一个文件中,追加
docker_image_repo: dockerhub.azk8s.cn
gcr_image_repo: gcr.azk8s.cn
quay_image_repo: quay.azk8s.cn

被墙的二进制-方法1-不推荐

# 在开发机上,将kubelet、kubeadmin、kubectl手动下载好,地址如下,相应的替换版本和文件名
#https://storage.googleapis.com/kubernetes-release/release/v1.16.3/bin/linux/amd64/kubectl

#开http服务器,路由和官方的一致
sudo apachectl start
sudo mkdir -p /Library/WebServer/Documents/kubernetes-release/release/v1.16.3/bin/linux/amd64/
move kubectl kubeadmin kubelet /Library/WebServer/Documents/kubernetes-release/release/v1.16.3/bin/linux/amd64/
#修改kubespray的下载url,从mac上下载,10.0.0.153是我mac的ip
kubelet_download_url: "http://10.0.0.153/kubernetes-release/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubelet"
kubectl_download_url: "http://10.0.0.153/kubernetes-release/release/{{ kube_version }}/bin/linux/{{ image_arch }}/kubectl"
kubeadm_download_url: "http://10.0.0.153/kubernetes-release/release/{{ kubeadm_version }}/bin/linux/{{ image_arch }}/kubeadm"

被墙的二进制-方法2-推荐

默认情况下每个node各自下载自己的binary和image,可以修改配置实现跑ansible的机器单独下载,然后分发给各node

# 同样是k8s-cluster.yml文件`
# 缓存目录在/tmp/kubespray_cache,二进制需要自己下载然后拷贝进去
download_run_once: true
download_localhost: true
# 缓存目录最终文件树如下
├── calicoctl
├── cni-plugins-linux-amd64-v0.8.1.tgz
├── images
│   ├── dockerhub.azk8s.cn_calico_cni_v3.7.3.tar
│   ├── dockerhub.azk8s.cn_calico_kube-controllers_v3.7.3.tar
│   ├── dockerhub.azk8s.cn_calico_node_v3.7.3.tar
│   ├── dockerhub.azk8s.cn_coredns_coredns_1.6.0.tar
│   ├── dockerhub.azk8s.cn_lachlanevenson_k8s-helm_v2.16.1.tar
│   ├── dockerhub.azk8s.cn_library_nginx_1.17.tar
│   ├── dockerhub.azk8s.cn_library_registry_2.6.tar
│   ├── gcr.azk8s.cn_google-containers_addon-resizer_1.8.3.tar
│   ├── gcr.azk8s.cn_google-containers_cluster-proportional-autoscaler-amd64_1.6.0.tar
│   ├── gcr.azk8s.cn_google-containers_k8s-dns-node-cache_1.15.8.tar
│   ├── gcr.azk8s.cn_google-containers_kube-apiserver_v1.16.3.tar
│   ├── gcr.azk8s.cn_google-containers_kube-controller-manager_v1.16.3.tar
│   ├── gcr.azk8s.cn_google-containers_kube-proxy_v1.16.3.tar
│   ├── gcr.azk8s.cn_google-containers_kube-scheduler_v1.16.3.tar
│   ├── gcr.azk8s.cn_google-containers_pause_3.1.tar
│   ├── gcr.azk8s.cn_google_containers_kube-registry-proxy_0.4.tar
│   ├── gcr.azk8s.cn_google_containers_kubernetes-dashboard-amd64_v1.10.1.tar
│   ├── gcr.azk8s.cn_google_containers_metrics-server-amd64_v0.3.3.tar
│   ├── gcr.azk8s.cn_google_containers_pause-amd64_3.1.tar
│   ├── gcr.azk8s.cn_kubernetes-helm_tiller_v2.16.1.tar
│   ├── quay.azk8s.cn_coreos_etcd_v3.3.10.tar
│   ├── quay.azk8s.cn_external_storage_cephfs-provisioner_v2.1.0-k8s1.11.tar
│   ├── quay.azk8s.cn_external_storage_rbd-provisioner_v2.1.1-k8s1.11.tar
│   ├── quay.azk8s.cn_jetstack_cert-manager-controller_v0.11.0.tar
│   └── quay.azk8s.cn_kubernetes-ingress-controller_nginx-ingress-controller_0.26.1.tar
├── kubeadm-v1.16.3-amd64
├── kubectl-v1.16.3-amd64
└── kubelet-v1.16.3-amd64

开始部署

ansible-playbook -i inventory/default/hosts.yaml --become --become-user=root -u root -vvv cluster.yml
# -u 使用 root用户登录远程机器
# -v -vv -vvv -vvvv 越来越详细的输出等级
# 在ansible.cfg中的defaults中加入log_path = log.log可以输出日志

优化配置

本次homelab集群的额外配置项

  1. docker_registry_mirrors(阿里云)
  2. cluster_name
  3. dynamic_kubelet_configuration
  4. kubeconfig_localhost
  5. supplementary_addresses_in_ssl_keys
  6. kubelet_load_modules
  7. kube_apiserver_node_port_range(改得过小可能导致端口冲突)
  8. addons
    1. dashboard_enabled:false
    2. ingress
  9. 修改invertory的[kube-node],把master移除,可以避免workload调度到master上

故障解决

  1. 在addon中启用ingress后,很多pod都会无法连接到apiserver,报错误connction refused,在github issue搜到讨论这个问题的网页。目前解决方法是修改ingress配置ingress_nginx_host_network: true dnsPolicy: ClusterFirstWithHostNet
  2. 默认的dashboard登陆后有bug,会报the server could not find the requested resource错误,github_issue。解决方案是修改kubespray配置,默认不安装dashboard,集群安装完成后手动安装较新版本的dashboard2.0-rc3

etcd&apiserver负载均衡

kubespray官方文档

对于集群内部,有自带的本地负载均衡器连接apiserver,详细见以上文档。

对于外部访问apiserver,需要自己部署额外的负载均衡。由于资源不足,暂时不做外部负载均衡,直接使用第一个master

dashboard权限

新建一个serviceaccount,用clusterrolebinding把这个sa和cluster-admin这个clusterrole绑定,然后取出这个sa的token,base64解码,放到kubeconfig文件的user的token字段里,即可使用这个kubeconfig文件作为集群管理员登陆dashboard

--token-ttl:登陆有效期

pod可用资源计算(allocable)

k8s官方文档

以top为准即可

节点伸缩

扩容worker节点:

  1. 准备节点
  2. 修改inventory里的hosts文件,增加新节点
  3. ansible跑scale.yml

删除worker节点:

  1. ansible-playbook -i inventory/home/hosts.yaml --become --become-user=root -u root -vvvv remove-node.yml --extra-vars "node=node5"
  2. 注意:在过程中,restart network后,节点的interface不能自动起来,需要手动ifup,然后流程才能继续。