k8s简介,安装,配置,测试

应用部署方式演变

在部署应用程序的方式上,主要经历了三个时代:

  • 传统部署:互联网早期,会直接将应用程序部署在物理机上

    优点:简单,不需要其它技术的参与

    缺点:不能为应用程序定义资源使用边界,很难合理地分配计算资源,而且程序之间容易产生影响

  • 虚拟化部署:可以在一台物理机上运行多个虚拟机,每个虚拟机都是独立的一个环境

    优点:程序环境不会相互产生影响,提供了一定程度的安全性

    缺点:增加了操作系统,浪费了部分资源

  • 容器化部署:与虚拟化类似,但是共享了操作系统

    优点:

    可以保证每个容器拥有自己的文件系统、CPU、内存、进程空间等

    运行应用程序所需要的资源都被容器包装,并和底层基础架构解耦

    容器化的应用程序可以跨云服务商、跨Linux操作系统发行版进行部署

image-20200505183738289

容器化部署方式给带来很多的便利,但是也会出现一些问题,比如说:

  • 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器
  • 当并发访问量变大的时候,怎么样做到横向扩展容器数量

这些容器管理的问题统称为容器编排问题,为了解决这些容器编排问题,就产生了一些容器编排的软件:

  • Swarm:Docker自己的容器编排工具
  • Mesos:Apache的一个资源统一管控的工具,需要和Marathon结合使用
  • Kubernetes:Google开源的的容器编排工具

image-20200524150339551

kubernetes简介

image-20200406232838722

kubernetes,是一个全新的基于容器技术的分布式架构领先方案,是谷歌严格保密十几年的秘密武器----Borg系统的一个开源版本,于2014年9月发布第一个版本,2015年7月发布第一个正式版本。

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

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

......

kubernetes组件

一个kubernetes集群主要是由控制节点(master)工作节点(node)构成,每个节点上都会安装不同的组件。

master:集群的控制平面,负责集群的决策 ( 管理 )

ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制

Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上

ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等

Etcd :负责存储集群中各种资源对象的信息

node:集群的数据平面,负责为容器提供运行环境 ( 干活 )

Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器

KubeProxy : 负责提供集群内部的服务发现和负载均衡

Docker : 负责节点上容器的各种操作

image-20200406184656917

下面,以部署一个nginx服务来说明kubernetes系统各个组件调用关系:

  1. 首先要明确,一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中

  2. 一个nginx服务的安装请求会首先被发送到master节点的apiServer组件

  3. apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上

    在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer

  4. apiServer调用controller-manager去调度Node节点安装nginx服务

  5. kubelet接收到指令后,会通知docker,然后由docker来启动一个nginx的pod

    pod是kubernetes的最小操作单元,容器必须跑在pod中至此,

  6. 一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理

这样,外界用户就可以访问集群中的nginx服务了

kubernetes概念

Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控

Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行

Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等

Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod

Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签

NameSpace:命名空间,用来隔离pod的运行环境

kubernetes集群环境搭建

环境规划

安装方式

Kubernetes 有多种部署方式,目前主流的方式有 kubeadm 、minikube 、二进制包。

  • ① minikube:一个用于快速搭建单节点的 Kubernetes 工具。

  • ② kubeadm:一个用于快速搭建Kubernetes 集群的工具(可以用于生产环境)。

  • ③ 二进制包:从官网上下载每个组件的二进制包,依次去安装(建议生产环境使用)。

集群选择

Kubernetes 集群大致分为两类:一主多从和多主多从。

  • 一主多从:一个 Master 节点和多台 Node 节点,搭建简单,但是有单机故障风险,适合用于测试环境。

  • 多主多从:多台 Master 节点和多台 Node 节点,搭建麻烦,安全性高,适合用于生产环境。

img

为了测试方便,本次搭建的是一主多从类型的集群。

也就是类似这种结构

image-20210609000002940

主机和网络规划

角色 IP地址 操作系统 配置 hostname
Master 192.168.176.100 CentOS 7.9,基础设施服务器 2核CPU,2G内存,50G硬盘 master
Node1 192.168.176.101 CentOS 7.9,基础设施服务器 2核CPU,2G内存,50G硬盘 node1
Node2 192.168.176.102 CentOS 7.9,基础设施服务器 2核CPU,2G内存,50G硬盘 node2
子网掩码 255.255.255.0
网关 192.168.176.2
DNS 223.5.5.5

