华为UOS欧拉版 K3S+Rancher 安装完全版

2023-11-08

文章目录

K3S服务 happy path安装过程

本文仅适合基于欧拉系统的UOS

核心思想说明:

对于一个小型环境,因为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. 修改网卡名称为eth0

默认安装好的网卡名比较奇怪: 以ens160为例,重命名为eth0

cp /etc/sysconfig/network-scripts/ifcfg-ens160 mv /etc/sysconfig/network-scripts/ifcfg-ens160.bak
mv /etc/sysconfig/network-scripts/ifcfg-ens160 /etc/sysconfig/network-scripts/ifcfg-eth0

查看ifconfig,记录ens160的MAC地址

修改eth0配置

nano /etc/sysconfig/network-scripts/ifcfg-eth0

NAME=eth0  #name修改为eth0
DEVICE=eth0  #name修改为eth0
HWADDR=xx:xx:xx:xx:xx #刚才查到的ens160的MAC地址

禁用该可预测命名规则。编辑/etc/default/grub并加入“net.ifnames=0 biosdevname=0 ”到GRUBCMDLINELINUX变量

nano /etc/default/grub
#找到GRUB_CMDLINE_LINUX,在quiet后面加上 net.ifnames=0 biosdevname=0

重新生成GRUB配置并更新内核参数

grub2-mkconfig -o /boot/grub2/grub.cfg

重启

reboot

1.2. 切换yum源

首先设置欧拉的yum源头。由于欧拉是基于Centos的,因此可以直接使用Centos的yum源。
华为官网上可以查看到处理方式如下:

CentOS-AltArch的镜像地址为:https://repo.huaweicloud.com/centos-altarch/

  1. 备份配置文件:

cp -a /etc/yum.repos.d/uosEuler_aarch64.repo /etc/yum.repos.d/uosEuler_aarch64.repo.bak
rm -f /etc/yum.repos.d/uosEuler_aarch64.repo

  1. 下载新的CentOS-Base.repo文件到/etc/yum.repos.d/目录下(因gpgkey无法动态适配,已将gpgcheck设置为0,关闭校验,如需打开请设置为1,并修改gpgkey地址),执行如下命令:

wget -O /etc/yum.repos.d/CentOS-Base.repo https://repo.huaweicloud.com/repository/conf/CentOS-AltArch-7.repo

  1. 执行yum clean all清除原有yum缓存。
  2. 执行yum makecache(刷新缓存)或者yum repolist all(查看所有配置可以使用的文件,会自动刷新缓存)。

如果要切换其他源,比如清华的,那么先到这个地址去查看可用的源,然后

将上面的CentOS-Base.repo备份
修改CentOS-Base.repo中的内容
将查到的源替换掉baseurl=xxxxx中对应的部分
执行yum clean all
执行yum makecache

  1. 加入openEuler源(这一步对安装docker非常重要)

我们参考了华为欧拉操作系统openEuler安装docker最新版和他里面引用的OpenEuler配置DNF软件源才最终装好19.03的docker。
其中要说一下,DNF的操作其实也就是yum的操作,所以,在看参考第二篇的时候,重点是知道了可以配置openEuler源,并且还知道了华为的openEuler镜像站。然后根据实际的操作系统情况cat /etc/os-release,最终找到https://mirrors.huaweicloud.com/openeuler/openEuler-20.09 这个地址是可用的

wget -O /etc/yum.repos.d/openEulerOS.repo https://repo.huaweicloud.com/repository/conf/openeuler_aarch64.repo
将下载后文件里面的baseurl地址换成https://mirrors.huaweicloud.com/openeuler/openEuler-20.09
yum clean all
yum makecache

1.3. 关闭防火墙以及selinux

systemctl stop firewalld
systemctl disable firewalld

setenforce 0
sed -i s#SELINUX=enforcing#SELINUX=disabled# /etc/selinux/config
重启

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
echo -e “172.16.149.124\tks303” | tee -a /etc/hosts

1.5. 在UOS(基于华为欧拉)上安装docker

  1. 安装container-selinux

yum install -y container-selinux

  1. 安装docker

