一、k8s基础

1.概述

简单来说,K8s 是一个容器编排平台。它的核心作用可以概括为一句话:帮你自动部署、扩展和管理海量的容器化应用。

2.特点

kubernetes 的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。它的目的就是实现资源管理的自动化,主要提供了如下的主要功能:

  • 自我修复:一旦某一个容器崩溃,能够在 1 秒钟左右迅速启动新的容器
  • 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
  • 服务发现:服务可以通过自动发现的形式找到他所依赖的服务
  • 负载均衡:如果一个服务启动了多个容器,能够自动实现请求的负载均衡
  • 版本回退:如果发现新发布的程序版本有问题,可以立刻回退到原来的版本
  • 存储编排:可以根据自身的需求自动创建存储卷

3.架构

K8s 的架构为 Master / Node 模式

K8s 集群至少需要一个 master 节点和一个 node 节点,master 节点为控制节点,负责整个集群的管理与控制,主节点主要用于暴露 API、调度任务和管理 node 节点。而工作节点负责运行各种任务容器。

在高可用的 K8s 集群中,会包含多个 Master 节点与 Node 节点,再通过两地三中心的部署方式,以保证其高可用性,即使部分节点宕机,也不会影响整个集群的正常运行。

  1. 一个 nginx 服务的安装请求会首先被发送到 master 节点的 apiServer 组件
  2. apiServer 组件会调用 scheduler 组件来决定到底应该把这个服务安装到哪个 node 节点上
  3. 在此时,它会从 etcd 中读取各个 node 节点的信息,然后按照一定的算法进行选择,并将结果告知 apiServer
  4. apiServer 调用 controller-manager 去调度 Node 节点安装 nginx 服务
  5. kubelet 接收到指令后,会通知 docker,然后由 docker 来启动一个 nginx 的 pod
  6. pod 是 kubernetes 的最小操作单元,容器必须跑在 pod 中至此
  7. 一个 nginx 服务就运行了,如果需要访问 nginx,就需要通过 kube-proxy 来对 pod 产生访问的代理这样,外界用户就可以访问集群中的 nginx 服务了

4.相关概念

  • Master:集群控制节点,每个集群需要至少一个 master 节点负责集群的管控
  • Node:工作负载节点,由 master 分配容器到这些 node 工作节点上,然后 node 节点上的 docker 负责容器的运行
  • Pod:kubernetes 的最小控制单元,容器都是运行在 pod 中的,一个 pod 中可以有 1 个或者多个容器 
  • Controller:控制器,通过他来实现对pod的管理,比如启动pod、停止pod、一个pod中可以有多个容器(k8s通常不会直接创建pod,而是会先创建一个Deployment控制器来管理pod)
  • Service:pod 对外服务的统一入口,下面可以维护者同一类的多个 pod
  • Label:标签,用于对 pod 进行分类,同一类 pod 会拥有相同的标签
  • NameSpace:命名空间,用来逻辑隔离 pod 的运行环境(在一个node节点里面可以有多个pod而pod也一个通过命令空间进行分组进行隔离运行环境)

二、k8s搭建

1.kubeadm搭建k8s

Kubernetes集群主要两种方式:kubeadm、二进制包

2.kubeadm 部署方式介绍

kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具,这个工具能通过两条指令完成一个 kubernetes 集群的部署:

  • 创建一个 Master 节点 kubeadm init
  • 将 Node 节点加入到当前集群中 $ kubeadm join

3.安装要求

在开始之前,部署 Kubernetes 集群机器需要满足以下几个条件:

  • 一台或多台机器,操作系统 CentOS7.x-86_x64
  • 硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 30GB 或更多
  • 集群中所有机器之间网络互通
  • 可以访问外网,需要拉取镜像
  • 禁止 swap 分区

4.环境初始化

环境准备

初始化环境,关闭防火墙,安装yum源拓展源,常用软件

1.为方便集群节点间的直接调用,在这个配置一下主机名解析
hostnamectl set-hostname master01
su - root

