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

概述

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

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

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

服务器

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

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

所有虚拟服务器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,需要实际环境情况进行替换。

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

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

配置过程

安装容器运行时

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

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

  • 配置模块加载

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

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

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

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

    1. sudo mkdir -p /etc/containerd
    2. containerd config default | sudo tee /etc/containerd/config.toml
    1. # 配置systemd cgroup驱动
    2. 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\]\n\1 SystemdCgroup = true|g' /etc/containerd/config.toml
    1. # (可选)配置阿里云容器镜像源
    2. sudo sed -i 's/registry-1.docker.io/xrb7j2ja.mirror.aliyuncs.com/g' /etc/containerd/config.toml
    3. # (可选)配置sandbox image地址
    4. # 为了方便,这里配置为与kubelet所需相同的版本(可以使用kubeadm config images list命令查看)
    5. sudo sed -i 's|k8s.gcr.io/pause:.\+|registry.cn-beijing.aliyuncs.com/choral-k8s/pause:3.5|g' /etc/containerd/config.toml
    1. # 重启containerd服务
    2. sudo systemctl restart containerd

安装kubeadm

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

  • 配置APT源

    1. # 根据网络环境选择官方源或镜像源
    2. # 1. 配置Docker官方源
    3. curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg \
    4. | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
    5. echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" \
    6. | sudo tee /etc/apt/sources.list.d/kubernetes.list
    7. # 2. 配置Aliyun镜像源
    8. curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg \
    9. | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-archive-keyring.gpg
    10. echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" \
    11. | sudo tee /etc/apt/sources.list.d/kubernetes.list
  • 安装kubeadmkubeletkubectl

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

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

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

配置控制平面节点

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

  • 预先下载所需镜像

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

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

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

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

    1. mkdir -p ~/.kube
    2. sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
    3. sudo chown $(id -u):$(id -g) ~/.kube/config
  • 安装网络组件

    1. # 1. 使用默认镜像仓库(quay.io/coreos)安装
    2. kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    3. # 2. 使用给自定义镜像仓库安装
    4. kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml \
    5. | sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f -
    6. # 2.1 如果访问raw.githubusercontent.com上的文件存在网络问题
    7. # 可以使用jsdelivr提供的GitHub CDN地址(https://www.jsdelivr.com/github)
    8. curl -s https://cdn.jsdelivr.net/gh/coreos/flannel@master/Documentation/kube-flannel.yml \
    9. | sed -e 's|quay.io/coreos|registry.cn-beijing.aliyuncs.com/choral-k8s|g' | kubectl apply -f -

添加工作节点

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

  • 添加工作节点

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

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

    1. kubectl get nodes
    2. kubectl top nodes

安装Helm工具(可选)

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

  • 安装Helm工具

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

安装Metrics Server(可选)

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

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

  • 执行清单文件

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

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

安装负载均衡组件

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

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

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

  • 安装MetalLB

    1. # 创建用于部署MetalLB的命名空间
    2. kubectl create namespace metallb-system
    3. # 创建必须的配置文件
    4. cat <<EOF | kubectl apply -f - --dry-run=client
    5. apiVersion: v1
    6. kind: ConfigMap
    7. metadata:
    8. namespace: metallb-system
    9. name: config
    10. data:
    11. config: |
    12. address-pools:
    13. - name: default
    14. protocol: layer2
    15. addresses:
    16. - 10.0.0.201-10.0.0.254
    17. EOF
    18. # 1. 直接执行清单文件
    19. kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml
    20. # 1.1 为避免特殊网络环境中的清单文件加载问题,可以使用jsdelivr提供的加速方案加速地址
    21. kubectl apply -f https://cdn.jsdelivr.net/gh/metallb/metallb@v0.10.2/manifests/metallb.yaml
    22. # 2. 替换命名空间。命名空间需要与刚刚创建的ConfigMap相同。
    23. curl -sL https://cdn.jsdelivr.net/gh/metallb/metallb@v0.10.2/manifests/metallb.yaml \
    24. | sed -e "s|namespace: metallb-system|namespace: kube-system|g" | kubectl apply -f -

安装持久卷供应程序

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

  • 创建所需的目录

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

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

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

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

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

检查集群工作状态

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

  • 查看节点状态

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

    1. kubectl get pods -A
    1. kubectl top pods -A

附加内容

同步所需镜像

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

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

  • 同步kubelet所需镜像

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

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

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

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

    该脚本有两种使用方法。

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

    1. # 根据需要将`registry.cn-beijing.aliyuncs.com/choral-k8s/`替换为私有镜像仓库地址。
    2. # 同步metrics server所需镜像
    3. docker pull k8s.gcr.io/metrics-server/metrics-server:v0.5.0
    4. docker tag k8s.gcr.io/metrics-server/metrics-server:v0.5.0 registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
    5. docker push registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
    6. docker rmi k8s.gcr.io/metrics-server/metrics-server:v0.5.0
    7. docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/metrics-server:v0.5.0
    8. # 同步flannel所需镜像
    9. docker pull quay.io/coreos/flannel:v0.14.0
    10. docker tag quay.io/coreos/flannel:v0.14.0 registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
    11. docker push registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0
    12. docker rmi quay.io/coreos/flannel:v0.14.0
    13. docker rmi registry.cn-beijing.aliyuncs.com/choral-k8s/flannel:v0.14.0