yum install -y yum-utils
yum-config-manager \
–add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
#下载之后,修改docker的源
nano /etc/yum.repo.d/docker-ce.repo
#将baseurl修改为可访问的源(主要是欧拉改了$AACH,获取不到)
baseurl=https://download.docker.com/linux/centos/7/aarch64/stable/ (或者选一个国内的源更好)

yum -y install docker-ce
systemctl start docker

1.5.2. 修改Docker limit。非常重要!

如果后续要在该集群上安装mongodb,那么必须设置docker limit参数。
如果不设置,mongodb将因为ulimit的问题,导致不断重启
在日志中一般会发现:

Failed to mlock: Cannot allocate locked memory…

配置方法(参考这里):

  1. 执行 systemctl status docker ; systemctl status containerd(arm版本的老docker可能会使用containerd底层)。找到他们的配置文件地址
    假如上述服务的配置地址分别是:/usr/lib/systemd/system/docker.service,/usr/lib/systemd/system/containerd.service
  2. 添加LimitMEMLOCK=infinity

    find / -iname “docker.service” 找到docker服务

    vi ${目录}/docker.service

    如果有contaninerd find / -iname “containerd.service”

    vi ${目录}/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. 修改启动参数,更改iptables规则(可选)

这里 可以看到,有时候存在一种情况

“查阅了不少资料才看到docker 1.13 版本对iptables的规则进行了改动,默认FORWARD 链的规则为DROP ,带来的问题主要一旦DROP后,不同主机间就不能正常通信了(kubernetes的网络使用flannel的情况)”

因此,这里先让docker启动的时候搞一搞事情

find / -iname “docker.service”

vi ${目录}/docker.service

在[Service]一节追加

[Service]
............
ExecStartPost=iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT

1.5.6. 重启docker

systemctl stop docker

systemctl daemon-reload

如果有containerd,systemctl stop containerd

systemctl daemon-reload

如果有containerd,systemctl start containerd

systemctl start docker

1.6. 节点优化(可选)

  1. 节点内核调优
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

  1. nofile
cat >> /etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65536
EOF
  1. 关闭网卡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. 安装etcd

etcd必须3节点起

由于在UOS(欧拉版)上面,直接yum 安装etcd,会报openssl版本相关的错误,因此选择通过docker来安装etcd.

  1. 预备etcd数据目录

mkdir -p /sobey/dbu/etcd/data

  1. 拉取etcd github

docker pull quay.io/coreos/etcd:v3.3.11-arm64 #这里用的3.3.11,不是一定的

  1. run

在每个节点上执行run脚本。注意,里面的
a)< e t c d 1 > ——每个 e t c d 节点的名称,比如 e t c d 1 、 e t c d 2...... b ) < etcd1> ——每个etcd节点的名称,比如etcd1、etcd2...... b)< etcd1>——每个etcd节点的名称,比如etcd1etcd2......b<this_host> ——当前节点的IP
c)<$cluster_info> ——集群信息,比如:etcd1=http://172.16.149.125:2380,etcd2=http://172.16.149.126:2380,etcd3=http://172.16.149.127:2380

docker run -itd -e ETCD_UNSUPPORTED_ARCH=arm64 -p 2379:2379 -p 2380:2380 -v /sobey/dbu/etcd/data:/var/lib/etcd --name etcd quay.io/coreos/etcd:v3.3.11-arm64 /usr/local/bin/etcd --data-dir=/var/lib/etcd --name <KaTeX parse error: Undefined control sequence: \< at position 46: …er-urls http://\̲<̲this_host>:2380 --listen-peer-urls http://0.0.0.0:2380 --advertise-client-urls http://<KaTeX parse error: Undefined control sequence: \< at position 78: …itial-cluster "\̲<̲cluster_info>" --initial-cluster-state new --initial-cluster-token sobey-arm-etcd-cluster

  1. 检查

docker exec -ti etcd etcdctl member list
#应该有类似输出
3f0c84fe44e57f94: name=etcd3 peerURLs=http://172.16.149.127:2380 clientURLs=http://172.16.149.127:2379 isLeader=false
5cd7e7666d25d834: name=etcd2 peerURLs=http://172.16.149.126:2380 clientURLs=http://172.16.149.126:2379 isLeader=false
b33d3325cadf5ff2: name=etcd1 peerURLs=http://172.16.149.125:2380 clientURLs=http://172.16.149.125:2379 isLeader=true

