Kubernetes 学习笔记以及 Kubernetes 集群 +KubeSphere 部署指南

kubernetes 学习笔记

Kubernetes 中的各种东西介绍

  1. Kubernetes API Server

    提供 Kubernetes 各类资源对象的增删改查的 HTTP Rset 接口,是整个系统的数据总线和数据中心,提供了集群管理的 REST API 接口,包括认证授权、数据校验以及集群状态变更、提供了其他模块之间的数据交互和通信的枢纽,是资源配额控制的入口,拥有完备的安全机制

  2. Kubernetes Controller Manager

    作为集群内部的管理控制中心,负责集群内的 Node 节点,Pod 副本、服务端点(Endpoint)、命名空间(NameSpace)、服务账号(ServiceAccount)、资源配额(ResourceQuota)的管理。当某个 Node 意外宕机时,Controller 会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态

  3. Kubernetes Scheduler(调度器)

    Kubernetes Scheduler 的作用是根据特定的调度算法把 Pod 调度到指定的工作节点(Node)上,这一过程也叫绑定(Bind)。Scheduler 的输入为需要调度的 Pod 和可以被调度的节点的信息,输出为调度算法选择的 Node 节点,并将该 Pod 绑定到这个 Node 节点

  4. Etcd

    是 Kubernetes 集群中的一个十分重要的组件,用于保存集群中所有的网络配置和对象的状态信息

  5. Kubelet

    在 Kubunetes 集群中,每个 Node 节点都会启动 kubelet 进程,用来处理 Master 节点下发到本节点的任务,管理 Pod 和其中的容器。kubelet 会在 API Server 上注册节点信息,定期向 Master 汇报节点资源的使用情况,并通过 cAdvisor 监控容器和节点资源。可以把 kubelet 理解成是一个代理进程,是 Node节点上的 Pod 管家

    是一个 Kubernetes 的客户端工具,通常会在 Kubernetes 的 Master 节点的安装过程中被一同安装,在任意环境安装,只要能连接 Master 节点,就可以通过它来管理 Kubernetes 集群

  6. Kube-proxy

    它运行在所有的 Node 节点上,监听每个节点上 Kubernetes API 中定义的服务变化情况,并创建路由规则来进行服务负载均衡

  7. Pod

    是 Kubernetes 最基本的操作单元,一个 Pod 中可以包含一个或多个紧密相关的容器,一个 Pod 可以被一个容器化的环境看作应用层的逻辑宿主机。每个Pod 中运行着一个特殊的被称之为 Pause 的容器,其他容器则称为业务容器,业务容器共享 Pause 容器的网络栈和 Volume 挂载卷

  8. Service(服务)

    通常由一组 Pod 组成一个集群来提供服务,服务的特点:

    • 拥有一个指定的名字,比如 mysql-server
    • 拥有一个虚拟 IP 地址和端口号,销毁之前不会改变,只能内网访问
    • 能够提供某种远程服务能力
    • 被映射到了提供这种服务能力的一组容器应用上
  9. CoreDNS

CoreDNS 是模块化且可插拔的 DNS 服务器,每个插件都为 CoreDNS 添加了新功能。 可以通过维护 Corefile,即 CoreDNS 配置文件, 来定制其行为。 集群管理员可以修改 CoreDNS Corefile 的 ConfigMap,以更改服务发现的工作方式

  1. Cilium

    Cilium 是一款开源软件,用于透明地保护使用 Linux 容器管理平台(如 Docker 和 Kubernetes)部署的应用程序服务之间的网络连接

    Cilium 的基础是一种名为 eBPF 的新 Linux 内核技术,它支持在 Linux 本身内动态插入强大的安全可见性和控制逻辑。由于 eBPF 在 Linux 内核中运行,因此可以应用和更新 Cilium 安全策略,而无需对应用程序代码或容器配置进行任何更改

  2. kube-proxy

    Kubernetes 网络代理在每个节点上运行。网络代理反映了每个节点上 Kubernetes API 中定义的服务,并且可以执行简单的 TCP、UDP 和 SCTP 流转发,或者在一组后端进行 循环 TCP、UDP 和 SCTP 转发。 当前可通过 Docker-links-compatible 环境变量找到服务集群 IP 和端口, 这些环境变量指定了服务代理打开的端口。 有一个可选的插件,可以为这些集群 IP 提供集群 DNS。 用户必须使用 apiserver API 创建服务才能配置代理。

  3. kube-state-metrics

    kube-state-metrics是 Kubernetes 组织下的一个项目,根据 Kubernetes 原生资源的当前状态生成 Prometheus 格式的指标。它通过侦听 Kubernetes API 并收集有关资源和对象的信息来做到这一点,例如 Deployment、Pod、Service 和 StatefulSet。kube-state-metrics的文档中提供了完整的资源列表。

使用 Kubeadm 安装 Kubernetes 集群

