1. 为什么要在私有环境构建高可用Rancher?
如果你正在管理一个企业内部的Kubernetes集群,或者负责一个完全离线的数据中心,那你肯定遇到过这样的问题:想用Rancher这个强大的容器管理平台,却发现官方镜像拉不动,网络不通,安全审计又要求所有组件必须从内部仓库拉取。我之前给一家制造业客户做项目,他们的生产环境是完全物理隔离的,连外网DNS都没有。当时为了部署一个管理平台,真是费了九牛二虎之力,到处找离线包,手动导镜像,步骤繁琐不说,还容易出错。后来我摸索出了一套成熟的方法,就是基于Helm和私有镜像仓库来部署高可用的Rancher,这套方案后来成了我们团队在内网环境下的标准操作流程。
简单来说,这套方案的核心思路就是:把互联网上的能力“搬”到内网里。我们不再依赖公网的Docker Hub或Rancher的官方仓库,而是事先把所有需要的容器镜像(比如Rancher Server、Fleet Agent、Webhook等)下载到本地,然后推送到我们自己搭建的私有镜像仓库(比如Harbor)里。接着,利用Helm这个Kubernetes的“包管理器”,通过一个高度可定制的配置文件(values.yaml),告诉Rancher:“别去外面找了,你的所有‘家当’都在咱们内部的这个仓库地址里,这是钥匙(镜像拉取密钥),去那里拿吧。” 同时,我们还会为Rancher配置自签名的或企业内部的CA证书,确保所有通信都是加密且受信的。
这么做的好处非常明显。第一是稳定性:再也不用担心因为网络波动导致部署失败或Pod启动不了,所有依赖都在内网,速度飞快。第二是安全性:符合企业安全合规要求,镜像经过内部扫描和审计,流量不出内网。第三是高可用:通过Helm我们可以轻松配置多副本,结合Kubernetes的调度策略,即使某个节点挂了,Rancher服务也能秒级切换到其他节点,业务管理界面不间断。接下来,我就带你一步步拆解这个过程的每一个环节,从环境准备到最终登录 dashboard,保证你跟着做就能成功。
2. 部署前,你需要准备好这些“食材”
想把这道“大菜”做出来,准备工作是关键。你不能等到下锅了才发现少油少盐。根据我的经验,一个清晰的前期清单能避免80%的部署错误。
2.1 基础环境规划
首先,你得有一个正在运行的Kubernetes集群。别担心,它不需要多强大,一个简单的三节点集群就足够了。比如像下面这样规划:
| IP地址 | 主机名 | 角色 | 备注 |
|---|---|---|---|
| 192.168.100.3 | k8s-master | 控制平面 & 工作节点 | 也将作为Ingress控制器节点 |
| 192.168.100.4 | k8s-node1 | 工作节点 | 同时作为私有镜像仓库(Harbor)节点 |
| 192.168.100.5 | k8s-node2 | 工作节点 |
这里我做了点小调整,把私有镜像仓库(比如Harbor)部署在了k8s-node1上。这样规划更贴近真实场景,镜像仓库独立于Master节点,既减轻Master压力,也方便统一管理。当然,Harbor的安装不是本文重点,你可以参考其官方文档快速部署。假设现在你的Harbor已经跑在 http://192.168.100.4 上,并且创建了一个名为 library 的公开项目。
其次,确保你的Kubernetes集群网络插件(如Calico、Flannel)工作正常,节点之间网络互通,并且 kubectl 命令可以正常操作集群。一个快速的检查命令是 kubectl get nodes 和 kubectl cluster-info。
2.2 关键软件包与镜像准备
这是离线部署的核心。你需要提前准备好两个东西:Helm的二进制文件,和Rancher全套的Docker镜像。
1. 获取Helm客户端:因为网络隔离,我们无法直接使用 curl | bash 这种在线安装方式。你需要找一台能通外网的机器,从Helm的GitHub Release页面下载对应版本的二进制包,比如 helm-v3.17.3-linux-amd64.tar.gz。然后上传到你的k8s-master节点。
2. 准备Rancher离线镜像包:这是最费功夫但也最重要的一步。Rancher官方提供了生成离线镜像清单和打包脚本的方法。通常,你需要在一台能访问外网的机器上,使用 docker save 命令将Rancher Chart依赖的所有镜像打包。一个完整的Rancher v2.9.3部署,可能包括以下镜像(具体以Helm Chart解析为准):
rancher/rancher:v2.9.3rancher/rancher-webhook:v0.5.3rancher/fleet:v0.10.4rancher/fleet-agent:v0.10.4rancher/shell:v0.2.2- 以及一些基础设施镜像如
rancher/mirrored-cluster-api-controller:v1.7.3等。
你可以通过 helm template 命令解析出Chart需要的所有镜像列表,然后逐个拉取、打包。最终你会得到一个或多个 .tar 文件。把这些文件和你下载的Helm压缩包、Rancher的Helm Chart包(rancher-2.9.3.tgz)一起,打包成一个大的 Rancher.tar.gz,上传到master节点的 /root 目录下。
我这里假设你已经完成了以上步骤,手头已经有了这个“离线安装包”。接下来,我们就进入实战环节。
3. 搭建舞台:安装Helm与推送镜像到私有仓库
现在,我们登录到k8s-master节点,开始具体的操作。
3.1 安装与配置Helm
首先解压我们的资源包,并安装Helm。
# 解压总包
[root@k8s-master ~]# tar xf Rancher.tar.gz
[root@k8s-master ~]# cd Rancher/
# 解压并安装Helm
[root@k8s-master Rancher]# tar xf helm-v3.17.3-linux-amd64.tar.gz
[root@k8s-master Rancher]# cp linux-amd64/helm /usr/local/bin/
[root@k8s-master Rancher]# helm version
version.BuildInfo{Version:"v3.17.3", GitCommit:"e4da49785aa6e6ee2b86efd5dd9e43400318262b", GitTreeState:"clean", GoVersion:"go1.23.7"}
看到版本信息,说明Helm安装成功了。为了让后续操作更顺手,我强烈建议你配置一下命令补全。
# 安装bash-completion(如果系统没有的话)
[root@k8s-master ~]# yum install -y bash-completion
# 为当前用户启用helm命令补全
[root@k8s-master ~]# echo "source <(helm completion bash)" >> ~/.bashrc
[root@k8s-master ~]# source ~/.bashrc
这样,你输入 helm in 再按Tab键,就能自动补全为 helm install 了,效率提升不止一点点。
3.2 加载与推送镜像到Harbor
接下来,要把离线镜像包加载到本地Docker,然后重新打标签并推送到我们自己的Harbor仓库。
# 1. 加载所有镜像到本地Docker(在存放.tar文件的目录下执行)
[root@k8s-master Rancher]# for i in `ls *.tar`; do docker load -i $i; done
# 这个命令会遍历当前目录下所有.tar文件,并将其中的镜像加载到本地。
# 2. 登录私有镜像仓库
[root@k8s-master Rancher]# docker login -u admin -p Harbor12345 192.168.100.4
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
登录成功后,我们需要为每一个Rancher相关的镜像打上私有仓库的标签。这里有个小坑要注意:如果你在Harbor里创建的项目名不是 library,或者你想把镜像放到特定的项目下,标签的格式需要相应改变。标准格式是 仓库地址/项目名/镜像名:标签。
# 3. 为镜像重新打标签(示例,请根据你实际加载的镜像列表调整)
docker tag rancher/rancher:v2.9.3 192.168.100.4/library/rancher/rancher:v2.9.3
docker tag rancher/rancher-webhook:v0.5.3 192.168.100.4/library/rancher/rancher-webhook:v0.5.3
docker tag rancher/fleet:v0.10.4 192.168.100.4/library/rancher/fleet:v0.10.4
docker tag rancher/fleet-agent:v0.10.4 192.168.100.4/library/rancher/fleet-agent:v0.10.4
# ... 为所有需要的镜像执行此操作
# 4. 推送镜像到私有仓库
docker push 192.168.100.4/library/rancher/rancher:v2.9.3
docker push 192.168.100.4/library/rancher/rancher-webhook:v0.5.3
# ... 推送所有打标后的镜像
这个过程可能需要一些时间,取决于你的网络和镜像大小。推送完成后,你可以登录Harbor的Web界面(http://192.168.100.4),在 library 项目下应该能看到所有这些镜像了。这步完成后,你的私有镜像仓库就成为了所有Rancher组件的“唯一指定货源”。
3.3 配置Docker信任私有仓库
为了让集群所有节点都能从这台Harbor拉取镜像,我们需要在每个节点的Docker配置中,将其添加为“非安全仓库”(因为我们用的是HTTP,如果是HTTPS且有正式证书可跳过)。在master节点上配置:
[root@k8s-master ~]# sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json << 'EOF'
{
"insecure-registries": ["192.168.100.4"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
重要:别忘了在k8s-node1和k8s-node2上也执行同样的配置修改,并重启Docker服务。否则,将来Pod调度到那些节点上时,会因无法拉取镜像而启动失败。
4. 为Rancher铺平道路:Ingress与证书
Rancher通常通过HTTPS访问,在私有环境里,我们一般使用自签名证书或者内部CA颁发的证书。同时,我们需要一个Ingress控制器作为流量入口。
4.1 部署Ingress Nginx控制器
我们选择Nginx Ingress Controller,它功能成熟且社区活跃。同样,我们需要使用离线镜像。
# 1. 加载Ingress Nginx镜像(假设你已将其放入离线包)
[root@k8s-master Rancher]# docker load -i ingress-nginx-controller-v1.8.0.tar
[root@k8s-master Rancher]# docker load -i ingress-nginx-kube-webhook-certgen-v20230407.tar
# 2. 为需要运行Ingress Controller的节点打标签
# 这里我选择让master节点也承担Ingress角色
[root@k8s-master ~]# kubectl label nodes k8s-master node-role=ingress
# 3. 部署Ingress Nginx
# 你需要一个对应的部署YAML文件,可以从Ingress Nginx官网下载离线版,或使用如下命令。
# 这里假设你已经准备好了名为 deploy-ingress-nginx.yaml 的清单文件。
[root@k8s-master ~]# kubectl apply -f deploy-ingress-nginx.yaml
部署完成后,检查一下Pod状态:
[root@k8s-master ~]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-xxxxx 0/1 Completed 0 2m
ingress-nginx-admission-patch-yyyyy 0/1 Completed 0 2m
ingress-nginx-controller-zzzzz 1/1 Running 0 2m
看到Controller的Pod是 Running 状态,就说明Ingress控制器已经就绪了。
4.2 生成自签名证书
在内网环境,我们可以自己充当CA,为Rancher的域名签发证书。我习惯用一个脚本来自动化这个过程,非常方便。创建一个名为 create_self-signed-cert.sh 的脚本,内容如下(脚本逻辑是生成CA证书,再用CA签发服务器证书):
#!/bin/bash -e
# 脚本内容较长,核心是使用openssl生成CA证书和服务器证书。
# 它会生成 ca.key, ca.crt, tls.key, tls.crt 等文件。
# 具体脚本内容可以参考你提供的原始材料中的那个长脚本,这里不重复占用篇幅。
运行这个脚本,为我们的Rancher域名(例如 rancher.internal.company.com)生成证书。假设我们内网DNS解析这个域名到Master节点的IP 192.168.100.3。
[root@k8s-master ~]# bash create_self-signed-cert.sh --ssl-domain=rancher.internal.company.com --ssl-trusted-ip=192.168.100.3,192.168.100.4,192.168.100.5 --ssl-size=2048 --ssl-date=3650
执行成功后,当前目录下会生成 tls.crt(服务器证书+CA证书链)和 tls.key(服务器私钥)这两个关键文件,以及CA的 cacerts.pem 和 cakey.pem。
5. 核心部署:使用Helm安装高可用Rancher
万事俱备,只欠Helm。现在我们要告诉Helm:“请用我指定的镜像仓库、我指定的证书,在这个命名空间里安装Rancher,并且启动3个副本以实现高可用。”
5.1 创建命名空间与Kubernetes Secret
首先,为Rancher创建一个独立的命名空间,这是一个好习惯。
[root@k8s-master ~]# kubectl create namespace cattle-system
然后,我们需要创建几个Kubernetes Secret,把证书和镜像仓库的登录凭证交给集群。
1. 创建CA证书的Secret:让Rancher组件信任我们自己的CA。
[root@k8s-master ~]# kubectl create secret generic tls-ca \
--from-file=cacerts.pem=./cacerts.pem -n cattle-system
2. 创建TLS证书的Secret:给Ingress控制器使用,用于HTTPS终端。
[root@k8s-master ~]# kubectl create secret tls tls-rancher-ingress \
--cert=./tls.crt --key=./tls.key -n cattle-system
3. 创建镜像拉取密钥(Image Pull Secret):这是让Kubernetes能够从私有Harbor仓库拉取镜像的关键。
[root@k8s-master ~]# kubectl create secret docker-registry harbor-regcred \
--docker-server=192.168.100.4 \
--docker-username=admin \
--docker-password=Harbor12345 \
--docker-email=admin@company.com \
--namespace=cattle-system
5.2 编写定制的Helm Values文件
直接使用 --set 参数在命令行设置所有选项容易出错且难以维护。我强烈推荐使用一个 values.yaml 文件来管理所有配置。创建一个 rancher-values.yaml 文件:
# rancher-values.yaml
hostname: rancher.internal.company.com # 你的Rancher访问域名
ingress:
tls:
source: secret # 使用我们刚才创建的secret
ingressClassName: nginx # 指定我们部署的Ingress控制器类型
privateCA: true # 告诉Rancher我们使用了私有CA
# 高可用配置:设置3个副本
replicas: 3
# 指定私有镜像仓库地址
systemDefaultRegistry: 192.168.100.4/library
# 如果某些镜像在私有仓库中的路径与默认不同,可以单独指定
# rancherImage: 192.168.100.4/library/rancher/rancher
# fleetImage: 192.168.100.4/library/rancher/fleet
# ... 其他镜像
# 引用我们创建的镜像拉取密钥
imagePullSecrets:
- name: harbor-regcred
# 使用捆绑的系统图表(离线环境必须)
useBundledSystemChart: true
# 资源限制与请求(根据你的集群配置调整)
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"
# 持久化存储(确保Rancher数据不丢失)
persistence:
enabled: true
storageClass: "local-path" # 假设你有一个名为local-path的StorageClass
size: 20Gi
这个配置文件把我们的核心诉求都写清楚了:去哪拉镜像、用什么证书、启动几个实例、资源给多少。管理起来一目了然。
5.3 执行Helm安装命令
现在,使用这个 values.yaml 文件来安装Rancher。首先,我们需要把本地的Rancher Helm Chart添加到Helm的仓库列表(虽然我们是离线安装,但Helm需要知道这个chart的存在形式)。
# 添加本地chart目录(假设rancher-2.9.3.tgz在当前目录)
# 我们不用远程repo,直接安装本地文件
[root@k8s-master ~]# helm install rancher ./rancher-2.9.3.tgz \
--namespace cattle-system \
--values ./rancher-values.yaml \
--wait # --wait 会等待所有资源就绪,推荐加上
执行这个命令后,Helm会在 cattle-system 命名空间里创建一系列资源:Deployment、Service、Ingress等等。你可以通过以下命令观察部署进度:
# 查看Pod启动状态
[root@k8s-master ~]# kubectl get pods -n cattle-system -w
NAME READY STATUS RESTARTS AGE
rancher-7fb7f7b549-xxxxx 0/1 Running 0 30s
rancher-7fb7f7b549-yyyyy 0/1 Pending 0 30s
rancher-7fb7f7b549-zzzzz 0/1 ContainerCreating 0 30s
rancher-webhook-6d99657f98-aaaaa 0/1 ContainerCreating 0 30s
...
# 最终,所有Pod都应该变为 Running 1/1 或 2/2 状态。
# 查看Ingress资源
[root@k8s-master ~]# kubectl get ingress -n cattle-system
NAME CLASS HOSTS ADDRESS PORTS AGE
rancher nginx rancher.internal.company.com 80, 443 2m
如果一切顺利,几分钟后,所有Pod都会运行起来。这时候,访问 https://rancher.internal.company.com 应该就能看到Rancher的初始化界面了。但是,因为我们的证书是自签名的,浏览器会提示不安全,需要手动信任或添加例外。
6. 访问与初始化:拿到管理权
部署成功只是第一步,我们还需要完成初始登录和配置。
6.1 获取Bootstrap密码
Rancher首次安装后,会生成一个随机的bootstrap密码。我们需要从Secret中把它取出来。
[root@k8s-master ~]# kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}'
r9lbnplkc7pp8bjh6fprbfwxz2n5c9k2wbp6b5lhlm44xvzrjrtr6c
记下这串密码,它就是你第一次登录的“钥匙”。
6.2 配置本地DNS解析
由于我们用的是内网域名,需要在访问Rancher的机器上(比如你的办公电脑)配置hosts文件,将域名指向Rancher Service的入口IP。如果你的Ingress Controller是NodePort类型(像我们这样),那么这个IP就是运行了Ingress Controller Pod的节点IP(我们之前给master打了标签,所以是192.168.100.3)。
在Windows上:编辑 C:\Windows\System32\drivers\etc\hosts 文件,添加一行:
192.168.100.3 rancher.internal.company.com
在Linux上:编辑 /etc/hosts 文件,添加同样内容。
6.3 登录并完成设置
打开浏览器,访问 https://rancher.internal.company.com。由于是自签名证书,浏览器会发出警告,选择“高级”->“继续前往”即可。
- 在登录页面,首次会要求你设置一个新的、强密码(不少于12位)。请务必牢记。
- 设置服务器URL。这里填写
https://rancher.internal.company.com,这是Rancher对外提供服务的地址,非常重要,后续Agent会通过这个地址连接Server。 - 进入主界面后,你首先会看到一个“本地”集群(即部署Rancher Server的这个K8s集群)。至此,一个基于私有仓库的高可用Rancher管理平台就部署完成了!
7. 踩坑指南与进阶配置
按照上面的步骤,大部分同学应该能成功部署。但根据我多年的经验,总会有一些“坑”在等着你。我把我遇到过的问题和解决方案分享出来,希望能帮你节省时间。
坑1:Pod一直处于 ImagePullBackOff 状态。
这几乎可以肯定是镜像拉取问题。首先检查Pod描述:
kubectl describe pod <pod-name> -n cattle-system
看Events部分,是不是显示 Failed to pull image 或者 pull access denied。排查思路:
- 确认
imagePullSecrets配置正确,且Secret确实存在于cattle-system命名空间:kubectl get secret harbor-regcred -n cattle-system。 - 确认Pod配置中确实挂载了这个Secret:
kubectl get pod <pod-name> -n cattle-system -o yaml | grep imagePullSecrets。 - 登录到Pod所在节点,手动尝试
docker pull 192.168.100.4/library/rancher/rancher:v2.9.3,看是否能成功。如果失败,检查节点上的Dockerdaemon.json是否配置了insecure-registries,并确认已重启Docker服务。
坑2:Rancher Web界面能打开,但一直卡在加载中或提示“server not available”。 这通常是证书或网络问题。排查思路:
- 检查Ingress配置是否正确引用了我们创建的TLS Secret:
kubectl get ingress rancher -n cattle-system -o yaml,看spec.tls.secretName是不是tls-rancher-ingress。 - 检查Rancher Pod的日志,看是否有证书相关的错误:
kubectl logs -f deployment/rancher -n cattle-system。 - 确认你访问的域名和证书里签发的域名(SAN)完全一致。我们的脚本里通过
--ssl-trusted-ip添加了IP,所以用IP访问也应该能通,但最好还是用域名。
坑3:如何将服务类型从默认的ClusterIP改为NodePort或LoadBalancer? 在离线环境,可能没有云厂商的LoadBalancer。我们可以修改Rancher的Service为NodePort,通过节点的IP和端口访问。
# 查看当前Service
kubectl get svc rancher -n cattle-system
# 修改Service类型
kubectl patch svc rancher -n cattle-system -p '{"spec":{"type":"NodePort"}}'
# 再次查看,会分配随机NodePort,也可以编辑svc指定端口
kubectl edit svc rancher -n cattle-system
# 在ports字段下,为https端口(比如443)添加 nodePort: 32443(选择一个30000-32767之间的端口)
进阶配置:配置持久化存储。
为了确保Rancher Server的数据(如用户信息、集群信息、应用商店目录等)在Pod重启或迁移后不丢失,必须配置持久化存储。在上面的 values.yaml 中我们已经启用了。你需要确保你的K8s集群中有可用的StorageClass。对于简单的测试环境,可以使用 local-path 或者 hostPath 类型的存储。在生产环境,则应该配置网络存储,如NFS、Ceph RBD等。
部署完成后,你可以在Rancher的“系统项目”->“存储”中看到创建的PVC(持久卷声明)是否绑定成功。这是保障Rancher高可用和数据安全的关键一步,千万不要忽略。
整个流程走下来,你会发现,虽然步骤不少,但每一步都有其明确的目的。从准备离线资源,到搭建私有仓库,再到用Helm这个“配置大师”统一部署,最后处理访问和安全问题。这套组合拳打下来,一个完全内网化、自主可控、高可用的Rancher容器管理平台就稳稳地跑起来了。以后再部署其他应用,都可以沿用这个模式:准备镜像 -> 推送到Harbor -> 编写Helm Values -> 一键部署,效率和安全都能得到保障。
103



被折叠的 条评论
为什么被折叠?



