一、定义
全称:Kubernetes,因ks之间有8个字母,所以简称k8s。是为容器服务而生的一个可移植容器编排管理工具。
1. 有状态 和 无状态
(1) 有状态 SatefulSet
- 集群节点之间的关系;
- 数据不完全一致;
- 实例之间不对等的关系;
- 依靠外部存储的应用;
- 通过DNS维持身份
(2) 无状态 deployment
- 认为所有pod都是一样的,不具备与其他实例有不同的关系;
- 没有顺序的要求;
- 不用考虑再那个
Node
上运行 - 随意扩容缩容
二、特性
1、自动化上线和回滚:业务高可用、便于升级、降级。
2、存储编排:支持各种分布式存储系统;
3、自动装箱
4、IPv4、IPv6双协议栈:为pod和service分配IPv4和IPv6地址;
5、自我修复:健康检查功能,出了问题、自我修复。
6、服务发现与负载均衡:内置DNS,基于主机名实现机器通信,并实现负载均衡;
7、Secret和配置管理:管理大量的配置文件,隐私密码
8、批量执行:除了服务之外,k8s还可以管理你的批处理和CI工作负载,在期望时替换掉失效的容器。
9、水平扩缩:使用一个简单的命令,一个UI或基于CPU使用情况自动对应用程序进行扩展。
10、为扩展性设计:无需更改上游代码即可扩展你的k8s集群。
三、k8s工作流程图
1、Master
节点
Master节点指的是集群控制节点,管理和控制整个集群,基本上k8s所有控制命令都发给它,它负责具体的执行过程。在Master上主要运行着:
(1)Kubernetes Controller Manager
:k8s中所有资源对象的自动化控制中心,维护管理集群的状态,比如故障检测,自动扩展,滚动更新等;维持副本的期望数目;
(2)Kubernetes Scheduler
:负责资源调度,按照预定的调度策略将Pod调度到相应的机器上。
(3)etcd
:键值对数据库,存储k8s集群所有重要信息。使用时需要为etcd数据提供备份计划
(4)api server
:所有服务访问的统一入口
2、Node
节点
除了master以外的节点被称为Node或者Worker节点,可以在master中使用命令kubectl get nodes
查看集群中node节点。每个Node都会被Master分配一些工作负载(Docker容器),当某个Node宕机时,该节点上的工作负载会被Master自动转移到其他节点上。在Node上主要运行着:
(1)kubelet
:负责Pod对应的容器的创建、启停等任务,同时与Master密切协作,实现集群管理的基本功能以及pod的生命周期。
(2)kube-proxy
:写入规则至IPTABLES、IPVS和负载均衡以及实现服务的映射访问。
(3)docker (Docker Engine)
:Docker引擎,负责本机的容器创建和管理
面试题:pod是如何被创建到目标机器上的原理流程
- 1.在master节点写yaml:描述对容器的运行以及创建pod的要求;
- 2.针对kubectl命令去创建pod的动作发出请求;
- 3.api-server收到请求,是否允许kuberctl命令发来的请求(利用本地https证书,直接写入Kuberctl配置文件的请求被允许后,才会执行);
- 4.api-server将创建pod的信息,记录到etcd中(镜像版本、容器名、是否要暴露端口);
- 5.api-server会通知调度器组件-scheduler准备pod调度;
- 6.scheduler调度->ectd查询部署的pod信息,最后选择出一台合适的node节点部署pod;
- 7.scheduler调度器告诉api-server:决定要将pod部署到哪台node节点上;
- 8.api-server将第7步的信息写入到etcd中;
- 9.api-server通知远程具体node上的kubelet,去读取etcd中的信息,去创建pod
四、Pod类型
创建一个pod,则自动运行一个pause容器,多个容器共享一个Network namespace,在同一个pod各容器的端口必须唯一。
1. 自主式Pod
只要运行了pod,就会启动成功pause,一个pod可以封装>=1个容器,容器共用pause的网络站和存储卷,同一个pod中容器的端口不能冲突
2. 控制器管理的Pod
(1)ReplicationController:用来确保容器应用的副本数始终和用户定义的副本数一致。即如果有容器异常退出,会自动创建新的Pod来替代;异常多出来的容器也会自动回收。
在新版本的Kuberneters中建议使用ReplicaSet来取代Replication,虽然ReplicaSet可以独立使用,但还是建议使用Deployment(不负责pod的创建)来自动管理ReplicaSet,这样就无需担心跟其他机器的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)
(2)Horizontal Pod Autoscaling仅适用于Deployment和ReplicaSet:
在V1版本:仅支持根据Pod的CPU利用率扩缩容
在vlalpha版本:支持根据内存和用户自定义的metric扩缩容(还不是稳定版)
(3)StatefulSet:是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:
稳定的持久化存储
:即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现。
稳定的网络标志
:即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
有序部署,有序扩展
:即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
有序收缩,有序删除
:即从N-1到0
(4)DaemonSet确保全部(或者一些)Node上运行一个Pod的副本。当有Node加入/移除集群时,也会为他们新增/回收一个Pod。删除DaemonSet将会删除它创建的所有Pod
使用DaemonSet的一些典型用法:
运行集群存储daemon,例如在每个Node上运行glusterd、ceph
在每个Node上运行日志收集daemon,例如fluentd、logstash
在每个Node上运行监控daemon,例如Prometheus Node Exporter
(5)Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束
Cron Job管理基于时间的Job,即:
在给定时间点只运行一次
周期性地给定时间点运行
五、网络通讯模式
模式1
Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中
,这在GCE(Goole Compute Engine)里面是现成的网络模型,Kebernetes假定这个网络已经存在。而在私有云搭建Kebernetes集群,就不能假定这个网络已经存在了,我们需要自己实现这个网络假设,将不同节点上的Docker容器之间的互相访问先打通,然后运行Kebernetes。
模式2
- 同一个Pod内的多个容器之间:
lo
- 各Pod之间的通讯:Overlay Network
- Pod与Service之间的通讯:各节点的Iptables规则
名词解释:
Flannel:让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址
。而且它还能在这些IP地址之间建立一个覆盖网络(Overlay Network),通过这个覆盖网络,将数据包原封不动地传递到目标容器内。
ETCD和Flannel之间的关系:
1> 存储管理Flannel可分配的IP地址段资源;
2> 监控ETCD中每个Pod的实际地址,并在内存中建立维护Pod节点路由表;
六、重要组件
k8s安装好,默认有以下8个组件
1. etcd
保存了整个集群的状态(即存储所有节点信息以及节点上部署的容器信息),分布式高性能(key-value)数据库
2. api-server
资源操作的唯一入口,每个组件的请求或响应都经过改组件。提供认证、授权、访问控制、API注册和发现等机制。
3.controller manager
负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- Replication Controller
- Node Controller
- ResourceQuota Controller
- Namespace Controller
- ServiceAccount Controller
- Tocken Controller
- Service Controller
- Endpoints Controller
4.scheduler
负责资源的调度,按照预定的调度策略将Pod调度到响应的Node机器上(即决定容器部署到那个节点组件)
5.kubelet进程
负责维护容器的生命周期,同时也负责Volume和网络的管理;
- 运行在每一个node节点上的 代理软件,脏活累活都是它干;一直监听etcd数据库变化。
- pod管理:kubelet定期从所监听的数据源获取节点上的pod/container的期望状态(运行什么容器、运行的副本数量、网络或者存储如何配置等);
- 容器健康检测:kubelet创建了容器之后还要查看容器是否正常运行,如果容器运行出错,就要根据pod设置的重启策略进行处理。
- 容器监控:kebelet会监控所在节点的资源使用情况,并定时向master报告,资源使用数据都是通过cAdvisor获取的。
6.kubectl-客户端
命令行接口,和api-server交互,用于对k8s集群运行命令。
7.Container runtime
负责镜像管理以及Pod和容器的真正运行(CRI)
8.kube-proxy
负责为Service提供cluster内部的服务发现和负责均衡,主要提供iptables、ipvs规则。
七、重要概念
1.Node概念
Node是Pod真正运行的主机,为了管理Pod,每个Node节点上至少要运行container runtime(比如docker或者rkt)、kubelet和kube-proxy服务。
1.pod概念
- Kubernetes使用pod来管理容器,每个Pod可以包含一个或多个紧密关联的容器。
- Pod是一组紧密关联的容器集合,它们共享进程间通信和Network namespace。
- Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
- Pod是k8s集群中所有业务类型的基础,可以看作运行在k8s集群中的小机器人,不同类型的业务就需要不同类型的小机器人去执行。分别对应的小机器人控制器为Deployment、Job、DaemonSet和StatefulSet。
- 目前k8s中的业务主要分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application)
通俗解释:
pod是在k8s集群中运行部署应用或服务的最小单元,它是可以支持多容器的。
pod的IP是随机变化的,删除pod重建,IP变化。
pod内部有一个根容器。
一个pod内可以有一个或者多个容器。
一个pod内所有容器,共享根容器的网络名称空间、文件系统、进程资源。
一个pod内的容器网络地址,由根容器提供。
八、部署
配置k8s命令补全
操作节点:k8s-master
yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
1.环境准备
- master:集群的master节点,集群的初始化节点,基础配置不低于2c 4g;
- slave:集群的slave节点,可以多点,基础配置不低于1c 2g;
主机名 节点ip 部署组件
# k8s kubeadm 一键自动化,安装k8s集群,安装所有运行需要的组件
k8s-master 10.241.90.64 etcd,kube-apiserver,kube-controller-manager,kubectl,kubeadm,kubelet,kube-proxy,flannel
k8s-node1 10.241.90.65 kubectl,kubelet,kube-proxy,flannel,docker
k8s-node2 10.241.90.66 kubectl,kubelet,kube-proxy,flannel,docker
装网络插件flannel,确保三台机器的跨节点互相通信
2.环境初始化(每个节点)
# 通过以下命令可一次性输入多行内容
cat >>/etc/hosts << 'EOF'
> 10.241.90.64 k8s-master-10
> 10.241.90.65 k8s-node-11
> 10.241.90.66 k8s-node-12
> EOF
# 测试发送2个数据包是否能ping通
cat /etc/
ping -c 2 k8s-master-10
ping -c 2 k8s-node-11
ping -c 2 k8s-node-12
3.防火墙初始化(每个节点)
systemctl stop firewalld NetworkManager
systemctl disable firewalld NetworkManager
sed -ri 's#(SELINUX=).*#\1disable#' /etc/selinux/config
setenforce 0
systemctl disable firewalld && systemctl stop firewalld
getenforce 0
iptables -F
iptables -X
iptables -Z
iptables -P FORWARD ACCEPT
4.关闭swap(每个节点)
k8s默认禁用swap功能
swapoff -a
#方式开机自动挂载swap分区
sed -i '/swap / s/^\(.*\)$/#\1/g' /etc/fstab
5.阿里云源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/CentOS-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
sed -i '/aliyuncs/d' /etc/yum.repos.d/*.repo
yum clean all && yum makecache fast
6.确保ntp网络正确
yum install chrony -y
systemctl start chronyd
systemctl enable chronyd
date
hwclock -w
ping -c 2 www.ynchaoit.cn
7.修改内核参数(master)
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
vm.max_map_count=262144
EOF
modprobe br_netfilter
# 加载读取内核配置文件
sysctl -p /etc/sysctl.d/k8s.conf
8.安装docker基础环境(每个节点)
yum remove docker docker-common docker-selinux docker-engine -y
curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum list docker-ce --showduplicates
yum install docker-ce-19.03.15 docker-ce-cli-19.03.15 -y
#配置docker加速器,以及crgroup驱动,改为k8s官网推荐的systemd,否则初始化会报错
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors":[
"https://ms9glx6x.mirror.aliyuncs.com"],
"exec-opts":["native.cgroupdriver=systemd"]
}
EOF
#启动
systemctl start docker && systemctl enable docker
9.安装k8s初始化工具kubeadm命令(所有节点)
kubelet-1.19.3 # 组件,增删改查
kubeadm-1.19.3 # k8s版本,自动拉取k8s基础组件镜像的一个工具
kubectl-1.19.3 #管理、维护k8s客户端,和服务端交互的一个命令行工具
安装kubeadm工具
#设置阿里云源
curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce
yum clean all && yum makecache
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-e17-x86_64
enabled=1
gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum install kuberlet-1.19.3 kubeadm-1.19.3 kubectl-1.19.3
yum install -y ipvsadm ipset # 使用lvs负载均衡调用集群的负载均衡
ipvsadm -Ln # 查看设置的规则
10.设置kubelet开机启动
该工具用于建立起k8s工具,master,node之间的关系。
#查看kubeadm版本
kubeadm version
#设置kubelet开机启动
systemctl enable kubelet
systemctl enable docker
netstat -tunlp # 查看机器的端口
11.master节点上初始化集群
1.kubeadm部署K8s集群
[root@master ~] kubeadm config images list # 查询k8s集群镜像的清单,可以用docker pull下载
说明:
1.apiserver-advertise-address:集群通告地址,master主机
2.image-repository:指定阿里云镜像仓库
3.kubernetes-version:k8s版本
4.service-cidr:集群内部虚拟网络,Pod统一访问入口
5.pod-network-cidr:Pod网络,与下面部署的CNI网络组件yaml中保持一致。
[root@master ~] kubeadm init \
--apiserver-advertise-address=master主机 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.0 \
--service-cidr=10.244.0.0/16 \
--pod-network-cidr=10.254.0.0/16
2.执行命令完成集群授权
[root@master ~] mkdir -p $HOME/.kube
[root@master ~] sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master ~] sudo chown $(id -u):$(id -g) $HOME/.kube/config
3.验证kubeadm安装
[root@master ~]# kubectl version
[root@master ~]# kubectl get componentstatus
4.获取master的tocken,认证文件tocken存放到/etc/kubernetes/pki/ca.crt
[root@master ~]# cat /etc/kubernetes/pki/ca.crt
[root@master ~]# kubeadm token list 列出当前的token
[root@master ~]# kubeadm token delete srsdkdkkdkdk
[root@master ~]# kubeadm token create --ttl=0 --print-join-command # 创建生命周期为无限的token
[root@master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt |openssl rsa -pubin -outform der |openssl dgst -sha256 -hex
# 获取token_hash
kubectl get nodes # 此命令直接于api-server交互,默认会加载ssl证书,确保安全
kubectl get nodes -owide # 查询更详细的信息
12.加入node到k8s集群中
kubeadm join master_ip:6443 \
--token <token> \
--discovery-token-ca-cert-hash \
sha256:<token ca hash>
kubelet不是以容器的形式容器的,而是以1号进程systemd去启动的kubelet进程。
systemctl status kuberlet
13.k8s故障排查
1、[root@master ~]# kubectl get componentstatuses
报错信息如下:
The connection to the server 10.241.90.64:6443 was refused - did you specify the right host or port?
解决方案:必须先授权再执行命令
[root@master ~]# mkdir -p $HOME/.kube
[root@master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
再执行kubectl get componentstatuses,显示如下kebuadm安装成功。
2.node节点加入master节点,报错信息如下:
解决方案:
1.执行命令:kubeadm reset
2.再执行join命令即可