Kubeadm 官方教程

  1. 前期准备(所有节点)

    安装 docker

    1
    2
    3
    yum -y install docker
    systemctl enable docker
    systemctl start docker

    禁用 SELinux

    1
    2
    sed -i 's/SELINUX=permissive/SELINUX=disabled' /etc/sysconfig/selinux
    setenforce 0

    安装 kubelet

    添加镜像 repo

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
    exclude=kubelet kubeadm kubectl
    EOF
    1
    2
    3
    sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
    systemctl enable kubelet
    systemctl start kubelet

    禁用交换分区

    1
    2
    3
    4
    swapoff -a
    vim /etc/fstab
    #修改/etc/fstab文件,注释掉下面该行
    #/dev/mapper/centos-swap swap swap default 0 0

    修改防火墙规则

    1
    2
    iptables -P FORWARD ACCEPT 
    iptables-save

    配置转发

    1
    2
    3
    4
    5
    6
    7
    8
    9
    cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
    br_netfilter
    EOF

    cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF
    sudo sysctl --system

    设置域名解析(否则后期 API-SERVER 会报错,也可以在 DNS 服务器上添加解析记录)

    1
    2
    3
    4
    5
    6
    7
    8
    cat >> /etc/hosts << EOF

    # K8S Cluster
    100.x.x.x m.x.yhsyc.club
    100.x.x.x s1.x.yhsyc.club
    100.x.x.x s2.x.yhsyc.club

    EOF
  2. 部署 Master 节点
    1
    kubeadm init --apiserver-advertise-address 100.88.1.99 --control-plane-endpoint m.x.yhsyc.club --pod-network-cidr 192.168.0.0/17 --service-cidr 192.168.128.0/18 --service-dns-domain x.yhsyc.club --node-name m.yhsyc.club

    这个过程中,kubeadm 完成了以下几个主要步骤:

    • 检查初始化节点所需要的先决条件,如果不满足,就给出错误提示
    • 生成 Kubernetes 集群的令牌
    • 生成自签名的 CA 和客户端证书
    • 自动创建 kubeconfig 配置文件,该文件是提供给 kubelet 连接 API Server 时使用的
    • 配置基于角色的访问控制,并且设置 Master 节点只允许控制组件服务
    • 创建其他的相关服务,例如 kube-proxy 和 kube-dns 等

    要注意init完成之后的提示信息,有操作指引,可以复制之后的指令直接加入 master

    1
    2
    3
    4
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    #如果不导入,那么会报证书问题
  3. 下载网络插件 Cilium
    1
    2
    3
    4
    curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz{,.sha256sum}
    sha256sum --check cilium-linux-amd64.tar.gz.sha256sum
    sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
    rm cilium-linux-amd64.tar.gz{,.sha256sum} -rf

    安装 Cilium

    1
    cilium install

    微信截图_20220309193213.png

    1
    2
    3
    # apply 安装 flannel 作为网络插件 
    # 这里我试了 flannel,网络容器起不起来,之后转用 cilium,发现是我内核版本太低导致装不上,但不确定 flannel 是不是也是
    #kubectl apply -f https://raw.githubusercontent.com/flannel-#io/flannel/master/Documentation/kube-flannel.yml
  4. 部署 Node 节点
    1
    2
    3
    token=$(kubeadm token list | grep authentication,signing | awk '{print $1}')
    kubeadm join --token $token <ip-address>
    --node-name s1.x.yhsyc.club # << 加这一行
    1
    2
    #示例
    kubeadm join m.x.yhsyc.club:6443 --token mdd3oz.l3ld96hi07nvfqyr --discovery-token-ca-cert-hash sha256:ed8f89b489a70a515a68182bf5b30ec2aaaf8cf336d1f2d8dfa2a307f0c40522 --node-name s1.x.yhsyc.club

    微信截图_20220311092742.png

  5. 如果部署过程中有什么不对的,可以重新部署 init
    1
    kubeadm reset
  6. 部署完成后可以通过下面指令来显示节点信息
    1
    kubectl get nodes

    微信截图_20220311092917.png

  7. 可以看一下 pod 服务都有什么,有没有状态不对的 pod
    1
    kubectl get pod -A

    到这里的话 K8S 集群就是可以开始工作的了