软件和镜像准备

VMware 虚拟机

链接:https://pan.baidu.com/s/1czVESTWnPXIqLDTxyW0t2Q?pwd=j5do
提取码:j5do

CentOS镜像

相关镜像地址:

https://www.cnblogs.com/shijunxian/p/12864691.html

镜像选择:

https://www.cnblogs.com/shijunxian/archive/2020/05/14/12866010.html

本文所使用镜像:

http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso

CentOS系统安装和配置

语言选择

简体中文

image-20220510141654372

软件选择

基础设施服务器

image-20220510141929280

image-20220510142047131

系统安装位置

image-20220510142230375

网络和主机名

打开配置

image-20220510142413378

配置自动连接和所有用户可连接

image-20220510142504169

配置IPV4 将自动获取改为静态

image-20220510142906462

添加ip

由于虚拟机是NAT模式的,我们需要知道我们的虚拟机NAT模式网卡在哪个网段,打开编辑->虚拟网络编辑器

image-20220510143147166

现在我们知道了虚拟机在哪个网段了,开始编辑IPV4设置

image-20220510144556651

配置主机名

image-20220510144754174

image-20220510145114191

设置root用户密码

这里我设置成root

image-20220510145225992

重新启动和测试

image-20220510145708733

测试

image-20220510145908325

配置没啥问题

查看主机名

hostname
# master

以上为master节点的配置

node节点的安装

node节点的安装可以按照上面的步骤自己配置,但是这样太麻烦了,这里使用VMware 的克隆功能会更方便

参考:https://blog.csdn.net/qq_41125219/article/details/118641132

克隆完成之后需要配置主机名和网络

配置主机名

vi /etc/hostname

image-20220510150805447

:wq保存退出

配置网络

相关命令:

# 查看网卡
ip addr 
# 修改网络配置(最后一个为网卡名称)
vi /etc/sysconfig/network-scripts/ifcfg-ens33 
# 重启网络
service network restart

修改为101

image-20220510151358333

重启一下,重启即可生效,另一个节点也可以按照这个方式即可

系统初始化(所有节点)

由于是多台服务器,不可能说把所有命令在每个会话里面都敲一遍,所以这里就要借助工具了

我用的是这个:http://www.hostbuf.com/t/988.html

检查操作系统版本

# 检查操作系统的版本(要求操作系统的版本至少在7.5以上)
cat /etc/redhat-release

image-20220510162254327

关闭防火墙禁止防火墙开机启动

# 关闭防火墙
systemctl stop firewalld
# 禁止防火墙开机启动
systemctl disable firewalld

直接发送到全部会话即可

image-20220510162745386

禁用iptables

kubernetes和docker在运行中会产生大量的iptables规则,为了不让系统规则跟她们混淆,直接关闭系统的规则

# 关闭iptables
systemctl stop firewalld
# 禁止iptables开机启动
systemctl disable firewalld

image-20220510175307108

主机名解析

为了方便后面集群节点间的直接调用,需要配置一下主机名解析,企业中推荐使用内部的DNS服务器。

# 同时修改三台服务器的/etc/hosts
cat >> /etc/hosts << EOF
192.168.176.100 master
192.168.176.101 node1
192.168.176.102 node2
EOF

image-20220510163707110

测试

image-20220510163809431

能ping通表示配置成功

时间同步

kubernetes要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步

这里直接使用chronyd服务从网络同步时间

企业中建议配置内部的时间同步服务器

# 启动服务
systemctl start chronyd
# 设置服务开机自启
systemctl enable chronyd
# 使用date命令验证时间
date

image-20220510174809919

image-20220510175412066

禁用selinux

selinux是linux系统下的一个安全服务,如果不关闭它,在安装集群中会产生各种各样的奇葩问题

# 查看selinux是否开启
getenforce
# 临时关闭selinux,重启之后,无效
setenforce 0
# 永久关闭selinux,需要重启

