Kubernetes——Kubernetes的介绍和使用 kubeadm方式搭建Kubernetes集群

Posted stan Z

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes——Kubernetes的介绍和使用 kubeadm方式搭建Kubernetes集群相关的知识,希望对你有一定的参考价值。

前言

我是根据《Kubernetes in Action》这本书来学习Kubernetes的。只能算是自己的笔记。不能作为学习的参考

Kubernetes的介绍

  • 随着系统可部署组建的数量增长,把它们都管理起来会变得越辣越困难。因此需要一个更好的方式来部署和管理这些组件,并支持基础设施的全球性伸缩。

  • 谷歌于2014年,开放了Kubernetes,一个基于Borg、Omege及其他谷歌内部系统实践的开源系统

  • kubernetes,简称K8s,是用8 代替8 个字符“ubernete”而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes 提供了应用部署,规划,更新,维护的一种机制。

  • 传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。

  • 新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的。

Kubernetes的功能

  • 简化应用程序部署

    • 基于容器对应用运行环境的资源配置要求自动部署应用容器
  • 更好地利用硬件

    • Kubernetes会自动根据应用程序的需求描述和每个节点上的可用资源选择最合适的节点来运行应用程序
  • 健康检查和自修复

    • 当容器失败时,会对容器进行重启

    • 当所部署的Node节点有问题时,会对容器进行重新部署和重新调度

    • 当容器未通过监控检查时,会关闭此容器直到容器正常运行时,才会对外提供服务

    • 如果某个服务器上的应用不响应了,Kubernetes会自动在其它的地方创建一个

  • 自动扩容

    • 通过简单的命令、用户UI 界面或基于CPU 等资源使用情况,对应用容器进行规模扩大或规模剪裁
  • 服务发现

    • 用户不需使用额外的服务发现机制,就能够基于Kubernetes 自身能力实现服务发现和负载均衡
  • 滚动更新

    • 可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新(添加应用的时候,不是加进去就马上可以进行使用,而是需要判断这个添加进去的应用是否能够正常使用)
  • 版本回退

    • 可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退
  • 密钥和配置管理

    • 在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署。
  • 存储编排

    • 自动实现存储系统挂载及应用,特别对有状态应用实现数据持久化非常重要

    • 存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph 等)、公共云存储服务

  • 多处理

    • 提供一次性任务,定时任务;满足批量数据处理和分析的场景

Kubernetes架构组件

在这里插入图片描述

在这里插入图片描述
K8S架构主要包含两部分:Master(主控节点)和 Node(工作节点)

  • Master节点架构图
    在这里插入图片描述
    • Node节点架构图
      在这里插入图片描述

k8s 集群控制节点,对集群进行调度管理,接受集群外用户去集群操作请求;

  • Master:主控节点

    • API Server:集群统一入口,以restful风格进行操作,同时交给etcd存储
      • 提供认证、授权、访问控制、API注册和发现等机制
    • scheduler:节点的调度,选择Node节点应用部署
    • controller-manager:处理集群中常规后台任务,一个资源对应一个控制器
    • etcd:存储系统,用于保存集群中的相关数据
  • Work Node:工作节点

    • Kubelet:Master派到Node节点代表,管理本机容器
      • 一个集群中每个节点上运行的代理,它保证容器都运行在Pod中
      • 负责维护容器的生命周期,同时也负责Volume(CSI) 和 网络(CNI)的管理
    • kube-proxy:提供网络代理,负载均衡等操作
  • 容器运行环境【Container Runtime】

    • 容器运行环境是负责运行容器的软件
    • Kubernetes支持多个容器运行环境:Docker、containerd、cri-o、rktlet以及任何实现Kubernetes CRI (容器运行环境接口) 的软件。
  • fluentd:是一个守护进程,它有助于提升集群层面日志

K8S核心概念

Pod

  • Pod是K8s中最小的单元
  • 一组容器的集合
  • 共享网络【一个Pod中的所有容器共享同一网络】
  • 生命周期是短暂的(服务器重启后,就找不到了)

Volume

  • 声明在Pod容器中可访问的文件目录
  • 可以被挂载到Pod中一个或多个容器指定路径下
  • 支持多种后端存储抽象【本地存储、分布式存储、云存储】

Controller

  • 确保预期的pod副本数量【ReplicaSet】
  • 无状态应用部署【Depoltment】
    • 无状态就是指,不需要依赖于网络或者ip
  • 有状态应用部署【StatefulSet】
    • 有状态需要特定的条件
  • 确保所有的node运行同一个pod 【DaemonSet】
  • 一次性任务和定时任务【Job和CronJob】

Deployment

  • 定义一组Pod副本数目,版本等
  • 通过控制器【Controller】维持Pod数目【自动回复失败的Pod】
  • 通过控制器以指定的策略控制版本【滚动升级、回滚等】