参考资料

Kubernetes集群部署笔记的更多相关文章

  1. kubernetes集群部署

    鉴于Docker如此火爆,Google推出kubernetes管理docker集群,不少人估计会进行尝试.kubernetes得到了很多大公司的支持,kubernetes集群部署工具也集成了gce,c ...

  2. Kubernetes集群部署关键知识总结

    Kubernetes集群部署需要安装的组件东西很多,过程复杂,对服务器环境要求很苛刻,最好是能连外网的环境下安装,有些组件还需要连google服务器下载,这一点一般很难满足,因此最好是能提前下载好准备 ...

  3. RocketMQ 简单梳理 及 集群部署笔记【转】

    一.RocketMQ 基础知识介绍Apache RocketMQ是阿里开源的一款高性能.高吞吐量.队列模型的消息中间件的分布式消息中间件. 上图是一个典型的消息中间件收发消息的模型,RocketMQ也 ...

  4. 基于Kubernetes集群部署skyDNS服务

    目录贴:Kubernetes学习系列 在之前几篇文章的基础,(Centos7部署Kubernetes集群.基于kubernetes集群部署DashBoard.为Kubernetes集群部署本地镜像仓库 ...

  5. 为Kubernetes集群部署本地镜像仓库

    目录贴:Kubernetes学习系列 经过之前两篇文章:Centos7部署Kubernetes集群.基于kubernetes集群部署DashBoard,我们基本上已经能够在k8s的集群上部署一个应用了 ...

  6. Kubernetes 集群部署(2) -- Etcd 集群

    Kubenetes 集群部署规划: 192.168.137.81  Master 192.168.137.82  Node 192.168.137.83  Node 以下在 Master 节点操作. ...

  7. Gitlab CI 集成 Kubernetes 集群部署 Spring Boot 项目

    在上一篇博客中,我们成功将 Gitlab CI 部署到了 Docker 中去,成功创建了 Gitlab CI Pipline 来执行 CI/CD 任务.那么这篇文章我们更进一步,将它集成到 K8s 集 ...

  8. Docker学习-Kubernetes - 集群部署

    Docker学习 Docker学习-VMware Workstation 本地多台虚拟机互通,主机网络互通搭建 Docker学习-Docker搭建Consul集群 Docker学习-简单的私有Dock ...

  9. kubernetes 集群部署

    kubernetes 集群部署 环境JiaoJiao_Centos7-1(152.112) 192.168.152.112JiaoJiao_Centos7-2(152.113) 192.168.152 ...

随机推荐

  1. 最大网络流dinic

    初始化flow(最大流量)为INF(极大值),建边(正向弧和反向弧) bfs寻找增广路看看有没有路,顺便进行深度标号.如果没有路直接结束输出flow. 如果有,我们按照深度dfs.dfs时注意在给正向 ...

  2. C++第四十一篇 -- 安装成功的第一个驱动文件

    参考链接:https://blog.csdn.net/LEON1741/article/details/87291839 一.新建工程 二.写一个Driver.c #include <ntddk ...

  3. 入门Kubernetes-数据存储

    一.Volume介绍: 在k8s中Pod的生命周期可能很短,会被频繁地销毁和创建.容器销毁时,保存在容器内部文件系统中的数据都会被清除. 为了持久化保存容器数据,k8s 提供了卷(Volume)的抽象 ...

  4. Linux从头学05-系统启动过程中的几个神秘地址,你知道是什么意思吗?

    作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...

  5. 18Oracle入门

    1 Oracle的服务 Oracle的监听服务:OralceOraDB12Home1TNSListener 需要通过程序链接数据库进行开发的时候,此服务必须打开,如果只是在本机使用,此服务可不启动 O ...

  6. Distance Queries 距离咨询 (LCA倍增模板)

    农夫约翰有N(2<=N<=40000)个农场,标号1到N.M(2<=M<=40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地 ...

  7. Java 线程安全的实现方法

    概述 在软件业发展的初期,程序编写都是以算法为核心的,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间中的客体, 程序代码则用于处理这些数据,这种思维方式直接站在计算机的角度去抽象问题和 ...

  8. Python 列表解析式竟然支持异步?

    PEP原文:https://www.python.org/dev/peps/pep-0530 PEP标题:PEP 530 -- Asynchronous Comprehensions PEP作者:Yu ...

  9. 如何读懂Framework源码?如何从应用深入到Framework?

    如何读懂Framework源码? 首先,我也是一个应用层开发者,我想大部分有"如何读懂Framework源码?"这个疑问的,应该大都是应用层开发. 那对于我们来讲,读源码最大的问题 ...

  10. PrismWPF网盘

    技术点 文件分片上传与下载 Vue 正在努力中.... 客户端 采用 WPF:Net5+Prism8+RestSharp 客户端基本结构如下 模块说明 Model: 主要放置Prism模块 ZFile ...