Skip to content

第13章 通过 Rancher 管理k8s 集群本章所讲内容:

13.1 Rancher 简介

13.2 安装 rancher

13.3 通过 Rancher 管理已存在的 k8s 集群

13.4 通过 Rncher 仪表盘管理 k8s-部署 web 站点

13.5 实战-分布式 LNMP 环境部署电商网站

13.6 实战-ingress-对外发布服务

实验环境:需要有一套已经存在的 k8s 集群(rancher2.6 目前仅支持到 k8s1.23),确定 k8s 集群正常:

$ kubectl get node
NAME           STATUS   ROLES                  AGE    VERSION
k8s-master01   Ready    control-plane,master   27d    v1.23.0
k8s-node01     Ready    work                   7d6h   v1.23.0
k8s-node02     Ready    work                   7d6h   v1.23.1

13.1 Rancher 基本介绍

13.1.1 Rancher 简介

​ Rancher 是一个开源的容器管理平台,用于简化容器化应用程序的部署、管理和运维。它提供了一套 强大的工具和界面,使得构建、部署和扩展容器化应用变得更加容易。 以下是 Rancher 的一些基本介绍

  1. 容器编排和管理:Rancher 支持多种容器编排和管理技术,包括 Kubernetes、Docker Swarm 和 Apache Mesos 等。它提供了一个统一的界面和工具集,使得用户可以轻松地创建、部署和 管理容器化应用程序,无论是单个容器、多容器应用还是微服务架构。
  2. 多集群管理:Rancher 允许用户在一个统一的控制平台上管理多个容器集群。这些集群可以是位 于云服务商(如 AWS、Azure)或私有数据中心的 Kubernetes 集群,也可以是使用 Docker Swarm 部署的容器集群。用户可以轻松地切换和管理不同集群之间的资源和应用。
  3. 应用商店和模板:Rancher 提供了一个应用商店和模板库,其中包含了一系列预定义的应用模 板,如 WordPress、MySQL、Prometheus 等。用户可以通过简单的几步操作选择并部署这些 模板,快速搭建常见的应用环境。

  4. 安全和权限管理:Rancher 提供了强大的安全性和权限管理功能,允许管理员对集群、命名空间 和资源进行细粒度的访问控制。用户可以根据需求定义角色和权限,并管理用户、团队和项目的 访问权限,以确保容器环境的安全性。

  5. 监控和日志:Rancher 集成了广泛的监控和日志工具,如 Prometheus、Grafana、ELK Stack 等。用户可以实时监控集群和应用程序的状态、性能指标和日志信息,以便及时发现和解决问 题

​ 总的来说,Rancher 是一个功能丰富的容器管理平台,通过简化和集中化容器化应用程序的部署、管理和运维,帮助用户更高效地构建和运行容器化环境。无论是单个容器应用还是复杂的微服务架构, Rancher 提供了强大的工具和界面,使得容器化应用的开发和运维变得更加简单和可靠

13.2 安装 rancher

在 rancher 上操作

13.2.1 初始化实验环境新创建一台虚拟机

环境说明(centos7.9):

IP 主机名 内存 cpu
192.168.2.202 rancher 4G 4vCPU

配置主机名:

hostnamectl set-hostname rancher && bash

配置 hosts 文件:

所有节点 hosts 文件要保持一致: 打开/etc/hosts 文件,新增加如下几行:

192.168.2.201 k8s-master01 m1
192.168.2.202 mariab-pinpoint m-p       ## 此处为rancher地址
192.168.2.204 k8s-node01 n1
192.168.2.205 k8s-node02 n2
192.168.2.206 harbor

关闭防火墙

$ systemctl stop firewalld ; systemctl disable firewalld

关闭 selinux

$ setenforce 0

$ sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

注意:修改 selinux 配置文件之后,重启机器,selinux 才能永久生效

配置时间同步

$ ntpdate cn.pool.ntp.org 
$ crontab -e

* * * * * /usr/sbin/ntpdate   cn.pool.ntp.org

修改内核参数

内核参数修改:br_netfilter 模块用于将桥接流量转发至 iptables 链,br_netfilter 内核参数需要开启转发。

$ modprobe br_netfilter 
$ cat > /etc/sysctl.d/k8s.conf <<EOF 
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

$ sysctl -p /etc/sysctl.d/k8s.conf