使用 NFS 作为 K8S 集群的存储

  1. 安装 NFS 服务器

    这里我用了一台 200 G SSD 的 Alpine 来作为 NFS 服务器

    1
    apk add nfs-utils

    安装完成之后在 /etc/exports 中加一行配置

    1
    2
    vim /etc/exports
    /data 100.x.x.0/24(rw,async,no_subtree_check,no_wdelay,crossmnt,no_root_squash,insecure_locks,sec=sys,anonuid=0,anongid=0)

    设置NFS服务开机自启并重启服务器

    1
    rc-update add nfs && reboot
  2. 在所有节点安装 nfs 客户端
    1
    2
    yum -y install nfs-utils
    systemctl start nfs && systemctl enable nfs
  3. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    vi /etc/kubernetes/manifests/kube-apiserver.yaml

    #添加- --feature-gates=RemoveSelfLink=false
    #
    ...
    - command:
    - kube-apiserver
    - --advertise-address=192.168.5.11
    - --allow-privileged=true
    - --feature-gates=RemoveSelfLink=false
    ...
    #

    保存退出,kubernetes 会自动重建 apiserver,如果没有这一步的话后面创建 pod 会一直 pending,挂载失败

  4. 部署 nfs-client-provisioner(master)
    1
    2
    3
    4
    #从github上clone yaml
    git clone https://github.com/kubernetes-incubator/external-storage.git
    cp -R external-storage/nfs-client/deploy/ $HOME
    cd deploy

    创建权限 rbac.yaml

    1
    2
    3
    4
    5
    # Set the subject of the RBAC objects to the current namespace where the provisioner is being deployed
    NS=$(kubectl config get-contexts|grep -e "^\*" |awk '{print $5}')
    NAMESPACE=${NS:-default}
    sed -i'' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/rbac.yaml ./deploy/deployment.yaml
    kubectl create -f deploy/rbac.yaml

    配置 deploy/class.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
    name: managed-nfs-storage
    provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
    parameters:
    archiveOnDelete: "false" # When set to "false" your PVs will not be archived
    # by the provisioner upon deletion of the PVC.

    修改 deployment.yaml 文件
    这里修改的参数包括 NFS 服务器所在的 IP 地址(192.168.5.11),以及 NFS 服务器共享的路径(/nfs/data/pv002),两处都需要修改为你实际的 NFS 服务器和共享目录

    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
    [root@master deploy]# cat deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: nfs-client-provisioner
    labels:
    app: nfs-client-provisioner
    namespace: default
    spec:
    replicas: 1
    strategy:
    type: Recreate
    selector:
    matchLabels:
    app: nfs-client-provisioner
    template:
    metadata:
    labels:
    app: nfs-client-provisioner
    spec:
    serviceAccountName: nfs-client-provisioner
    containers:
    - name: nfs-client-provisioner
    image: quay.io/external_storage/nfs-client-provisioner:latest
    volumeMounts:
    - name: nfs-client-root
    mountPath: /persistentvolumes
    env:
    - name: PROVISIONER_NAME
    value: fuseim.pri/ifs
    - name: NFS_SERVER
    value: 100.88.1.96
    - name: NFS_PATH
    value: /data
    volumes:
    - name: nfs-client-root
    nfs:
    server: 100.88.1.96
    path: /data

    应用 nfs

    1
    kubectl apply -f deploy/deployment.yaml -f deploy/class.yaml

    微信截图_20220310163620.png

  5. 测试环境

    部署测试 pod

    1
    kubectl create -f deploy/test-claim.yaml -f deploy/test-pod.yaml

    查看 pvc,pv 状态

    1
    kubectl get pvc,pv

    能看到下面就说明成了

    1
    2
    3
    4
    5
    6
    [root@master]# kubectl get pvc,pv
    NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
    persistentvolumeclaim/test-claim Bound ingress-nginx-test-claim-pvc-efd702ba-102d-4d61-9a5f-6fc4805f12c0 1Mi RWX managed-nfs-storage 25m

    NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
    persistentvolume/ingress-nginx-test-claim-pvc-efd702ba-102d-4d61-9a5f-6fc4805f12c0 1Mi RWX Delete Bound ingress-nginx/test-claim managed-nfs-storage 19m

    删除测试 pod

    1
    kubectl delete -f deploy/test-pod.yaml -f deploy/test-claim.yaml
  6. 设置默认 StorageClass(master 节点)
    1
    kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

安装 Prometheus 和 Grafana

建议不要在完全翻墙的环境下去拉镜像,很有可能拉不成功,有时候拉失败,要考虑一下是不是网络环境的问题

GitHub link : Prometheus and Grafana

快速安装

1
2
kubectl apply \
--filename https://raw.githubusercontent.com/giantswarm/prometheus/master/manifests-all.yaml

安装KubeSphere

GitHub link : KubeSphere

最小化快速部署
1
2
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.2.1/kubesphere-installer.yaml
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.2.1/cluster-configuration.yaml
查看部署进度及日志
1
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f

微信截图_20220310201916.png

部署完成后可执行如下命令查看控制台的服务端口,使用 IP:consolePort(default: 30880) 访问 KubeSphere UI 界面,默认的集群管理员账号为 admin/P@88w0rd

1
kubectl get svc/ks-console -n kubesphere-system

微信截图_20220323214439.png

在安装前或者安装后开启插件

  1. 编辑你的 cluster-configuration.yaml
  2. 找到你要启用的插件 将 enable 后的 false 改为 true,保存退出
  3. 重新应用一下该文件,搞定

示例:

1
2
3
4
5
6
7
8
9
vi cluster-configuration.yaml
/openpitrix #搜索openpitrix插件

openpitrix:
store:
enabled: true # 将“false”更改为“true”

:wq #保存退出
kubectl apply -f cluster-configuration.yaml

可以查看安装进度

1
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f