Service

  • 定义一组pod的访问规则
  • Pod的负载均衡,提供一个或多个Pod的稳定访问地址
  • 支持多种方式【ClusterIP、NodePort、LoadBalancer】可以用来组合pod,同时对外提供服务

Label

  • label:标签,用于对象资源查询,筛选

Namespace

  • 命名空间,逻辑隔离

    • 一个集群内部的逻辑隔离机制【鉴权、资源】
    • 每个资源都属于一个namespace
    • 同一个namespace所有资源不能重复
    • 不同namespace可以资源名重复

API

  • 我们通过Kubernetes的API来操作整个集群

  • 同时我们可以通过 kubectl 、ui、curl 最终发送 http + json/yaml 方式的请求给API Server,然后控制整个K8S集群,K8S中所有的资源对象都可以采用 yaml 或 json 格式的文件定义或描述

完整流程

在这里插入图片描述

  • 通过Kubectl提交一个创建RC(Replication Controller )的请求,该请求通过APlserver写入etcd
  • 此时Controller Manager通过API Server的监听资源变化的接口监听到此RC事件
  • 分析之后,发现当前集群中还没有它所对应的Pod实例
  • 于是根据RC里的Pod模板定义一个生成Pod对象,通过APIServer写入etcd
  • 此事件被Scheduler发现,它立即执行执行一个复杂的调度流程,为这个新的Pod选定一个落户的Node,然后通过API Server讲这一结果写入etcd中
  • 目标Node上运行的Kubelet进程通过APiserver监测到这个"新生的Pod.并按照它的定义,启动该Pod并任劳任怨地负责它的下半生,直到Pod的生命结束
  • 随后,我们通过Kubectl提交一个新的映射到该Pod的Service的创建请求
  • ControllerManager通过Label标签查询到关联的Pod实例,然后生成Service的Endpoints信息,并通过APIServer写入到etod中,
  • 接下来,所有Node上运行的Proxy进程通过APIServer查询并监听Service对象与其对应的Endponts信息,建立一个软件方式的负载均衡器来实现Service访问到后端Pod的流量转发功能

一些解释

  • Replication Controller(简称rc)用来管理Pod的副本,保证集群中存在指定数量的Pod副本。集群中副本的数量大于指定数量,则会停止指定数量之外的多余容器数量,反之,则会启动少于指定数量个数的容器,保证数量不变。Replication Controller是实现弹性伸缩、动态扩容和滚动升级的核心。
  • Controller Manager 是集群内部的管理控制中心,负责集群内的Node,Pod副本,服务端点(endpoint),命名空间(namespace)等的管理,当某个Node意外宕机,CM会及时发现此故障并执行自动化修复流程,确保集群始终处于预期的工作状态。
  • etcd被形容为Kubernetes集群的大脑,是 Kubernetes的关键组件,因为它存储了集群的整个状态:其配置,规格以及运行中的工作负载的状态。etcd用作服务发现的后端,并存储集群的状态及其配置
  • Scheduler是容器调度器。kube-scheduler是Kubernetes中的关键模块,扮演管家的角色遵从一套机制为Pod提供调度服务

开始使用Kubernetes

准备环境

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

  • 一台或多台机器,操作系统 CentOS7.x-86_x64
  • 硬件配置:4GB内存或更多内存,2个CPU或更多CPU,硬盘30GB或更多【注意master需要两核】
  • 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
  • 禁止swap分区
服务器角色ip
k8s master192.168.188.88
k8s node1192.168.188.89
k8s node2192.168.188.90
开始在每台机器上执行下面的命令
因为我是购买阿里云服务器来进行实验 因此只需配置安全组

关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

关闭selinux
# 永久关闭
sed -i 's/enforcing/disabled/' /etc/selinux/config  
# 临时关闭
setenforce 0  

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

# 根据规划设置主机名【master节点上操作】
hostnamectl set-hostname master
# 根据规划设置主机名【node1节点操作】
hostnamectl set-hostname node1
# 根据规划设置主机名【node2节点操作】
hostnamectl set-hostname node2

添加ip到hosts
cat >> /etc/hosts << EOF
192.168.188.88 master
192.168.188.89 node1
192.168.188.90 node2
EOF

验证
[root@master ~]# cat /etc/hosts
::1	localhost	localhost.localdomain	localhost6	localhost6.localdomain6
127.0.0.1	localhost	localhost.localdomain	localhost4	localhost4.localdomain4

192.168.188.88	kubernetes	kubernetes

192.168.188.88 master
192.168.188.89 node1
192.168.188.90 node2


将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 生效
sysctl --system  

# 时间同步
yum install ntpdate -y

