K3s 1.26版本构建跨公有云的云原生环境

K3s是什么?

K3s 是轻量级的 Kubernetes,是一个完全兼容的 Kubernetes 发行版,占用内存小,非常适合在有限的资源下部署体验云原生环境。
更多参考:官方文档

为什么选择K3s?

笔者趁着腾讯云、天翼云等云服务做活动时,入手了2台轻量级云服务器。在实操K8s相关技术知识时,总觉得用虚拟机缺少了真实环境下的体验。而事实也证明,当尝试用公有云搭建K8s环境时,就遇到了跨Node访问网络不通的问题。

选择K3s的原因:

  • 占用更少的资源:对于2核4G的云服务器,部署一个K8s master节点内存直接就去了一半,更别说搭建Harbor、Gitlab等CICD相关的环境
  • 跨公有云搭建容器集群:公有云暴露的公网IP不在机器网卡上,使用K8s Calico搭建网络环境时,会存在跨Node访问网络不通问题
  • 麻雀虽小五脏俱全:与K8s体验一致,该有的它都有。

快速开始

环境准备

云服务器可以选择Centos7.x系统,这个版本比较成熟,坑会少一些。swap内存交换、firewalld防火墙是默认关闭的。
高版本K8s/K3s默认不再使用Docker,这里我们也可以不安装Docker。

配置hostname

注意每台机器的hostname不要出现相同的名称

# 分别在2台云服务器上执行
hostnamectl set-hostname tenxunyun
hostnamectl set-hostname tianyiyun
# 修改完可以执行一下su 切换刷新hostname

开启iptables转发支持

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# 加载内核模块,overlay模块是用于实现容器技术中的联合文件系统,br_netfilter模块是Linux内核中用于配置和管理网络过滤规则的模块
sudo modprobe overlay
sudo modprobe br_netfilter

# 开启iptables转发
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system
# 如果执行结果里面/etc/sysctl.conf 中net.ipv4.ip_forward=0,注意需要修改为1

# 验证内核模块是否加载成功
lsmod | grep br_netfilter
lsmod | grep overlay

安装wireguard

K3s 使用 wireguard 为集群流量建立 VPN 网格,实现不同公有云中的节点可以通过公网IP相互访问。

sudo yum install epel-release elrepo-release -y
sudo yum install kmod-wireguard wireguard-tools -y
# 安装后先重启系统,然后加载wireguard模块
sudo modprobe wireguard
# 验证wireguard是否加载成功
lsmod | grep wireguard

安装K3s 1.26

K3s架构

K3s 分为控制节点Server、工作节点Agent,对应K8s中master和worker。
这里我们使用Postgresql作为外部数据库,搭建高可用K3s集群。


下面章节示例2节点组成双server节点集群的安装步骤

安装Postgresql 15

可以直接在一台云服务器上安装,参考文档

#安装
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

sudo yum install -y postgresql15-server
sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
sudo systemctl enable postgresql-15
sudo systemctl start postgresql-15

#修改配置,允许远程访问
cd /var/lib/pgsql/15/data && vim postgresql.conf 
listen_addresses = '*'
max_connections = 1000

vim pg_hba.conf 
#最后一行加
host   all              all             0.0.0.0/0                 scram-sha-256

# 重启
 systemctl restart postgresql-15

#修改密码
sudo -i -u postgres
psql
alter user postgres with password '123456';

此时可以使用本地dbeaver访问该Postgresql了,ip是云服务器公网ip,端口是5432,用户名postgres
记得创建一个名为 kubernetes 的数据库

Treafik ingress配置

K3s默认使用Treafik作为Ingress Controller,可以提前配置Treafik EntryPoint入口方便进行TCP端口转发访问容器内的MySQL、Redis等组件。

在每个Server节点的机器上新增traefik配置文件:/var/lib/rancher/k3s/server/manifests/traefik-config.yaml

