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
准备安装环境
在一台能够访问互联网的服务器作为控制机,并执行以下动作。
安装包管理器
# 安装 Helm
SCRIPT_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}
# 删除默认 repo
for 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.yml
sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/ansible/roles/ex-lb/defaults/main.yml
sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' /etc/ansible/roles/kube-node/defaults/main.yml
sed -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 -S
docker exec -it kubeasz /bin/bash
cd /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.yml
ansible-playbook 02.etcd.yml
ansible-playbook 03.docker.yml
ansible-playbook 04.kube-master.yml
ansible-playbook 05.kube-node.yml
ansible-playbook 06.network.yml
ansible-playbook 07.cluster-addon.yml
验证方法:
# 查看节点状态
kubectl get nodes
# 查看 pod 状态
kubectl get pods -A
持久化存储
持久化存储使用 ceph,目前只支持在线安装。
本例使用一台单独的控制机,部署由6个节点组成的 ceph 集群,并使用单独的业务网络
和集群网络
隔离不同类型的网络流量,避免集群内的流量对业务造成影响。
基础安装
配置业务网络 hosts 解析
包括 ceph 集群各节点和控制机,都需要配置 ceph 集群内各节点主机名到业务网络 IP 地址的静态解析。
$ cat /etc/hosts
192.168.2.1 ops-ceph1
192.168.2.2 ops-ceph2
192.168.2.3 ops-ceph3
192.168.2.4 ops-ceph4
192.168.2.5 ops-ceph5
192.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=octopus
echo 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-ce502710d7a0
public_network = 192.168.2.0/24
cluster_network = 172.16.0.0/24
mon_initial_members = ops-ceph1, ops-ceph3, ops-ceph5
mon_host = 192.168.2.112,192.168.2.114,192.168.2.116
auth_cluster_required = cephx
auth_service_required = cephx
auth_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/sdn
ceph-deploy osd create ops-ceph2 --data /dev/sdn
ceph-deploy osd create ops-ceph3 --data /dev/sdn
ceph-deploy osd create ops-ceph4 --data /dev/sdn
ceph-deploy osd create ops-ceph5 --data /dev/sdn
ceph-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 stat
ceph mon dump
启用/禁用 Dashboard
- 生产环境慎用
- 使用强密码
# 启用仪表板模块
ceph mgr module enable dashboard
# 生成自签证书
ceph dashboard create-self-signed-cert
# 设置账号密码,协议 https,端口8443
ceph 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 的 pool
ceph osd pool create kube 256
# 创建 cephfs 的数据和元数据两个 pool
ceph osd pool create cephfs_data 256 256
ceph osd pool create cephfs_meta 256 256
# 使用已创建的元数据和数据池创建一个新的 ceph 文件系统,名为 cephfs
ceph 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.admin
AQCmJL5f5fRzJRAAKmPqhND42loXoxvtQF1dYw==
$ ceph auth get-key client.kube
AQADTb5fYCJMFBAAgZO1GFTrC5OLHYsST2a1Ew==
控制机上执行
- 创建 secret
# 创建 admin 的 secret
kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" -n kube-system \
--from-literal=key=AQCmJL5f5fRzJRAAKmPqhND42loXoxvtQF1dYw==
# 创建 pvc 用于访问 ceph 的 secret
kubectl create secret generic ceph-user-secret --type="kubernetes.io/rbd" \
--from-literal=key=AQADTb5fYCJMFBAAgZO1GFTrC5OLHYsST2a1Ew==
- 配置 StorageClass
$ vim storageclass-ceph-rdb.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: ceph-block
provisioner: kubernetes.io/rbd
parameters:
monitors: 192.168.2.1:6789,192.168.2.3:6789,192.168.2.5:6789 # 填写全部 mon 实例
adminId: admin
adminSecretName: ceph-secret
adminSecretNamespace: kube-system
pool: kube
userId: kube
userSecretName: ceph-user-secret
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
$ kubectl apply -f storageclass-ceph-rdb.yaml
storageclass.storage.k8s.io/ceph-block created
$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ceph-block kubernetes.io/rbd Delete Immediate false 18s
负载均衡
ansible-playbook /etc/ansible/roles/ex-lb/ex-lb.yml
ingress
# 安装 traefik
helm upgrade --install -n kube-system -f chart_values/traefik-settings.yaml traefik topvdn/traefik
# 创建 traefik middleware
kubectl apply -f manifests/traefik-middleware/redirect-https.yaml
# 访问 dashboard
## forward dashboard port
kubectl -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 dashboard
kubernetes-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 和 token
helm -n kube-system status kuboard
日志
helm upgrade --install -n kube-public -f chart_values/loki-settings.yaml loki topvdn/loki
helm 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
# 安装或更新 grafana
helm 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 -
# 创建 dashboard
kubectl -n monitor create configmap dashboard-prometheus --from-file=prometheus.json=dashboard_grafana/Prometheus自监控大盘.json
kubectl -n monitor label configmap dashboard-prometheus grafana_dashboard="1"
kubectl -n monitor create configmap dashboard-mysql --from-file=prometheus.json=dashboard_grafana/mysql监控大盘.json
kubectl -n monitor label configmap dashboard-mysql grafana_dashboard="1"
kubectl -n monitor create configmap dashboard-nacos --from-file=prometheus.json=dashboard_grafana/Nacos监控大盘.json
kubectl -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.host
helm 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
## 查询命名空间确认需要导入的空间id
nacosctl 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
## 将生成的配置导入nacos
nacosctl 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
## 将生成的配置导入nacos
docker 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 命令行预览模式