2.如果是动态ip地址当master节点的ip地址改变会导致集群不可用,因此需要修改为静态ip地址
cat <<EOF > /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
IPV6INIT=no
NAME=ens33
DEVICE=ens33
ONBOOT=yes
# ip地址,不同主机修改成不同IP
IPADDR=192.168.22.156
NETMASK=255.255.255.0
GATEWAY=192.168.217.2
DNS1=114.114.114.114
EOF

3. 时间同步
# kubernetes要求集群中的节点时间必须精确一致,这里使用chronyd服务从网络同步时间

# master配置
yum -y install chrony
vim /etc/chrony.conf
# 注释前面几行的server配置添加下面三行配置
server master01 iburst
allow 192.168.22.0/24
local stratum 10

systemctl enable chronyd.service && systemctl restart chronyd.service
timedatectl set-ntp yes && timedatectl status

# node配置
yum -y install chrony
vim /etc/chrony.conf
server master01 iburst

systemctl enable chronyd && systemctl restart chronyd
chronyc sources

4. 禁用iptable和firewalld服务以及禁用selinux
# kubernetes和docker 在运行的中会产生大量的iptables规则,为了不让系统规则跟它们混淆,直接关闭系统的规则
# selinux是linux系统下的一个安全服务,如果不关闭它,在安装集群中会产生各种各样的奇葩问题
systemctl stop firewalld && systemctl disable firewalld
iptables -L                          # 获取iptables规则信息
iptables -F                          # 关闭iptables过滤规则
iptables -P INPUT ACCEPT
iptables -t nat -F
setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

5. 禁用swap分区
# swap分区指的是虚拟内存分区,它的作用是物理内存使用完,之后将磁盘空间虚拟成内存来使用,启用swap设备会对系统的性能产生非常负面的影响,因此kubernetes要求每个节点都要禁用swap设备,但是如果因为某些原因确实不能关闭swap分区,就需要在集群安装过程中通过明确的参数进行配置说明
# 编辑分区配置文件/etc/fstab,注释掉swap分区一行,注意修改完毕之后需要重启linux服务
vim /etc/fstab
# /dev/mapper/centos-swap swap

6. 修改linux的内核参数,添加网桥过滤和地址转发功能
# 改linux的内核采纳数,添加网桥过滤和地址转发功能
vim /etc/sysctl.d/kubernetes.conf
# 添加如下配置
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

sysctl -p                          # 重新加载配置
modprobe br_netfilter              # 加载网桥过滤模块
lsmod | grep br_netfilter          # 查看网桥过滤模块是否加载成功

7. 配置ipvs功能
# 在Kubernetes中Service有两种带来模型,一种是基于iptables的,一种是基于ipvs的两者比较的话,ipvs的性能明显要高一些,但是如果要使用它,需要手动载入ipvs模块
# 1.安装ipset和ipvsadm
yum install ipset ipvsadm -y

# 2.添加需要加载的模块写入脚本文件
cat <<EOF> /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF

# 3.为脚本添加执行权限
chmod +x /etc/sysconfig/modules/ipvs.modules

# 4.执行脚本文件
/bin/bash /etc/sysconfig/modules/ipvs.modules

# 5.查看对应的模块是否加载成功
lsmod | grep -e ip_vs -e nf_conntrack_ipv4

5.安装docker

# 1. 安装需要的软件包, yum-utils 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils

# 2. 配置阿里云的镜像源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 3. 查看当前镜像源中支持的docker版本
yum list docker-ce --showduplicates

# 4. 安装特定版本的docker-ce,必须指定--setopt=obsoletes=0,否则yum会自动安装更高版本
yum install --setopt=obsoletes=0 docker-ce-20.10.24-3.el7 -y

# 5. 添加docker配置文件
# Docker 在默认情况下使用Vgroup Driver为cgroupfs,而Kubernetes推荐使用systemd来替代cgroupfs
mkdir /etc/docker/
vim /etc/docker/daemon.json
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "registry-mirrors": [
      "https://docker.xuanyuan.me",
      "https://docker.1ms.run",
      "https://docker.m.daocloud.io"
  ]
}