ntpdate time.windows.com

安装Docker、kubeadm、kubelet

所有节点安装Docker、kubeadm、kubelet,Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker

安装docker

首先配置一下Docker的阿里yum源
安装需要的安装包
yum install -y yum-utils

设置镜像仓库
我们用阿里云

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

更新yum软件包索引
yum makecache fast

安装docker	docker-ce 社区
yum -y install docker-ce

查看版本
docker version

设置开机启动
systemctl enable docker --now

配置docker的镜像源
mkdir -p /etc/docker

这个是我自己阿里云的加速 每个人都不一样 可以去阿里云官方查看

tee /etc/docker/daemon.json <<-EOF
 {
   "registry-mirrors": ["https://m0rsqupc.mirror.aliyuncs.com"]
 }
EOF

验证
[root@master ~]# cat /etc/docker/daemon.json 
 {
   "registry-mirrors": ["https://m0rsqupc.mirror.aliyuncs.com"]
 }

然后重启docker
systemctl restart docker

安装

添加kubernetes软件源

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


安装kubelet、kubeadm、kubectl,同时指定版本

yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0

systemctl enable kubelet --now

部署Kubernetes Master(master节点)

在 192.168.188.88 执行,也就是master节点

kubeadm init --apiserver-advertise-address=192.168.188.88 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.96.0.0/12  --pod-network-cidr=10.244.0.0/16

由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址,(执行上述命令会比较慢,因为后台其实已经在拉取镜像了)
我们 docker images 命令即可查看已经拉取的镜像

在这里插入图片描述
表示kubernetes的镜像已经安装成功
在这里插入图片描述
下面红色圈出来的部分 是下面加入从节点需要使用的命令

使用kubectl工具
mkdir -p $HOME/.kube

cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

chown $(id -u):$(id -g) $HOME/.kube/config

查看运行的节点
kubectl get nodes

[root@master .kube]# kubectl get nodes
NAME     STATUS     ROLES    AGE    VERSION
master   NotReady   master   8m4s   v1.18.0

目前有一个master节点已经运行了,但是还处于未准备状态

加入Kubernetes Node(Slave节点)

需要到 node1 和 node2服务器,向集群添加新节点

执行在kubeadm init输出的kubeadm join命令

以下的命令是在master初始化完成后,每个人的都不一样!!!需要复制自己生成的

kubeadm join 192.168.188.88:6443 --token klosch.hwdnms0hh3l0gky5 \\
    --discovery-token-ca-cert-hash sha256:d691cf804ca0bee62a9b319999435ce52d2ef1cf134da13a3a7c9a618bbb1788 

如果找不到这串命令
可用手动生成
kubeadm token create --print-join-command

当我们把两个节点都加入进来后,我们就可以去Master节点 查看
kubectl get node

[root@master .kube]# kubectl get node
NAME     STATUS     ROLES    AGE   VERSION
master   NotReady   master   14m   v1.18.0
node1    NotReady   <none>   64s   v1.18.0
node2    NotReady   <none>   61s   v1.18.0

发现从节点已经加入,但状态仍然是没准备好

部署CNI网络插件

上面的状态还是NotReady,下面我们需要网络插件,来进行联网访问

flannel网络的官方github地址为 链接

在官方文档中有对使用那个flannel的配置有说明,所以我们按照如下指示来安装flannel网络插件

下载kube-flannel.yml

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

拉取flannel镜像到本地

  • 由于我们无法直接下载官方提供的镜像,所以我们去阿里云的镜像服务中使用其他用户转存的flannel镜像,在这里我就使用了阿里云用户公开镜像中的 k8sos/flannel 这个镜像,由于kube-flannel.yml中使用的镜像是 v0.13.1-rc2 版本,所以我们也从阿里云上下载了 k8sos/flannel:v0.13.1-rc2版本

  • 阿里云镜像服务地址: 阿里云镜像 选择镜像搜索,输入关键字“k8sos/flannel” 进行搜索,即可搜索到。

  • 然后使用docker pull 将镜像拉取下来

# 在我写这篇文章时该镜像的公网地址如下,如果你在使用时无法通过该公网地址拉取镜像,请去阿里云获取最新镜像地址
docker pull registry.cn-hangzhou.aliyuncs.com/k8sos/flannel:v0.13.1-rc2

修改kube-flannel.yml

镜像拉取本地后,修改kube-flannel.yml将里面使用的官方镜像的名字改为自己拉取的镜像名称

# 查看镜像拉取到本地后的名称
docker images | grep flannel

# 输出 
# registry.cn-hangzhou.aliyuncs.com/k8sos/flannel      v0.13.1-rc2   dee1cac4dd20   3 weeks ago     64.3MB