docker exec -ti etcd etcdctl cluster-health
#应该有类似输出
member 3f0c84fe44e57f94 is healthy: got healthy result from http://172.16.149.127:2379
member 5cd7e7666d25d834 is healthy: got healthy result from http://172.16.149.126:2379
member b33d3325cadf5ff2 is healthy: got healthy result from http://172.16.149.125:2379
cluster is healthy

3. 高可用网络配置

在官方文档上,希望通过一个负载均衡+一个DNS来解决高可用及负载均衡。
负载均衡的目标是接管多个rancher主节点上Traefik Ingress提供的80和443
DNS是解决集群中多个主节点上的负载均衡提供统一入口

因为我们是多机主节点部署方案,并且希望集中式部署所有组件,因此,我们有如下选择:

  1. [DNS]<---->[负载均衡1|80 443,负载均衡2|80 443]<–>[节点1|80 443,节点N|80 443]
  2. [DNS]<---->[(负载均衡1|8880 8443,节点1|80 443),(负载均衡2|8880 443,节点N|80 443)]
  3. [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_new/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官方提供的配置文件

  1. mkdir -p /sobey/dbu/nginx/conf.d
  2. mkdir -p /sobey/dbu/nginx/logs
  3. 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;
    }
}
  1. 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;
    }
}
  1. 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

通过etcd的API检查keepalived的情况

curl -L http://VIP:2379/v3beta/cluster/member/list -X POST -d ‘{ “linearizable”: true }’

如果返回以下类似信息,说明OK

{"header":{"cluster_id":"10921885921143998869","member_id":"4543152351722438548","raft_term":"2"},"members":[{"ID":"4543152351722438548","name":"etcd3","peerURLs":["http://172.16.149.127:2380"],"clientURLs":["http://172.16.149.127:2379"]},{"ID":"6690070198586038324","name":"etcd2","peerURLs":["http://172.16.149.126:2380"],"clientURLs":["http://172.16.149.126:2379"]},{"ID":"12915535543778893810","name":"etcd1","peerURLs":["http://172.16.149.125:2380"],"clientURLs":["http://172.16.149.125:2379"]}]}

至此,准备工作做完


4. 安装K3S

安装命令可以使用环境变量的方式进行安装参数设置及3中所述的启动参数设置
这里描述了应该如何使用环境变量

主要参考的是

  1. 使用外部数据库实现高可用安装,这里我们采用是的etcd方案,前面已经安装好了。在启动k3s的时候,要带上外部数据库地址,这里(datastore)有配置说明
  2. 这里(instal-option)给出了在线安装时候,shell脚本可以设置的重要环境变量
  3. 其他额外的需要的启动参数,可以在这里(server-config)看到所有的项

完整在线安装命令就不写了,参考官方即可(注意如果是使用Mysql,其连接信息应该是VIP)。

这里主要讲下载后手动安装

基于脚本的离线安装

  1. 下载k3s安装脚本
    wget https://get.k3s.io > k3s.sh
    或者
    curl -o k3s.sh https://get.k3s.io

  2. 获取二进制文件和镜像文件
    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

  1. 添加环境变量并执行安装
    #跳过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连接到私有镜像库

注意1:我们的私有镜像库是固定了域名images.sobey.com的,因此,这里就直接标出这个域名
注意2:我们的密码也是固定的,但是公有云和私有云有所不同,需提前了解
注意3:我需要提前拿到tls签名文件,以及根证书

在每个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作为安装目标。

注意:下面的所有内容,都是基于2.4.10这个特定版本!

在每个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-arm64 images.sobey.com/rancher/rancher:v2.4.10

由于rancher需要依赖一些其他的软件,也需要安装起来。因此,这里还需要进行这部分镜像的拉取。
具体有哪些,可以从这里,了解到,我们需要准备一些离线镜像。

一种方法是通过rancher-images.txt找到所需要软件镜像列表,然后在hub上找到这些镜像的正确版本,依次pull下来。

当然,在一般环境中,可以不太关心每一个镜像的实际情况,也可以通过官方给出的方式直接处理