注意路径和文件名要和上面的一致,这里使用宿主机端口映射hostPort方式

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    ports:
      web:
        expose: false
        hostPort: 80
        port: 8000
      websecure:
        expose: false
        hostPort: 443
        port: 8443
      traefik:
        expose: false
       # exposedPort: 9000
        hostPort: 9000
        port: 9000
        protocol: TCP
      mysql:
        expose: false
        #exposedPort: 3306
        hostPort: 3306
        port: 3306
        protocol: TCP
      redis:
        expose: false
        hostPort: 6379
        #exposedPort: 6379
        port: 6379
        protocol: TCP
    service: 
      enabled: false
    deployment:
      replicas: 2
    affinity:
      podAntiAffinity:
        preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchExpressions: #用于配置Treafik pod调度到哪个Node
                - key: kubernetes.io/hostname
                  operator: In
                  values: ["你的主机hostname","你的主机hostname"]
              topologyKey: kubernetes.io/hostname
            weight: 1

K3s Server/Agent配置

在每个节点机器的指定目录创建配置文件:/root/rancher/k3s/config.yaml

# server节点配置
node-external-ip: 云服务器公网ip
flannel-backend: wireguard-native
flannel-external-ip: true
datastore-endpoint: "postgres://postgres:123456@127.0.0.1:5432/kubernetes"
disable: "servicelb"

# agent节点配置
#node-external-ip: 云服务器公网ip

127.0.0.1修改为pgsql所在的服务器的公网ip。这里禁用了K3s自带的负载均衡器servicelb

执行k3s安装脚本

配置准备完毕后,就可以开始执行安装脚本
注意点:
下载国内站点的k3s安装脚本(rancher提供)
配置镜像仓库为aliyun镜像源
指定K3s版本为v1.26.5+k3s1

# 在线安装 (会自动下载安装文件和脚本)
#从国内加速镜像下载安装脚本
wget https://rancher-mirror.rancher.cn/k3s/k3s-install.sh
chmod +x k3s-install.sh
# 在其中一台安装,默认安装server节点
K3S_SYSTEM_DEFAULT_REGISTRY=registry.cn-hangzhou.aliyuncs.com \
K3S_CONFIG_FILE=/root/rancher/k3s/config.yaml \
INSTALL_K3S_MIRROR=cn INSTALL_K3S_VERSION="v1.26.5+k3s1" ./k3s-install.sh

K3s的版本Release Note
如果想安装Rancher,注意K3s不要选择太高的版本,目前Rancher 2.7最高支持1.26版本的K3s,参考Rancher和K3s版本矩阵

kubectl命令环境配置

安装完成后,可以使用k3s命令查看全部pod情况
k3s kubectl get po -A
查看pod占用资源情况
k3s kubectl top po -A
查看机器内存使用情况,会发现K3s基础环境占用内存还不到1G

如果加入agent,会发现agent节点占用的内存更少

free -m


本地安装了kubectl、helm环境的情况,只需要执行以下命令即可使用kubectl、helm管理云环境
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config

添加新的Server节点到K3s集群

# 在刚刚安装了K3s机器上查看token,后面K3S_TOKEN会用到
cat /var/lib/rancher/k3s/server/token
# 在新的Server节点上安装K3s并加入集群(记得先下载安装脚本)
K3S_SYSTEM_DEFAULT_REGISTRY=registry.cn-hangzhou.aliyuncs.com \
INSTALL_K3S_MIRROR=cn K3S_URL=https://前面安装K3s的云服务器公网ip:6443 \
K3S_CONFIG_FILE=/root/rancher/k3s/config.yaml \
INSTALL_K3S_EXEC="server" INSTALL_K3S_VERSION="v1.26.5+k3s1" \
K3S_TOKEN=K10b2d0a5c99e33baa3c3deeac8a6c2f0c6b38a0b886e74ffb41c2a5b59cb135698::server:5c5c90b242ca167e3542e2d18115bd5c \
./k3s-install.sh 