从上面输出可以看出该镜像在我本地服务器的名称为 registry.cn-hangzhou.aliyuncs.com/k8sos/flannel

修改 kube-flannel.yml 将其中的 “image: quay.io/coreos/flannel:v0.13.1-rc2” 修改为 “image: registry.cn-hangzhou.aliyuncs.com/k8sos/flannel:v0.13.1-rc2”

应用flannel网络
使用 kubectl apply 命令应用网络

# -f 后面指定kube-flannel.yml的文件路径
kubectl apply -f ./kube-flannel.yml

在应用网络之后,我们就可以查看一下,flannel 的pod是否启动成功,在我的服务器上执行如下命令效果如下,代码flannel已经应用成功

kubectl get pod -n kube-system | grep flannel

[root@master ~]# kubectl get pod -n kube-system | grep flannel
kube-flannel-ds-2fjc2            1/1     Running   0          16m
kube-flannel-ds-b6l9f            1/1     Running   0          16m
kube-flannel-ds-znj8f            1/1     Running   0          16m

查看所有节点
kubectl get nodes

[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   38m   v1.18.0
node1    Ready    <none>   25m   v1.18.0
node2    Ready    <none>   25m   v1.18.0

所有状态已经是Ready了

如果上述操作完成后,还存在某个节点处于NotReady状态,可以在Master将该节点删除

master节点将该节点删除

kubectl drain node1 --delete-local-data --force --ignore-daemonsets

kubectl delete node node1
 
# 然后到k8snode1节点进行重置
 kubeadm reset
# 重置完后在加入
kubeadm join 192.168.188.88:6443 --token klosch.hwdnms0hh3l0gky5 \\
    --discovery-token-ca-cert-hash sha256:d691cf804ca0bee62a9b319999435ce52d2ef1cf134da13a3a7c9a618bbb1788

测试kubernetes集群

我们都知道K8S是容器化技术,它可以联网去下载镜像,用容器的方式进行启动

在Kubernetes集群中创建一个pod,验证是否正常运行:

下载nginx 会联网拉取nginx镜像
kubectl create deployment nginx --image=nginx

查看状态
kubectl get pod

[root@master ~]# kubectl get pod
NAME                    READY   STATUS              RESTARTS   AGE
nginx-f89759699-brsx7   0/1     ContainerCreating   0          8s
[root@master ~]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
nginx-f89759699-brsx7   1/1     Running   0          47s

pod状态显示Running 说明成功运行

下面我们就需要将端口暴露出去,让其它外界能够访问

暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort

查看一下对外的端口
kubectl get pod,svc

[root@master ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed
[root@master ~]# kubectl get pod,svc
NAME                        READY   STATUS    RESTARTS   AGE
pod/nginx-f89759699-brsx7   1/1     Running   0          118s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        44m
service/nginx        NodePort    10.100.38.185   <none>        80:30844/TCP   5s

能够看到,我们已经成功暴露了 80端口 到 30844上

阿里云安全组上打开30844端口
通过浏览器访问主节点ip+端口
在这里插入图片描述
访问两个从节点+端口
在这里插入图片描述
在这里插入图片描述

运行kubia应用

拉取作者写的kubia镜像
kubectl run kubia --image=luksa/kubia --port=8080 

创建一个外部的负载均衡,可用通过负载均衡的公共IP访问pod
kubectl expose pod kubia --type=LoadBalancer

扩容 三个副本
kubectl scale deploy kubia-deployment --replicas 3

浏览器访问
在这里插入图片描述

[root@master ~]# kubectl get svc
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP          105m
kubia-http   LoadBalancer   10.104.90.190   <pending>     8080:32580/TCP   2m26s
nginx        NodePort       10.100.38.185   <none>        80:30844/TCP     61m

实现负载均衡
[root@master ~]# curl 10.104.90.190:8080
You've hit kubia-6c68d68756-zx455
[root@master ~]# curl 10.104.90.190:8080
You've hit kubia-6c68d68756-bnsjp
[root@master ~]# curl 10.104.90.190:8080
You've hit kubia-6c68d68756-zx455
[root@master ~]# curl 10.104.90.190:8080
You've hit kubia-6c68d68756-bnsjp
[root@master ~]# curl 10.104.90.190:8080
You've hit kubia-6c68d68756-l5l5s

以上是关于Kubernetes——Kubernetes的介绍和使用 kubeadm方式搭建Kubernetes集群的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes-Service介绍-服务发现

01-Kubernetes 组件介绍

KUBERNETES01_概述特征介绍组织架构图动画演示

KUBERNETES01_概述特征介绍组织架构图动画演示

Kubernetes基础自学系列 | Kubernetes组件介绍

Kubernetes in Action 笔记 —— Kubernetes 介绍