#根据上面的地址,到官方下载对应的脚本和数据文件。也可以到国内镜像

  1. rancher-images.txt
  2. rancher-load-images.sh
  3. 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 私库地址

特别注意1:
在镜像拉取过程中,一定要注意控制台日志,其中Image pull failed的需要记录下来
有可能是没有官方的平台版本,比入arm64。也可能其他原因导致的失败
针对这些failed的,要手动拉取 docker pull xxxxxx
如果是因为平台不对,那么可以去hub.docker.com其github中,找到对应的镜像,拉取后手动修改标签

情况一:官方压根儿没有相应的版本
这里以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,rancher/istio-coredns-plugin:0.2-istio-1.1,rancher/kubernetes-external-dns:v0.7.3,rancher/thanosio-thanos:v0.15.0
但是目测这些都是和istio有关,而目前我们还不会大规模使用istio,因此可以暂时忽略

特别注意2:
上述镜像,应该同时推送到私有库,以备后续的Agent节点使用
或者,export出来,拷贝到Agent节点上
最笨的,将这个Faild List拷贝出来,在Agent上按红色的说明执行一次

特别注意3:

如果【没有推送到私有镜像库】,那么,我们应该对【需要的镜像】进行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. 自建证书

  1. 创建证书目录

mkdir -p /sobey/dbu/tls/rancher

  1. 拷贝下面的内容到 /sobey/dbu/tls/rancher/mktls.sh,并且chmod +x /sobey/dbu/tls/rancher/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
  1. 使用参数执行上述脚本

–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.138,172.16.149.125,172.16.149.126,172.16.149.127 --ssl-size=2048 --ssl-date=3650

  1. 查看结果

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的内容加入到当前生成的根证书中

  1. 从渠道拿到rootCA.pem
  2. cat rootCA.pem | tee -a /sobey/dbu/tls/rancher/cacerts.pem

或者,用官网的说明,由于rancher要访问自定义的仓库或商店,那么需要按此附加授信CA

  1. 在6.3.2的2渲染charts中,增加参数 --set additionalTrustedCAs=true
  2. 从渠道拿到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文件即可。但是,需要注意:

  1. 证书文件必须是PEM格式
  2. 证书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

  1. 在节点外的机器上拉取rancher charts

这里我们没有创建和注册charts repo,也没有像官网所述去regsitry一个rancher的charts repo,而是直接通过URL拉取一个完整的rancher-charts到本地后使用

  1. 在任意一个可以上网的环境中,安装helm
  2. helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
  3. helm pull rancher-stable/rancher --version 2.4.10
  4. 将上述下载好的2.4.10 rancher charts tar文件,拷贝到在6.1拉取镜像的时候创建好的/sobey/rancher_install中
    cp xxxx.tar.gz /sobey/rancher_install/
  1. 然后开始渲染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

占位符 描述
<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:完全离线安装

上面的整个过程,多少都利用了在线处理。
如果要完整的离线安装,主要是通过这几个点来达成:

  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

  2. 但凡需要docker pull的地方
    方法一)和上面相似,先到一个联网机"docker pull需要的镜像",然后"docker export这个镜像",拷贝镜像到目标机,在目标机上执行"docker load < 镜像"
    方法二)利用一个私有,可访问的Harbor作为镜像库

  3. 但凡是wget或curl下载的,在联网机下载好以后拷贝即可

+1.1. 已经准备好的离线包

可以从DBU开发人员那里拿到离线包,离线包包含如下内容:

/1.yum-utils/2.docker/3.etcd/4.k3s/5.rancher

