kubernetes 搭建手册
本文档为内部的 Kubernetes 以及基础组件安装手册,你可以将它视作基础组件的安装规范。因此,安装过程中应严格按照本手册操作。
本文仅包含安装步骤,不会关注于组件介绍、名词解释或概念科普等内容。但是不排除会提供一些超链接,可以将你导航到更加详细的科普文档,这些文档里可能会提供一些安装步骤,但是请你以本文的安装步骤为准。
关于信任的基础组件列表,请参考组件列表,也就是说,在生产环境中,禁止引入本手册以外的组件。如确有必要,我们会在测试环境充分验证后,加入本文档。
组件列表
- 配置管理:etcd
- docker
- kubernetes
- 网络插件:flannel
- ntp 服务:chrony
- ingress:traefix
- 负载均衡:haproxy + keepalived
- dashboard:kuboard + kubernetes dashboard
- 监控:prometheus + grafana
- 日志:loki
- 配置中心:nacos
- 持久化存储:ceph
安装工具列表
- Kubernetes 集群自动化安装脚本:kubeasz
- 离线文件准备脚本:https://git.topvdn.com/lingda_ops/kubeasz_init
- kubernetes 包管理工具:helm
准备 & 规划
升级内核
Kubernetes 各节点升级内核版本,内核下载地址:https://kernel.ubuntu.com/~kernel-ppa/mainline/
建议内核版本:
- ubuntu16.04 - 4.15.18
- ubuntu18.04 - 4.20.17
准备安装环境
在一台能够访问互联网的服务器作为控制机,并执行以下动作。
安装包管理器
# 安装 HelmSCRIPT_PATH=$(pwd)HOST="http://file.topvdn.com/containers/helm"OS=$(uname -s | tr A-Z a-z)ARCH="amd64"NAME="helm"VERSION="$(curl -sSL ${HOST}/stable.txt)"SUFFIX="tar.gz"FILENAME="${NAME}-${VERSION}-${OS}-${ARCH}.${SUFFIX}"BIN_DIR="/usr/local/bin"mkdir -p ${BIN_DIR}curl -Lo /tmp/${FILENAME} ${HOST}/${FILENAME} && cd /tmp && tar xf ${FILENAME} && install /tmp/${OS}-${ARCH}/${NAME} ${BIN_DIR}/${NAME} && rm -r /tmp/${OS}-${ARCH} && rm ${FILENAME}cd ${SCRIPT_PATH}# 删除默认 repofor r in `helm repo list | awk '{print $1}' | sed '1d'`; do helm repo remove $r; done# 添加私有 repo,用户名、密码找运维部获取helm repo add topvdn https://harbor.topvdn.com/chartrepo/private --username <username> --password <password># 更新软件包列表helm repo update
离线文件准备脚本
# 克隆安装脚本仓库git clone http://git.topvdn.com/lingda_ops/kubeasz_init.git
离线文件准备
如选择在线安装,可以跳过此步骤,直接开始规划。
下载好离线文件以后,将/etc/ansible目录打包,传输到需要部署环境内的一台机器上即可。
在同一台服务器上执行事先准备好的脚本:
cd kubeasz_init# 下载离线镜像、二进制文件,在线安装可省略bash easzup_2.2.1 -D# 下载离线系统软件包,在线安装可省略bash easzup_2.2.1 -P
easzup_<version>脚本第23行可修改离线文件存放的私有 docker 仓库地址,通常不需要修改。特殊情况下,如公司内网部署,将此处修改为内网私有仓库地址,会显著提高下载速度。
执行成功后,所有文件均已整理好放入目录/etc/ansible,只要把该目录整体复制到任何离线的机器上,即可开始安装集群,离线文件包括:
/etc/ansible包含 kubeasz 版本为 ${release} 的发布代码/etc/ansible/bin包含 k8s/etcd/docker/cni 等二进制文件/etc/ansible/down包含集群安装时需要的离线容器镜像/etc/ansible/down/packages包含集群安装时需要的系统基础软件
离线文件不包括:
- 管理端 ansible 安装,但可以使用 kubeasz 容器运行 ansible 脚本
- 其他更多 kubernetes 插件镜像
设置离线参数
# 设置参数允许离线安装,在线安装可省略sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/ansible/roles/chrony/defaults/main.ymlsed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/ansible/roles/ex-lb/defaults/main.ymlsed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/ansible/roles/kube-node/defaults/main.ymlsed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/ansible/roles/prepare/defaults/main.yml
规划
cd /etc/ansible# 以下样本文件根据实际情况二选一# 单机cp example/hosts.allinone hosts# 集群cp example/hosts.multi-node hosts# 根据实际情况修改配置,通常只需要修改 ip 地址vi hosts
配置 ssh 免密
自动化部署基于 ansible,因此需要配置控制机到 kubernetes 集群内机器的 ssh 免密登录。
方法:略
安装
kubernetes 套件
此步骤会安装 etcd、docker、kubernetes、flannel、chrony。
在控制机上执行以下命令:
# 启动 kubeasz 容器,包含安装代码和代码的运行环境./easzup -Sdocker exec -it kubeasz /bin/bashcd /etc/ansible# 如果修改了 ssh 服务的默认端口,需要修改全局的连接配置# SSH_PORT=<ssh_port># mkdir group_vars && echo "ansible_ssh_port: $SSH_PORT" > group_vars/all# 测试连通性ansible all -m ping# 以下两种安装方式二选一# 一步安装ansible-playbook 90.setup.yml# 分步安装ansible-playbook 01.prepare.ymlansible-playbook 02.etcd.ymlansible-playbook 03.docker.ymlansible-playbook 04.kube-master.ymlansible-playbook 05.kube-node.ymlansible-playbook 06.network.ymlansible-playbook 07.cluster-addon.yml
验证方法:
# 查看节点状态kubectl get nodes# 查看 pod 状态kubectl get pods -A
持久化存储
持久化存储使用 ceph,目前只支持在线安装。
本例使用一台单独的控制机,部署由6个节点组成的 ceph 集群,并使用单独的业务网络和集群网络隔离不同类型的网络流量,避免集群内的流量对业务造成影响。
基础安装
配置业务网络 hosts 解析
包括 ceph 集群各节点和控制机,都需要配置 ceph 集群内各节点主机名到业务网络 IP 地址的静态解析。
$ cat /etc/hosts192.168.2.1 ops-ceph1192.168.2.2 ops-ceph2192.168.2.3 ops-ceph3192.168.2.4 ops-ceph4192.168.2.5 ops-ceph5192.168.2.6 ops-ceph6
配置 ssh 免密登录
后续步骤用到的部署工具需要通过 ssh 连接 ceph 集群内各节点,所以需要配置控制机到 ceph 集群内机器的 ssh 免密登录。
方法:略
部署工具无法修改 ssh 端口,因此,如果修改了 ssh 服务的默认监听端口,则需要临时开启 ssh 的22端口监听。
添加 ceph 仓库
ceph 集群各节点、控制机和 kubernetes 集群所有节点都需要添加 ceph 软件仓库。
wget -q -O- 'https://mirrors.aliyun.com/ceph/keys/release.asc' | sudo apt-key add -ceph_stable_release=octopusecho deb https://mirrors.aliyun.com/ceph/debian-$ceph_stable_release/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list
安装部署工具
在控制机安装部署工具:ceph-deploy
apt update && apt install -y ceph-deploy
安装客户端
kubernetes 要使用 ceph 持久化存储,必须安装 ceph 客户端软件。
apt update && apt install -y ceph-common
ceph 集群部署
集群部署全部在控制机上操作。
创建一个集群
# 生产环境通常至少3个 mon 节点$ ceph-deploy new --public-network 192.168.2.0/24 --cluster-network 172.16.0.0/24 ops-ceph1 ops-ceph3 ops-ceph5$ cat ceph.conf[global]fsid = de898995-8362-4a7f-80f2-ce502710d7a0public_network = 192.168.2.0/24cluster_network = 172.16.0.0/24mon_initial_members = ops-ceph1, ops-ceph3, ops-ceph5mon_host = 192.168.2.112,192.168.2.114,192.168.2.116auth_cluster_required = cephxauth_service_required = cephxauth_client_required = cephx
- 可以在 ceph 配置文件里的默认副本数从 3 改成 2 ,这样只有两个 OSD 也可以达到 active + clean 状态。把下面这行加入
[global]段:
osd_pool_default_size = 2
ceph 组件安装
# 该命令应包含所有 ceph 节点ceph-deploy install --no-adjust-repos ops-ceph1 ops-ceph2 ops-ceph3 ops-ceph4 ops-ceph5 ops-ceph6
初始化监控节点并收集 keyring
ceph-deploy mon create-initial
创建 mgr 节点
# 生产环境通常至少3个 mgr 节点ceph-deploy mgr create ops-ceph1 ops-ceph3 ops-ceph5
添加 osd 节点
ceph-deploy osd create ops-ceph1 --data /dev/sdnceph-deploy osd create ops-ceph2 --data /dev/sdnceph-deploy osd create ops-ceph3 --data /dev/sdnceph-deploy osd create ops-ceph4 --data /dev/sdnceph-deploy osd create ops-ceph5 --data /dev/sdnceph-deploy osd create ops-ceph6 --data /dev/sdn
创建 mds 节点(cephfs 功能)
# 安装 mds 到与 mgr 节点相同的机器上ceph-deploy mds create ops-ceph1 ops-ceph3 ops-ceph5
验证
控制机并没有安装 ceph,ceph 相关命令无法在控制机上执行。因此,需要将安装过程中生成的一系列 key 文件拷贝到 ceph 集群节点上,使之有权限进行容器管理。
# 控制机执行scp ceph*keyring ops-ceph1:/etc/ceph
# ops-ceph1节点执行# 查看集群状态ceph -s# 查看仲裁ceph quorum_status --format json-pretty# 查看 mon 状态ceph mon statceph mon dump
启用/禁用 Dashboard
- 生产环境慎用
- 使用强密码
# 启用仪表板模块ceph mgr module enable dashboard# 生成自签证书ceph dashboard create-self-signed-cert# 设置账号密码,协议 https,端口8443ceph dashboard set-login-credentials 'admin' 'fhe8792ofdih'# 禁用仪表盘模块ceph mgr module disable dashboard
配置
ceph 管理节点上运行
- 创建 pool
pg_num 的值要根据 OSD 的数量进行调整,计算公式是:Total PGs = (Total_number_of_OSD * 100) / max_replication_count,但是最后算出的结果一定要接近或者等于一个2的指数。
本例有6个 OSD,因此设置pg_num为256:
# 创建 cephrbd 的 poolceph osd pool create kube 256# 创建 cephfs 的数据和元数据两个 poolceph osd pool create cephfs_data 256 256ceph osd pool create cephfs_meta 256 256# 使用已创建的元数据和数据池创建一个新的 ceph 文件系统,名为 cephfsceph fs new cephfs cephfs_meta cephfs_data# 查看 cephfs 信息ceph fs ls
- 创建 k8s 访问 ceph 的用户
ceph auth get-or-create client.kube mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=kube'
- 查看 key
$ ceph auth get-key client.adminAQCmJL5f5fRzJRAAKmPqhND42loXoxvtQF1dYw==$ ceph auth get-key client.kubeAQADTb5fYCJMFBAAgZO1GFTrC5OLHYsST2a1Ew==
控制机上执行
- 创建 secret
# 创建 admin 的 secretkubectl create secret generic ceph-secret --type="kubernetes.io/rbd" -n kube-system \--from-literal=key=AQCmJL5f5fRzJRAAKmPqhND42loXoxvtQF1dYw==# 创建 pvc 用于访问 ceph 的 secretkubectl create secret generic ceph-user-secret --type="kubernetes.io/rbd" \--from-literal=key=AQADTb5fYCJMFBAAgZO1GFTrC5OLHYsST2a1Ew==
- 配置 StorageClass
$ vim storageclass-ceph-rdb.yamlkind: StorageClassapiVersion: storage.k8s.io/v1metadata:name: ceph-blockprovisioner: kubernetes.io/rbdparameters:monitors: 192.168.2.1:6789,192.168.2.3:6789,192.168.2.5:6789 # 填写全部 mon 实例adminId: adminadminSecretName: ceph-secretadminSecretNamespace: kube-systempool: kubeuserId: kubeuserSecretName: ceph-user-secretfsType: ext4imageFormat: "2"imageFeatures: "layering"$ kubectl apply -f storageclass-ceph-rdb.yamlstorageclass.storage.k8s.io/ceph-block created$ kubectl get scNAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGEceph-block kubernetes.io/rbd Delete Immediate false 18s
负载均衡
ansible-playbook /etc/ansible/roles/ex-lb/ex-lb.yml
ingress
# 安装 traefikhelm upgrade --install -n kube-system -f chart_values/traefik-settings.yaml traefik topvdn/traefik# 创建 traefik middlewarekubectl apply -f manifests/traefik-middleware/redirect-https.yaml# 访问 dashboard## forward dashboard portkubectl -n kube-system port-forward --address 0.0.0.0 $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name -n kube-system) 9000:9000## 获取访问方式echo http://$(hostname -I | awk '{print $1}'):9000/dashboard/
dashboard
- 官方 dashboard
# 查看 NodePort 端口$ kubectl get svc -n kube-system | grep dashboardkubernetes-dashboard NodePort 10.68.125.217 <none> 443:32436/TCP 350d# 可以看到,dashboard的NodePort端口是 32436,访问 https://<任意节点ip>:<NodePort> 即可打开 dashboard。# 查看登录令牌$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')`
- kuboard - 国产控制台,推荐
# 创建证书 secret (kube-system 命名空间)kubectl create -n kube-system secret tls antelopecloud.cn-tls \--cert=STAR.antelopecloud.cn.crt --key=STAR.antelopecloud.cn.key# 安装helm upgrade --install -n kube-system kuboard topvdn/kuboard \--set ingress.enabled=True --set ingress.hosts[0]=tz-ops.antelopecloud.cn \--set ingress.tlsEnabled=True --set ingress.tls[0].secretName=antelopecloud.cn-tls# 查看访问 URL 和 tokenhelm -n kube-system status kuboard
日志
helm upgrade --install -n kube-public -f chart_values/loki-settings.yaml loki topvdn/lokihelm upgrade --install -n kube-public promtail topvdn/promtail --set "loki.serviceName=loki"
监控
以下域名和域名证书文件需自行准备,并修改。
- 创建 namespace
kubectl create ns monitor
- 安装 prometheus
helm upgrade --install -n monitor -f chart_values/prometheus-settings.yaml prometheus topvdn/prometheus
- 安装 grafana
# 创建证书 secret(monitor 命名空间)kubectl create -n monitor secret tls antelopecloud.cn-tls \--cert=STAR.antelopecloud.cn.crt --key=STAR.antelopecloud.cn.key# 安装或更新 grafanahelm upgrade grafana topvdn/grafana --install -n monitor -f chart_values/grafana-settings.yaml \--set ingress.enabled=True \--set ingress.hosts[0]=tz-ops.antelopecloud.cn \--set ingress.tls[0].secretName=antelopecloud.cn-tls# 创建 http 到 https 跳转sed 's/<HOST>/tz-ops.antelopecloud.cn/' manifests/grafana-ingress-http.yaml | kubectl apply -f -# 创建 dashboardkubectl -n monitor create configmap dashboard-prometheus --from-file=prometheus.json=dashboard_grafana/Prometheus自监控大盘.jsonkubectl -n monitor label configmap dashboard-prometheus grafana_dashboard="1"kubectl -n monitor create configmap dashboard-mysql --from-file=prometheus.json=dashboard_grafana/mysql监控大盘.jsonkubectl -n monitor label configmap dashboard-mysql grafana_dashboard="1"kubectl -n monitor create configmap dashboard-nacos --from-file=prometheus.json=dashboard_grafana/Nacos监控大盘.jsonkubectl -n monitor label configmap dashboard-nacos grafana_dashboard="1"
登录方式
- grafana - URL:https://tz-ops.antelopecloud.cn/grafana,username:
admin,password:Megaium! - prometheus
- grafana - URL:https://tz-ops.antelopecloud.cn/grafana,username:
export POD_NAME=$(kubectl get pods --namespace monitor -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")kubectl --namespace monitor --address 0.0.0.0 port-forward $POD_NAME 9090## 获取访问方式echo http://$(hostname -I | awk '{print $1}'):9090
- alertmanager
export POD_NAME=$(kubectl get pods --namespace monitor -l "app=prometheus,component=alertmanager" -o jsonpath="{.items[0].metadata.name}")kubectl --namespace monitor --address 0.0.0.0 port-forward $POD_NAME 9093## 获取访问方式echo http://$(hostname -I | awk '{print $1}'):9093
配置中心
- 安装mysql
helm upgrade --install -n kube-public -f chart_values/mysql-settings.yaml mysql topvdn/mysql
- 安装nacos
# 获取 mysql 密码MYSQL_ROOT_PASSWORD=$(kubectl get secret -n kube-public mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)# 安装,根据实际情况修改 ingress.hosts.hosthelm upgrade --install -n kube-public -f chart_values/nacos-settings.yaml \--set ingress.hosts.host=nacos.lingda.com \--set mysql.rootPassword=$MYSQL_ROOT_PASSWORD \nacos topvdn/nacos# 获取 nacos 登录方式helm -n kube-public status nacos
配置
导入 nacos 配置
# 从仓库拉取配置模板和变量模板git clone ssh://git@42.51.12.153:10022/lingda_ops/lm_conf_generator.git -b ${版本号:0.6.0}# 使用port-forward映射nacos网站kubectl port-forward -n kube-public nacos-0 8848:8848 --address 0.0.0.0# 使用二进制工具导入## 首先登录之前映射的nacos网站nacosctl login 127.0.0.1 -p 8848## 查询命名空间确认需要导入的空间idnacosctl get ns## 渲染配置模板与变量,输出到命令行,进行检查nacosctl gen -f ../../lm_conf_generator/config/tz-pre.ini -t ../../lm_conf_generator/templates --st## 将渲染的变量输出到指定目录nacosctl gen -f ../../lm_conf_generator/config/tz-pre.ini -t ../../lm_conf_generator/templates -o ./conf## 将生成的配置导入nacosnacosctl import all -d ./conf -n pro -u 127.0.0.1 -U nacos -P nacos -p 8848-----------------------------------------------------------------------------# 使用镜像工具导入## 先登录(把nacos域名换成自环境域名,并使用账号密码登录)docker run -it --rm -v /tmp:/root/.nacos/ harbor.lingda.com/internal/nacosctl:1.1 nacosctl login 127.0.0.1 -p 8848## 导入(导入前确保命名空间已经创建)### 查询已创建的命名空间docker run -it --rm -v /opt:/opt harbor.lingda.com/internal/nacosctl:1.1 nacosctl get ns### 渲染配置检查变量赋值docker run -it --rm -v /opt:/opt harbor.lingda.com/internal/nacosctl:1.1 nacosctl gen -f /opt/lm_conf_generator/config/tz-pre.ini -t /opt/lm_conf_generator/templates --st## 将渲染的变量输出到指定目录docker run -it --rm -v /opt:/opt harbor.lingda.com/internal/nacosctl:1.1 nacosctl gen -f /opt/lm_conf_generator/config/tz-pre.ini -t /opt/lm_conf_generator/templates -o ./conf## 将生成的配置导入nacosdocker run -it --rm -v /opt:/opt harbor.lingda.com/internal/nacosctl:1.1 nacosctl import all -d ./conf -n pro -u 127.0.0.1 -U nacos -P nacos -p 8848> -n 指定命名空间> -G 指定公共配置项的group_name> -f 指定配置项目文件路径> -d 指定目录路径> -t 指定模板路径> -o 指定输出的目录地址> -u 指定网站> -p 指定网站端口> -U 指定网站用户> -P 指定网站密码> --st 命令行预览模式
