• 云原生部署手册01:构建k8s集群并配置持久化存储


    写在前面:k8s弃用docker的影响其实没那么大

    k8s通过dockershim对docker的支持从1.20版本后就已经移除,仅支持符合Container Runtime Interface(CRI)的容器运行环境,比如containerd。containerd本身就是docker底层的容器运行环境,只不过docker在containerd的基础上增加了符合人类操作的接口。docker构建的镜像并不是docker特有的镜像,它是一个OCI(开放容器标准)镜像。所以,虽然k8s移除了使用docker作为容器运行环境,但通过dockerfile构建的镜像依然可以被符合CRI接口的容器运行环境使用。

    对于熟悉docker的开发者,仍然可以使用docker打包镜像,并上传到私有或公共镜像仓库,再通过k8s拉取镜像构建容器和管理pod。

    一、构建k3s集群

    (一) 准备集群环境

    准备三个运行Ubuntu系统的node。测试环境下可以使用multipass构建三个虚拟机。

    $ multipass launch -n master01
    $ multipass launch -n worker01
    $ multipass launch -n worker02
    $ multipass list
    Name                    State             IPv4             Image
    master01                Running           192.168.64.15    Ubuntu 22.04 LTS
    worker01                Running           192.168.64.16    Ubuntu 22.04 LTS
    worker02                Running           192.168.64.17    Ubuntu 22.04 LTS
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (二) 使用脚本安装k3s master和worker

    Rancher是一家提供容器管理软件的国内企业,他们在国内部署了安装k3s所需的镜像服务。使用该公司提供的安装脚本,可实现一键安装和后台服务启动。

    1. 安装脚本

    master安装脚本:

    curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

    worker安装脚本:

    curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -

    其中K3S_URL参数设置master节点的ip,K3S_TOKEN使用的值存储在master节点上的/var/lib/rancher/k3s/server/node-token路径下。

    2. 实操

    切换到master01节点,安装k3s master:

    $ multipass shell master01
    ubuntu@master01:~$ curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
    ubuntu@master01:~$ ip a | grep 192	#查看master节点ip地址
        inet 192.168.64.15/24 metric 100 brd 192.168.64.255 scope global dynamic enp0s1
    ubuntu@master01:~$ sudo cat /var/lib/rancher/k3s/server/node-token	#查看K3S_TOKEN
    K106f19b5abfec691fb3d92bf92dd894bc22b835fe0a787a2edda37f709dff5fbc0::server:aef034344579142feb3822207e654689
    ubuntu@master01:~$ exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    切换到worker01节点,安装k3s worker:

    $ multipass shell worker01
    ubuntu@worker01:~$ curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.64.15:6443 K3S_TOKEN=K106f19b5abfec691fb3d92bf92dd894bc22b835fe0a787a2edda37f709dff5fbc0::server:aef034344579142feb3822207e654689 sh -
    ubuntu@worker01:~$ exit
    
    • 1
    • 2
    • 3

    切换到worker02节点,安装k3s worker:

    $ multipass shell worker02
    ubuntu@worker02:~$ curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://192.168.64.15:6443 K3S_TOKEN=K106f19b5abfec691fb3d92bf92dd894bc22b835fe0a787a2edda37f709dff5fbc0::server:aef034344579142feb3822207e654689 sh -
    ubuntu@worker02:~$ exit
    
    • 1
    • 2
    • 3

    (三) 宿主机使用kubectl管理集群

    1. 在宿主机安装kubectl

    mac可使用brew一键安装:brew install kubectl

    2. kubectl上下文和配置

    设置kubectl与哪个k8s集群通信,需要进行相关配置。

    master节点安装后,在/etc/rancher/k3s/k3s.yaml文件中保存了集群配置。为了将该配置文件导入宿主机,需要修改该文件权限:

    $ multipass shell master01
    ubuntu@master01:~$ ll /etc/rancher/k3s/k3s.yaml
    -rw------- 1 root root 2969 Mar 14 10:01 /etc/rancher/k3s/k3s.yaml
    ubuntu@master01:~$ sudo chmod a+r /etc/rancher/k3s/k3s.yaml		#为所有用户添加读权限
    ubuntu@master01:~$ ll /etc/rancher/k3s/k3s.yaml 
    -rw-r--r-- 1 root root 2969 Mar 14 10:01 /etc/rancher/k3s/k3s.yaml
    ubuntu@master01:~$ exit
    $ multipass transfer master01:/etc/rancher/k3s/k3s.yaml ~/.kube/	#将master01的配置文件导入宿主机
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    修改该配置文件,将其中server的ip地址从127.0.0.1修改为master01的ip地址:

    $ vim ~/.kube/k3s.yaml
        server: https://192.168.64.15:6443
    
    • 1
    • 2

    kubectl连接k8s集群时,默认使用~/.kube/config文件作为配置文件。可将导入的k3s.yaml重命名为config。

    $ mv ~/.kube/k3s.yaml ~/.kube/config
    
    • 1

    至此,实现了使用宿主机的kubectl管理k8s集群:

    $ kubectl get node
    NAME       STATUS   ROLES                  AGE   VERSION
    master01   Ready    control-plane,master   86m   v1.28.7+k3s1
    worker01   Ready    <none>                 59m   v1.28.7+k3s1
    worker02   Ready    <none>                 52m   v1.28.7+k3s1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (四) 集群节点维护

    有三对命令与节点维护相关:

    • cordon/uncordon:停止/恢复调度,停止调度后,新创建的pod不会被调度到该节点,但原有pod不受影响,仍正常提供服务;
    • drain:驱逐pod。首先需要使用cordon封锁节点,再使用drain驱逐节点上的pod,master将该节点标记为SchedulingDisabled。节点可维护、关闭、重启,再通过uncordon命令重新激活;
    • delete:首先驱逐pod,然后从master节点删除该node,master失去对其控制。需要重新进入节点,重启kubelet,重新注册到集群。

    drain的参数:

    –force: 当一些pod不是经ReplicationController, ReplicaSet, Job, DaemonSet或者StatefulSet管理的时候就需要用–force来强制执行 (例如:kube-proxy);

    –ignore-daemonsets: 无视DaemonSet管理的pod;

    –delete-local-data: 若存在挂载了本地存储的pod,会强制删掉该pod,并将存储清除。

    $ kubectl get nodes
    $ kubectl cordon 
    $ kubectl drain  --force --ignore-daemonsets --delete-local-data
    $ kubectl uncordon 
    
    • 1
    • 2
    • 3
    • 4

    二、为集群配置持久化存储

    (一) 配置nfs服务器

    创建nfs虚拟机,安装nfs服务器,用于给集群提供共享存储。

    $ multipass launch -n nfs -d 25G
    $ multipass shell nfs
    ubuntu@nfs:~$ sudo apt install nfs-kernel-server	#安装nfs服务
    ubuntu@nfs:~$ mkdir nfs				#创建一个目录,用于共享
    ubuntu@nfs:~$ sudo chmod 777 nfs			#修改目录权限
    ubuntu@nfs:~$ sudo vim /etc/exports		#编辑nfs配置文件,允许集群内部网段10和宿主机网段192访问,insecure参数允许从高端口访问nfs,否则mac连接报错
    /home/ubuntu/nfs 192.0.0.0/1(rw,sync,no_subtree_check,insecure)
    /home/ubuntu/nfs 10.0.0.0/1,(rw,sync,no_subtree_check,insecure)
    ubuntu@nfs:~$ sudo exportfs -arv			#发布共享目录
    ubuntu@nfs:~$ showmount -e localhost		#查看共享目录(在其它节点可通过指定ip地址来查看)
    Export list for localhost:
    /home/ubuntu/nfs 192.0.0.0/1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    给所有集群节点安装nfs客户端:

    $ sudo apt install nfs-common
    
    • 1

    在宿主机安装nfs客户端,验证挂载。

    $ showmount -e 192.168.64.15		#查看共享目录
    Exports list on 192.168.64.15:
    /home/ubuntu/nfs                    192.0.0.0/1
    $ make abcd
    $ sudo mount 192.168.64.15:/home/ubuntu/nfs /Users/deepbodhi/abcd
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (二) 配置持久化卷

    1. 创建pv

    假设nfs服务器所在节点的ip为192.168.64.20,创建pv.yaml文件:

    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: registry-pv
      namespace: default
      labels:
        pv: registry-pv
    spec:
      capacity:
        storage: 1Gi
      accessModes:
        - ReadWriteMany
      storageClassName: registry-pv
      nfs:
        path: /home/ubuntu/nfs
        server: 192.168.64.20
        readOnly: false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    查看资源状态:

    $ kubectl create -f pv.yaml
    $ kubectl get pv
    NAME          CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE
    registry-pv   1Gi        RWX            Retain           Bound    default/registry-pvc   registry-pv             18m
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2. 创建pvc

    创建pvc.yaml文件:

    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: registry-pvc
      namespace: default
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 500Mi
      storageClassName: registry-pv		# 通过storageClassName匹配pv
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    查看资源状态:

    $ kubectl create -f pvc.yaml
    $ kubectl get pvc
    NAME           STATUS   VOLUME        CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    registry-pvc   Bound    registry-pv   1Gi        RWX            registry-pv    17m
    
    • 1
    • 2
    • 3
    • 4

    若pvc处于pending状态,请检查pvc配置。可通过 kubectl describe pvc 来查看日志。

    3. 测试

    安装nginx容器,将nginx主页目录绑定到pvc指定的目录。创建nginx.yaml文件:

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-pvc
      namespace: default
      labels:
        app: nginx-pvc
    spec:
      selector:
        matchLabels:
          app: nginx-pvc
      template:
        metadata:
          labels:
            app: nginx-pvc
        spec:
          containers:
            - name: nginx-test-pvc
              image: nginx:latest
              imagePullPolicy: IfNotPresent
              ports:
                - name: web-port
                  containerPort: 80
                  protocol: TCP
              volumeMounts:
                - name: nginx-persistent-storage
                  mountPath: /usr/share/nginx/html
          volumes:
            - name: nginx-persistent-storage
              persistentVolumeClaim:
                claimName: registry-pvc
    ---
    # 通过service暴露端口:
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      namespace: default
      labels:
        app: nginx
    spec:
      ports:
        - port: 80
          targetPort: 80
          nodePort: 30080
          protocol: TCP
      selector: 
        app: nginx-pvc
      type: NodePort
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    查看资源状态:

    $ kubectl create -f nginx.yaml
    $ kubectl get svc nginx
    NAME    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
    nginx   NodePort   10.43.60.227   <none>        80:30080/TCP   19m
    $ kubectl get deployment
    NAME        READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-pvc   1/1     1            1           20m
    $ kubectl get pod
    NAME                         READY   STATUS    RESTARTS   AGE
    nginx-pvc-687c675c7b-46j5k   1/1     Running   0          21m
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这里需要注意,首次创建nginx容器时,需要到网络拉取镜像,可通过 kubectl describe 跟踪资源创建状态。

    上例中,nginx的主页目录被绑定到pv存储中,pv存储指定了前面建立的nfs服务器目录。因此,可在nfs服务器对应目录下创建index.html文件,观察集群中的nginx容器是否的确使用了nfs存储:

    $ multipass shell nfs
    ubuntu@nfs:~$ vim ~/nfs/index.html
    <html>
    <head>
    <title>test</title>
    </head>
    <body>
    <h1>Test</h1>
    Hello World
    </body>
    </html>
    ubuntu@nfs:~$ exit
    $ multipass ls	#查看集群节点ip
    Name                    State             IPv4             Image
    master01                Running           192.168.64.23    Ubuntu 22.04 LTS
                                              10.42.0.0
                                              10.42.0.1
    nfs                     Running           192.168.64.20    Ubuntu 22.04 LTS
    worker01                Running           192.168.64.24    Ubuntu 22.04 LTS
                                              10.42.1.0
                                              10.42.1.1
    worker02                Running           192.168.64.25    Ubuntu 22.04 LTS
                                              10.42.2.0
                                              10.42.2.1
    $ curl 192.168.64.23:30080	#访问集群中任意节点的30080端口
    <html>
    <head>
    <title>test</title>
    </head>
    <body>
    <h1>Test</h1>
    Hello World
    </body>
    </html>
    (base) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    HyperLynx(十四)高级分析技术
    表情识别-情感分析-人脸识别(代码+教程)
    win安装vue并运行 vue-admin-template
    猴赛雷 ! 上次我见过这么厉害的安全测试实战演练还是上次!
    14.3.6 创建组合索引
    Python学习笔记—基本语法
    request、session 和 application的区别
    2022-2028全球前列腺癌诊断和治疗行业调研及趋势分析报告
    【校招VIP】java语言类和对象之map、set集合
    linux top命令按内存/CPU排序显示
  • 原文地址:https://blog.csdn.net/deepbodhi/article/details/136745894