安装方式

  1. yum localinstal -y /1.yum-utils/*.rpm
  2. yum localinstal -y /2.docker/*.rpm
  3. docker load < /3.etcd/etcd.,参考2.1 安装etcd进行etcd安装
  4. 使用/4.k3s目录中的内容,参考4. 安装K3S进行k3s的安装
  5. 使用/5.rancher目录中的内容,参考6. 高可用安装rancher进行rancher的安装。其中helm相关内容在/5.rancher/helm中
    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. 执行本文“1. 准备工作”中的所有内容
  2. 写入VIP域名解析

echo -e “xxxx.xxx.xx.xx \t dburancher.sobey.com” | tee -a /etc/hosts

  1. 将本文“4. 安装K3S”中在server节点上放置的的k3s.shK3Sk3s-airgap-images-$ARCH.tar文件拷贝过来(因为我们一般在root目录下操作,所以先放到这里面)

scp root@172.16.149.122:/root/* /root/

  1. 将文件放置到目标位置,并做比较要的步骤处理

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/k3sairgapimagesARCH.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按红色字体说明执行一次

  1. 按照本文“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文件的路径
  1. 如果是内网环境,并且没有DNS服务,那么需要手动修改hosts

echo -e “xx.xx.xx.xx \t images.sobey.com” | tee -a /etc/hosts

+2.2. 启动Agent节点

  1. 获取token

参考官网说明,获取token

scp root@172.16.149.122:/var/lib/rancher/k3s/server/node-token /root/k3s_server_token

  1. 启动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 这一节的说明

  1. 打节点标签(可选)

标签根据实际情况打不同的标签

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的镜像库地址。

  1. 修改每个主机的hosts文件,IP指向正确的镜像库域名
  2. 在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

如果上述处理删除不掉,则通过终极大法:

  1. k3s kubectl get namespace <namespace-to-delete> -o json > tmp.json
  2. vi tmp.json,删除任何"finalizers"里面的"kubernetes"
    #开启一个代理终端,主要是避免环境变量问题
  3. k3s kubectl proxy
    #应该会看到Starting to serve on 127.0.0.1:8001
  4. 打开另一个ssh终端
    #在新打开的终端执行
  5. 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

操作方式:

  1. 列出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

  1. 删除etcd1

etcdctl member remove 8fa08b2e4744707e

  1. 在etcd1上停止etcd服务

systemctl stop etcd

  1. etcd1的IP改好以后,重新加入节点

在etcd2或etcd3上操作
etcdctl member add etcd1 http://xxxxxx:2380

此时,会看到一些要求你配置的信息

  1. 参考4中给出的信息,修改etcd1的/etc/etcd/etcd.conf

  2. 重启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的流量艺术。

  1. K3S默认会安装Traefik作为IngressController,接管集群内80和443的流量。如果看到写的最好的文章,我们就知道,一般情况下,其实IngressController本身并不会(除非特殊的启用hostPort)并不会在主机上监听端口,它依然属于集群内部。
  2. 写的最好的文章我们知道,让IngressController能够对外服务,可以有三种做法:1)给IngressController开一个NodePort服务;2)IngressController作为DaemonSet部署,暴露hostPort;3)给IngressController暴露一个LoadBalancer服务;
    其实说白了,就是想办法让IngressController这个容器,能够对外暴露服务端口。
    不过,K3S没有采用上面三种做法,它使用了一个特别的办法,在官网我们可以得知(官网中文翻译根本看不懂,难啃),它采用了DaemonSet部署特殊的Klipper Load Balancer进程的方式,来给Traefik Ingress Controller提供流量导入
  3. 2所述的流量导入,可以简单图解为:
    [client]----->(主机port)<—iptables监听—>[DaemonSet-Klipper]—iptables转发—>[集群内Traefik]
    也就是说,K3S通过在每个节点部署Klipper,然后以iptables路由的方式,将节点流量转发到内部的IngressController。
  4. 我们可以在节点中通过
    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来处理流量的。里面使用了一些环境变量来设置入口端口和转发信息
于是:

  1. k3s kubectl edit daemonset svclb-traefik -n kube-system
  2. 修改里面的环境变量端口以及容器端口
  3. 等待相关POD自动更新

或者,因为了解了刚才的艺术过程。
同样是在官网-ServiceLB如何工作这一节,我们可以得知——由于它使用了
Klipper Load Balancer,因此,你在K3S上创建一个L4负载均衡(即type: LoadBalancer服务),K3S会自动启动一个Klipper Load Balancer,在主机上打开L4负载均衡中设置的服务端口,通过iptables转发你的请求到这个L4负载均衡上面,然后由L4负载均衡再转发到配置的内部端口上。基于这个信息,那么

  1. 打开服务发现,创建一个L4负载均衡,其目标选择POD:traefik
  2. 设置L4负载均衡的服务端口为需要的端口
  3. 保存,等待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),那么可以手动修改

在需要修改的每个节点上执行

  1. systemctl stop k3s
  2. vi /etc/systemd/system/k3s.service

这里假设需要修改为200个

  1. 修改 ExecStart=/usr/local/bin/k3s server --docker --kubelet-arg max-pod=200
  2. systemctl daemon-reload
  3. systemctl start k3s

+10. IP修改后,以灾难恢复方式重建ETCD

某些情况下,节点的IP被改变了,此时需要重建ETCD

主要参考官网说明,这里我把完整的试错后的经验记录下来

1、重新启动ETCD单节点

因为此时etcd已经无法正常启动,必须先从一个节点以灾难恢复方式重启

  1. 在准备恢复的节点上修改/etc/etcd/etcd.conf,ETCD_INITIAL_CLUSTER去掉其他节点的信息,只保留当前节点的新IP信息

    并且将里面的所有与IP内容相关的内容修改为正确的新IP
  2. 修改/usr/lib/systemd/system/etcd.service,在ExecStart中,加入--force-new-cluster 参数
  3. systemctl daemon-reload && systemctl start etcd

    如果一切正常,ETCD会启动。可通过etcd member list查看情况

2、修改当前节点的peerURLs配置信息

  1. ETCDCTL_API=3 etcdctl member update {上一步etcd member list得到的memberid} --peer-urls=http://新的地址:2380
  2. 修改/usr/lib/systemd/system/etcd.service,在ExecStart中去掉--force-new-cluster
  3. systemctl stop etcd
  4. systemctl daemon-reload && systemctl start etcd

至此,新的ETCD单节点就重建成功

3、重新加入其他etcd节点

  1. 在本节点上执行ETCDCTL_API=3 etcdctl member add {etcdname} --peer-urls=http://{加入节点的地址}
  2. 拿到上一步返回的环境变量

    在前其他ETCD节点上,修改各自的/etc/etcd/etcd.conf,将里面的所有与IP内容相关的内容修改为正确的新IP

    将得到的环境变量修改到/etc/etcd/etcd.conf对应的地方
  3. 在其他ETCD节点上rm -fr /var/lib/etcd/* && systemctl start etcd

4、修改所有节点的配置

依次修改每个节点的/etc/etcd/etcd.conf,将其ETCD_INITIAL_CLUSTER修改为完整的节点信息
依次重启

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

华为UOS欧拉版 K3S+Rancher 安装完全版 的相关文章

  • Bash 解析和 shell 扩展

    我对 bash 解析输入和执行扩展的方式感到困惑 对于输入来说 hello world 作为 bash 中的参数传递给显示其输入内容的脚本 我不太确定 Bash 如何解析它 Example var hello world displaywh
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • 抑制 makefile 中命令调用的回显?

    我为一个作业编写了一个程序 该程序应该将其输出打印到标准输出 分配规范需要创建一个 Makefile 当调用它时make run gt outputFile应该运行该程序并将输出写入一个文件 该文件的 SHA1 指纹与规范中给出的指纹相同
  • 如何通过替换为空页映射来取消映射 mmap 文件

    Linux 用户空间有没有办法用空页面 映射自 dev null 或者可能是一个空页面 重复映射到从文件映射的页面的顶部 对于上下文 我想找到这个 JDK bug 的修复 https bugs openjdk java net browse
  • 跟踪 Linux 程序中活跃使用的内存

    我想跟踪各种程序在特定状态下接触了多少内存 例如 假设我有一个图形程序 最小化时 它可能会使用更少的内存 因为它不会重新绘制窗口 这需要读取图像和字体并执行大量库函数 这些对象仍然可以在内存中访问 但实际上并没有被使用 类似的工具top它们
  • GLIBCXX_3.4.26 未找到在 BeagleBone 上运行交叉编译的程序

    我有以下程序 include
  • 如何禁用 GNOME 桌面屏幕锁定? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何阻止 GNOME 桌面在几分钟空闲时间后锁定屏幕 我已经尝试过官方手册了在红帽 https access redhat com doc
  • 针对容器优化操作系统的 GCP 云监控

    我在用着GCP计算引擎 with 容器优化操作系统 我启用了Logging and 监控就那个例子而言 日志记录和监控具有写权限 但总是显示不适用于代理在监控仪表板中 If I SSH在我的实例中并运行docker images然后我看到输
  • nginx 上的多个网站和可用网站

    通过 nginx 的基本安装 您的sites available文件夹只有一个文件 default 怎么样sites available文件夹的工作原理以及如何使用它来托管多个 单独的 网站 只是为了添加另一种方法 您可以为您托管的每个虚拟
  • 如何在 shell 脚本中并行运行多个实例以提高时间效率[重复]

    这个问题在这里已经有答案了 我正在使用 shell 脚本 它读取 16000 行的输入文件 运行该脚本需要8个多小时 我需要减少它 所以我将其划分为 8 个实例并读取数据 其中我使用 for 循环迭代 8 个文件 并在其中使用 while
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • 使用 Docker 在本地主机上的“requests”连接错误

    我正在尝试开发客户端服务器应用程序 但遇到了一些问题 我的两个服务都是在单独的 docker 容器中本地开发的 客户端使用 api 从 api 获取数据requestspython 库 它可以在生产中使用 但在本地 我无法使用 reques
  • Linux中的定时器类

    我需要一个计时器来以相对较低的分辨率执行回调 在 Linux 中实现此类 C 计时器类的最佳方法是什么 有我可以使用的库吗 如果您在框架 Glib Qt Wx 内编写 那么您已经拥有一个具有定时回调功能的事件循环 我认为情况并非如此 如果您
  • 具有 blobfuse 或 Azure 存储 Blob 的 Azure 容器实例

    我正在从 azure 容器注册表 azure cli 和 或门户 部署到 azure 容器实例 Azure blobfuse 在 ubuntu 18 上 出现以下错误 未找到设备 请先尝试 modprobe fusion 解决这个问题的方法
  • 域套接字“sendto”遇到“errno 111,连接被拒绝”

    我正在使用域套接字从另一个进程获取值 就像 A 从 B 获取值一样 它可以运行几个月 但最近 A 向 B 发送消息时偶尔会失败 出现 errno 111 连接被拒绝 我检查了B域套接字绑定文件 它是存在的 我也在另一台机器上做了一些测试 效
  • 如何判断我是否通过脚本登录到私有 Docker 注册表?

    如何判断我是否通过脚本登录到私有 Docker 注册表服务器 换句话说 有docker login some registry com已成功运行 并且仍然有效 注意 我问的是任意私有注册表 而不是docker io注册表 如果 docker
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 两种情况或 if 哪个更快? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我必须制作一个 非常 轻的脚本 它将接受用户的选项并调用脚本中的函数来执行一些任务 现在我可以使用 IF 和 CASE 选项 但我想知道两

随机推荐

  • openswan 移植

    最近一周都在移植openswan 这是个非常想大的ipsec VPN实现工具 编辑CROSSCOMPILE sh 文件 这是openswan自带的专门用于交叉编译的脚本 修改如下 bin sh cross compile example e
  • vue-devtools的安装

    下载 解压过入目录 进入目录后 不要使用 npm install 会出错的 我们就用 yarn 来就可以了 npm install g yarn yarn install yarn run build 等待结束就可以了 进入 package
  • 保持 SSH 连接

    SSH 总是被强行中断 尤其是用 VSCode 代码写的好好的 突然刷新窗口 不仅效率低 更惹人恼火 可以通过配置服务端或客户端的 SSH 来保持 SSH 链接 方法一 配置服务端 可以在服务端配置 让 server 每隔 30 秒向 cl
  • 力扣:最大值(Java)

    给定一组非负整数 nums 重新排列每个数的顺序 每个数不可拆分 使之组成一个最大的整数 注意 输出结果可能非常大 所以你需要返回一个字符串而不是整数 class Solution public String largestNumber i
  • redux总结兼开发者工具

    Redux简介 使用Hook实现功能 不使用redux Redux三大核心概念 完整版代码 未优化 Redux异步action react redux库 react redux数据共享 总结 合并reducers 单独写成一个文件 继续简写
  • web3钱包系统开发

    web3技术概念介绍 近期 演员周星驰在ins开通首个社交账号 并发布人才招募令 在漆黑中找寻鲜明出众的Web3人才 将 Web3 带入大众视野 但有不少人对其感到陌生 到底何为Web3 早在2018年 就有人开始谈论web3了 它其实是一
  • CSS中关于z-index的堆叠顺序

    1 同级的z index div class container div class div1 h1 Division Element 1 z index 10 h1 div div class div2 h1 Division Eleme
  • Vs2019简单快速的打包可安装项目(图文教程)

    声明本项目在已安装vs2019和加载了installer Projects的情况下才能操作 右键解决方案 gt 添加 gt 新建项目 新建一个Setup Project 进入这个页面 右键Application Foluder gt Add
  • CVPR 2023

    作者 张倩 小舟 来源 机器之心 在文生图领域 扩散模型似乎已经一统天下 让曾经也风头无两的 GAN 显得有些过时 但两相比较 GAN 依然存在不可磨灭的优势 这使得一些研究者在这一方向上持续努力 并取得了非常实用的成果 相关论文已被 CV
  • 遍历Github仓库并提取所有图片

    遍历Github仓库并提取所有图片 项目介绍 一个简易的Github图床客户端 项目仓库 GithubImageHost 利用 QElapsedTimer QCoreApplication processEvents 可是实现UI同步 QE
  • html静态页面中引入scss的样式调整

    问题 静态页面样式和vue动态页面的样式不统一 截图了一个角落 需求 静态页面的样式要和动态页面的一样 解决步骤 F12 查看样式文件引用的区别 找到vue动态页面中的样式区别是在vue项目中用了自带的scss文件 将文件引入到静态页面的文
  • SSH通道的Kettle链接MySQL方法

    参考文献 http www ukettle org thread 452 1 1 html 对于采用SSH通道的MySQL服务器 Kettle无法直接连接 需要使用到 使用 SSH 工具 PUTTY
  • yolov5的TensorRT部署--warpaffine_cuda核函数

    从0到1实现基于tensorrt的yolo部署教程 http t csdn cn HUn4T 请点击该链接 即可看到全文 本文对于上面的案例 将预处理使用cuda核函数进行加速 一 cuda核函数的基本概念 1 1 CUDA C基础 核函数
  • Redis入门(一)

    1 简介 Redis 是完全开源的 遵守 BSD 协议 是一个高性能的 key value 数据库 Redis 与其他 key value 缓存产品有以下三个特点 Redis支持数据的持久化 可以将内存中的数据保存在磁盘中 重启的时候可以再
  • 计算机组成原理实验二 存储系统预习报告

    实验一 静态RAM 一 实验目的 掌握静态随机存储器 RAM 工作特性及数据的读写方法 基于信号时序图 了解读写静态随机存储器的原理 二 实验预习 1 阅读实验指导书 然后回答问题 实验所用的静态存储器由一片 6116 2K 8bit 构成
  • 离散信号的Matlab表示

    对任意离散序列x k 需用2个向量来表示 一个表示k的取值范围 另一个表示序列的值 例如序列x k 2 1 1 1 3 0 2 可用Matlab表示为 k 2 4 x 2 1 1 1 3 0 2 若序列从0开始 则只用一个向量x就可表示序列
  • 前端开发: 微信小程序 (文字,链接)生成二维码

    首先最主要的还是通过weapp qrcode js 靠这个轮子就可以了 GitHub yingye weapp qrcode weapp qrcode js 在 微信小程序 中 快速生成二维码https github com yingye
  • 人工智能和机器学习

    机器学习 1 什么是机器学习 在进行特定的编程的情况下 给与计算机学习能力的领域 机器学习是从数据中自动分析获得模型 并利用模型对未知数据进行预测 2 机器学习与人工智能 2 1人工智能发展的三个阶段 1980年代是正式形成时期 1990
  • Java接口详解

    http hi baidu com cxgfhfiupuanour item 370967f74ecbe9cca835a2b4 对初学者来说 接口不是很好理解 现将某高手的一篇文章贴出来 共大家分享 我们来看一个类 class A priv
  • 华为UOS欧拉版 K3S+Rancher 安装完全版

    文章目录 K3S服务 happy path安装过程 1 准备工作 1 1 修改网卡名称为eth0 1 2 切换yum源 1 3 关闭防火墙以及selinux 1 4 修改主机名 并修改hosts 1 5 在UOS 基于华为欧拉 上安装doc