一、前期准备
1、主机环境
节点名称 | IP地址 | 系统 | 安装组件 |
---|---|---|---|
nginx | 192.168.0.41 | CentOS7.6 | nginx |
node1 | 192.168.0.51 | CentOS7.6 | etcd,docker,k8s |
node2 | 192.168.0.52 | CentOS7.6 | etcd,docker,k8s |
node3 | 192.168.0.53 | CentOS7.6 | etcd,docker,k8s |
2、软件版本
rancher-2.3.5
kubernetes-1.17.2
rke-1.0.4
kubectl-1.17.2
helm-3.0.3
docker-18.09.9
这里要特别提说一下,helm这里我用的是3.x版本。关于Helm3和Helm2的区别可以参考你不得不了解Helm 3中的5个关键新特性
3、安装方法介绍
在Rancher中文文档中提供了两种HA的安装方法:
1)RKE HA安装
2)Helm HA安装
因为RKE HA安装仅支持Rancher-v2.0.8以及早期的版本,这种方式已经弃用。Rancher-v2.0.8以后的版本,欢迎您采用Helm chart方式部署Rancher HA。所以我这里采用Helm chart方式安装。
4、推荐的架构
- Rancher的DNS应解析为第4层负载均衡器
- Load Balancer应将端口
TCP/80
和TCP/443
转发到Kubernetes集群中的所有节点IP上。 - Ingress控制器将
HTTP
重定向到HTTPS
,并将作为端口TCP/443上的SSL/TLS终止。 - Ingress控制器将流量转发到Rancher pod的
TCP/80
端口。
二、环境初始化
主机初始化,三台node上都要执行。
1、主机名等设置
设置永久主机名,然后重新登录
[root@localhost ~]# hostnamectl set-hostname node1
[root@localhost ~]# hostnamectl set-hostname node2
[root@localhost ~]# hostnamectl set-hostname node3
在/etc/hosts中设置主机名解析
[root@node1 ~]# cat >> /etc/hosts << EOF
192.168.0.51 node1
192.168.0.52 node2
192.168.0.53 node3
EOF
2、关闭相关服务
关闭selinux
[root@node1 ~]# setenforce 0
[root@node1 ~]# vim /etc/sysconfig/selinux
SELINUX=disabled #修改为disabled
关闭防火墙
[root@node1 ~]# systemctl stop firewalld
[root@node1 ~]# systemctl disable firewalld
关闭swap
[root@node1 ~]# swapoff -a
为了防止系统重启之后/etc/fstab
的重新挂载,也许要将/etc/fstab
中的swap分区给注释了。
3、设置内核参数
[root@node1 ~]# cat <<EOF > /etc/sysctl.d/rancher.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
vm.max_map_count = 655360
EOF
使配置生效
[root@k8s-node1 ~]# modprobe br_netfilter
[root@k8s-node1 ~]# sysctl -p /etc/sysctl.d/rancher.conf
4、安装基础软件
[root@node1 ~]# yum -y install vim screen lrzsz tree openssl openssh-clients openssl-devel openssh-server telnet iftop iotop sysstat wget ntpdate dos2unix lsof net-tools mtr gcc gcc-c++ cmake zip unzip git sudo psmisc && /usr/sbin/ntpdate ntp1.aliyun.com &> /dev/null && hwclock --systohc &> /dev/null
5、创建用户、免密登录
创建rancher并添加到docker组
[root@node1 ~]# groupadd docker
[root@node1 ~]# useradd rancher -G docker
[root@node1 ~]# echo "123456" | passwd --stdin rancher
ssh免密登录,这一步只需在node1
上执行,授权node1可以免密登录到这三台node上,后面安装k8s的时候会用到。
[root@node1 ~]# su - rancher
[root@node1 ~]# ssh-keygen
[root@node1 ~]# ssh-copy-id rancher@192.168.0.51
[root@node1 ~]# ssh-copy-id rancher@192.168.0.52
[root@node1 ~]# ssh-copy-id rancher@192.168.0.53
6、升级内核
这段是我在使用了一段时间的rancher之后,特意跑回来加上的。因为在使用的过程中,其中有一个节点出现了下面所说的第二个bug。
CentOS7.x系统自带的额3.10.x内核存在一些Bug,导致运行的Docker、Kubernetes不稳定,例如:
1、高版本的docker(1.13以后)启用了 3.10 kernel 实验支持的 kernel memory account 功能(无法关闭),当节点压力大如频繁启动和停止容器时会导致 cgroup memory leak;
2、网络设备引用计数泄漏,会导致类似于报错:“kernel:unregister_netdevice: waiting for eth0 to become free. Usage count = 1”;
解决方案如下:
1)升级内核到 4.4.X 以上;
2)或者,手动编译内核,disable CONFIG_MEMCG_KMEM 特性;
3)或者,安装修复了该问题的 Docker 18.09.1 及以上的版本。但由于 kubelet 也会设置 kmem(它 vendor 了 runc),所以需要重新编译 kubelet 并指定 GOFLAGS="-tags=nokmem";
git clone --branch v1.14.1 --single-branch --depth 1 https://github.com/kubernetes/kubernetes
cd kubernetes
KUBE_GIT_VERSION=v1.14.1 ./build/run.sh make kubelet GOFLAGS="-tags=nokmem"
这里采用升级内核的解决方法:
yum -y install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
# 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装一次!
yum --enablerepo=elrepo-kernel install -y kernel-lt
# 设置开机从新内核启动
grub2-set-default 0
重启主机:
sync
reboot
三、安装docker
在三台主机上都执行下面的Docker安装操作。
在安装docker之前,要先确定docker的版本,那么怎么来确定呢?
先来看看Rancher-v2.3.5支持的各个软件的版本:
可以看到默认安装的是v1.17.2版本的Kubernetes,所以我们要选择支持v1.17.2版本Kubernetes的docker版本。这里选择docker-18.09.9
。
1、使用国内yum源
[root@node1 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@node1 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
2、卸载旧版本的docker
如果主机上已经有docker存在且不是想要安装的版本,需要先进行卸载。
[root@node1 ~]# yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
container*
3、安装Docker18.09版本
[root@node1 ~]# yum -y install docker-ce-18.09.9-3.el7 docker-ce-cli-18.09.9-3.el7
4、启动docker
[root@node1 ~]# systemctl start docker
[root@node1 ~]# systemctl enable docker
[root@node1 ~]# systemctl status docker
5、优化docker配置
[root@node1 ~]# cat > /etc/docker/daemon.json << EOF
{
"oom-score-adjust": -1000,
"registry-mirrors": ["https://7bezldxe.mirror.aliyuncs.com/","https://kw88y6eh.mirror.aliyuncs.com"],
"insecure-registries":["192.168.0.153"],
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
OOMScoreAdjust=-1000
:防止docker服务OOM
registry-mirrors
:公网的加速器地址,可以设置多个,地址需要添加协议头(https或者http)
storage-driver
:使用OverlayFS的overlay2存储驱动。(OverlayFS是一个新一代的联合文件系统,类似于AUFS,但速度更快,实现更简单。Docker为OverlayFS提供了两个存储驱动程序:旧版的overlay,新版的overlay2(更稳定))
6、重启docker
[root@node1 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl restart docker
四、安装Nginx
nginx的安装详见Nginx安装
修改配置文件nginx.conf
user nginx;
worker_processes 4;
worker_rlimit_nofile 40000;
events {
worker_connections 8192;
}
http {
# Gzip Settings
gzip on;
gzip_disable "msie6";
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_vary on;
gzip_static on;
gzip_proxied any;
gzip_min_length 0;
gzip_comp_level 8;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml application/font-woff text/javascript application/javascript application/x-javascript text/x-json application/json application/x-web-app-manifest+json text/css text/plain text/x-component font/opentype application/x-font-ttf application/vnd.ms-fontobjectfont/woff2 image/x-icon image/png image/jpeg;
server {
listen 80;
return 301 https://$host$request_uri;
}
}
stream {
upstream rancher_servers {
least_conn;
server 192.168.0.51:443 max_fails=3 fail_timeout=5s;
server 192.168.0.52:443 max_fails=3 fail_timeout=5s;
server 192.168.0.53:443 max_fails=3 fail_timeout=5s;
}
server {
listen 443;
proxy_pass rancher_servers;
}
}
启动nginx
[root@nginx~]# systemctl restart nginx.service
[root@nginx~]# systemctl enable nginx.service
五、 Rancher集群部署
以下操作只需在node1
上执行
1、安装必备工具
需要以下的CLI工具:
- rke - Rancher Kubernetes Engine用于构建Kubernetes集群。
- kubectl - Kubernetes命令行工具。
- helm - Kubernetes的包管理。
安装rke
#rke下载地址:https://github.com/rancher/rke/tags,下载v1.0.4
[root@node1 ~]# chmod +x rke_linux-amd64
[root@node1 ~]# mv rke_linux-amd64 /usr/bin/rke
安装kubectl
[root@node1 ~]# wget http://storage.googleapis.com/kubernetes-release/release/v1.17.2/bin/linux/amd64/kubectl
[root@node1 ~]# chmod +x kubectl
[root@node1 ~]# mv kubectl /usr/bin/kubectl
安装helm
#helm下载地址:https://github.com/helm/helm/tags 下载v3.0.3
[root@node1 ~]# tar -zxf helm-v3.0.3-linux-amd64.tar.gz
[root@node1 ~]# mv linux-amd64/helm /usr/bin/helm
[root@node1 ~]# rm -rf helm-v3.0.3-linux-amd64.tar.gz linux-amd64
2、安装k8s
1)切换到rancher用户
[root@node1 ~]# su - rancher
这里要注意一下,必须使用普通用户进行操作,否则后边的操作会报错。
2)创建rancher-cluster.yml
文件
[rancher@node1 ~]$ cat > rancher-cluster.yml << EOF
nodes:
- address: 192.168.0.51
user: rancher
role: [controlplane,worker,etcd]
- address: 192.168.0.52
user: rancher
role: [controlplane,worker,etcd]
- address: 192.168.0.53
user: rancher
role: [controlplane,worker,etcd]
services:
etcd:
snapshot: true
creation: 6h
retention: 24h
EOF
常规RKE节点选项
Option | Required | Description |
---|---|---|
address | yes | 公共域名或IP地址 |
user | yes | 可以运行docker命令的用户,需要是普通用户 |
role | yes | 分配给节点的Kubernetes角色列表 |
ssh_key_path | no | 用于对节点进行身份验证的SSH私钥的路径(默认为~/.ssh/id_rsa) |
port | no | 节点的SSH端口号 |
3)创建Kubernetes集群
运行RKE命令创建Kubernetes集群
[rancher@node1 ~]$ rke up --config ./rancher-cluster.yml
由于需要下载docker镜像文件,所以需要一段时间才能安装好。完成后,它应显示Finished building Kubernetes cluster successfully
。
并且RKE会自动创建kube_config_rancher-cluster.yml
。这个文件包含kebectl和helm访问K8S的凭据。
4)配置环境变量
切换到root用户
[rancher@node1 ~]$ su - root
[root@node1 ~]# vim /etc/profile
export KUBECONFIG=/home/rancher/kube_config_rancher-cluster.yml
[root@node1 ~]# source /etc/profile
5)通过kubectl
测试您的连接,并查看您的所有节点是否处于Ready
状态
这里先配置下kubectl的命令补全功能。
[root@node1 ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@node1 ~]# source ~/.bashrc
[rancher@node1 ~]$ su - rancher
[rancher@node1 ~]$ echo "source <(kubectl completion bash)" >> ~/.bashrc
[rancher@node1 ~]$ source ~/.bashrc
查看节点的状态
[rancher@node1 ~]$ kubectl get node
NAME STATUS ROLES AGE VERSION
192.168.0.51 Ready controlplane,etcd,worker 15h v1.17.2
192.168.0.52 Ready controlplane,etcd,worker 15h v1.17.2
192.168.0.53 Ready controlplane,etcd,worker 15h v1.17.2
6)检查集群的Pod运行状况
[rancher@node1 ~]$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
ingress-nginx default-http-backend-67cf578fc4-rcxnf 1/1 Running 0 11m
ingress-nginx nginx-ingress-controller-6snj4 1/1 Running 0 11m
ingress-nginx nginx-ingress-controller-fk67x 1/1 Running 1 11m
ingress-nginx nginx-ingress-controller-lpbwr 1/1 Running 0 11m
kube-system canal-2hpwj 2/2 Running 2 15h
kube-system canal-9cw6p 2/2 Running 2 15h
kube-system canal-l4ssv 2/2 Running 2 15h
kube-system coredns-7c5566588d-8zw6n 1/1 Running 0 11m
kube-system coredns-7c5566588d-btg2z 1/1 Running 0 11m
kube-system coredns-autoscaler-65bfc8d47d-xkssf 1/1 Running 0 11m
kube-system metrics-server-6b55c64f86-jpz64 1/1 Running 0 11m
kube-system rke-coredns-addon-deploy-job-5tgtc 0/1 Completed 0 11m
kube-system rke-ingress-controller-deploy-job-6dtcd 0/1 Completed 0 11m
kube-system rke-metrics-addon-deploy-job-pf2jv 0/1 Completed 0 11m
kube-system rke-network-plugin-deploy-job-2r22w 0/1 Completed 0 15h
7)保存配置文件
保存kube_config_rancher-cluster.yml
和rancher-cluster.yml
文件的副本,后期将需要这些文件来维护和升级Rancher实例。
3、安装配置Helm
注意
:Helm的3.x版本和2.x版本的安装配置是不同的。3.x版本只需要安装好Helm客户端就行,其他的啥都不用配置。如果你用的是Helm的2.x版本,那可以参考rancher中文文档中的安装配置Helm。
Helm是Kubernetes首选的包管理工具。Helm charts为Kubernetes YAML清单文档提供模板语法。使用Helm,我们可以创建可配置的部署,而不仅仅是使用静态文件。
1)安装Helm客户端
客户端在上面的安装必备工具
中已经安装。由于我这里是安装的Helm-v3.x版本,所以不需要配置Helm客户端的访问权限。
2)安装Helm Server(Tiller)
由于我这里是安装的Helm-v3.x版本,所以不需要安装Helm Server。
4、Helm安装Rancher
1)添加Chart仓库地址
使用helm repo add
命令添加Rancher chart仓库地址,访问Rancher tag和Chart版本
替换<CHART_REPO>
为您要使用的Helm仓库分支(即latest或stable)。
[rancher@node1 ~]$ helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
[rancher@node1 ~]$ helm repo update
2)使用自签名SSL证书安装安装Rancher Server
Rancher Server设计默认需要开启SSL/TLS配置来保证安全,将ssl证书以Kubernetes Secret
卷的形式传递给Rancher Server或Ingress Controller
。首选创建证书密文,以便Rancher和Ingress Controller
可以使用。
我这里使用自签名ssl证书。
[1]如果没有自签名ssl证书,可以参考自签名ssl证书,一键生成ssl证书。
[rancher@node1 ~]$ mkdir ssl
[rancher@node1 ~]$ cd ssl/
#先把一键生成ssl证书的脚本另存为create_self-signed-cert.sh,这里因为脚本的内容太多,就不贴出来了,详见上面的超链接。
#然后再用这个脚本生成ssl证书
[rancher@node1 ssl]$ ./create_self-signed-cert.sh --ssl-domain=my.rancher.com --ssl-trusted-ip=192.168.0.41 --ssl-size=2048 --ssl-date=3650
[2]一键生成的ssl自签名证书脚本将自动生成tls.crt、tls.key、cacerts.pem
三个文件,文件名称不能修改。如果使用你自己生成的自签名ssl证书,则需要将服务证书
和CA中间证书链
合并到tls.crt
文件中,将私钥
复制到或者重命名为tls.key
文件,将CA证书
复制到作者重命名为cacerts.pem
。
[3]使用kubectl
在命名空间cattle-system
中创建tls-ca
和tls-rancher-ingress
两个secret
。
# 创建命名空间
[rancher@node1 ~]$ kubectl create namespace cattle-system
#服务证书和私钥密文
[rancher@node1 ~]$ kubectl -n cattle-system create \
secret tls tls-rancher-ingress \
--cert=/home/rancher/ssl/tls.crt \
--key=/home/rancher/ssl/tls.key
#ca证书密文
[rancher@node1 ~]$ kubectl -n cattle-system create secret \
generic tls-ca \
--from-file=/home/rancher/ssl/cacerts.pem
[4]安装Rancher Server
[rancher@node1 ~]$ helm install rancher rancher-stable/rancher \
--namespace cattle-system \
--set hostname=my.rancher.com \
--set ingress.tls.source=secret \
--set privateCA=true
注意:证书对应的域名
需要与hostname
选项匹配,否则ingress
将无法代理访问Rancher。
my.rancher.com
是后面访问rancher的域名,需要在/etc/hosts文件中添加关联(所有主机):
[root@node1 ~]$ echo "192.168.0.41 my.rancher.com" >> /etc/hosts
[root@node2 ~]$ echo "192.168.0.41 my.rancher.com" >> /etc/hosts
[root@node3 ~]$ echo "192.168.0.41 my.rancher.com" >> /etc/hosts
[root@nginx ~]$ echo "192.168.0.41 my.rancher.com" >> /etc/hosts
3)为Agent Pod添加主机别名
由于我们是通过添加/etc/hosts
主机名的方式制定的Rancher Server域名,所以需要为Agent Pod添加主机名(/etc/hosts),让其可以正常通过Rancher Server Url
与Rancher Server通信。
[1]执行以下命令为Rancher Server容器配置hosts:
[rancher@node1 ~]$ kubectl -n cattle-system patch deployments rancher --patch '{
"spec": {
"template": {
"spec": {
"hostAliases": [
{
"hostnames":
[
"my.rancher.com"
],
"ip": "192.168.0.41"
}
]
}
}
}
}'
[2]cattle-cluster-agent Pod
和cattle-node-agent pod
需要在LOCAL
集群初始化之后才会部署,所以先通过Rancher Server URL
访问Rancher Web UI进行初始化。
将刚刚的域名映射关系写入到Windows主机的hosts文件中。
192.168.0.41 my.rancher.com
然后浏览器使用域名访问 https://my.rancher.com
输入:admin/admin。
设置好URL之后,进入到Rancher。
刚进来,会看到一个问题。
报这个问题的原因是cattle-cluster-agent Pod
和cattle-node-agent pod
还没有被创建成功,不急,接着往下看。
[3]在Rancher Web UI中依次进入local集群/system项目
,在cattle-system
命名空间中查看是否有cattle-cluster-agent Pod
和cattle-node-agent pod
被创建。如果有创建则进行下面的步骤,没有创建则等待;
[4]cattle-cluster-agent pod
[rancher@node1 ~]$ kubectl -n cattle-system \
patch deployments cattle-cluster-agent --patch '{
"spec": {
"template": {
"spec": {
"dnsPolicy": "ClusterFirstWithHostNet",
"hostNetwork": true,
"hostAliases": [
{
"hostnames":
[
"my.rancher.com"
],
"ip": "192.168.0.41"
}
]
}
}
}
}'
[5]cattle-node-agent pod
[rancher@node1 ~]$ kubectl -n cattle-system \
patch daemonsets cattle-node-agent --patch '{
"spec": {
"template": {
"spec": {
"hostAliases": [
{
"hostnames":
[
"my.rancher.com"
],
"ip": "192.168.0.41"
}
]
}
}
}
}'
稍等一段时间之后,再来看cattle-system
命名空间中的状态,发现cattle-cluster-agent Pod
和cattle-node-agent pod
都变为了Active
状态了。
通过命令行来查看下pod的状态:
[rancher@node1 ~]$ kubectl get -n cattle-system pod
NAME READY STATUS RESTARTS AGE
cattle-cluster-agent-7dc756ff44-skjml 1/1 Running 0 5m25s
cattle-node-agent-5pcnn 1/1 Running 0 5m1s
cattle-node-agent-6hbxt 1/1 Running 0 5m4s
cattle-node-agent-hwk2l 1/1 Running 0 5m5s
rancher-58b6b8cfd-9tg8m 1/1 Running 0 12m
rancher-58b6b8cfd-r5bft 1/1 Running 2 12m
rancher-58b6b8cfd-vz82g 1/1 Running 1 12m
都是running
状态,没问题。
然后再回头来看看Rancher中local
集群的状态,就不会报连接问题了。
到这里,Rancher集群的HA部署就基本完成了。
参考文章:
https://docs.rancher.cn/rancher2x/
http://www.eryajf.net/2725.html