# 方式一 vi编辑
# 编辑 /etc/selinux/config 文件,修改SELINUX的值为disabled
vi /etc/selinux/config
# 注意修改完毕之后需要重启linux服务
SELINUX=disabled

# 方式二 临时关闭并修改文件内容
setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

# 查看
 cat /etc/selinux/config

image-20220511103200360

关闭swap分区

swap分区是指虚拟内存分区,它的作用实在物理内存使用完之后,将磁盘空间虚拟成内存来使用

启用swap设备会对系统的性能产生非常负面的影响,k8s要求每个节点都禁用swap设备

但是如果是因为某些原因确实不能关闭swap分区,就需要在集群安装过程中通过明确的参数进行配置说明

参考:https://github.com/kubernetes/kubernetes/issues/53533

swap优化设置参考:

https://www.jianshu.com/p/8690d6bcf059

# 永久关闭swap分区,需要重启
sed -ri 's/.*swap.*/#&/' /etc/fstab
# 临时关闭swap分区,重启之后,无效
swapoff -a
# 查看 已存在的swap分区,同时会开启,注意
swapon -s

# 临时关闭加永久关闭
swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab

image-20220511105228615

修改linux的内核参数

在每个节点上将桥接的IPv4流量传递到iptables的链

# 修改linux的内核参数,添加网桥过滤和地址转发功能
cat > /etc/sysctl.d/kubernetes.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
# vm.swappiness的默认值为60,它表示激活交换之前可用内存的百分比。值越低,使用的交换越少
# 0:禁用交换
# 1:不完全禁用交换的最小数量
# 10:当系统中有足够内存时为提高性能而推荐的值
# 100:主动交换
vm.swappiness = 0
EOF

# 由于前面已经禁用了swap这里可以不设置,所以直接写入下面的配置即可
cat > /etc/sysctl.d/kubernetes.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# 重新加载配置
sysctl --system

# 加载网桥过滤模块br_netfilter
modprobe br_netfilter

# 查看是否加载
lsmod | grep br_netfilter

image-20220511112251244

开启并配置ipvs

在kubernetes中service有两种代理模型,一种是基于iptables,另一种是基于ipvs的。ipvs的性能要高于iptables的,但是如果要使用它,需要手动载入ipvs模块。

在每个节点安装ipset和ipvsadm

yum -y install ipset ipvsadm

配置-在所有节点执行如下脚本

创建配置脚本

cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF

为脚本添加执行权限

chmod +x /etc/sysconfig/modules/ipvs.modules

执行脚本

/bin/bash /etc/sysconfig/modules/ipvs.modules

查看对应模块是否加载成功

lsmod | grep -e ipvs -e nf_conntrack_ipv4

image-20220511113236619

安装信息

image-20220511113747276

image-20220511113822549

重启服务器

到现在我们已经初始化了相关的配置,有些配置需要重启才能生效,所以现在重启所有节点

reboot

k8s和docker之间的版本对应关系

docker和k8s之间是有明确的对应关系的

官方文档:

https://github.com/kubernetes/kubernetes/tree/master/CHANGELOG

如k8s的1.18 对应
image-20220511142227571

安装docker

切换镜像源

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo

查看当前镜像源中支持的docker版本

yum list docker-ce --showduplicates

安装指定版本的docker-ce

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

配置docker

# 添加一个配置文件
# Docker 在默认情况下使用Vgroup Driver为cgroupfs,而Kubernetes推荐使用systemd来替代cgroupfs
# 由于默认镜像源默认是国外的,所以将镜像改为国内
# 关于镜像配置参考https://www.cnblogs.com/makalochen/p/14230753.html#%E8%8E%B7%E5%8F%96%E9%95%9C%E5%83%8F%E5%9C%B0%E5%9D%80

mkdir /etc/docker
cat <<EOF> /etc/docker/daemon.json
{
	"exec-opts": ["native.cgroupdriver=systemd"],
	"registry-mirrors": ["https://68o5mgrg.mirror.aliyuncs.com"]
}
EOF

启动docker并设置开机自启动

systemctl enable docker && systemctl start docker

查看docker版本

docker version

image-20220511144609468

image-20220511145929621

安装kubernetes组件

配置kubernetes镜像源

