基于 centos7 搭建 kubernetes 集群

1,301 阅读10分钟

Kubernetes 是什么?

Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。
名称 Kubernetes 源于希腊语,意为“舵手”或“飞行员”。Google 在 2014 年开源了 Kubernetes 项目。 Kubernetes 建立在 Google 在大规模运行生产工作负载方面拥有十几年的经验 的基础上,结合了社区中最好的想法和实践。

让我们回顾一下容器时代的演化进程

image.png
传统部署时代(Traditional Deployment):
早期,各个组织机构在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界,这会导致资源分配问题。 例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况, 结果可能导致其他应用程序的性能下降。 一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展, 并且维护许多物理服务器的成本很高。

虚拟化部署时代(Virtualized Deployment):
作为解决方案,引入了虚拟化。虚拟化技术允许你在单个物理服务器的 CPU 上运行多个虚拟机(VM)。 虚拟化允许应用程序在 VM 之间隔离,并提供一定程度的安全,因为一个应用程序的信息 不能被另一应用程序随意访问。
虚拟化技术能够更好地利用物理服务器上的资源,并且因为可轻松地添加或更新应用程序 而可以实现更好的可伸缩性,降低硬件成本等等。
每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

容器部署时代(Container Deployment):
容器类似于 VM,但是它们具有被放宽的隔离属性,可以在应用程序之间共享操作系统(OS)。 因此,容器被认为是轻量级的。容器与 VM 类似,具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。
容器因具有许多优势而变得流行起来。下面列出的是容器的一些好处:

  • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
  • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
  • 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像, 从而将应用程序与基础架构分离。
  • 可观察性不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
  • 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
  • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
  • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
  • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
  • 资源隔离:可预测的应用程序性能。
  • 资源利用:高效率和高密度。

K8s架构简介


image.png
在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。
Kubernetes节点有运行应用容器必备的服务,而这些都是受Master的控制。
每次个节点上当然都要运行Docker。Docker来负责所有具体的映像下载和容器运行。
Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

除了核心组件,还有一些推荐的Add-ons:

  • kube-dns负责为整个集群提供DNS服务
  • Ingress Controller为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

使用 kubeadmin 引导集群搭建

在了解了k8s大致架构及基础知识后,我们动手来搭建一套集群环境,具体的k8s各个组件及功能学习大家可以参照k8s官网进行学习,本章只介绍集群搭建。

准备条件

  • 一台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令,本文用 **centos7 **建议一致
  • 本地搭建需要虚拟机环境,推荐使用virtualBox
  • 每台机器 2 GB 或更多的 RAM (如果少于这个数字将会影响你应用的运行内存)
  • 至少2 CPU 核或更多
  • 集群中的所有机器的网络彼此均能相互连接(公网和内网都可以)
  • 节点之中不可以有重复的主机名、MAC 地址或 product_uuid。请参见这里了解更多详细信息。
  • 开启机器上的某些端口。请参见这里 了解更多详细信息。建议直接关闭防火墙。
  • 禁用交换分区。为了保证 kubelet 正常工作,必须 禁用交换分区

安装 Vagrant 和 virtualBox

vagrant是一个工具,用于创建和部署虚拟化开发环境的。拿VirtualBox举例,VirtualBox会开放一个创建虚拟机的接口,Vagrant会利用这个接口创建虚拟机,并且通过Vagrant来管理,配置和自动安装虚拟机。

VagrantFile 脚本文件编写

Vagrant.configure("2") do |config|
#循环创建3台虚拟机
  (1..3).each do |i|
      #定义节点变量
      config.vm.define "k8s-node#{i}" do |node|
      # box配置
      node.vm.box = "mycentos7"
	    # boxurl配置 使用国内源
      node.vm.box_url = "http://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7-x86_64-Vagrant-2004_01.VirtualBox.box"
      # 设置虚拟机的主机名
      node.vm.hostname = "k8s-node#{i}"
      # 设置虚拟机的IP
      node.vm.network "private_network", ip: "192.168.56.#{1+i}"
      # VirtaulBox相关配置
      node.vm.provider "virtualbox" do |v|
          # 设置虚拟机的名称
          v.name = "k8s-node#{i}"
          # 设置虚拟机的内存大小
          v.memory = 4096
          # 设置虚拟机的CPU个数
          v.cpus = 4
      end
    end
  end
end

开始创建虚拟机

然后在vagrantFile 文件所处目录下执行 vagrant up 命令就会创建3台虚拟机,查看virtualBox创建情况
image.png
针对每个节点都可以使用 vagrant ssh <boxName>** **方式来连接,如果需要第三方ssh工具连接,则需要修改sshd配置,并重启服务。如:vagrant ssh k8s-node1

修改 /etc/ssh/sshd_config 改为 yes
image.png
然后重启

systemctl restart sshd
systemctl restart network

安装一些工具包

yum install -y yum-utils device-mapper-persistent-data lvm2

docker安装

配置docker国内源

yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 查看docker-ce数据源信息可以看到有一个 `docker-ce.repo` 的文件
ls /etc/yum.repos.d

安装docker

