前言
前文搭建了高可用的Kubernetes集群,本来规划继续探索实际中的应用部署以及如何改造现有的技术架构使Kubernetes初步落地。不过在搭建完集群后,还是不可遏制的想找寻一款图形化管理工具,毕竟我的关注点更多在于如何把现有技术架构和流程向云原生做落地,过于繁琐和复杂的命令行运维方式目前并不适合我。
于是发现了Rancher。经过初步的信息检索,不论从Rancher的技术方向、知名度、社区活跃度、以及平台技术能力都算得上优秀和主流,所以穿插了这部分的内容的学习。
Rancher主要的知识点来源自官方文档,官方文档还算面面俱到和详细,英文好的也可以对照英文文档,细微上还是有些小差别。
整体架构
那么对于使用Rancher本身以及被管理集群架构,我画了一张架构图
Rancher高可用安装
首先我们需要做的是Rancher的安装,Rancher支持多种安装方式,最简单的就是单机安装,使用docker跑个镜像就行。我使用的是高可用安装方式。最新版本的2.5已经支持了将Rancher安装在各种Kubernetes集群上,比如现有的Kubernetes集群,或者RKE、K3s、Amazon EKS等等。并且官方建议为了性能,最好将该Kubernetes集群专门用于运行Rancher。
经过简单的对比,最终决定使用Rancher自家推出的K3s来部署Rancher应用。Kubernetes 和 K3S 是什么关系呢,官网原话:
k3s 旨在成为完全兼容的 Kubernetes 发行版,相比 k8s 主要更改如下:
- 旧的、Alpha 版本的、非默认功能都已经删除。
- 删除了大多数内部云提供商和存储插件,可以用插件替换。
- 新增 SQLite3 作为默认存储机制,etcd3 仍然有效,但是不再是默认项。
- 封装在简单的启动器中,可以处理大量 LTS 复杂性和选项。
- 最小化到没有操作系统依赖,只需要一个内核和 cgroup 挂载。
并且K3s是一个符合标准的、已获CNCF官方认证的Kubernetes发行版,在开发环境或者轻量级需求时优势明显。
准备工作
Mysql外部数据库
K3s使用 etcd 以外的数据存储运行 Kubernetes,使得某种意义上更加灵活,我们可以使用现成的数据库,例如Mysql,这里需要创建一个Mysql数据库。
负载均衡
当我们的Rancher节点运行在K3s上时,需要一个负载均衡器将流量引导到多个节点上。官方示例使用nginx做L4负载均衡,配置文件如下:
worker_processes 4; worker_rlimit_nofile 40000; events { worker_connections 8192; } stream { upstream rancher_servers_http { least_conn; server 10.128.2.53:80 max_fails=3 fail_timeout=5s; ##rancher节点 server 10.128.2.52:80 max_fails=3 fail_timeout=5s; } server { listen 80; proxy_pass rancher_servers_http; } upstream rancher_servers_https { least_conn; server 10.128.2.53:443 max_fails=3 fail_timeout=5s; server 10.128.2.52:443 max_fails=3 fail_timeout=5s; } server { listen 443; proxy_pass rancher_servers_https; } }
启动nginx时需要开启stream模块。
安装kubectl
K3s节点机器上需要安装kubectl,方便通过命令行来管理集群。至于后续通过Rancher安装的Kubernetes集群节点上如果需要通过命令行管理,也需要安装kubectl。至于如何安装就不赘述了,前文有。
K3s管理
安装
K3s的安装相当简单,并且由于引入了外部mysql数据库做存储,K3s的节点已经变成无状态,对于节点数的要求并不需要一定3个起步,官方给的例子就是2个节点。安装k3s命令如下
curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - server \ --datastore-endpoint="mysql://k3s:k3s123456@tcp(10.11.0.194:3306)/k3s" #若要安装指定版本 curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=vX.Y.Z sh -s - server \ --datastore-endpoint="mysql://username:password@tcp(hostname:3306)/database-name"
等待后启动成功
此时可以通过
k3s kubectl get nodes
来确认k3s节点状态。若想通过kubectl工具访问的话,需要配置kubeconfig文件
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
~/.kube/config
文件中默认server地址是127.0.0.1,需要改成前端负载均衡器的DNS,更改nginx配置就行了。这里由于前面根据Kubeadm部署的集群我使用的是haproxy + keepalived,所以这里我就继续使用了,此处server地址配置的是keepalived的VIP。
卸载
K3s会在本地放置卸载文件,如果需要删除K3s,可以执行
/usr/local/bin/k3s-uninstall.sh
Helm安装
先贴上Helm文档地址。
Helm是什么?
Helm 是一个Kubernetes 应用的包管理工具,用来管理chart——预先配置好的安装包资源,有点类似于Ubuntu 的APT 和CentOS 中的YUM
Helm安装
关于安装,官方安装部分说的很详细,两种方式自取。
添加Rancher源
后续使用Helm方式安装Rancher,需要新增Rancher的源,稳定版本和最新版本任选
# 稳定版本 helm repo add rancher-stable http://rancher-mirror.oss-cn-beijing.aliyuncs.com/server-charts/stable # 最新版本 helm repo add rancher-latest http://rancher-mirror.oss-cn-beijing.aliyuncs.com/server-charts/latest
证书生成
Rancher Server 默认需要 SSL/TLS 配置来保证访问的安全性。
提示: 如果您想要将 SSL/TLS 访问在外部终止,请查看使用外部 TLS 负载均衡器。有三种关于证书来源的推荐选项,证书将用来在 Rancher Server 中终止 TLS:
- Rancher 生成的自签名证书: 在这种情况下,您需要在集群中安装
cert-manager
。 Rancher 利用cert-manager
签发并维护证书。Rancher 将生成自己的 CA 证书,并使用该 CA 签署证书。然后,cert-manager
负责管理该证书。- Let's Encrypt: Let's Encrypt 选项也需要使用
cert-manager
。但是,在这种情况下,cert-manager
与特殊的 Issuer 结合使用,cert-manager
将执行获取 Let's Encrypt 发行的证书所需的所有操作(包括申请和验证)。此配置使用 HTTP 验证(HTTP-01
),因此负载均衡器必须具有可以从公网访问的公共 DNS 记录。- 使用您自己的证书: 此选项使您可以使用自己的权威 CA 颁发的证书或自签名 CA 证书。 Rancher 将使用该证书来保护 WebSocket 和 HTTPS 流量。在这种情况下,您必须上传名称分别为
tls.crt
和tls.key
的 PEM 格式的证书以及相关的密钥。如果使用私有 CA,则还必须上传该证书。这是由于您的节点可能不信任此私有 CA。 Rancher 将获取该 CA 证书,并从中生成一个校验和,各种 Rancher 组件将使用该校验和来验证其与 Rancher 的连接。
以上是官方关于证书的描述,Rancher提供了三种证书方式,国内的文档建议选用自己证书的方式,理由是cert-manager
需要额外的运维精力,听人劝吃饱饭。再次强调,以下操作都是基于使用自有证书的方式!!!
SSL证书生成
官方提供了生成证书的脚本,我在这里贴一下
#!/bin/bash -e help () { echo ' ================================================================ ' echo ' --ssl-domain: 生成ssl证书需要的主域名,如不指定则默认为www.rancher.local,如果是ip访问服务,则可忽略;' echo ' --ssl-trusted-ip: 一般ssl证书只信任域名的访问请求,有时候需要使用ip去访问server,那么需要给ssl证书添加扩展IP,多个IP用逗号隔开;' echo ' --ssl-trusted-domain: 如果想多个域名访问,则添加扩展域名(SSL_TRUSTED_DOMAIN),多个扩展域名用逗号隔开;' echo ' --ssl-size: ssl加密位数,默认2048;' echo ' --ssl-cn: 国家代码(2个字母的代号),默认CN;' echo ' 使用示例:' echo ' ./create_self-signed-cert.sh --ssl-domain=www.test.com --ssl-trusted-domain=www.test2.com \ ' echo ' --ssl-trusted-ip=1.1.1.1,2.2.2.2,3.3.3.3 --ssl-size=2048 --ssl-date=3650' echo ' ================================================================' } case "$1" in -h|--help) help; exit;; esac if [[ $1 == '' ]];then help; exit; fi CMDOPTS="$*" for OPTS in $CMDOPTS; do key=$(echo ${OPTS} | awk -F"=" '{print $1}' ) value=$(echo ${OPTS} | awk -F"=" '{print $2}' ) case "$key" in --ssl-domain) SSL_DOMAIN=$value ;; --ssl-trusted-ip) SSL_TRUSTED_IP=$value ;; --ssl-trusted-domain) SSL_TRUSTED_DOMAIN=$value ;; --ssl-size) SSL_SIZE=$value ;; --ssl-date) SSL_DATE=$value ;; --ca-date) CA_DATE=$value ;; --ssl-cn) CN=$value ;; esac done # CA相关配置 CA_DATE=${CA_DATE:-3650} CA_KEY=${CA_KEY:-cakey.pem} CA_CERT=${CA_CERT:-cacerts.pem} CA_DOMAIN=cattle-ca # ssl相关配置 SSL_CONFIG=${SSL_CONFIG:-$PWD/openssl.cnf} SSL_DOMAIN=${SSL_DOMAIN:-'www.rancher.local'} SSL_DATE=${SSL_DATE:-3650} SSL_SIZE=${SSL_SIZE:-2048} ## 国家代码(2个字母的代号),默认CN; CN=${CN:-CN} SSL_KEY=$SSL_DOMAIN.key SSL_CSR=$SSL_DOMAIN.csr SSL_CERT=$SSL_DOMAIN.crt echo -e "\033[32m ---------------------------- \033[0m" echo -e "\033[32m | 生成 SSL Cert | \033[0m" echo -e "\033[32m ---------------------------- \033[0m" if [[ -e ./${CA_KEY} ]]; then echo -e "\033[32m ====> 1. 发现已存在CA私钥,备份"${CA_KEY}"为"${CA_KEY}"-bak,然后重新创建 \033[0m" mv ${CA_KEY} "${CA_KEY}"-bak openssl genrsa -out ${CA_KEY} ${SSL_SIZE} else echo -e "\033[32m ====> 1. 生成新的CA私钥 ${CA_KEY} \033[0m" openssl genrsa -out ${CA_KEY} ${SSL_SIZE} fi if [[ -e ./${CA_CERT} ]]; then echo -e "\033[32m ====> 2. 发现已存在CA证书,先备份"${CA_CERT}"为"${CA_CERT}"-bak,然后重新创建 \033[0m" mv ${CA_CERT} "${CA_CERT}"-bak openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}" else echo -e "\033[32m ====> 2. 生成新的CA证书 ${CA_CERT} \033[0m" openssl req -x509 -sha256 -new -nodes -key ${CA_KEY} -days ${CA_DATE} -out ${CA_CERT} -subj "/C=${CN}/CN=${CA_DOMAIN}" fi echo -e "\033[32m ====> 3. 生成Openssl配置文件 ${SSL_CONFIG} \033[0m" cat > ${SSL_CONFIG} <<EOM [req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth EOM if [[ -n ${SSL_TRUSTED_IP} || -n ${SSL_TRUSTED_DOMAIN} ]]; then cat >> ${SSL_CONFIG} <<EOM subjectAltName = @alt_names [alt_names] EOM IFS="," dns=(${SSL_TRUSTED_DOMAIN}) dns+=(${SSL_DOMAIN}) for i in "${!dns[@]}"; do echo DNS.$((i+1)) = ${dns[$i]} >> ${SSL_CONFIG} done if [[ -n ${SSL_TRUSTED_IP} ]]; then ip=(${SSL_TRUSTED_IP}) for i in "${!ip[@]}"; do echo IP.$((i+1)) = ${ip[$i]} >> ${SSL_CONFIG} done fi fi echo -e "\033[32m ====> 4. 生成服务SSL KEY ${SSL_KEY} \033[0m" openssl genrsa -out ${SSL_KEY} ${SSL_SIZE} echo -e "\033[32m ====> 5. 生成服务SSL CSR ${SSL_CSR} \033[0m" openssl req -sha256 -new -key ${SSL_KEY} -out ${SSL_CSR} -subj "/C=${CN}/CN=${SSL_DOMAIN}" -config ${SSL_CONFIG} echo -e "\033[32m ====> 6. 生成服务SSL CERT ${SSL_CERT} \033[0m" openssl x509 -sha256 -req -in ${SSL_CSR} -CA ${CA_CERT} \ -CAkey ${CA_KEY} -CAcreateserial -out ${SSL_CERT} \ -days ${SSL_DATE} -extensions v3_req \ -extfile ${SSL_CONFIG} echo -e "\033[32m ====> 7. 证书制作完成 \033[0m" echo echo -e "\033[32m ====> 8. 以YAML格式输出结果 \033[0m" echo "----------------------------------------------------------" echo "ca_key: |" cat $CA_KEY | sed 's/^/ /' echo echo "ca_cert: |" cat $CA_CERT | sed 's/^/ /' echo echo "ssl_key: |" cat $SSL_KEY | sed 's/^/ /' echo echo "ssl_csr: |" cat $SSL_CSR | sed 's/^/ /' echo echo "ssl_cert: |" cat $SSL_CERT | sed 's/^/ /' echo echo -e "\033[32m ====> 9. 附加CA证书到Cert文件 \033[0m" cat ${CA_CERT} >> ${SSL_CERT} echo "ssl_cert: |" cat $SSL_CERT | sed 's/^/ /' echo echo -e "\033[32m ====> 10. 重命名服务证书 \033[0m" echo "cp ${SSL_DOMAIN}.key tls.key" cp ${SSL_DOMAIN}.key tls.key echo "cp ${SSL_DOMAIN}.crt tls.crt" cp ${SSL_DOMAIN}.crt tls.crt
使用说明如下
--ssl-domain: 生成ssl证书需要的主域名,如不指定则默认为www.rancher.local,如果是ip访问服务,则可忽略;
--ssl-trusted-ip: 一般ssl证书只信任域名的访问请求,有时候需要使用ip去访问server,那么需要给ssl证书添加扩展IP,多个IP用逗号隔开;
--ssl-trusted-domain: 如果想多个域名访问,则添加扩展域名(TRUSTED_DOMAIN),多个TRUSTED_DOMAIN用逗号隔开;
--ssl-size: ssl加密位数,默认2048;
--ssl-cn: 国家代码(2个字母的代号),默认CN;
生成一个10年有效期的使用示例:
./create_self-signed-cert.sh --ssl-domain=rancher.xxx.com \
--ssl-trusted-ip=10.11.0.220,10.128.2.52,10.128.2.53 --ssl-size=2048 --ssl-date=3650
证书提交
# rancher命名空间新建 kubectl create namespace cattle-system # 创建secret kubectl create secret generic tls-ca -n cattle-system --from-file=cacerts.pem kubectl create secret tls tls-rancher-ingress -n cattle-system --cert=./tls.crt --key=./tls.key
安装Rancher
# helm安装rancher
helm install rancher rancher-stable/rancher \
--namespace cattle-system \
--set hostname=rancher.xxx.com \
--set ingress.tls.source=secret \
--set privateCA=true
# helm更新rancher
helm upgrade --install rancher rancher-stable/rancher \
--namespace cattle-system \
--set hostname=rancher.xxx.com \
--set ingress.tls.source=secret \
--set privateCA=true
可以通过kubectl命令查看相关启动情况,这个过程会持续一会,整个rancher集群状态才会变为active。
kubectl get ingress -n cattle-system
kubectl -n cattle-system rollout status deploy/rancher
使用Rancher
在访问Rancher页面前若使用的是内网IP域名映射,需要本机host配置映射域名和IP。浏览器访问域名
出现以上页面,设置好密码后就可以正常使用rancher了。
设置阿里源
系统设置里
设置为
registry.cn-hangzhou.aliyuncs.com
创建自定义集群
郑重忠告
先说说我掉的坑,我用来创建的集群的机器不是干净的,上面既有Java进程,也有Docker部署的服务。集群创建后,Java进程正常,但是Docker部署的服务全都访问不通,我猜想是由于集群创建时设置了CNI,从而影响到了Docker的网络设置。
所以我郑重建议:在使用Rancher创建管理自定义集群时,最好使用干净的无服务部署的机器,切忌上面有包含Docker部署的服务。
创建集群
Rancher创建集群的过程我就不详细说了,不停下一步就行了,最后会出现节点机器加入集群的命令,在相关机器上执行命令就行。整个集群创建的过程让我总结就是一个字:等待!可能会比较漫长。。。
各个节点机器上会下载很多镜像,启动多个容器
Rancher镜像上也会展示集群当前的信息
对我来说是很漫长的流程,至少比有的人说的7,8分钟要漫长多。
集群状态未成功以后,可以下载Kubeconfig文件到本地的,便可通过kubectl操作集群。
关于仪表盘报错以及kubectl命令行1006的问题
Kubernetes集群创建成功后,发现2个问题:
- 点击集群仪表盘报错,进去后空白页
执行kubectl命令行
按钮点击后出现1006报错
于是通过kubectl命令行查看pod情况
发现cattle-cluster-agent2个节点处于CrashLoopBackOff状态,并不断在重启。于是查看日志
发现rancher.xxx.com域名访问不通,集群中节点不知道rancher.xxx.com是谁,需要进行如下配置
kubectl -n cattle-system patch deployments cattle-cluster-agent --patch '{
"spec": {
"template": {
"spec": {
"hostAliases": [
{
"hostnames":
[
"rancher.xxx.com"
],
"ip": "10.11.0.220"
}
]
}
}
}
}'
# 配置 cattle-node-agent
kubectl -n cattle-system patch daemonsets cattle-node-agent --patch '{
"spec": {
"template": {
"spec": {
"hostAliases": [
{
"hostnames":
[
"rancher.xxx.com"
],
"ip": "10.11.0.220"
}
]
}
}
}
}'
配置后一切正常。
清理节点
安装过集群的节点,如果需要卸载,需要执行官方提供的清理脚本,否则官方说了不保证下次会成功。
其实这个过程耗费了我不少时间,官方文档很全,但是在顺序上有待商榷,当然也有我自己的锅。这篇文章到此草草结束,后续在部署应用方面还会再涉及,到时再见。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。