**在 rancher 上配置docker 的 yum 源: **

$ yum install -y yum-utils 

## 配置 docker-ce 国内 yum 源(阿里云)
$ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装 docker-ce

$ yum install docker-ce -y
$ systemctl start docker && systemctl enable docker.service

修改 docker 配置文件,配置镜像加速器

$ tee /etc/docker/daemon.json << 'EOF'
{
 "registry-mirrors":["https://vh3bm52y.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "insecure-registries":["192.168.2.206","harbor"]
}
EOF

$ systemctl restart docker 

13.2.2 安装 Rancher

Rancher2.6.4 支持 k8s1.23.1,我们安装 rancher2.6.4 版本,

rancher_2.6.4.tar.gz上传到 rancher

rancher-agent_2.6.4.tar.gz 上传到 K8S所有节点中

[root@rancher ~]# docker load -i rancher_2.6.4.tar.gz 
[root@k8s-master01 ~]# docker load -i rancher-agent_2.6.4.tar.gz 
[root@k8s-node01 ~]# docker load -i rancher-agent_2.6.4.tar.gz 
[root@k8s-node02 ~]# docker load -i rancher-agent_2.6.4.tar.gz 


[root@rancher ~]# docker run --name rancher -d --restart=unless-stopped -p 88:80 -p 444:443 --privileged rancher/rancher:v2.6.4

注意:unless-stopped,在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器

验证 rancher 是否启动:

$ docker ps |grep rancher
53233dc529c4   rancher/rancher:v2.6.4                    "entrypoint.sh"           16 seconds ago   Up 15 seconds             0.0.0.0:88->80/tcp, :::88->80/tcp, 0.0.0.0:444->443/tcp, :::444->443/tcp                                                                                                                                                                stoic_ptolemy

显示如上,说明启动成功:

13.2.3 登录 Rancher 平台

在浏览器访问 rancher 的 ip 地址:

image-20230917171822994

选择高级,接受风险并继续

image-20230917172802006

获取密码:

$ docker logs  rancher  2>&1 | grep "Bootstrap Password:"
2023/09/17 09:22:13 [INFO] Bootstrap Password: 6lsb89dctsql6h925bx55bfrmmknlrz6447z2x2cq495c4sqs7vwdt

image-20230917173117888

点击 Log in 登录,显示如下:

设置新的密码:

image-20230917180107032

点击 Continue 之后,需要重新登录 Rancher,显示如下:

image-20230917185434166

13.3 通过 Rancher 管理已存在的k8s 集群


Rancher 自带的 rke 安装 k8s 对应的版本说明:

将 Windows 工作负载从 RKE2 迁移到 RKE2 | Rancher

1、把已经存在的 k8s 集群导入到 rancher

image-20230917185750674

选择 Import Existing,出现如下:

img

选择 Generic,出现如下:

img

点击 Create

image-20230917185913063

出现如下:

image-20230917190005952

在 k8s 控制节点复制上图红色箭头标注的一串命令:

$ curl --insecure -sfL https://192.168.2.202:444/v3/import/d6xh674zsrcfkqld4s7h9kd5kr7xg8jhddk2fsdxrftrv5n9ksftxh_c-m-5qbp85m7.yaml | kubectl apply -f -

2、验证

验证 rancher-agent 是否部署成功:

$ kubectl get pod -n cattle-system
NAME                                    READY   STATUS    RESTARTS   AGE
cattle-cluster-agent-656fc5d676-47x82   1/1     Running   0          4m17s
cattle-cluster-agent-656fc5d676-rf5v2   1/1     Running   0          4m10s

看到 cattle-cluster-agent-67df6b5cf8-lh6k5 是 running,说明 rancher-agent 部署成功了, 在 rancher ui 界面可以看到如下内容:

image-20230917190728327

打开 rancher 主页面:https://192.168.2.202:444/dashboard/home 可以看到如下内容:

image-20230917191330438

通过上图可以看到 xuegod 集群已经导入到 rancher 了,导入的 k8s 版本是 1.23.1

13.4 通过Rancher 仪表盘管理k8s-部署 web 站点

打开 rancher 主页面

https://192.168.2.202:444/dashboard/home

选择 K8S集群:

image-20230917191435140

1、创建名称空间

image-20230917191623362

创建名称空间:k8s-test

image-20230917191654273

2、创建 Deployment 资源

点击创建:

image-20230917191740553

名称空间:xuegod-test Name: tomcat

image-20230917191928226


添加标签

image-20230917192022368

容器配置

image-20230917192333082


指定镜像: tomcat:8.5.34-jre8-alpine

tomcat:8.5.34-jre8-alpine
$ docker load -i tomcat_8.5.tar.gz

給 pod 打上标签

img

容器配置完成,点击创建

img

查看资源是否创建成功:

image-20230917192533074

3、创建 Service 资源,把 k8s 集群内部的 tomcat 暴露出来

点击 Create

image-20230917192654332

选择节点端口

img

定义服务端口

Name: tomcat-service

img

定义选择器,点击创建

img

查看 service 是否创建成功

image-20230917192943326

通过上面可以看到已经创建了 tomat-service

img

4、验证

访问 k8s 任何一个节点+端口 30180/TCP,可以访问内部的 tomcat 了:

http://192.168.2.201:30180/

image-20230917193158564

13.5 实战-分布式 LNMP 环境部署电商网站

linux nginx mysql php

为了方便理解 K8S 中集群服务是如何工作的,究竟服务是以什么方式进行通讯的,所以我们实践搭建 LNMP 环境来深入体验。

13.5.1 部署 nfs 共享存储和 pv

实验背景说明:nginx 和 php 不在一台机器上,怎么运行?

​ **nginx pod 192.168.1.71 192.168.1.62/data/2.php -> php **

php pod 192.168.1.72 找不到/data/2.php ,不能解析!

注:nginx 转给 php 服务是一个 php 脚本的路径,不是脚本内容!

必须把 nginx 网站根共享给 php 所在的服务器,而且路径要一样。

1、创建数据卷

$ cd /data/;mkdir -p web/{html,data}

注:生产环境可以使用 raid 来保证数据可靠性。

2、安装 nfs

$ yum -y install nfs-utils rpcbind  
$ systemctl restart nfs
$ vim /etc/exports

/data/v1 *(rw,no_root_squash)
/data/web/html *(rw,no_root_squash)
/data/web/data *(rw,no_root_squash)

*:表示任何人都有权限连接,当然也可以是一个网段,一个 IP,也可以是域名

rw:读写的权限

sync:表示文件同时写入硬盘和内存

no_root_squash:当登录 NFS 主机使用共享目录的使用者是 root 时,其权限将被转换成为匿名使用者,通常它的 UID 与 GID,都会变成 nobody 身份

$ exportfs -arv

配置开机自启并立即启动 rpcbind

$ systemctl enable --now rpcbind

配置开机自启并立即启动 nfs(注意启动顺序,必须先启动 rpcbind)

$ systemctl enable --now nfs

13.5.2 k8s 的 pv 与 pvc 持久化存储

1、上传资源文件到控制节点,解压资源文件

$ tar xf lnmp-v9.tar.gz 
$ cd lnmp 
$ unzip ecshop.zip 
## mv ecshop/* /web/html/                       ## 若NFS服务端在本地则执行
$ scp -r ecshop/* 192.168.2.202:/data/web/html/ ## scp传输到NFS服务端

2、查看 pv 文件

$ vim /root/lnmp/pv.yaml

注: kind: PersistentVolume ;种类:持久卷 Persistent [pəˈsɪstənt] 持久的

image-20230917195630237

3、创建 pv

$ kubectl apply -f /root/lnmp/pv.yaml

$ kubectl get pv |egrep "mysql|web"
mysql-pv         5Gi        RWX            Retain           Available                                                         6m51s
web-pv           1Gi        RWX            Retain           Available                                                         6m51s

​ **注:pv.yaml 一共创建了 2 个 pv 分别是 mysql-pv、web-pv **

​ **ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载 **

​ **ReadOnlyMany(ROX):只读权限,可以被多个节点挂载 **

ReadWriteMany(RWX):读写权限,可以被多个节点挂载

img

PV 描述的是持久化存储卷,主要定义的是一个持久化存储在宿主机上的目录,比如一个 NFS 的挂载目录。

PVC 描述的是 Pod 所希望使用的持久化存储的属性,比如,Volume 存储的大小、可读写权限等等。

使用过程是: nfs→pv→pvc→volume→volumeMount to path

13.5.3 部署 php 服务

1、创建php-deployment

[root@k8s-master01 lnmp]# vim php-deployment.yaml 

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-server
  labels:
    name: php-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: php-server
  template:
    metadata:
      labels:
        app: php-server
    spec:
      containers:
      - name: php-server
        image: php:v1
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: php-data
          mountPath: /var/www/html/
        ports:
        - containerPort: 9000
        lifecycle:
          postStart:
            exec:
              command: [ "/bin/bash","-c","chown apache:apache /var/www/html -R" ]
      volumes:
      - name: php-data
        persistentVolumeClaim:
          claimName: web-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: web-pvc
  labels:
    app: php-server
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  selector:
    matchLabels:
      apps: web-pv
$ kubectl apply -f php-deployment.yaml
$ kubectl get pod 
NAME                          READY   STATUS    RESTARTS   AGE
php-server-77764cb4b6-9mvxs   1/1     Running   0          19s

2、创建php-service

[root@k8s-master01 lnmp]# vim php-svc.yaml 
[root@k8s-master01 lnmp]# cat php-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: php
spec:
  ports:
  - name: php
    port: 9000
    protocol: TCP
  selector:
    app: php-server
$ kubectl apply -f php-svc.yaml
$ kubectl get svc |grep php
php          ClusterIP   10.107.240.249   <none>        9000/TCP   31s

13.5.4 部署 nginx 服务

1、nginx配置文件

配置文件注意事项,该配置文件是通过 yum 安装nginx 获取的

$ vim /root/lnmp/conf/nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    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;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        location / {
            index index.php;
        }
        location ~ \.php$ {
        ##    root           html;
            fastcgi_pass   php:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www/html/$fastcgi_script_name;
            include        fastcgi_params;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

注:nginx 的站点根目录是/usr/share/nginx/html 而 php 的解析目录是/var/www/html/两者仅仅是挂载到容器中的路径不一样,但是同源。fastcgi_pass 指定后端 php 解析地址时只需要指定php-svc 的名称即可,查看 svc 名称方式如下:

$ kubectl get svc |grep php
php          ClusterIP   10.107.240.249   <none>        9000/TCP   31s

2、ConfigMap 创建 nginx 配置文件

ConfigMap 简单介绍:ConfigMap 是 k8s 中非常重要的一个资源对象,简称 cm,常用于向容器中注入配置文件等操作,不仅可以保存单个属性值,也可以保存整个配置文件。

语法格式: kubectl create configmap name --from-file=path

$ kubectl create configmap lnmp-nginx-config --from-file=/root/lnmp/conf/nginx.conf

$ kubectl get configmap |grep lnmp
lnmp-nginx-config   1      21s

3、创建 nginx-deployment

$ vim nginx-deployment.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-shop
spec:
  selector:
    matchLabels:
      app: nginx-shop
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx-shop
    spec:
      containers:
      - name: nginx-shop
        image: nginx:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-data
          mountPath: /usr/share/nginx/html
        - name: nginx-conf
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
      volumes:
      - name: nginx-data
        persistentVolumeClaim:
          claimName: web-pvc
      - name: nginx-conf
        configMap:
          name: lnmp-nginx-config

部署 nginx

$ kubectl apply -f nginx-deployment.yaml

4、创建 nginx-svc

$ vim nginx-svc.yaml 

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-shop
spec:
  type: NodePort
  ports:
  - name: nginx
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30010
  selector:
    app: nginx-shop

注:nginx-svc 增加了 nodePort 对外提供服务

$ kubectl apply -f nginx-svc.yaml

$ kubectl get svc  |grep nginx
nginx-shop   NodePort    10.105.175.138   <none>        80:30010/TCP   30s

5、测试

访问测试:http://192.168.2.201:30010/

img

可以看到安装界面则表示 php 解析正确没有问题现在不要部署网站,因为还没有安装数据库了。

13.5.5 部署 mysql 服务

1、创建mysql-deployment(使用PVC绑定PV做成的卷)

mysql 服务我们就不额外挂载数据卷和指定 node 运行了,生产环境中还是建议单独挂载数据卷使用

$ vim mysql-deployment.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: default
  labels:
    k8s-app: mysql
spec:
  selector: 
    matchLabels:
      k8s-app: mysql
  replicas: 1
  template:
    metadata:
      labels:
        k8s-app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3306
          protocol: TCP
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
        env:
          - name: MYSQL_ROOT_PASSWORD
            value: "123456"
      volumes:
      - name: mysql-data
        persistentVolumeClaim:
          claimName: mysql-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  labels:
    k8s-app: mysql
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  selector:
    matchLabels:
      apps: mysql-pv

mysql 容器中存在初始化脚本,使用 MYSQL_ROOT_PASSWORD 变量配置 mysql 登录密码。

$ kubectl apply -f mysql-deployment.yaml 
2、创建 mysql-svc
$ vim mysql-svc.yaml 

---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    k8s-app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
    protocol: TCP
    targetPort: 3306
  selector:
    k8s-app: mysql
$ kubectl apply -f mysql-svc.yaml

$ kubectl get svc |grep mysql
mysql        ClusterIP   10.101.207.54    <none>        3306/TCP       47s

13.6 实战-ingress-对外发布服务

1、创建ingress-nginx

注意:没有安装 Ingress-controller 的,需要安装 Ingress-controller 七层代理

## 工作节点导入镜像
$ docker load -i kube-webhook-certgen_1.1.1.tar.gz 
$ docker load -i nginx-ingress-controller_v1.1.1.tar.gz

## 控制节点创建资源对象
$ mkdir ingress
$ cd ingress/

$ kubectl apply -f deploy.yaml          ## 单节点版本
$ kubectl apply -f ingress-deploy.yaml  ## 高可用版本

$ kubectl create clusterrolebinding clusterrolebinding-user-3 --clusterrole=cluster-admin --user=system:serviceaccount:ingress-nginx:ingress-nginx


## 查看创建状态
$ kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-bfhd7        0/1     Completed   0          2m36s
ingress-nginx-admission-patch-rvb4v         0/1     Completed   0          2m36s
ingress-nginx-controller-66db8cb57c-bxg7b   1/1     Running     0          2m36s
ingress-nginx-controller-66db8cb57c-smq7s   1/1     Running     0          2m36s
ingress-nginx-controller-66db8cb57c-x57gv   1/1     Running     0          2m36s

发布服务是通过反向代理实现的,也就是通过 nginx 反向代理我们 k8s 中的服务,有些同学会想那nginx 代理我们的服务了,那 ingress 到底是做什么的?原因很简单,nginx 并不能实时监测我们后端pod 的变化,比如增加或减少后端服务需要手工修改 nginx 配置,而 ingress 有一个监听器可以通过监听 kube-apiserver 来感知后端的 servcice、pod 变化。然后根据 ingress 的配置将后端信息更新给我们的反向代理。

工作原理:域名解析指向集群边缘节点,然后 ingress 匹配域名规则将请求转发至对应的服务。扩展:边缘节点

边缘节点是指我们 k8s 集群中对外提供服务的节点,因为 k8s 集群如果每一台主机都拥有公网 IP 的话其实是没有必要的,通常我们只需要边缘节点能够对外提供服务就可以了。此时我们发布服务时只要把域名解析指向边缘节点的 ip 就可以访问 k8s 中的服务。

注:rancher 中自带了服务发布的功能,是通过 nginx 实现的,如果是自建的 k8s 集群则建议使 Traefik。

2、rancher创建 ingress 规则

img

点击 Create

image-20230917204145336

添加注解:

kubernetes.io/ingress.class         nginx

image-20230917204237399

点击 Create

image-20230917204425014

3、浏览器配置

添加本地 hosts 解析。

img

C:\Windows\System32\drivers\etc

添加行:

192.168.2.201 yq.shop.com

img

浏览器访问:http://yq.shop.com/

img

注:管理员 admin 的密码要大于或等于 8 位,且最少要包括字母和数字。

账号:damin

密码:admin@456

img

image-20230917204733646

http://yq.shop.com/

img

http://yq.shop.com/admin/

image-20230917204649313

前后台页面均正常。

多个服务的发布:多个域名解析到边缘节点,ingress 创建域名对应的后端服务规则即可。反向代理会先匹配域名规则再将请求调度到后端,和基于域名的虚拟主机一样。

总结:

13.1 Rancher 简介

13.2 安装 rancher

13.3 通过 Rancher 管理已存在的 k8s 集群

13.4 通过 Rncher 仪表盘管理 k8s-部署 web 站点

13.5 实战-分布式 LNMP 环境部署电商网站

13.6 实战-ingress-对外发布服务