官网指引docker install

#查询docker版本
yum list docker-ce --showduplicates | sort -r

image.png

#默认最新版
yum install docker-ce docker-ce-cli containerd.io

# 安装指定版本 的VERSION_STRING 从第一个冒号开始 本文是20.10.6版本
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

不同版本的k8s对应的各项依赖版本查看k8s依赖
修改docker镜像仓库源
image.png
启动docker ,并设置为开机启动
systemctl start docker
systemctl enable docker

虚拟机配置

#关闭SELINUX 你必须这么做,直到 kubelet 做出对 SELinux 的支持进行升级为止。
#临时关闭:
setenforce 0          
#永久关闭:修改配置文件 将值改为disabled
vim /etc/selinux/config
SELINUX=disabled

#禁用swap
#临时禁用
swapoff  -a

#永久禁用
vim  /etc/fstab 
# 注释掉挂载swap分区的那行,保存退出

#配置iptables使k8s流量统计更精确
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 重新加载所有配置文件
sysctl --system

集群引导安装

安装kubeadm 、kubectl、kubelet

# 添加 kubernetes 源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

检查添加的源中是否包含我们需要的软件yum list all |grep "^kube"
image.png

版本倾斜政策

版本 v1.21 的kubeadm 工具可以使用版本 v1.21 或 v1.20 的控制平面部署集群。kubeadm v1.21 还可以升级现有的 kubeadm 创建的 v1.20 版本的集群。
由于没有未来,kubeadm CLI v1.21 可能会或可能无法部署 v1.22 集群。
这些资源提供了有关 kubelet 与控制平面以及其他 Kubernetes 组件之间受支持的版本倾斜的更多信息:

yum install kubeadm  kubectl kubelet

#也可以指定版本安装
yum install -y kubeadm-1.21.1-0 kubelet-1.21.1-0 kubectl-1.21.1-0

启动 kubelet 且设置为开机自启动

systemctl start kubelet
systemctl enable kubelet
systemctl status kubelet
# 这时候会如下图所示显示启动失败,因为这时候还没有生成相应的配置文件导致,此时可以先不用管它
# 等kubeadm生成对应的配置文件之后再查看

导出集群化配置文件

# 切换到家目录
cd ~

# 导出配置文件
kubeadm config print init-defaults --kubeconfig ClusterConfiguration > kubeadm.yml

vi kubeadm.yaml

# 然后替换 imageRepository: k8s.gcr.io 国外地址为阿里地址
imageRepository: registry.cn-hangzhou.aliyuncs.com

# 替换之后,查看所需镜像列表
kubeadm config images list --config kubeadm.yml

image.png

拉取k8s集群所需要的镜像

kubeadm config images pull --config kubeadm.yml

coredns 问题

image.png
coredns 镜像可能拉取不到,需要去docker hub 主动拉取对应的版本然后打上tag 标签,删除旧版的镜像就可以了

#拉取docker hub 的 coredns 镜像
docker pull coredns/coredns:1.8.0

#打tag标签 不然不会识别到
docker tag  coredns/coredns:1.8.0 registry.cn-hangzhou.aliyuncs.com/google_containers/coredns/coredns:v1.8.0

#删除docker hub 镜像
docker rmi coredns/coredns:1.8.0

Master 节点初始化

初始化master

kubeadm init --kubernetes-version=1.21.1  \
--apiserver-advertise-address=10.0.2.15  \
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers  \
--pod-network-cidr=10.244.0.0/16

# --kubernetes-version:kubelet 版本信息,可以通过kubelet --version 查看
# --apiserver-advertise-address:填写master节点的IP地址
# --image-repository:填写registry.cn-hangzhou.aliyuncs.com/google_containers;
# k8s默认的镜像是从k8s.gcr.io仓库下拉取镜像的
# 因为k8s地址被墙,所以kubeadm.yml中将镜像仓库替换了
# 然后我们将镜像拉取到了本地之后一样会以阿里地址开头
# 如果这里不指明使用阿里地址下的镜像的话默认会从k8s.gcr.io 下找
# --pod-network-cidr:指定集群中pod的网段

初始化完注意提示操作

# 注意以下操作必须要在家目录操作
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

初始化work节点

# 将master的输出信息,在work节点执行加入
kubeadm join 10.0.2.15:6443 --token 7tjayn.43smtouy6b24nujn \
    --discovery-token-ca-cert-hash sha256:f674da21d422317082a0725c695c4bd16fcf1d94ee7b838c672679dbc5baa1a7
 
# token默认有过期时间
kubeadm token list
# 过期了就重新创建,并重新加入集群
kubeadm token create

安装pod网络插件(所有节点)


image.png
这里使用 flannel 来进行安装,首先下载 flannel.yml ,然后执行 kubectl apply -f kube-flannel.yml 进行安装。
查看pods状态 kubectl get pods -A 为Running有一份部署
image.png

查看节点和pod部署状态

查看节点状态kubectl get nodes -o wide 两个work一个master
image.png
查看kube-system名称空间下的pods状态kubectl get pods -n kube-system -o wide -n 指定名称空间
image.png