文章目录
- Centos下安装K3S+Rancher
- 1. 准备工作
- 2. 集群数据库方案
- 3. 高可用网络配置
- 4. 安装K3S
- 5. 安装并指定私有镜像库
- 6. 高可用安装Rancher
- 7. 设置keepalived检测脚本
- 8. cattle-cluster-agent和cattle-node-agent几乎一定会处理的问题
- 结束
- +1:完全离线安装
- +2:在K3S集群加入一个Agent节点
- +3. 更换rancher的默认镜像库地址
- +4. 删除rancher
- +5. 修改ETCD节点信息
- +6. 修改K3S_DATASTORE_ENDPOINT
- +7. 高可用安装情况下修改80和443端口(本章节网上找不到,纯属原创精华)
- +8. 在Rancher上手动创建Ingress
- +9. 修改max-pods
- +10. IP修改后,以灾难恢复方式重建ETCD
Centos下安装K3S+Rancher
’+1’章节:完全离线安装中需要用到的离线包在这里,提取码:h813
适用于centos7+,x86或arm都一样
在每个server节点上执行一次。
核心思想说明:
对于一个小型环境,因为k3s的server节点高可用,最少只需要2个节点(使用外部数据库)
对于中型环境,那么可以考虑更多的server节点,以及其他数据库方案(比如etcd、三节点galary mysql),方案上选择较多。
开始安装过程
以下工作以3台节点:172.16.149.122(k3s01),172.16.149.123(k3s02),172.16.149.124(k3s03),VIP172.16.149.139为例
1. 准备工作
每台机器上执行
1.1. disable firewall
systemctl stop firewalld
systemctl disable firewalld
1.2. disable selinux
setenforce 0
sed -i s#SELINUX=enforcing#SELINUX=disabled# /etc/selinux/config
重启机器
1.3. disable swap(仅列出,可以暂不执行,效果不明)
swapoff -a
# 找到fstab中,swap defaults那一行,行首加一个注释
sed -i ‘s/.*swap.defaults./#&/g’ /etc/fstab
1.4. 修改主机名,并修改hosts
hostnamectl set-hostname k3s01(节点2为k3s02)
echo -e “172.16.149.122\tk3s01” | tee -a /etc/hosts
echo -e “172.16.149.123\tks302” | tee -a /etc/hosts
1.5. 安装docker
用rancher提供的方式安装
curl https://releases.rancher.com/install-docker/19.03.sh | sh
|
或者用docker其他方式安装
1.5.1. 修改Docker loglimit。非常重要!
因为docker中的程序syslog,默认会使用emptyDir主机存储,
也就是会在/var/lib/kubernetes/中的产生很多ephemeral-storage
内容。
如果不设置,后续会遇到
The node was low on resource: ephemeral-storage. Container xxxx which exceeds its request of xxx
这种问题。
解决办法可以参考这里
vi /etc/docker/daemon.json
设置以下内容,用于限制log的ephemeral-storage大小:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
}
}
1.5.2. 修改Docker limit。非常重要!
如果后续要在该集群上安装mongodb,那么必须设置docker limit参数。
如果不设置,mongodb将因为ulimit的问题,导致不断重启
在日志中一般会发现:
Failed to mlock: Cannot allocate locked memory…
配置方法(参考这里):
- 执行 systemctl status docker ; systemctl status containerd(arm版本的老docker可能会使用containerd底层)。找到他们的配置文件地址
假如上述服务的配置地址分别是:/usr/lib/systemd/system/docker.service,/usr/lib/systemd/system/containerd.service- 添加
LimitMEMLOCK=infinity
vi /usr/lib/systemd/system/docker.service
如果有contaninerd
vi /usr/lib/systemd/system/containerd.service
在[Service]一节增加LimitMEMLOCK=infinity
1.5.3. 强制使用overlay2存储引擎
vi /etc/docker/daemon.json
设置以下内容,
{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
1.5.4. 修改docker数据目录(可选)
某些机器,由于/var/lib/docker/目录空间不大,可以考虑迁移该目录到其他地方
比如迁移到 /home下
systemctl stop docker
mkdir -p /home/docker
rsync -avz /var/lib/docker /home/docker (需要安装rsync)
vi /etc/systemd/system/docker.service.d/devicemapper.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --graph=/home/docker
将上述内容写入
:wq!
1.5.5. 重启docker
systemctl stop docker
systemctl daemon-reload
如果有containerd,systemctl stop containerd
systemctl daemon-reload
如果有containerd,systemctl start containerd
systemctl start docker
1.6. 节点优化(可选)
- 节点内核调优
echo "
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
net.ipv4.ip_forward=1
net.ipv4.conf.all.forwarding=1
net.ipv4.neigh.default.gc_thresh1=4096
net.ipv4.neigh.default.gc_thresh2=6144
net.ipv4.neigh.default.gc_thresh3=8192
net.ipv4.neigh.default.gc_interval=60
net.ipv4.neigh.default.gc_stale_time=120
# 参考 https://github.com/prometheus/node_exporter#disabled-by-default
kernel.perf_event_paranoid=-1
#sysctls for k8s node config
net.ipv4.tcp_slow_start_after_idle=0
net.core.rmem_max=16777216
fs.inotify.max_user_watches=524288
kernel.softlockup_all_cpu_backtrace=1
kernel.softlockup_panic=0
kernel.watchdog_thresh=30
fs.file-max=2097152
fs.inotify.max_user_instances=8192
fs.inotify.max_queued_events=16384
vm.max_map_count=262144
fs.may_detach_mounts=1
net.core.netdev_max_backlog=16384
net.ipv4.tcp_wmem=4096 12582912 16777216
net.core.wmem_max=16777216
net.core.somaxconn=32768
net.ipv4.ip_forward=1
net.ipv4.tcp_max_syn_backlog=8096
net.ipv4.tcp_rmem=4096 12582912 16777216
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1
kernel.yama.ptrace_scope=0
vm.swappiness=0
# 可以控制core文件的文件名中是否添加pid作为扩展。
kernel.core_uses_pid=1
# Do not accept source routing
net.ipv4.conf.default.accept_source_route=0
net.ipv4.conf.all.accept_source_route=0
# Promote secondary addresses when the primary address is removed
net.ipv4.conf.default.promote_secondaries=1
net.ipv4.conf.all.promote_secondaries=1
# Enable hard and soft link protection
fs.protected_hardlinks=1
fs.protected_symlinks=1
# 源路由验证
# see details in https://help.aliyun.com/knowledge_detail/39428.html
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_announce=2
# see details in https://help.aliyun.com/knowledge_detail/41334.html
net.ipv4.tcp_max_tw_buckets=5000
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_synack_retries=2
kernel.sysrq=1
" >> /etc/sysctl.conf
- nofile
cat >> /etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65536
EOF
- 关闭网卡offload(
谨慎操作)
如果出现【主机上】nodeport访问慢的问题,尝试执行以下内容
特别注意:
1)eth0代表主机网卡,应该按照实际情况修改
2)只有在默认使用flannel网络的情况下执行
ethtool -K eth0 rx off tx off sg off tso off
ethtool -K flannel.1 rx off tx off sg off tso off
2. 集群数据库方案
2.1 使用etcd(推荐)
# [member]
#etcd实例名称,每个节点不一样
ETCD_NAME=etcd1
#etcd数据保存目录
ETCD_DATA_DIR="/var/lib/etcd"
#供外部客户端使用的url
ETCD_LISTEN_CLIENT_URLS="http://本机IP:2379,http://127.0.0.1:2379"
#广播给外部客户端使用的url
ETCD_ADVERTISE_CLIENT_URLS="http://本机IP:2379"
#[cluster]
#集群内部通信使用的URL
ETCD_LISTEN_PEER_URLS="http://本机IP:2380"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://本机IP:2380"
#广播给集群内其他成员访问的URL
ETCD_INITIAL_CLUSTER="[ETCD_NAME]=http://本机IP:2380[,[其他节点ETCD_NAME]=http://其他节点IP:2380]"
#初始集群成员列表
#用于指示本次是否为新建集群。有两个取值new和existing。如果填为existing,该
#member启动时会尝试与其他member交互。集群初次建立时,要填为new,经尝试最后
#一个节点填existing也正常,其他节点不能填为existing。集群运行过程中,一个
#member故障后恢复时填为existing,经尝试填为new也正常。全没问题的
ETCD_INITIAL_CLUSTER_STATE="new|existing"
#集群的名称
ETCD_INITIAL_CLUSTER_TOKEN="sobey-arm-etcd-cluster"
- systemctl restart etcd
- etcdctl member list检查集群情况
- etcdctl cluster-health
member eabc202e74d53d3 is healthy: got healthy result from http://172.16.149.124:2379
member b6e44ea4f023b88a is healthy: got healthy result from http://172.16.149.122:2379
member e50821dfde62301e is healthy: got healthy result from http://172.16.149.123:2379
一些情况:
1.在部署etcd集群时,尝试启动etcd1时,出现报错
Apr 12 01:06:49 k8s-master etcd[3092]: health check for peer 618d69366dd8cee3 could not connect: dial tcp 192.168.81.12:2380: getsockopt: connection refused
Apr 12 01:06:49 k8s-master etcd[3092]: health check for peer acd2ba924953b1ec could not connect: dial tcp 192.168.81.60:2380: getsockopt: connection refused
Apr 12 01:06:48 k8s-master etcd[3092]: publish error: etcdserver: request timed out
分析是因为etcd1的配置文件/etc/etcd/etcd.conf中的ETCD_INITIAL_CLUSTER_STATE是new,而在配置中ETCD_INITIAL_CLUSTER写入了etcd2/3的IP:PORT,这时etcd1尝试去连接etcd2、etcd3,但是etcd2、3的etcd服务此时还未启动,因此需要先启动etcd2和3的etcd服务,再去启动etcd1。
2.在初次部署etcd完成后,尝试执行etcdctl cluster-health命令来查询集群的运行状态,但是报错
cluster may be unhealthy: failed to list members
Error: client: etcd cluster is unavailable or misconfigured; error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused
; error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused
error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused
error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused
在etcd配置文件中的ETCD_LISTEN_CLIENT_URLS项,只写入了http://192.168.81.60:2379,而没有写入http://127.0.0.1:2379,加入后即可正常查询。
note:初始集群成员列表 其他机器为existing。或者参考2中所述的方式,用yml一次性启动
2.2 使用mysql双机热备(实验性)
基本目标:使用docker host模式部署在两个server节点上部署mysql。配置参考这里,形成双机主主热备的mysql高可用集群
我们在两个节点,172.16.149.122,172.16.149.123 上先安装各自的mysql,这里我们直接采用docker方式安装
2.2.1 准备工作
- docker pull mysql:latest(版本自己考虑,要求5.7以上,比如:docker pull mysql:5.7.32)
对于ARM机器官方版本只有8.0,docker pull mysql/mysql-server:8.0-aarch64- 先启动一个容器,把/etc/my.cnf拷贝出来备用,这个我们要放到主机上
docker run -itd --name mysqltest mysql
mkdir -p /sobey/dbu/mysql
docker cp mysqltest:/etc/my.cnf /sobey/dbu/mysql/my.cnf- 配置好主机数据目录
mkdir -p /sobey/dbu/mysql/datas- 删除这个容器
docker stop mysqltest
docker rm mysqltest
2.2.2 正式安装
2.2.2.1 修改配置文件
vi /sobey/dbu/mysql/my.cnf。
这里有一个特殊的地放:把目录改为/var/games,主要是为了映射数据到主机。因为/var/games是存在且未用的,否则只有重新编辑镜像,然后创建一个存放data的目录,如果不创建,mysql会报错没有创建目录
datadir=/var/games
socket=/var/lib/mysql/mysql.sock
log-error=/var/games/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
user=mysql
# 配置server-id 每个MySQL实例的server-id都不能相同
server-id=1 # 两个节点的server-id必须不同
# MySQL的日志文件的名字
log-bin=mysql_log_bin
# 作为从库时 更新操作是否写入日志 on:写入 其他数据库以此数据库做主库时才能进行同步
log-slave-updates=on
auto_increment_offset=1 # 设置奇偶自增id,节点1设置为1,节点2设置为2
auto_increment_increment=2
# MySQL系统库的数据不需要同步 我们这里写了3个 更加保险
# 同步数据时忽略一下数据库 但是必须在使用use db的情况下才会忽略;如果没有使用use db 比如create user 数据还是会同步的
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-ignore-db=performance_schema
replicate-ignore-db=sys
# 使用通配符忽略MySQL系统库的表 这样在create user时也不会进行同步了
replicate_wild_ignore_table=information_schema.%
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=performance_schema.%
replicate_wild_ignore_table=sys.%
# MySQL系统库的日志不计入binlog 这样更加保险了
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
上面比较特殊的点:
- 节点1和节点2的server-id必须不一样
server-id=1 - 节点1自增长ID
auto_increment_offset = 1
auto_increment_increment = 2 #奇数ID - 节点2自增加ID
auto_increment_offset = 2
auto_increment_increment = 2 #偶数ID
2.2.2.2 正式启动容器,映射端口、my.cnf、data存放目录.
- docker run -itd --name k3smysql -p 3306:3306 -v /sobey/dbu/mysql/my.cnf:/etc/my.cnf -v /sobey/dbu/mysql/datas:/var/games --net=host -e MYSQL_ROOT_PASSWORD=[这里填root密码] mysql
- docker ps检查一下安装情况,用客户端连接看看情况
- 进入容器,修改root用户允许远程访问
docker exec -it k3smysql /bin/sh
mysql -u root -p
输入root密码,进入后
修改远程权限,具体查一下5.x和8.0+是不一样的,这里因为是用8.0,所以
use mysql;
update user set host=’%’ where user=‘root’;
flush privileges;- 如果是8.0的数据库,默认使用的是caching_sha2_passsword作为验证plugin,会导致很多客户端报错,有两个办法处理:
- a) 在my.cnf中设置
default_authentication_plugin=mysql_native_password- b) 按照3的方法进入mysql
ALTER USER ‘root’@’%’ IDENTIFIED BY ‘root的密码’ PASSWORD EXPIRE NEVER;
ALTER USER ‘root’@’%’ IDENTIFIED WITH mysql_native_password BY ‘root的密码’;
FLUSH PRIVILEGES;
其实只有第二句有意义
2.2.2.3 设置主主
接下来开始配置双机主主模式,这里需要在每个节点上的mysql容器中执行一次不同的操作。其实主主模式就是配置两个主从,先配置(节点1)->(节点2)的主从,然后再反过来配置(节点2)->(节点1)的主从,这样主主的模式就配置好了
2.2.2.3.1 先设置(节点1)->(节点2)的主从
第一步:登录节点1的数据库,并执行如下命令:
- 创建用于数据同步的账号 使用mysql_native_password的方式加密,用户名密码根据喜好决定
CREATE USER ‘replicauser’@’%’ IDENTIFIED WITH mysql_native_password BY ‘replicauser’;- 对replicauser授予备份的权限
GRANT REPLICATION SLAVE ON *.* TO ‘replicauser’@’%’;- 刷新权限
FLUSH PRIVILEGES;- 查看MySQL主节点的状态
SHOW MASTER STATUS;±------------------±--------±-------------±--------------------------------------------±-----------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
±------------------±--------±-------------±--------------------------------------------±-----------------+
| mysql_master.000001 | 516 | | information_schema,mysql,performance_schema,sys | |
±------------------±--------±-------------±--------------------------------------------±-----------------+
1 row in set上面得到的File和Position必须记好
第二步:再登录到节点2的数据库,执行如下命令:
#设置节点2的主节点和同步信息
CHANGE MASTER TO MASTER_HOST=‘节点1的ip’,MASTER_PORT=3306,MASTER_USER=‘replicauser也就是上面创建的那个user’,MASTER_PASSWORD=‘replicauser对应的密码’,MASTER_LOG_FILE=‘第一步show master status得到的File’,MASTER_LOG_POS=第一步show master status得到的Postion;
# 开启从库
START SLAVE;
第三步:检查。在节点2上面执行
mysql> SHOW SLAVE STATUS\G;# 查看从库的状态
如果在结果中看到
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
说明OK
===========
如果结果中看到 Slave_IO_Running: No
首先检查网络是否通
其次就是看Last_SQL_Error的信息
如果Last_SQL_Error中有“Could not find first log file name in binary log index file”这种信息
就做如下操作:
- 在[节点2]的mysql,执行:stop slave;
- 在[节点1]的mysql,执行:
a)flush logs;
b) show master status; 也就是第一步中的第4点,重新得到最新的File和Position- 切换回[节点2]的mysql,执行:
a)CHANGE MASTER TO MASTER_LOG_FILE=‘最新的File’,MASTER_LOG_POS=最新的Position;
b) start slave;- SHOW SLAVE STATUS\G;# 查看从库的状态
如果在结果中看到
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
这样,(节点1)->(节点2)的主从就搭建好了。
2.2.2.3.2 设置(节点2)->(节点1)的主从
- 先通过客户端在节点1上执行一个建库建表动作,验证节点1->节点2的同步已经成功
- 登录节点2的mysql,执行和节点1第一步相同的命令,创建用户,并且得到File和Position
- 切换到节点1上执行前面第二步相同的操作,只是IP换成节点2的,将节点1设置为节点2的从
- 在节点1上执行检查动作和处理手段
至此,Mysql双机主主就配置完了。
3. 高可用网络配置
在官方文档上,希望通过一个负载均衡+一个DNS来解决高可用及负载均衡。
负载均衡的目标是接管多个rancher主节点上Traefik Ingress提供的80和443
DNS是解决集群中多个主节点上的负载均衡提供统一入口
因为我们是多机主节点部署方案,并且希望集中式部署所有组件,因此,我们有如下选择:
- [DNS]<---->[负载均衡1|80 443,负载均衡2|80 443]<–>[节点1|80 443,节点N|80 443]
- [DNS]<---->[(负载均衡1|8880 8443,节点1|80 443),(负载均衡2|8880 443,节点N|80 443)]
- [DNS]<---->[节点1|80 443,节点N|80 443]
在一个小型化的集群环境中,选择方案3,并且DNS用keepalived主备安装提供VIP来支持。这样其实就只是让多主节点成为一个多机热备的环境,不必提供负载均衡,目的就是让rancher的server节点高可用而已,而不让rancher server节点负载均衡。如果要负载均衡,采用nginx方案
如果是个中型环境,可以考虑在集群外部nginx做L4负载均衡接管mysql(或etcd)、80、443,同时选择方案1或2。
3.1. 安装nginx(可选)
安装nginx应该是在server节点上服务化安装,但是:由于nginx的 Linux packages,对于arm的支持,都是较高的系统版本,比如centos8、debian10+。不过其docker版本倒是可以很好的无感安装,所以通过docker host网络方式安装nginx
因为rancher需要L4代理,因此nginx的版本要高于1.9才行。https://docs.rancher.cn/docs/rancher2/installation/options/nginx/_index/。 这里有个非常重要的提示:官方安装目标是nginx接管rancher的Traefix提供的80和443,那么就建议nginx单独找机器安装,否则端口冲突。而我们希望集中安装在节点上,那么就要注意,nginx的80转发和443转发,需要修改为8880(或其他)->80,8443(或其他)->443
。
直接参考hub https://hub.docker.com/_/nginx
docker pull nginx
启动的时候,把配置文件目录给映射到主机上便于后续修改,同时映射一个用于存放日志的地方。然后,在主机上设置一个K3S官方提供的配置文件
- mkdir -p /sobey/dbu/nginx/conf.d
- mkdir -p /sobey/dbu/nginx/logs
- vi /sobey/dbu/nginx/sobey.conf 将内容设置为下面这段配置,注意IP_NODE_1,2…x要修改为正确的server节点IP
user nginx;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes 4;
worker_rlimit_nofile 40000;
events {
worker_connections 8192;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
stream {
log_format info '$remote_addr [$time_local] ' '$protocol $status $bytes_sent $bytes_received' '$session_time "$upstream_addr" ' '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/stream-access.log info;
upstream rancher_servers_http {
least_conn;
server <IP_NODE_1>:80 max_fails=3 fail_timeout=5s;
server <IP_NODE_2>:80 max_fails=3 fail_timeout=5s;
}
server {
listen 8880;
proxy_pass rancher_servers_http;
}
upstream rancher_servers_https {
least_conn;
server <IP_NODE_1>:443 max_fails=3 fail_timeout=5s;
server <IP_NODE_2>:443 max_fails=3 fail_timeout=5s;
}
server {
listen 8443;
proxy_pass rancher_servers_https;
}
upstream mysql_server {
}
server {
listen 3307;
proxy_pass rancher_servers_https;
}
}
- vi /sobey/dbu/nginx/conf.d/default.conf 设置为下面的内容。因为映射了conf.d目录,所以要设置一个default.conf文件,由于上面用stream方式监听了80,所以http方式的默认端口改为58080(或其他)
server {
listen 58080;
listen [::]:58080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
- docker run --name nginx --net=host -v /sobey/dbu/nginx/conf.d:/etc/nginx/conf.d -v /sobey/dbu/nginx/logs:/var/log/nginx -v /sobey/dbu/nginx/sobey.conf:/etc/nginx/nginx.conf -d nginx
3.2. 安装keepalived
keepalived解决给双机主节点提供VIP,替代DNS的作用
keepalived需要自定义检测脚本来提供切换依据,而检测脚本应该要检测rancher、K3S,但是由于安装K3S需要指定一个外部数据库,因此这里我们先配置并启动keepalived,让他暂时只起到提供VIP的能力。等K3S和Rancher安装完以后,再设置etcd(或Mysql)、K3S和Rancher的检测脚本,然后重启keepalived
开始安装,在每个节点上都安装Keepalived,执行命令如下:
yum -y install keepalived
将配置文件写入
vi /etc/keepalived/keepalived.conf
注意里面的VIP地址
要修改为实际的地址
! Configuration File for keepalived
global_defs {
vrrp_garp_master_refresh 60
router_id sobeydbuk3s
}
vrrp_script chk_mysql_and_rancher {
script /sobey/dbu/keep_check.sh
interval 2
weight -10
}
vrrp_instance VIP {
state BACKUP
interface eth0
dont_track_primary
track_interface {
eth0
}
virtual_router_id 39
garp_master_delay 3
priority 101 #不同节点填写不同的权重
preempt_delay 5
mcast_src_ip 节点本机IP地址
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_mysql_and_rancher
}
virtual_ipaddress {
VIP地址 dev eth0 scope global
}
}
同时创建一个检测文件备用
vi /sobey/dbu/keep_check.sh
#!/bin/bash
exit 0
chmod +x /sobey/dbu/keep_check.sh
在两个节点启动keepalived
systemctl start keepalived
至此,准备工作做完
4. 安装K3S
安装命令可以使用环境变量的方式进行安装参数设置及3中所述的启动参数设置
这里描述了应该如何使用环境变量
主要参考的是
- 使用外部数据库实现高可用安装,这里我们采用是的etcd方案,前面已经安装好了。在启动k3s的时候,要带上外部数据库地址,这里(datastore)有配置说明
- 这里(instal-option)给出了在线安装时候,shell脚本可以设置的重要环境变量
- 其他额外的需要的启动参数,可以在这里(server-config)看到所有的项
完整在线安装命令就不写了,参考官方即可(注意如果是使用Mysql,其连接信息应该是VIP)。
这里主要讲下载后手动安装
基于脚本的离线安装
- 下载k3s安装脚本
wget https://get.k3s.io > k3s.sh
或者
curl -o k3s.sh https://get.k3s.io
- 获取二进制文件和镜像文件
去https://github.com/rancher/k3s/releases下载
写这篇文章的时候,最新是1.19,但是请下载1.18,因为这里> https://github.com/rancher/k3s/issues/2548有个问题
1)下载二进制文件拷贝到目标主机的/usr/local/bin中,注意,命名一定要是k3s
比如这里下载的是k3s-arm64
wget -O k3s https://github.com/rancher/k3s/releases/download/v1.18.12%2Bk3s1/k3s-arm64
chmod +x k3s
cp ./k3s /usr/local/bin/
2)下载air-gap
镜像文件拷贝到/var/lib/rancher/k3s/agent/images/中
mkdir -p /var/lib/rancher/k3s/agent/images/
下载tar,比如这里下载的是k3s-airgap-images-arm64.tar
wget https://github.com/rancher/k3s/releases/download/v1.18.12%2Bk3s1/k3s-airgap-images-arm64.tar
cp ./k3s-airgap-images-arm64.tar /var/lib/rancher/k3s/agent/images/
docker load < /var/lib/rancher/k3s/agent/images/k3s-airgap-images-arm64.tar
- 添加环境变量并执行安装
#跳过selinux
INSTALL_K3S_SELINUX_WARN=true
#跳过二进制文件下载
export INSTALL_K3S_SKIP_DOWNLOAD=true
#设置k3s的二进制文件地址,默认是/usr/local/bin,如果步骤2已经放到这个目录,则可以不用设置
export INSTALL_K3S_BIN_DIR=2中下载文件所在的目录
#K3S_DATASTORE_ENDPOINT代表的是外部数据库的连接,这里使用的是etcd的。如果用其他方案,参考官网说明
export K3S_DATASTORE_ENDPOINT=“http://[etcd1.ip]:2379,http://[etcd2.ip]:2379,http://[etcd3.ip]:2379”
export INSTALL_K3S_EXEC=“server --docker --kubelet-arg max-pods=200”
sh k3s.sh
或者
INSTALL_K3S_SELINUX_WARN=true INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_EXEC=‘server --docker --kubelet-arg max-pods=200’
K3S_DATASTORE_ENDPOINT=‘http://[etcd1.ip]:2379,http://[etcd2.ip]:2379,http://[etcd3.ip]:2379’ ./k3s.sh
其中:–kubelet-arg=max-pods=200表示,每个节点上最多支持200个POD(Kubernetes默认是110个)
–kubelet-arg的作用是设置kubelet参数,在官网这里有描述。其正确格式可以从这里和这里参考
kubelet参数可以参考K8S的官网
PS: 特别说明:如果启动后需要修改max-pods,参见+9 修改max-pods
这里面特别有几个坑说一下:
1.尽量使用K3S_DATASTORE_ENDPOINT这种方式指定连接参数。如果链接的是mysql数据库,如果参考官网上的内容或其他网络内容,采用启动参数方式指定,会遇到unknown network tcp这种日怪的错误,根本原因是,官网内容中的启动参数中,mysql连接串前后不能用双引号!!!已经提了issue
2.尽量使用1.18版本,因为这里(https://github.com/rancher/k3s/issues/2548)有个错误,我已经遇到了,我在(https://github.com/rancher/k3s/issues/2553)这里提了相同的问题
检查以下安装结果
k3s kubectl get nodes
===========================
NAME STATUS ROLES AGE VERSION
k3s01 Ready master 3m14s v1.18.12+k3s1
k3s02 Ready master 2m17s v1.18.12+k3s1
k3s03 Ready master 2m17s v1.18.12+k3s1
可能出现的问题
如果启动失败,K3S的默认日志在journalctl中,通过journalclt -xe -u k3s
可以查看
如果遇到说
no default routes found
这种问题,参考这里和这里,我们需要设置
1、 可能需要设置ip route
在每个节点上ip route add default via 节点IP
2、 如果还出现了无法启动,且日志中不停出现tls handshake error, 127.0.0.1
类似信息
启动参数中加入--flannel-iface <网卡名称> --node-ip 节点IP
样例:
INSTALL_K3S_SELINUX_WARN=true INSTALL_K3S_SKIP_DOWNLOAD=true \
INSTALL_K3S_EXEC=‘server --docker --kubelet-arg max-pods=200 --flannel-iface <网卡名称> --node-ip 节点IP’
K3S_DATASTORE_ENDPOINT=‘http://[etcd1.ip]:2379,http://[etcd2.ip]:2379,http://[etcd3.ip]:2379’ ./k3s.sh
打节点标签(可选)
标签根据实际情况打
k3s kubectl label nodes [节点名(比如k3s01)] env-executor=true env-ficus=true env-java-executor=true env-python-executor=true env-python-ai-executor=true env-java-media-executor=true env-usercenter=true env-schedule=true
一个需要了解的说明
一个k3s server节点,默认情况下也会在当前节点启动agent,也就是既是server也是agent。如果有明确的部署要求,则可以通过–disable-agent,安装一个裸 server
至此,双主节点K3S环境已经准备好
5. 安装并指定私有镜像库
5.1. 安装私有镜像库(可选)
由于我们本身有一个明确的私有镜像库,因此这步对我们的实施来说基本上都可以考虑忽略。
如果是在客户那边需要独立部署一个私有库,那么就找一个机器安装即可。
搜索“docker 安装私有镜像库”或“Harbor”,参考安装
5.2. 配置K3S Server连接到私有镜像库
在每个K3S Server节点上执行
#拷贝签名文件和根证书
mkdir -p /sobey/dbu/tls
上传私有镜像库签名文件和证书到该目录中
#编辑K3S证书配置信息
vi /etc/rancher/k3s/registries.yaml
mirrors:
docker.io:
endpoint:
- "https://images.sobey.com:5000"# 私有镜像库地址
configs:
"images.sobey.com:5000":
auth:
username: admin # 这是私有镜像仓库的用户名
password: sobeyhive # 这是私有镜像仓库的密码
tls:
cert_file: /sobey/dbu/tls/ficus_crt.crt # 镜像仓库中使用的cert文件的路径。
key_file: /sobey/dbu/tls/ficus_crt.key # 镜像仓库中使用的key文件的路径。
ca_file: /sobey/dbu/tls/rootCA.crt # 镜像仓库中使用的ca文件的路径。
如果是内网环境,并且没有DNS服务,那么需要手动修改hosts
echo -e “xx.xx.xx.xx \t images.sobey.com” | tee -a /etc/hosts
重启k3s
systemctl restart k3s
6. 高可用安装Rancher
我们的目标就是在K3S Server双节点安装基于K3S ENV的高可用Rancker。单机Docker安装不在这里讨论。
选择rancher版本为2.4.10_release。因为这个版本开始,kubernetes1.18作为默认支持,并且修复了一些bug。
4中安装K3S的时候,由于有红色字体的因素,因为我们就选择2.4.10_release作为安装目标。
在每个K3S Server节点上执行
6.1. 准备rancher 2.4.10 以及相关的docker镜像
在hub上找到正确的镜像,这里以arm64作为样例
docker pull rancher/rancher:v2.4.10-linux-arm64
#因为此时没有设置镜像库,因此设置标签为images.sobey.com/rancher/rancher:v2.4.10
后续helm渲染需要
docker tag rancher/rancher:v2.4.10-linux-arm64images.sobey.com/rancher/rancher:v2.4.10
由于rancher需要依赖一些其他的软件,也需要安装起来。因此,这里还需要进行这部分镜像的拉取。
具体有哪些,可以从这里,了解到,我们需要准备一些离线镜像。
一种方法是通过rancher-images.txt
找到所需要软件镜像列表,然后在hub上找到这些镜像的正确版本,依次pull下来。
当然,在一般环境中,可以不太关心每一个镜像的实际情况,也可以通过官方给出的方式直接处理
#根据上面的地址,到官方下载对应的脚本和数据文件。也可以到国内镜像下
- rancher-images.txt
- rancher-load-images.sh
- rancher-save-images.sh
#拷贝上述文件到目标机器同一目录下
mkdir -p /sobey/rancher_install
cd /sobey/rancher_install
#拷贝进这个目录
curl -O https://github.com/rancher/rancher/releases/download/v2.4.10/rancher-images.txt
curl -O https://github.com/rancher/rancher/releases/download/v2.4.10/rancher-load-images.sh
curl -O https://github.com/rancher/rancher/releases/download/v2.4.10/rancher-save-images.sh
#按照 这里2、收集 cert-manager 镜像
所描述的方式执行
#去重
sort -u rancher-images.txt -o rancher-images.txt
#添加镜像拉取
chmod +x rancher-save-images.sh
./rancher-save-images.sh --image-list ./rancher-images.txt
#完成时,当前目录会输出名为rancher-images.tar.gz的压缩包
#同时,这些镜像已经save到本地镜像列表中,可以通过docker images查看
特别的:
如果是私有库,可以通过脚本将镜像推送到私有库
chmod +x rancher-load-images.sh
./rancher-load-images.sh --image-list ./rancher-images.txt --registry 私库地址
有可能是没有官方的平台版本,比入arm64。也可能其他原因导致的失败
针对这些failed的,要手动拉取 docker pull xxxxxx
如果是因为平台不对,那么可以去hub.docker.com中,查询民间的镜像,拉取后手动修改标签
情况一:官方压根儿没有相应的版本
这里以arm64上面rancher/configmap-reload:v0.3.0-rancher2为例
在arm64上面,会看到Image pull failed: rancher/configmap-reload:v0.3.0-rancher2
于是执行:docker pull rancher/configmap-reload:v0.3.0-rancher2
结果发现没有此镜像,原因是它没有官方的arm64版本,因此去hub.docker.com中查询configmap-reload
结果发现比较流行的jimmidyson/configmap-reload
于是执行:docker pull jimmidyson/configmap-reload:v0.3.0
完成后,打标签:docker tag jimmidyson/configmap-reload:v0.3.0 rancher/configmap-reload:v0.3.0-rancher2
情况二:官方有较近版本
1、rancher/coredns-coredns:1.6.2
我们发现官方上,1.6.3就支持了arm64,这种代差非常小,从官方issue里面可知差别不大
于是执行:docker pull rancher/coredns-coredns:1.6.3
docker tag rancher/coredns-coredns:1.6.3 rancher/coredns-coredns:1.6.2
情况三:有一些确实搞不定的,可能只有靠手动build了
截至此时,2.4.10中,arm64上面无法pull的有
rancher/fluentd:v0.1.19,rancher/istio-coredns-plugin:0.2-istio-1.1, rancher/istio-kubectl:1.5.10,rancher/kubernetes-external-dns:v0.7.3,rancher/thanosio-thanos:v0.15.0
但是目测这些都是和istio有关,而目前我们还不会大规模使用istio,因此可以暂时忽略
或者,export出来,拷贝到Agent节点上
最笨的,将这个Faild List拷贝出来,在Agent上按红色的说明执行一次
如果【没有推送到私有镜像库】,那么,我们应该对【需要的镜像】进行docker tag处理。
比如docker tag rancher/rancher:v2.4.10-linux-arm64 images.sobey.com/rancher/rancher:v2.4.10 因为没有私库,只有做一次相当于人工pull的操作。
——需要的镜像,意思是rancher本身,或者rancher运行起来之后,界面上提示无法pull的镜像
下面后续的操作,其实可以只在一台节点上操作。当然,也可以根据实际情况,每个节点都操作一次。
6.2. 准备Rancher Server证书
6.2.1. 从DBU人员手中获取证书
从DBU人员手中获取到Rancher访问需要的证书(和5.2中的是两个不同的证书),默认情况下会得到名为“dbu_rancher_crt”的证书,默认我们设置的DNS为dburancher.sobey.com
#拷贝签名文件和根证书
mkdir -p /sobey/dbu/tls/rancher
上传签名文件和证书到该目录中
6.2.2. 自建证书
- 拷贝下面的内容到 /root/mktls.sh
#!/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 ' --ssl-date: 有效天数;'
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} <<-EOF
[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
EOF
if [[ -n ${SSL_TRUSTED_IP} || -n ${SSL_TRUSTED_DOMAIN} ]]; then
cat >> ${SSL_CONFIG} <<-EOF
subjectAltName = @alt_names
[alt_names]
EOF
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-domain一样
–ssl-size: ssl加密位数,默认2048;
–ssl-cn: 国家代码(2个字母的代号),默认CN;
–ssl-date: 有效天数;
#使用示例:
./mktls.sh --ssl-domain=dburancher.sobey.com --ssl-trusted-domain=dburancher.sobey.com --ssl-trusted-ip=172.16.149.139,172.16.149.122,172.16.149.123,172.16.149.124 --ssl-size=2048 --ssl-date=3650
- 查看结果
ls -l
#可以看到
cacerts.pem #根证书,部署rancher会使用
cacerts.srl
cakey.pem
mktls.sh
openssl.cnf
tls.crt #证书,部署rancher渲染会使用
tls.key #证书密钥,部署rancher渲染会使用
uosrancher.test.com.crt #和tls.crt 是一个东西
uosrancher.test.com.csr
uosrancher.test.com.key #和tls.key 是一个东西
6.2.2.1. 将Charts仓库和镜像仓库的根证书加入到自建根证书(可选)
在使用自建rancher证书的情况下,如果Charts仓库和镜像仓库使用了其他证书,并且其他证书是从其他根证书签发,以harbor.sobey.com的证书为例,其签发根证书为rootCA.pem
那么,需要将rootCA.pem的内容加入到当前生成的根证书中
- 从渠道拿到rootCA.pem
- cat rootCA.pem | tee -a /sobey/dbu/tls/rancher/cacerts.pem
或者,用官网的说明,由于rancher要访问自定义的仓库或商店,那么需要按此附加授信CA
- 在6.3.2的2渲染charts中,增加参数
--set additionalTrustedCAs=true
- 从渠道拿到rootCA.pem(可能有多个),将其复制到一个名为ca-additional.pem的文件中
cat rootCA.pem | tee -a ca-additional.pem(如果还有多个,则依次创建)
然后在k3s中创建ca-additional密文
kubectl -n cattle-system create secret generic tls-ca-additional --from-file=ca-additional.pem=./ca-additional.pem
6.2.3. 使用已经签发好的证书(可选)
如果用户自己具备证书,那么可以使用用户提供的证书
只需要拷贝用户的证书文件和证书key文件即可。但是,需要注意:
- 证书文件必须是PEM格式
- 证书key文件必须是PKCS1格式
具体可以参考这里来处理
6.3. 准备Helm和rancher 2.4.10 charts
Helm 是安装 Rancher 高可用集群时会用到的工具。
Helm 是 Kubernetes 的软件包管理工具。Helm chart 为 Kubernetes YAML manifest 文件提供了模板语法。通过 Helm,可以创建可配置的 Deployment YAML,而不是只能用静态的 YAML。
6.3.1. 下载Helm
在每个server节点上执行
由于rancher官方推荐使用3.0以上的helm,因此在helm 3.4.0下载一个合适的版本
使用wget或curl下载对应的版本
tar -zxvf helm-v3.4.0-linux-$ARCH.tar.gz -C $target_dir
在解压目中找到helm程序,移动到需要的目录中
mv t a r g e t d i r / h e l m / u s r / l o c a l / b i n / h e l m < b r > ∗ 注 意 上 面 的 target_dir/helm /usr/local/bin/helm<br> *注意上面的 targetdir/helm/usr/local/bin/helm<br>∗注意上面的符号对应的都是要按实际情况修改的*
6.3.2. 拉取rancher charts
- 在节点外的机器上拉取rancher charts
这里我们没有创建和注册charts repo,也没有像官网所述去regsitry一个rancher的charts repo,而是直接通过URL拉取一个完整的rancher-charts到本地后使用
- 在任意一个可以上网的环境中,安装helm
- helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
- helm pull rancher-stable/rancher --version 2.4.10
- 将上述下载好的2.4.10 rancher charts tar文件,拷贝到在6.1拉取镜像的时候创建好的/sobey/rancher_install中
cp xxxx.tar.gz /sobey/rancher_install/
- 然后开始渲染charts
进入对应的目录,执行helm命令
cd /sobey/rancher_install
#按照官方说明,渲染charts模板
helm template rancher ./rancher-<VERSION>.tgz --output-dir . \
–namespace cattle-system \
–set hostname=<RANCHER.YOURDOMAIN.COM>
–set rancherImage=<IMAGE> \
–set rancherImageTag=<IMAGE_VERSION> \
–set ingress.tls.source=secret \
#【注意】,如果是使用已经签发的证书,这里【不设置】privateCA
–set privateCA=true \
#这个参数特别说明一下,如果是测试环境,可以考虑不设置。但是生产环境还是应该设置好。其作用
#就是设置rancher的system-default-registry。
#按理说生产环境的镜像库,应该包含所有需要的镜像,rancher管理的k3s默认会从镜像库地址拉取镜像,除非本地有对应的镜像
#如果不设置,那么就是从hub.docker.com拉取,除非本地有对应的镜像
–set systemDefaultRegistry=<REGISTRY.YOURDOMAIN.COM:PORT>
–set useBundledSystemChart=true
PS: set参数的时候,提醒一下,注意6.2.2.1. 中的内容
占位符 | 描述 |
---|---|
<VERSION> | Rancher 版本,这里是2.4.10 |
<RANCHER.YOURDOMAIN.COM> | 官方叫负载均衡器对应的 DNS,也就是6.2中rancher集群证书的域名,默认是dburancher.sobey.com |
<REGISTRY.YOURDOMAIN.COM:PORT> | 私有镜像库对应的 DNS,参见5.2,我们默认是images.sobey.com:5000 |
<IMAGE> | Rancher镜像名,官方给出的是<REGISTRY.YOURDOMAIN.COM:PORT>/rancher/rancher,因为它是从私有镜像库拉取,而我们因为在6.1中已经导入了rancher镜像,同时我们也没有在6.1中执行这里要求的推送镜像到私库,因此这里直接写导入到本地的镜像 |
<IMAGE_VERSION> | Rancher镜像版本,这里是v2.4.10。在6.1中设置了这个tag。当然,也可以不设置,直接指定为实际的tag |
一个完整的样例:helm template rancher ./rancher-2.4.10.tgz --output-dir . --namespace cattle-system --set hostname=dburancher.sobey.com --set rancherImage=rancher/rancher --set rancherImageTag=v2.4.10 --set ingress.tls.source=secret --set privateCA=true --set systemDefaultRegistry=images.sobey.com --set useBundledSystemChart=true
完成以后,在当前目录应该看到一个rancher目录,里面有生成的templates/各种yaml
6.4. 正式安装rancher
6.4.1. 在K3S中创建rancher的命名空间
在任意一个server节点中执行
k3s kubectl create namespace cattle-system
6.4.2. 设置rancher server的证书
参考官方说明,设置6.2中准备好的证书
在任意一个server节点中执行
#设置证书
k3s kubectl -n cattle-system create secret tls tls-rancher-ingress --cert=/sobey/dbu/tls/rancher/dbu_rancher_crt.crt --key=/sobey/dbu/tls/rancher/dbu_rancher_crt.key
#设置根证书
cp /sobey/dbu/tls/rancher/rootCA.crt /sobey/dbu/tls/rancher/rootCA.pem
k3s kubectl -n cattle-system create secret generic tls-ca --from-file=cacerts.pem=/sobey/dbu/tls/rancher/rootCA.pem
6.4.3 最后一步,安装rancher
进入6.1创建的/sobey/rancher_install目录
此目录在6.3.2还拉取了charts,并且生成了最终的包含所有yaml的rancher目录
在任意一个节点上操作
cd /sobey/rancher_install
k3s kubectl -n cattle-system apply -R -f ./rancher
最后的检查
k3s kubectl -n cattle-system rollout status deploy/rancher
#应该显示如下信息
Waiting for deployment “rancher” rollout to finish: 0 of 3 updated replicas are available…
Waiting for deployment “rancher” rollout to finish: 1 of 3 updated replicas are available…
Waiting for deployment spec update to be observed…
Waiting for deployment “rancher” rollout to finish: 1 of 3 updated replicas are available…
Waiting for deployment “rancher” rollout to finish: 2 of 3 updated replicas are available…
deployment “rancher” successfully rolled out
k3s kubectl get pods --namespace=cattle-system
#应该看到类似的信息
NAME READY STATUS RESTARTS AGE
rancher-7d688cbccb-9cldj 1/1 Running 1 5m54s
rancher-7d688cbccb-5jlcb 1/1 Running 0 5m54s
rancher-7d688cbccb-5zcmt 1/1 Running 0 5m54s
6.4.4. 验证
打开浏览器,设置hosts指向 dburancher.sobey.com(这是6.2证书的域名),访问rancher界面
如果要达成通过IP直接访问rancher,那么此时请不要配置任何rancher界面上的内容,直接看下面6.5
6.5. 配置通过IP直接访问多节点rancher(可选)
某些情况下,我们希望可以通过IP(比如VIP)直接访问rancher,而不需要配置域名。
我们可以通过配置L4负载均衡的方式来达成
在+7这一章节,我们可以知道,K3S通过L4负载均衡(svclb)可以直接开放引导主机流量到集群中
因此,如果需要直接通过IP访问,我们可以创建一个L4负载均衡
apiVersion: v1
kind: Service
metadata:
annotations:
field.cattle.io/targetDnsRecordIds: '["cattle-system:rancher"]'
labels:
cattle.io/creator: rancheripl4
name: traefik-ip-entrypoint-l4
namespace: cattle-system
spec:
externalTrafficPolicy: Cluster
ports:
- name: http
port: 30080
protocol: TCP
targetPort: 80
- name: https
port: 30443
protocol: TCP
targetPort: 443
sessionAffinity: None
type: LoadBalancer
拷贝以上内容,到某个主机的目录中,比如 ~/service-rancher-ip.yaml
注意,其中可能会修改的地方,是port字段。它表示通过IP的哪个端口来访问rancher
然后,在该主机上执行:
k3s kubectl apply -f ~/service-rancher-ip.yaml
如果正常,k3s会创建一个l4负载均衡,并且将主机的30080和30443引导到rancher的集群服务上。
6.5.1. 验证
打开浏览器,输入 http://${VIP}:30080
,访问rancher界面
7. 设置keepalived检测脚本
在3.2中,安装keepavlived,预留了一个keep_check.sh脚本。
这里我们需要设置这个检查脚本,用于keepalived的检测切换,何海强给了我们一段脚本
在每台server节点上执行(或scp拷贝)
vi /sobey/dbu/keep_check.sh
#!/bin/bash
KA_CHECK=$(ps -A -o pid,cmd|grep "keep_check.sh"|grep -v $$|grep -v grep|wc -l)
if [ "$KA_CHECK" -gt "1" ]; then
exit 0
fi
bin=$(cd $(dirname $0); pwd)
LOG_FILE="$bin/ka_check.log"
CONTAINER_NAME="k3smysql"
MYSQL_HEALTH_STATUS=$(docker inspect --format '{{.State.Health.Status}}' $CONTAINER_NAME)
if [ "$MYSQL_HEALTH_STATUS" = "healthy" ]; then
K3S_HEALTH_STATUS=$(systemctl is-active k3s)
if [ "$K3S_HEALTH_STATUS" = "active" ]; then
COMPONENT_HEALTH_STATUS=$(kubectl get cs|awk '/Healthy/{print $2}'|wc -l)
if [ "$COMPONENT_HEALTH_STATUS" != "2" ]; then
echo "$(date):
$(kubectl get cs)" >>$LOG_FILE
exit 1
fi
else
echo "$(date): K3S_HEALTH_STATUS = $K3S_HEALTH_STATUS" >>$LOG_FILE
exit 1
fi
else
echo "$(date): MYSQL_HEALTH_STATUS = $MYSQL_HEALTH_STATUS" >>$LOG_FILE
exit 1
fi
8. cattle-cluster-agent和cattle-node-agent几乎一定会处理的问题
8.1. 域名解析问题
我们看到cattle-cluster-agent和cattle-node-agent工作负载不能正常启动
从日志上看到,ERROR: https://xxxx/ping is not accessible (Could not resolve host: rancher.my.org)
或者,我们看到某些配置的域名无法访问,比如应用商店里面配置了一个harbor.sobey.com,无法连接,这些都是域名解析导致。
一般来说是这个地方导致的问题可以参照解决。
或者,点击工作负载的“编辑”—>“显示高级选项”–>“网络”—>手动设置hosts映射,将dburancher.sobey.com正确的映射到VIP地址上
但是,最好的一个办法是:
1、打开rancher,找到System下面的coredns工作负载。
2、可以看到coredns工作负载关联了一个coredns配置映射(config-map)。或者直接从“资源”–>“配置映射”中找到它
3、修改这个coredns的配置映射中的NodeHosts配置项,类似hosts文件一样修改它即可
这样,整个集群内,都可以通过此coredns进行域名解析
8.2. Ingress导致的证书解析错误
Traefik Ingress导致的证书问题
经过1的处理,在日志中看到
Issuer of last certificate found in chain does not match with CA certificate Issuer......
cattle-cluster-agent Server certificate is not valid......
并且日志堆栈中显示了一个压根儿没见过的CA信息
原因是因为默认开启了Traefik(安装的时候没有–disable Traefik)——在命名空间kube-system工作负载列表中可以看到部署了Traefik。
Traefik默认接管了K3S的L4入口,官网这里进行了说明,这里在介绍集群外部负载均衡入口配置的时候也说明了,因此,集群内部会通过此入口进行80和443的流量处理。
根据其yaml可以看到,它关联了一个名为 traefik-default-cert的SSL配置
- configMap:
defaultMode: 420
name: traefik
name: config
- name: ssl
secret:
defaultMode: 420
secretName: traefik-default-cert
status:
正因为这个SSL配置的证书信息并没有指定为我们自己的证书,而内部的通讯走的是集群内部的80和443,也就是经过Traefik,因此提示了证书问题导致无法启动。
处理方法:
#删除现有的 traefik-default-cert
k3s kubectl -n kube-system delete secret traefik-default-cert
#重新关联证书(这里的证书是6.2准备的)
k3s kubectl -n kube-system create secret generic traefik-default-cert --from-file=tls.crt=/sobey/dbu/tls/rancher/dbu_rancher_crt.crt --from-file=tls.key=/sobey/dbu/tls/rancher/dbu_rancher_crt.key
或者,手动拷贝crt和key的内容,在rancher中点击“资源”—>“密文”,找到traefik-default-cert进行修改
完成以后,在工作负载中重新部署Traefik
、catlle-cluster-agent
、cattle-node-agent
8.3. 某些CA证书无法验证,报X509错误
某些情况下,比如public证书过期了,甚至于,我们就想用自己的自签名证书
会看到容器中报错类似:X509: unknown autority zzzzzz
处理办法:
将
CA
证书内容(注意,是CA证书,也就是根证书),拷贝到/etc/kubernetes/ssl/certs/serverca
文件中
编辑cattle-cluster-agent
,参考cattle-node-agent
的数据卷:k8s-ssl
手动配置数据卷
这样即可解决SSL证书验证问题
结束
至此,基于Mysql主主的双节点高可用K3S+Rancher集群就部署完成了
+1:完全离线安装
上面的整个过程,多少都利用了在线处理。
如果要完整的离线安装,主要是通过这几个点来达成:
- 但凡需要yum install的地方
【联网机】---->yum install---->【rpm包】---->copy---->【不能联网机】---->yum localinstall
以nginx举例,创建一个你喜欢的目录,我这里是
mkdir -p /usr/local/rpms/nginx
下载包
yum install --downloadonly --downloaddir=/usr/local/rpms/nginx nginx
将下载的包拷贝到目标机/usr/local/rpms/nginx/
yum localinstall /usr/local/rpms/nginx/*.rpm
- 但凡需要docker pull的地方
方法一)和上面相似,先到一个联网机"docker pull需要的镜像",然后"docker export这个镜像",拷贝镜像到目标机,在目标机上执行"docker load < 镜像"
方法二)利用一个私有,可访问的Harbor作为镜像库
- 但凡是wget或curl下载的,在联网机下载好以后拷贝即可
+1.1. 已经准备好的离线包(以标准centos为例,UOS特殊处理)
可以从DBU开发人员那里拿到离线包,离线包包含如下内容:
/1.yum-utils
;/2.docker
;/3.etcd
;/4.k3s
;/5.rancher
安装方式
- yum localinstal -y /1.yum-utils/*.rpm
- yum localinstal -y /2.docker/*.rpm
- yum localinstal -y /3.etcd/*.rpm,参考2.1 安装etcd进行etcd安装
- 使用/4.k3s目录中的内容,参考4. 安装K3S进行k3s的安装
- 使用/5.rancher目录中的内容,参考6. 高可用安装rancher进行rancher的安装。
5.1. 其中helm相关内容在/5.rancher/helm中
5.2. 另外注意,由于离线包中已经存在rancher-images.tar.gz,因此,只需要docker load即可
+2:在K3S集群加入一个Agent节点
由于我们是采用的
创建双主机K3S-->K3S部署rancher
这种方式构建的部署方案,按照官方的说法,这仅仅是“高可用部署rancher”而已。也就是说,相当于我们为了部署一个高可用的rancher,所以部署了一个K3S而已。
按照官方建议,应该是用这个高可用的rancher,重新去创建一个新的集群来作为运行时集群
相当于
(Rancher【on K3S】)---->manage—>(new Cluster)
然而,我们在我们面对的一般项目中,更希望一体化运行,也就是
(Rancher【K3S】)-------
^ |
|_______
因此,我们目前需要手动的添加Agent节点到集群中
+2.1. 节点环境准备
准备一个节点,然后安装必须的东西
- 执行本文“1. 准备工作”中的所有内容
- 写入VIP域名解析
echo -e “xxxx.xxx.xx.xx \t dburancher.sobey.com” | tee -a /etc/hosts
- 将本文“4. 安装K3S”中在server节点上放置的的
k3s.sh
、K3S
、k3s-airgap-images-$ARCH.tar
文件拷贝过来(因为我们一般在root目录下操作,所以先放到这里面)
scp root@172.16.149.122:/root/* /root/
- 将文件放置到目标位置,并做比较要的步骤处理
cp /root/k3s /usr/local/bin/
chmod +x /usr/local/bin/k3s
mkdir -p /var/lib/rancher/k3s/agent/images/
cp ./k3s-airgap-images- A R C H . t a r / v a r / l i b / r a n c h e r / k 3 s / a g e n t / i m a g e s / d o c k e r l o a d < / v a r / l i b / r a n c h e r / k 3 s / a g e n t / i m a g e s / k 3 s − a i r g a p − i m a g e s − ARCH.tar /var/lib/rancher/k3s/agent/images/ docker load < /var/lib/rancher/k3s/agent/images/k3s-airgap-images- ARCH.tar/var/lib/rancher/k3s/agent/images/dockerload</var/lib/rancher/k3s/agent/images/k3s−airgap−images−ARCH.tar
yum install -y container-selinux selinux-policy-base(可选,如果安装报相应的错误,就按此处理)
yum install -y https://rpm.rancher.io/k3s/stable/common/centos/7/noarch/k3s-selinux-0.2-1.el7_8.noarch.rpm(可选,如果安装报相应的错误,就按此处理)
5(可选). load必要的镜像
如果6.1中推送了私库,那么本操作跳过。
如果在本文“6.1”中,没有推送镜像到私库,那么,将server节点上准备好的/sobey/rancher_install/rancher-images.tar.gz拷贝过来,然后load。
mkdir -p /sobey/rancher_install/
scp root@172.16.149.122:/sobey/rancher_install/rancher-images.tar.gz /sobey/rancher_install/rancher-images.tar.gz
docker load < /sobey/rancher_install/rancher-images.tar.gz
#针对6.1红色字体部分,如果没有上传相应的镜像到私有库,那么就只有拷贝,如果没有拷贝,那么就获取Failed List按红色字体说明执行一次
- 按照本文“5.2”的步骤,配置镜像库
#拷贝签名文件和根证书
mkdir -p /sobey/dbu/tls
scp root@172.16.149.122:/sobey/dbu/tls/* /sobey/dbu/tls/
#编辑K3S证书配置信息
mkdir -p /etc/rancher/k3s
vi /etc/rancher/k3s/registries.yaml
mirrors:
docker.io:
endpoint:
- "https://images.sobey.com:5000"# 私有镜像库地址
configs:
"images.sobey.com:5000":
auth:
username: admin # 这是私有镜像仓库的用户名
password: sobeyhive # 这是私有镜像仓库的密码
tls:
cert_file: /sobey/dbu/tls/ficus_crt.crt # 镜像仓库中使用的cert文件的路径。
key_file: /sobey/dbu/tls/ficus_crt.key # 镜像仓库中使用的key文件的路径。
ca_file: /sobey/dbu/tls/rootCA.crt # 镜像仓库中使用的ca文件的路径
- 如果是内网环境,并且没有DNS服务,那么需要手动修改hosts
echo -e “xx.xx.xx.xx \t images.sobey.com” | tee -a /etc/hosts
+2.2. 启动Agent节点
- 获取token
参考官网说明,获取token
scp root@172.16.149.122:/var/lib/rancher/k3s/server/node-token /root/k3s_server_token
- 启动Agent
cd root
INSTALL_K3S_SKIP_DOWNLOAD=true K3S_TOKEN_FILE=’/root/k3s_server_token’ K3S_URL=‘https://dburancher.sobey.com:6443’ INSTALL_K3S_EXEC=‘agent --docker --kubelet-arg=max-pods=200’./k3s.sh
其中–kubelet-arg=max-pods=200参考:4. 安装K3S 这一节的说明
- 打节点标签(可选)
标签根据实际情况打不同的标签
k3s kubectl label nodes [节点名] env-executor=true env-java-executor=true env-python-executor=true env-python-ai-executor=true env-java-media-executor=true
+3. 更换rancher的默认镜像库地址
在某些情况下,可能会更换rancher的镜像库地址。
- 修改每个主机的hosts文件,IP指向正确的镜像库域名
- 在rancher中找到rancher的工作负载,“编辑”–>“修改环境变量”,将CATTLE_SYSTEM_DEFAULT_REGISTRY修改为正确的镜像库域名(或者删除——参见6.3.2helm命令部分的说明)
+4. 删除rancher
某些情况下可能会删除rancher,操作方式
1、根据这里的说明,下载对应的system-tools
2、在某个机器上操作
如果这个机器是server节点以外的机器,则先拷贝节点的/etc/rancher/k3s/k3s.yaml
到准备好的路径
./system-tools remove --kubeconfig <KUBECONFIG>
其中KUBECONFIG就是/etc/rancher/k3s/k3s.yaml
拷贝后的路径
3、彻底清除kubernetes的namespace
2执行以后,通过 k3s kubectl get namespaces
,看到对应的namespace还是Terminating状态
此时,在server节点上执行
KUBE_EDITOR=“vi” kubectl edit namespaces <namespace>
其中 <namespace>是需要删除的 namespace
找到
finalizers:
- controller.cattle.io/namespace-auth
将其改为
finalizers: []
保存即可,此时将删除namespace
如果上述处理删除不掉,则通过终极大法:
- k3s kubectl get namespace <namespace-to-delete> -o json > tmp.json
- vi tmp.json,删除任何"finalizers"里面的"kubernetes"
#开启一个代理终端,主要是避免环境变量问题- k3s kubectl proxy
#应该会看到Starting to serve on 127.0.0.1:8001- 打开另一个ssh终端
#在新打开的终端执行- curl -k -H “Content-Type: application/json” -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/annoying-namespace-to-delete/finalize
+5. 修改ETCD节点信息
某些情况下,可能要切换ETCD地址,比如主机IP变更。
假设变更的节点为etcd1
操作方式:
- 列出etcd节点
etcdctl member list
可以看到
eabc202e74d53d3: name=etcd3 peerURLs=http://172.16.149.124:2380 clientURLs=http://172.16.149.124:2379 isLeader=false
8fa08b2e4744707e: name=etcd1 peerURLs=http://172.16.149.128:2380 clientURLs=http://172.16.149.128:2379 isLeader=false
e50821dfde62301e: name=etcd2 peerURLs=http://172.16.149.123:2380 clientURLs=http://172.16.149.123:2379 isLeader=true
- 删除etcd1
etcdctl member remove 8fa08b2e4744707e
- 在etcd1上停止etcd服务
systemctl stop etcd
- etcd1的IP改好以后,重新加入节点
在etcd2或etcd3上操作
etcdctl member add etcd1 http://xxxxxx:2380
此时,会看到一些要求你配置的信息
-
参考4中给出的信息,修改etcd1的
/etc/etcd/etcd.conf
-
重启etcd1的etcd服务
+6. 修改K3S_DATASTORE_ENDPOINT
因为+5
的原因,或某些其他原因,比如要切换一个ETCD集群,或完全切换为Mysql
我们需要修改K3S_DATASTORE_ENDPOINT
修改方式:
vi /etc/systemd/system/k3s.service.env
修改里面的存储地址
systemctl restart k3s
+7. 高可用安装情况下修改80和443端口(本章节网上找不到,纯属原创精华)
如果是单机安装,直接docker的-p就可以解决,但是高可用部署,由于是部署在K3S环境中,因此,不能简单的处理。必须通过修改K3S集群的流量控制入口(说白了,就是Ingress和LoadBanlencer)来处理。
这里,必须先搞清楚(我花了很多时间搞清楚)K3S的流量控制艺术,在搞清楚艺术之前,还得了解Ingress和IngressController,针对Ingress和IngressController,写的最好的文章是我认为写的最好的一篇。
有了Ingress和IngressController的认知之后,我们来看K3S的流量艺术。
- K3S默认会安装Traefik作为IngressController,接管集群内80和443的流量。如果看到写的最好的文章,我们就知道,一般情况下,其实IngressController本身并不会(除非特殊的启用hostPort)并不会在主机上监听端口,它依然属于集群内部。
- 从写的最好的文章我们知道,让IngressController能够对外服务,可以有三种做法:1)给IngressController开一个NodePort服务;2)IngressController作为DaemonSet部署,暴露hostPort;3)给IngressController暴露一个LoadBalancer服务;
其实说白了,就是想办法让IngressController这个容器,能够对外暴露服务端口。
不过,K3S没有采用上面三种做法,它使用了一个特别的办法,在官网我们可以得知(官网中文翻译根本看不懂,难啃),它采用了DaemonSet部署特殊的Klipper Load Balancer进程的方式,来给Traefik Ingress Controller提供流量导入
。 - 2所述的流量导入,可以简单图解为:
[client]----->(主机port)<—iptables监听—>[DaemonSet-Klipper]—iptables转发—>[集群内Traefik]
也就是说,K3S通过在每个节点部署Klipper,然后以iptables路由的方式,将节点流量转发到内部的IngressController。 - 我们可以在节点中通过
k3s kubectl get svc -n kube-system
k3s kubectl get pods -n kube-system
k3s kubectl get daemonset -n kube-system
k3s kubectl edit daemonset svclb-traefik -n kube-system
逐一验证2中所述的官网描述以及通过写的最好的文章所了解到的信息
有了上面的艺术刨析,我们就知道,端口的改造,重点是修改 Daemonset:svclb-traefik,我们从Klipper的github核心文件可以了解到,它是通过iptables来处理流量的。里面使用了一些环境变量来设置入口端口和转发信息
于是:
- k3s kubectl edit daemonset svclb-traefik -n kube-system
- 修改里面的环境变量端口以及容器端口,主要是环境变量部分
- 等待相关POD自动更新
或者,因为了解了刚才的艺术过程。
同样是在官网-ServiceLB如何工作这一节,我们可以得知——由于它使用了
Klipper Load Balancer
,因此,你在K3S上创建一个L4负载均衡(即type: LoadBalancer服务)
,K3S会自动启动一个Klipper Load Balancer,在主机上打开L4负载均衡中设置的服务端口,通过iptables转发你的请求到这个L4负载均衡上面,然后由L4负载均衡再转发到配置的内部端口上。基于这个信息,那么
- 打开服务发现,创建一个L4负载均衡,其目标选择POD:traefik
- 设置L4负载均衡的服务端口为需要的端口
- 保存,等待K3S自动构建svclb-traefik-xxxx
+8. 在Rancher上手动创建Ingress
注意: 此部分前提条件是,集群中部署了IngressContorller且正常运行。
如果是按照此文档部署K3S,默认情况下,会安装Traefik作为IngressContorller。
此时,假设我们要对minio进行Ingress路由发布,操作方式如下:
1、确认minio所在的命名空间
假设命名空间为:minio-ha
2(可选)、为此命名空间安装证书
k3s kubectl -n minio-ha create secret tls ypt-ingress --cert=/root/cert/tls.crt --key=/root/cert/tls.key
其中,minio-ha
是命名空间,ypt-ingress
是证书名(可按实际情况随意起名),后面的路径是6.4.2中安装的证书相关文件,应该在节点上
3、登录rancher
3.1、进入项目
3.2、选择工作负载
—>选择负载均衡
—>添加规则
3.2、设置对应的名称
3.3、选择minio所在的命名空间,这里是minio-ha
3.4、选择自定义域名
---->填写安装集群时证书对应的域名
3.5、添加规则
—>填写合适的路径,比如/minio
。选择正确的服务或pod,以及端口
3.6、展开SSL/TLS证书
—>如果2设置了证书,则选择该证书
3.7、标签
可不设置,或按情况设置
至此,集群外可以用过 https://域名:端口/minio
访问到minio的服务
特别说明:
默认情况下,Ingress规则会将路由地址(比如上面的/minio)直接转发到后端服务,如果有些服务必须使用“根路径”或“特别路径”访问,比如minio只能识别/index
那么,处理办法是:
在annonation(也就是“注释”)中,添加一个注释:
traefik.ingress.kubernetes.io/rewrite-target: /index
其中traefik是IngressController的名称(意思是也可能是nginx)
+9. 修改max-pods
如果启动K3S的时候没有指定max-pods(默认110),那么可以手动修改
在需要修改的每个节点上执行
- systemctl stop k3s
- vi /etc/systemd/system/k3s.service
这里假设需要修改为200个- 修改 ExecStart=/usr/local/bin/k3s server --docker --kubelet-arg max-pod=200
- systemctl daemon-reload
- systemctl start k3s
其中参数 --kubelet-arg 是官网提供的参数,其正确格式可以从这里和这里参考
+10. IP修改后,以灾难恢复方式重建ETCD
某些情况下,节点的IP被改变了,此时需要重建ETCD
主要参考官网说明,这里我把完整的试错后的经验记录下来
1、重新启动ETCD单节点
因为此时etcd已经无法正常启动,必须先从一个节点以灾难恢复方式重启
- 在准备恢复的节点上修改/etc/etcd/etcd.conf,ETCD_INITIAL_CLUSTER去掉其他节点的信息,只保留当前节点的新IP信息
并且将里面的所有与IP内容相关的内容修改为正确的新IP- 修改/usr/lib/systemd/system/etcd.service,在ExecStart中,加入
--force-new-cluster
参数- systemctl daemon-reload && systemctl start etcd
如果一切正常,ETCD会启动。可通过etcd member list查看情况
2、修改当前节点的peerURLs配置信息
- ETCDCTL_API=3 etcdctl member update {上一步etcd member list得到的memberid} --peer-urls=http://新的地址:2380
- 修改/usr/lib/systemd/system/etcd.service,在ExecStart中去掉
--force-new-cluster
- systemctl stop etcd
- systemctl daemon-reload && systemctl start etcd
至此,新的ETCD单节点就重建成功
3、重新加入其他etcd节点
- 在本节点上执行ETCDCTL_API=3 etcdctl member add {etcdname} --peer-urls=http://{加入节点的地址}
- 拿到上一步返回的环境变量
在前其他ETCD节点上,修改各自的/etc/etcd/etcd.conf,将里面的所有与IP内容相关的内容修改为正确的新IP
将得到的环境变量修改到/etc/etcd/etcd.conf对应的地方- 在其他ETCD节点上rm -fr /var/lib/etcd/* && systemctl start etcd
4、修改所有节点的配置
依次修改每个节点的/etc/etcd/etcd.conf,将其ETCD_INITIAL_CLUSTER修改为完整的节点信息
依次重启