# 由于kubernetes的镜像在国外,速度比较慢,这里切换成国内的镜像源
# 编辑/etc/yum.repos.d/kubernetes.repo,添加下面的配置
# 方式一 直接vi编辑
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgchech=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
			
# 方式二 直接写入
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装kubeadm、kubelet和kubectl

由于版本更新频繁,这里指定版本号部署

yum install --setopt=obsoletes=0 kubeadm-1.17.4-0 kubelet-1.17.4-0 kubectl-1.17.4-0 -y

配置kubelet的cgroup

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

直接使用cat修改

cat > /etc/sysconfig/kubelet << EOF
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
EOF

设置kubelet开机自启

systemctl enable kubelet

image-20220511153429973

image-20220511153605902

修改kube-proxy的configmap默认配置

不更改的话默认为iptables,更改为ipvs

编辑configmap文件

kubectl edit configmap kube-proxy -n kube-system

image-20220517105758683

准备集群镜像源

查看所需镜像

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

kubeadm config images list

下载镜像

# 下载镜像
# 此镜像kubernetes的仓库中,由于网络原因,无法连接,下面提供了一种替换方案
images=(
	kube-apiserver:v1.17.4
	kube-controller-manager:v1.17.4
	kube-scheduler:v1.17.4
	kube-proxy:v1.17.4
	pause:3.1
	etcd:3.4.3-0
	coredns:1.6.5
)

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

查看docker镜像

docker images

image-20220511154618565

集群初始化

master节点启动集群

下面的操作只需要在master节点上执行即可

# 创建集群
# 下面是启动的一些配置,只需要修改一个--apiserver-advertise-address 这个地址为你的master节点的ip地址
kubeadm init \
    --apiserver-advertise-address=192.168.176.100 \
    --kubernetes-version=v1.17.4 \
    --service-cidr=10.96.0.0/12 \
    --pod-network-cidr=10.244.0.0/16
# 创建必要文件
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

主节点执行

image-20220511160022170

注意看它的提示

image-20220511160137035

这也是为啥创建必要文件的原因,下面也说了node节点如何加入集群

node节点加入集群

下面的操作只需要在node节点上执行即可

将集群启动时的命令复制过来到node节点中执行

kubeadm join 192.168.176.100:6443 --token w6sl9b.zn7t2sv278xtnawc \
	--discovery-token-ca-cert-hash sha256:d3d4c028f275ae6b56aa1e2060672994ad022c430c66d9348598fdc3034a0bd2 

加入完成

image-20220511161308807

master查看节点信息

在master节点上执行

kubectl get nodes

image-20220511161341742

可以看到节点已经加入进来了,但是为NotReady状态,这是为什么呢?这是因为它的网络插件没有安装,他们之间无法正常通信

网络插件安装(只在master节点操作)

只在master节点操作即可

kubernetes支持多种网络插件,比如flannel、calico、canal等,任选一种即可,本次选择flannel

下载flannel配置文件

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

image-20220511163600889

如果失败,自行从其他路径下载

如:

https://www.yuque.com/fairy-era/yg511q/hg3u04#149d60be

[可选]修改flannel.yml 中的镜像源

打开flannel.yml文件 你会发现,其中有quay.io的仓库,这个仓库是国外的仓库

可以改成国内的quay-mirror.quay.com

使用配置文件启动fannel

kubectl apply -f kube-flannel.yml

image-20220511170044258

查看节点状态

kubectl get nodes

注意:等待一小会

image-20220511170359937

可以看到已经全部Ready

集群测试

上面已经将k8s集群安装配置完毕

下面在Kubernetes集群中部署一个Nginx程序,测试下集群是否正常工作。

部署Nginx

# 创建一个nginx服务
kubectl create deployment nginx  --image=nginx:1.14-alpine

暴露端口

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

查看服务

kubectl get pod,svc

image-20220511171313779

查看pod

image-20220511171437718

访问

怎么访问呢?可以看到nginx暴露的端口有两个80 和 32644 这两个那个是对外的呢?

32644是对外的

访问:

格式:

http://maser节点ip:暴露的端口

例:

http://192.168.176.100:32644

image-20220511171922256

posted @ 2022-05-11 17:23  makalo  阅读(3357)  评论(0编辑  收藏  举报