zoukankan      html  css  js  c++  java
  • Kubernetes集群部署笔记

    本作品Galen Suen采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。由原作者转载自个人站点

    更新记录

    • 2021-09-04

      1. 服务器操作系统由Debian 10 ("buster")更新至Debian 11 ("bullseye")
      2. 使用kube-router代替kube-proxyflannel实现Service ProxyPod Network
      3. 修复一些代码错误;
    • 2021-09-08

      1. 部署kube-router时添加运行参数--advertise-loadbalancer-ip=true
    • 2021-09-18

      1. Kubernetes版本由v1.22.1更新至v1.22.2

    概述

    本文用于整理基于Debian操作系统使用kubeadm工具部署Kubernetes集群的操作过程。该集群部署于一组本地虚拟服务器上,用于学习Kubernetes的基础概念和基本操作,并作为今后其他学习内容的实践部署提供环境。

    考虑到不同的网络环境,本文中一些步骤会记录两种操作方式,通过镜像等方式加快部署效率、避免部署错误。有关镜像同步的方案,可参考附件内容中的同步所需镜像

    随着操作系统和各相关组件版本的更新,笔者将在验证通过后对本文进行补充和更新。

    服务器

    受限于本地物理服务器的配置,虚拟服务器配置规划如下表。

    Host OS IP CPU RAM K8s Roles
    k8s-n0 Debian 11.0 10.0.0.50 2 vCPUs 4 GB v1.22.2 control-plane, master
    k8s-n1 Debian 11.0 10.0.0.51 4 vCPUs 8 GB v1.22.2
    k8s-n2 Debian 11.0 10.0.0.52 4 vCPUs 8 GB v1.22.2
    k8s-n3 Debian 11.0 10.0.0.53 4 vCPUs 8 GB v1.22.2

    所有虚拟服务器CPU均为amd64架构。

    截止本文发布时,笔者基于最新Debian 11 ("bullseye")部署的集群仍然存在一些问题,故暂且发布基于Debian 10 ("buster")的笔记。

    网络环境

    本地网络IP地址范围为10.0.0.0/24,其中:

    • 10.0.0.2-10.0.0.99为静态分配,供虚拟服务器使用
    • 10.0.0.100-10.0.0.200用于DHCP自动分配
    • 10.0.0.201-10.0.0.254为静态分配,供负载均衡器使用

    其他组件

    准备工作

    服务器配置

    本文假设服务器硬件和操作系统已经配置完毕,所有服务器上都已经正确配置了ssh服务和sudo权限。

    作为参考,这里记录笔者配置sudo权限和ssh服务的过程。

    • 配置sudo权限

      如操作人员的登录用户已经被正确配置了sudo权限,可跳过此步骤。

      本示例中,操作人员的登录用户名为tiscs,需要实际环境情况进行替换。

      # 使用root用户登录系统
      # 安装sudo,并配置sudo权限
      apt update
      apt install sudo
      echo "tiscs ALL=(ALL) NOPASSWD: ALL" | tee /etc/sudoers.d/tiscs # 这在生产环境绝不是个好主意,仅仅是为了演练环境操作方便
      
    • 配置ssh服务

      # 安装openssh-server,并配置ssh服务为自动启动
      sudo apt update
      sudo apt install openssh-server
      sudo systemctl enable ssh --now
      

    配置过程

    安装容器运行时

    本文配置的集群选择containerd作为容器运行时。

    在所有节点上执行如下操作。

    • 配置模块加载

      cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
      overlay
      br_netfilter
      EOF
      
      sudo modprobe overlay
      sudo modprobe br_netfilter
      
    • 配置sysctl参数

      cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
      net.bridge.bridge-nf-call-iptables  = 1
      net.ipv4.ip_forward                 = 1
      net.bridge.bridge-nf-call-ip6tables = 1
      EOF
      
      sudo sysctl --system
      
    • 配置APT源

      # 安装依赖项
      sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
      
      # 根据网络环境选择官方源或镜像源
      
      # 1. 配置Docker官方源
      curl -fsSL https://download.docker.com/linux/debian/gpg 
        | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
      echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" 
        | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
      
      # 2. 配置Aliyun镜像源
      curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg 
        | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
      echo "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian $(lsb_release -cs) stable" 
        | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
      
    • 安装containerd

      sudo apt update
      sudo apt install -y containerd.io
      
    • 初始化配置

      sudo mkdir -p /etc/containerd
      containerd config default | sudo tee /etc/containerd/config.toml
      
      # 配置systemd cgroup驱动
      sudo sed -i 's|(s+)[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]|1[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
      1  SystemdCgroup = true|g' /etc/containerd/config.toml
      
      # (可选)配置阿里云容器镜像源
      sudo sed -i 's/registry-1.docker.io/xrb7j2ja.mirror.aliyuncs.com/g' /etc/containerd/config.toml
      # (可选)配置sandbox image地址
      # 为了方便,这里配置为与kubelet所需相同的版本(可以使用kubeadm config images list命令查看)
      sudo sed -i 's|k8s.gcr.io/pause:.+|registry.cn-beijing.aliyuncs.com/choral-k8s/pause:3.5|g' /etc/containerd/config.toml
      
      # 重启containerd服务,使上述配置修改生效
      sudo systemctl restart containerd
      

    安装kubeadm

    在所有节点上执行如下操作。

    • 配置APT源

      # 根据网络环境选择官方源或镜像源
      
      # 1. 使用Google官方源
      curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg 
        | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
      echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" 
        | sudo tee /etc/apt/sources.list.d/kubernetes.list
      
      # 2. 使用Aliyun镜像源
      curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg 
        | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
      echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" 
        | sudo tee /etc/apt/sources.list.d/kubernetes.list
      
    • 安装kubeadmkubeletkubectl

      sudo apt install -y kubelet=1.22.2-00 kubeadm=1.22.2-00 kubectl=1.22.2-00
      sudo apt-mark hold kubelet kubeadm kubectl
      
    • 安装并配置crictl(可选)

      可以安装并配置crictl,便于在k8s节点上管理容器运行时。

      # 安装crictl工具
      sudo apt install -y cri-tools
      
      # 配置crictl使用containerd运行时
      cat <<EOF | sudo tee /etc/crictl.yaml
      runtime-endpoint: unix:///run/containerd/containerd.sock
      image-endpoint: unix:///run/containerd/containerd.sock
      timeout: 10
      debug: false
      EOF
      
      # 验证crictl配置
      sudo crictl images # 列出所有镜像
      

    配置控制平面节点

    k8s-n0节点上执行如下操作。

    • 预先下载所需镜像

      # 查看所需的镜像列表
      kubeadm config images list --kubernetes-version=v1.22.2 # --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s
      
      # 1. 使用默认容器镜像仓库
      sudo kubeadm config images pull --kubernetes-version=v1.22.2
      
      # 2. 使用自建容器镜像仓库
      sudo kubeadm config images pull --kubernetes-version=v1.22.2 
        --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s
      
    • 初始化控制平面节点

      # --apiserver-advertise-address: 当前节点IP地址
      # --pod-network-cidr           : Pod网络地址段(CIDR: https://datatracker.ietf.org/doc/html/rfc4632)
      
      # 1. 使用默认容器镜像仓库
      sudo kubeadm init --apiserver-advertise-address 10.0.0.50 
        --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.2 
        --skip-phases=addon/kube-proxy
      
      # 2. 使用自建容器镜像仓库
      sudo kubeadm init --apiserver-advertise-address 10.0.0.50 
        --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.22.2 
        --image-repository registry.cn-beijing.aliyuncs.com/choral-k8s 
        --skip-phases=addon/kube-proxy
      

      执行完上述操作后,kubeadm init命令会输出用于添加节点到集群中的说明,请保存该说明中的内容。示例如下:

      sudo kubeadm join 10.0.0.50:6443 
        --token vafq03.5dl6j1cbcd1yzf3c 
        --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
      
    • 添加kubectl配置(可选)

      mkdir -p ~/.kube
      sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
      sudo chown $(id -u):$(id -g) ~/.kube/config
      

    安装网络组件

    • 安装flannel(已废弃,使用kube-router代替)

      # 1. 使用默认镜像仓库(quay.io/coreos)安装
      kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
      
      # 2 如果访问raw.githubusercontent.com上的文件存在网络问题
      #   可以使用jsdelivr提供的GitHub CDN地址(https://www.jsdelivr.com/github)
      kubectl apply -f https://cdn.jsdelivr.net/gh/coreos/flannel@master/Documentation/kube-flannel.yml
      
    • 安装kube-router

      curl -s https://cdn.jsdelivr.net/gh/cloudnativelabs/kube-router@master/daemonset/generic-kuberouter-all-features.yaml 
        | sed 
          -e "s|%APISERVER%|$(kubectl get cm -n kube-public -o yaml cluster-info | sed -n 's/^ +server: (.+)/1/p')|g" 
          -e "s|%CLUSTERCIDR%|$(kubectl get cm -n kube-system -o yaml kubeadm-config | sed -n 's/^ +podSubnet: (.+)/1/p')|g" 
          -e "s|(s+)args:|1args:
      1- "--advertise-loadbalancer-ip=true"|g" 
        | kubectl apply -f -
      

    添加工作节点

    k8s-n1k8s-n2k8s-n3节点上执行如下操作。该操作中需要的token值和hash值通过上述步骤中的kubeadm init操作获取。

    • 添加工作节点

      sudo kubeadm join 10.0.0.50:6443 
        --token vafq03.5dl6j1cbcd1yzf3c 
        --discovery-token-ca-cert-hash sha256:6a725d98e0f6bda713c9f93b8441a735cc60e8ec7454fbe960c74ab80683f938
      
    • 查看节点状态

      k8s-n0节点上执行如下操作。

      kubectl get nodes
      kubectl top nodes
      

    安装Helm工具(可选)

    本文暂不涉及使用helm执行的操作,该步骤可选。

    • 安装Helm工具

      # 下载并安装
      curl -sL https://get.helm.sh/helm-v3.6.3-linux-amd64.tar.gz | tar xzf - linux-amd64/helm
      sudo cp ./linux-amd64/helm /usr/local/bin/helm
      rm -rf ./linux-amd64
      sudo chown root:root /usr/local/bin/helm
      sudo chmod 755 /usr/local/bin/helm
      
      # 验证helm安装
      helm version
      

    安装Metrics Server(可选)

    部署metrics server以启用指标服务,未安装metrics server前,kubectl top命令无法正常执行。

    k8s-n0节点上执行如下操作。

    • 执行清单文件

      这里需要注意,为解决证书错误,需要添加metrics-server容器的参数--kubelet-insecure-tls,这里选择通过sed命令修改清单文件后再使用kubectl执行。

      # 1. 使用官方镜像地址直接安装
      curl -sL https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml 
        | sed -e "s|(s+)- args:|1- args:
      1  - --kubelet-insecure-tls|" | kubectl apply -f -
      #   1.1 为避免特殊网络环境中的清单文件加载问题,可以使用FastGit提供的加速方案
      curl -sL https://endpoint.fastgit.org/https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml 
        | sed -e "s|(s+)- args:|1- args:
      1  - --kubelet-insecure-tls|" | kubectl apply -f -
      
      # 2. 使用自定义镜像地址安装
      curl -sL https://endpoint.fastgit.org/https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml 
        | sed 
          -e "s|(s+)- args:|1- args:
      1  - --kubelet-insecure-tls|" 
          -e "s|k8s.gcr.io/metrics-server|registry.cn-beijing.aliyuncs.com/choral-k8s|g" 
        | kubectl apply -f -
      

    安装负载均衡组件

    由云服务商提供的Kubernetes服务,通常会提供内置的负载均衡实现。而笔者部署环境为私有环境,需要一个轻量的负载均衡实现以支撑LoadBalancer类型的服务。

    笔者选择MetalLB作为负载均衡实现,配置为二层网络模式。LoadBalancer地址范围配置为10.0.0.201-10.0.0.254,需根据具体网络环境进行修改。

    k8s-n0节点上执行如下操作。

    • 安装MetalLB

      # 创建用于部署MetalLB的命名空间
      kubectl create namespace metallb-system
      
      # 创建必须的配置文件
      cat <<EOF | kubectl apply -f -
      apiVersion: v1
      kind: ConfigMap
      metadata:
        namespace: metallb-system
        name: config
      data:
        config: |
          address-pools:
            - name: default
              protocol: layer2
              addresses:
              - 10.0.0.201-10.0.0.254
      EOF
      
      # 1. 直接执行清单文件
      kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml
      
      # 2. 为避免特殊网络环境中的清单文件加载问题,可以使用jsdelivr提供的加速方案加速地址
      kubectl apply -f https://cdn.jsdelivr.net/gh/metallb/metallb@v0.10.2/manifests/metallb.yaml
      

    安装持久卷供应程序

    Kubernetes内置的local-storage存储类无法动态供应卷,为便于基于该环境演练时自动创建持久卷,选择使用local-path-provisioner作为持久卷供应程序。

    • 创建所需的目录

      在所有节点上执行如下操作。

      sudo mkdir -p /opt/local-path-provisioner
      
    • 安装local-path-provisioner

      k8s-n0节点上执行如下操作。

      # 1. 使用官方清单文件地址直接安装
      kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
      #   1.1 同样可以使用jsdelivr提供的加速方案
      kubectl apply -f https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml
      
      # 2. 替换命名空间
      curl -s https://cdn.jsdelivr.net/gh/rancher/local-path-provisioner@master/deploy/local-path-storage.yaml 
        | sed 
          -e "1,6d" 
          -e "s/local-path-storage/kube-system/" 
        | kubectl apply -f -
      
    • 配置默认存储类

      kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
      

    检查集群工作状态

    k8s-n0节点上执行如下操作。

    • 查看节点状态

      kubectl get nodes
      
      kubectl top nodes
      
    • 查看Pod状态

      kubectl get pods -A
      
      kubectl top pods -A
      

    附加内容

    同步所需镜像

    由于特殊网络环境问题,需要同步kubelet所需镜像至其他镜像仓库的,可参考如下操作。

    笔者开发环境中使用podman管理容器和镜像,已将docker设置为podman的别名(alias docker=podman)。

    • 同步kubelet所需镜像

      首先,需要创建私有镜像仓库认证凭据。

      # 根据需要将`registry.cn-beijing.aliyuncs.com`替换为私有镜像仓库地址
      docker login registry.cn-beijing.aliyuncs.com
      

      创建一个脚本gcr_mirror_sync.sh,内容如下。

      # gcr_mirror_sync.sh
      # 根据需要将`registry.cn-beijing.aliyuncs.com/choral-k8s/`替换为私有镜像仓库地址
      while read o
        do {
            t=$(echo $o | sed 's|k8s.gcr.io.*/|registry.cn-beijing.aliyuncs.com/choral-k8s/|g')
            docker pull $o
            docker tag $o $t
            docker push $t
            docker rmi $o
            docker rmi $t
        }
      done < "${1:-/dev/stdin}"
      

      该脚本有两种使用方法。

      kubeadm config images list --kubernetes-version=v1.22.2 | bash gcr_mirror_sync.sh
      
      # 列出所需镜像列表并保存到文件
      kubeadm config images list --kubernetes-version=v1.22.2 > gcr-image-list
      # 拷贝该文件至gcr_mirror_sync.sh所在主机,然后执行该脚本
      bash gcr_mirror_sync.sh gcr-image-list
      
    • 同步附加组件镜像

      # 根据需要将`registry.cn-beijing.aliyuncs.com/choral-k8s/`替换为私有镜像仓库地址。
      
      # 同步metrics server所需镜像
      docker pull k8s.gcr.io/metrics-server/metrics-server:v0.5.0
      docker tag k8s.gcr.io/metrics-server/metrics-server:v0.5.0 registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
      docker push registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
      docker rmi k8s.gcr.io/metrics-server/metrics-server:v0.5.0
      docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
      

    参考资料

  • 相关阅读:
    类型转换
    Java中this和super的用法总结
    关于网页乱码问题
    用cookie实现记住用户名和密码
    Before start of result set
    jsp页面错误The attribute prefix does not correspond to any imported tag library
    MySql第几行到第几行语句
    servelet跳转页面的路径中一直包含sevelet的解决办法
    <a>标签跳转到Servelet页面并实现参数的传递
    解决网页乱码
  • 原文地址:https://www.cnblogs.com/tiscs/p/notes-k8s-cluster.html
Copyright © 2011-2022 走看看