# 6. 启动docker
systemctl daemon-reload
systemctl restart docker && systemctl enable docker && systemctl status docker

6.安装K8S组件

# 1、由于kubernetes的镜像在国外,速度比较慢,这里切换成国内的镜像源
# 2、编辑vim /etc/yum.repos.d/kubernetes.repo,添加下面的配置
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
       http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

# 3、安装kubeadm、kubelet和kubectl(kubelet和kubectl可以不用安装)
yum install kubeadm-1.23.0 kubelet-1.23.0 kubectl-1.23.0 -y
# 检查版本:
kubeadm version

# 4、配置kubelet的cgroup
#编辑vim /etc/sysconfig/kubelet, 添加下面的配置
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"

# 5、设置kubelet开机自启
systemctl enable kubelet

7.准备集群镜像

# 在安装kubernetes集群之前,必须要提前准备好集群需要的镜像,所需镜像可以通过下面命令查看
kubeadm config images list

# 下载镜像
# 此镜像kubernetes的仓库中,由于网络原因,无法连接,下面提供了一种替换方案
vim images.sh

#!/bin/bash

images=(
    kube-apiserver:v1.23.0
    kube-controller-manager:v1.23.0
    kube-scheduler:v1.23.0
    kube-proxy:v1.23.0
    pause:3.6
    etcd:3.5.1-0
    coredns:v1.8.6
)

for imageName in ${images[@]};do
    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
    docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
    docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done

8.集群初始化

下面的操作只需要在master节点上执行即可,注意,在初始化集群的时候,先重启一下系统(主要是让禁用swap分区动作生效)下面是示例

# 初始化Kubernetes集群
kubeadm init \
    --apiserver-advertise-address=192.168.22.156 \
    --image-repository registry.aliyuncs.com/google_containers \
    --kubernetes-version=v1.23.0 \
    --service-cidr=10.96.0.0/12 \
    --pod-network-cidr=10.244.0.0/16

# 创建kubectl认证配置文件
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

初始化集群后就会产生下面一段加入集群的sha256的密文

获取各个组件的状态

kubectl get componentstatus

2.查看各个pod的信息

kubectl get pods -n kube-system

此时最上面的两个网络组件都是Pending状态没有运行,需要安装网络插件

9.安装网络插件

同样只需要在master节点完成

# 3. 使用配置文件启动flannel

# 先拉取需要的yml文件
wget https://raw.githubusercontent.com/flannel-io/flannel/v0.21.5/Documentation/kube-flannel.yml

# 执行安装yml文件之前先拉取一下镜像插件
# 拉取 flannel 插件镜像
docker pull docker.m.daocloud.io/flannel/flannel:v0.21.5
docker tag docker.m.daocloud.io/flannel/flannel:v0.21.5 docker.io/flannel/flannel:v0.21.5

# 拉取 flannel CNI 镜像
docker pull docker.m.daocloud.io/flannel/flannel-cni-plugin:v1.1.2
docker tag docker.m.daocloud.io/flannel/flannel-cni-plugin:v1.1.2 docker.io/flannel/flannel-cni-plugin:v1.1.2

# 安装检测启动
kubectl apply -f kube-flannel.yml
kubectl get ns
kubectl get pods -n kube-flannel
kubectl get pods -n kube-system

10.子节点添加到master节点

讲之前的密文添加到在子节点当中执行

主节点在次查看节点

三、集群测试

1.创建一个nginx服务

kubectl create deployment nginx --image=nginx:latest --replicas=3

2.暴露端口

kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort

3.查看服务

kubectl get services

4.查看pod

kubectl get pods

kubectl get pods -o wide -n default

5.访问测试

curl 10.103.157.22

这里因为之前执行过暴露端口的操作因此可以查看其是在映射在宿主机的那一个端口

kubectl get services

更多推荐