# 设置了K3S_URL、K3S_TOKEN 配置后,默认为agent节点;使用INSTALL_K3S_EXEC="server" 后把新节点也作为server节点 添加到集群

前面我们开放了Dashboard端口,此时我们可以访问Treafik Dashboard面板,地址:http://你的云服务器公网ip:9000/dashboard/
更多Treafik配置可以参考官方文档

新增TCP端口转发ingress

有时候我们想在外部使用MySQL、Redis客户端访问MySQL、Redis容器,可以配置TCP转发ingress
先创建namespace: kubectl create ns dev
然后新增traefik-ingTcpRoute.yaml文件

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: mysql-route
  namespace: dev
spec:
  entryPoints:
    - mysql
  routes:
  - match: HostSNI(`*`)
    services:
    - name: mysql
      port: 3306
      
---

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: redis-route
  namespace: dev
spec:
  entryPoints:
    - redis
  routes:
  - match: HostSNI(`*`)
    services:
    - name: redis-master
      port: 6379

然后执行 kubectl apply -f traefik-ingTcpRoute.yaml,如果有在容器内部署MySQL、Redis服务,并且新建了名为mysql、redis-master的Service,此时就可以用本地的dbeaver、Another Redis Desktop Manager访问对应的容器服务了

常用命令

配置简写

每次拼写kubectl比较繁琐,可以配置自动补全和简写

#安装自动补全
sudo yum install bash-completion

# 添加简写
echo 'alias k=kubectl' >>~/.bashrc
echo "alias kd='kubectl describe'" >>~/.bashrc
echo "alias klogt='kubectl logs --tail'" >>~/.bashrc

source ~/.bashrc

简写可以按自己的习惯自定义,上面自动了输入k 就是kubectl,kd就是查看pod详情的命令开头,klogt是查看pod日志最后多少行的命令开头

kubectl常用命令和简写

kubectl get po -A #查看全部pod
kubectl get pod -o wide #查看pod在哪个ip、node上启动
kubectl get svc -n default #查看default命名空间的service
kubectl describe pod xxx -n xxx #查看pod详情,一般分析启动失败时使用
kubectl logs --tail 20 xxxPod -n xxx #查看pod最后20行日志
kubectl get sts,deploy,ds,cm,ing,rs,secret #查看各种资源情况
# 查看secret中data中password属性的原始内容
k get secret -ngitlab my-gitlab-postgresql-password -o jsonpath='{.data.password}' | base64 --decode 
kubectl get pod -n dev -w # 监听pod变化
k explain deploy.spec.template.spec.containers #查看某类资源下可配置项

k label nodes master1 nodetype=base # 给node加标签
kubectl label pod nginx -n dev version=1.0 #给pod加标签
kubectl get pod -n dev --show-labels # 查看pod 标签
kubectl label pod nginx -n dev version=2.0 --overwrite # 更新标签
kubectl get pod -l "version=2.0" -n dev --show-labels # 筛选
kubectl get pod -l "version!=2.0" -n dev --show-labels # 筛选
kubectl label pod nginx -n dev version- # 删除标签
k delete po -ndev -l 'app in (bookkeeping,usercenter)' #集合筛选

K8s中很多资源都有简写,可以通过下面命令查看全部资源和简写
kubectl api-resources


查看K3s日志

有时候安装、运行出现报错,可以通过查看日志分析
journalctl -u k3s -e #查看server节点日志
journalctl -u k3s-agent -e #查看agent节点日志
如果在加入节点时报错:failed to get CA certs: Get "https://127.0.0.1:6444/cacerts
可能是没有关闭防火墙,在每个节点执行一下:systemctl stop firewalld

停止、卸载K3s

K3s的命令在/usr/local/bin目录
./k3s-killall.sh 停止K3s server节点全部容器
./k3s-agent-uninstall.sh 卸载K3s agent节点环境
./k3s-uninstall.sh 卸载K3s server节点环境

清理磁盘空间

如果发现磁盘空间被占用的太多,可以删除不用的镜像
k3s crictl rmi --prune

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355