Kubernetes是Google于2014年开源的一个容器编排工具,使用go语言编写的,是由Google内部已经运行近十年的容器编排工具(Borg系统)衍生而来的。由于docker的横空出世,导致Google原本准备作为秘密武器的容器技术胎死腹中。计划被打乱,容器层面已经痛失良机,慢人一步,只有在编排工具层面下手了,Google当机立断,基于Brog系统的逻辑编写出了Kubernetes,开源并捐给了CNCF(开源社区云原生计算基金会),由于Google近十年的使用经验,所以Kubernetes一出世就横扫了其它编排工具,时至今日,地位依然稳固。
Kubernetes 源于希腊语,意为 “舵手” 或 “飞行员”, 且是英文governor和 cybernetic的词根,简称K8s,是用8代替8个字符“ubernete”而形成的缩写。Google采用这个名字的深意就是:既然你docker把自己定位成驮着集装箱在大海上遨游的鲸鱼,那么我就以Kubernetes掌舵大航海时代的话语权,鲸鱼必须按照我设定的路线巡游。
Kubernetes的一大亮点就是自动化,在Kubernetes的解决方案中,一个服务可以自我扩展、自我诊断,并且容易升级,在收到服务扩容的请求后,Kubernetes会触发调度流程,最终在选定的目标节点上启动相应数量的服务实例副本,这些实例在启动成功后会自动加入负载均衡器中并生效,Kubernetes会定时巡查每个服务的所有实例的可用性,确保服务实例的数量与预期的数量一致,当它发现某个实例不可用时,会自动重启或在其它节点上重建该实例,整个过程无需额外的人工操作。
自愈
: 重新启动失败的容器,在当前节点不可用时,会替换和重新调度其他节点上的容器,同时会对容器进行健康检查,不响应的容器会被中止,并且在容器尚未准备好服务之前不会向客户端广播
弹性伸缩
: 通过监控容器的cpu的负载值,实现容器的弹性伸缩,如果这个平均高于设定值,则增加容器的数量,如果这个平均低于设定值,则减少容器的数量
滚动升级和一键回滚
: Kubernetes 会对应用程序或其配置的更改进行逐渐部署,同时监视应用程序的运行状况,以确保它不会同时终止所有实例。 如果出现问题,可以使用Kubernetes的一键回滚功能,恢复到原先的运行状态
服务的自动发现和负载均衡
: 不需要修改您的应用程序,Kubernetes会自行根据标识去发现服务。同时,Kubernetes 为容器提供了自己的 IP 地址和一组容器的单个 DNS 名称,并可以在它们之间进行负载均衡
Kubernetes 是经典的一对多模型,有一个主要的管理节点Master 和 许多的工作节点Node。当然,Kubernetes 也可以配置多个管理节点,拥有两个以上的管理节点Master被称为高可用。接下来就分别对管理节点Master 和 工作节点Node上的组件进行介绍。
Master组件可以在集群中任何节点上运行。但是为了简单起见,通常在一台虚拟机上启动所有的Master组件,并且不会在此虚拟机器上运行用户容器。同时,集群中的所有控制命令都是传递给Master组件,在Master管理节点上运行,所以kubectl命令在其他Node工作节点上是无法执行的,其Master组件如下所示:
api server
: 负责对外提供Restful的Kubernetes API服务,其他Master组件都通过调用api server提供的Restful接口实现各自的功能,如controller manager就是通过api server来实时监控各个资源的状态的
etcd
: 是 Kubernetes 提供的一个高可用的键值数据库,用于保存集群所有的网络配置和资源对象的状态信息,也就是保存了整个集群的状态信息。数据的变更都是通过api server进行的。整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置,分别是:
1. 网络插件flannel,其它网络插件也需要用到etcd存储网络的配置信息
2. kubernetes本身,包括各种资源对象的状态和元信息配置
scheduler
: 监听新建pod副本信息,并通过调度算法为该pod选择一个最合适的Node节点。会检索到所有符合该pod要求的Node节点,执行pod调度逻辑。调度成功之后,会将pod信息绑定到目标节点上,同时将信息写入到etcd中。一旦绑定,就由Node节点上的kubelet接手pod的接下来的生命周期管理。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node节点组成的列表,输出是pod和一个Node节点的绑定,即将这个pod部署到这个Node节点上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法
controller manager
: 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。每个资源一般都对应有一个控制器,这些controller通过api server实时监控各个资源的状态,controller manager就是负责管理这些控制器的。当有资源因为故障导致状态变化,controller就会尝试将系统由“现有状态”恢复到“期待状态”,保证其下每一个controller所对应的资源始终处于期望状态。比如我们通过api server创建一个pod,当这个pod创建成功后,api server的任务就算完成了。而后面保证pod的状态始终和我们预期的一样的重任就由controller manager去保证了
Node工作节点运行着Master管理节点分配的pod,当一个Node工作节点宕机时,其上的pod会被自动转移到其他Node工作节点上,每一个Node工作节点都安装了Node组件,其Node组件如下所示:
kubelet
: 会监视已分配给Node节点的pod,负责pod的创建、启动、监控、重启和销毁等工作,同时与Master节点密切协作,维护和管理该Node节点上面的所有容器,实现集群管理的基本功能。kubelet会把自己注册到Master节点上,当Node节点纳入集群管理的范围后,kubelet进程就会定时向Master节点上报自身的资源情况。Master节点就掌握着每个Node节点的资源情况,就可以实施高效的资源调度策略。当某个Node节点超过指定时间未上报信息时,Master节点会将该Node节点标记为Not Ready,同时会进行工作负载转移。即Node工作节点通过kubelet与master组件交互,可以理解为kubelet是Master节点在每个Node工作节点上面的代理人(agent)。本质上,它负责使pod的运行状态与期望的状态保持一致
kube-proxy
: 是实现Kubernetes Service的通信以及负载均衡的重要组件,将到service的请求转发到后端的pod上
Container runtime
: 容器运行环境,负责节点容器的创建与管理工作,目前Kubernetes支持docker和rkt两种容器
公共组件:
flannel
: flannel是一个专门为kubernetes定制的网络解决方案,主要解决pod跨主机通信问题安装方式 | 介绍 |
---|---|
源码编译安装 | 大神级别安装,需要安装golang编译环境,同时对golang版本还有要求,可以安装最新版本 |
二进制安装 | 二进制安装又分为 全程手动安装 和 自动安装,自动安装分为 shell、ansible 和 saltstack版,可以安装最新版本,网上安装文档比较多 |
kubeadm安装 | 全自动化官方安装工具,安装比较简单,但是对网络有要求,可以安装最新版本 |
minkube安装 | 并不适合在生产环境下使用,适合开发者学习使用,可以安装最新版本 |
yum安装 | 安装简单,唯一不足的是Kubernetes的版本固定为1.5.2,不能安装最新版本 |
1、需要准备三台Linux虚拟机,其配置如下所示:
主机名称 | 节点名称 | IP地址 | cpu (处理器数量) | 内存 | 系统及内核 |
---|---|---|---|---|---|
k8s-master | master | 192.168.198.145 | 1 | 1G | CentOS7.x,内核版本至少为3.10及以上 |
k8s-node1 | node1 | 192.168.198.146 | 1 | 1G | CentOS7.x,内核版本至少为3.10及以上 |
k8s-node2 | node2 | 192.168.198.147 | 1 | 1G | CentOS7.x,内核版本至少为3.10及以上 |
2、关闭三个节点(Linux虚拟机) 的firewalld防火墙和SELinux
firewalld会影响Docker的网络功能,SELinux是2.6+版本的Linux内核中提供的强制访问控制系统,在很大程度上加强了Linux的安全性,但是它会影响Kubernetes的某些组件功能,所以我们需要在安装部署前将其禁用掉
//1、关闭Firewalld防火墙
systemctl stop firewalld.service // 停止firewalld服务
systemctl disable firewalld.service // 禁止firewalld开机启动
//2、关闭SELinux
vim /etc/sysconfig/selinux //编辑selinux文件
SELINUX=disabled //把文件中的SELINUX=enforcing 改成 SELINUX=disabled 即可
//3、重启linux
reboot
3、修改三个节点(Linux虚拟机) 的主机名称
//1、查看当前主机的主机名称
hostname
//2、修改当前主机的主机名称
hostnamectl set-hostname 主机名称
这里以修改master节点的主机名为例 (node1 和 node2节点与修改master节点的主机名类似,只不过需要把k8s-master 替换为k8s-node1 和 k8s-node2即可)
4、配置三个节点(Linux虚拟机) 的ip地址 与 主机名的映射关系
//1、编辑hosts文件
vim /etc/hosts
//2、配置映射关系
192.168.198.145 k8s-master
192.168.198.146 k8s-node1
192.168.198.147 k8s-node2
这里以配置master节点的ip地址 与 主机名的映射关系为例 (node1 和 node2节点与配置master节点的ip地址 与 主机名的映射关系相同)
5、同步三个节点(Linux虚拟机) 的系统时间 (多个节点之间强烈建议同步时间)
//1、安装ntpdate
yum install -y ntpdate
//2、同步系统时间,ntp1.aliyun.com为阿里的时间(NTP)服务器
ntpdate ntp1.aliyun.com
//3、创建定时任务来自动同步阿里的时间(NTP)服务器
crontab -e
//4、设置每30分钟同步一次时间
0 */30 * * * ? /usr/sbin/ntpdate ntp1.aliyun.com
设置每30分钟同步一次时间
6、更新三个节点(Linux虚拟机) 的yum库
yum -y upgrade //只升级所有包,不升级软件和系统内核
注意:请不要使用yum -y update命令进行更新,该方式不仅会升级所有包,也会升级软件和系统内核,容易导致系统奔溃,同时在生产环境对软件版本和内核版本要求非常精确,所以该方式升级请慎重考虑
节点名称 | 相关组件 |
---|---|
master | etcd、api server、scheduler、controller-manager、flannel 和 docker |
node1 | docker、kubelet、proxy 和 flannel |
node2 | docker、kubelet、proxy 和 flannel |
1、安装etcd组件
yum install -y etcd
2、编辑etcd.conf配置文件
//1、编辑etcd.conf配置文件
vim /etc/etcd/etcd.conf
//2、修改etcd对外提供服务的的ip地址
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
修改为
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
//3、修改etcd对外公告该节点客户端的监听地址
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
修改为
ETCD_ADVERTISE_CLIENT_URLS="http://master节点的ip地址:2379"
3、启动etcd服务,并加入到开机启动
//1、启动etcd服务
systemctl start etcd
//2、设置etcd服务开机启动
systemctl enable etcd
1、安装kubernetes-master组件 (其组件包含apiserver、config、controller-manager 和 scheduler)
yum install -y kubernetes-master
可以看到在安装kubernetes-master组件的同时,会将依赖的kubernetes-client组件一同安装
2、编辑apiserver配置文件
//1、编辑apiserver配置文件
vim /etc/kubernetes/apiserver
//2、修改api server的监听地址
KUBE_API_ADDRESS="--insecure-bind-address=127.0.0.1"
修改为
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
//3、去掉前面的注释
KUBE_API_PORT="--port=8080" //api server监听的端口
KUBELET_PORT="--kubelet-port=10250" //kubelet监听的服务端口
//4、修改etcd的服务地址,如果有多个,请以逗号隔开
KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379"
修改为
KUBE_ETCD_SERVERS="--etcd-servers=http://master节点的ip地址:2379"
//5、去掉认证参数ServiceAccount
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
修改为
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
3、编辑config配置文件
//1、编辑config配置文件
vim /etc/kubernetes/config
//2、修改kubernetes master统一的管理入口ip地址
KUBE_MASTER="--master=http://127.0.0.1:8080"
修改为
KUBE_MASTER="--master=http://master节点的ip地址:8080"
4、启动apiserver、controller-manager 和 scheduler服务,并加入到开机启动
//1、启动apiserver服务,并设置开机启动
systemctl start kube-apiserver
systemctl enable kube-apiserver
//2、启动controller-manager服务,并设置开机启动
systemctl start kube-controller-manager
systemctl enable kube-controller-manager
//3、启动scheduler服务,并设置开机启动
systemctl start kube-scheduler
systemctl enable kube-scheduler
1、安装flannel组件
yum install -y flannel
2、编辑flanneld配置文件
//1、编辑flanneld配置文件
vim /etc/sysconfig/flanneld
//2、修改flanneld服务读取etcd数据库的ip地址
FLANNEL_ETCD_ENDPOINTS="http://127.0.0.1:2379"
修改为
FLANNEL_ETCD_ENDPOINTS="http://master节点的ip地址:2379"
3、分配docker网段
在etcd中添加一个名称为 /automic.io/network/config 的主键,通过该主键设置提供给docker容器使用的网段
etcdctl mk /atomic.io/network/config '{"Network":"172.17.0.0/16"}'
4、启动flanneld服务,并加入到开机启动
//1、启动flanneld服务
systemctl start flanneld
//2、设置开机启动
systemctl enable flanneld
kubectl get componentstatus
//查看flanneld启动服务的进程
ps -ef|grep flanneld
//1、安装epel-release 和 bash-completion
yum install -y epel-release bash-completion
//2、配置kubectl命令自动补全
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
//3、测试配置是否成功
kubectl tab键
由于HarBor镜像仓库需要更多的资源,所以这里我选择是Registry镜像仓库
docker安装:https://blog.csdn.net/qq_39135287/article/details/101012149
registry镜像仓库的搭建:https://blog.csdn.net/qq_39135287/article/details/103307664
如果Master节点服务器配置比较高 或者 电脑配置比较高可以虚拟出多台虚拟机的话,可以尝试搭建 企业级容器镜像仓库HarBor:https://blog.csdn.net/qq_39135287/article/details/104041772
由于接下来在安装Node节点时,kubelet配置文件中的pod-infrastructure镜像 默认是从红帽的registry.access.redhat.com/rhel7镜像仓库进行下载的,速度特别慢,所以我提前准备了其pod-infrastructure镜像,将其上传至Registry镜像仓库,在安装Node节点时,修改其下载的镜像仓库地址
pod-infrastructure镜像下载:https://pan.baidu.com/s/1GWxdGtl3oN4LnisHeOs6HQ 提取码:8xko
1、将下载好的 pod-infrastructure.tar 上传至Linux服务器,并导入pod-infrastructure镜像
docker load -i $(pwd)/pod-infrastructure.tar
注释:$(pwd)是docker支持的获取当前目录路径的方法,与linux的pwd类似
2、将下载好的 pod-infrastructure.tar 上传至Linux服务器,并导入pod-infrastructure镜像
//1、推送镜像至Registry镜像仓库
docker tag registry.access.redhat.com/rhel7/pod-infrastructure:latest registry镜像仓库地址:5000/rhel7/pod-infrastructure:latest
docker push registry镜像仓库地址:5000/rhel7/pod-infrastructure
1、安装kubernetes-node组件 (其组件包含config、kubelet 和 proxy )
yum install -y kubernetes-node
提示:如果在使用yum安装kubernetes-node组件之前,没有安装过docker,将不会出现如下安装失败现象
可以看到最后四行显示如下所示:
Error: docker-ce-cli conflicts with 2:docker-1.13.1-103.git7f2769b.el7.centos.x86_64
Error: docker-ce conflicts with 2:docker-1.13.1-103.git7f2769b.el7.centos.x86_64
You could try using --skip-broken to work around the problem
You could try running: rpm -Va --nofiles --nodigest
提示我们kubernetes-node组件安装失败,原因:在我们使用yum安装kubernetes-node组件时会自动安装docker,而在安装之前虚拟机上已经安装过docker了,所以导致安装kubernetes-node组件失败,按照提示执行rpm -Va --nofiles --nodigest
命令,还是解决不了问题,接下来就来记录一下解决的方法:
(1) 查询已经安装过的docker安装包
yum list installed | grep docker
(2) 删除已经安装过的docker安装包
//1、删除docker-ce-cli.x86_64 (同时还会删除docker-ce.x86_64)
yum remove -y docker-ce-cli.x86_64
//2、删除containerd.io.x86_64
yum remove -y containerd.io.x86_64
(3) 删除已经安装过的docker安装包
//1、删除镜像
rm -rf /var/lib/docker
//2、删除容器
rm -rf /var/run/docker
//3、删除daemon.json配置文件
rm -rf /etc/docker/daemon.json
(4) 再次安装kubernetes-node组件
yum install -y kubernetes-node
可以看到在安装kubernetes-node组件的同时,会将依赖的dcoker和其它组件一同安装
2、编辑kubelet配置文件
//1、编辑kubelet配置文件
vim /etc/kubernetes/kubelet
//2、修改kubelet的监听地址
KUBELET_ADDRESS="--address=127.0.0.1"
修改为
KUBELET_ADDRESS="--address=0.0.0.0"
//3、去掉前面的注释
KUBELET_PORT="--port=10250" //kubelet监听的服务端口
//4、修改主机名
KUBELET_HOSTNAME="--hostname-override=127.0.0.1"
修改为
KUBELET_HOSTNAME="--hostname-override=node节点的ip地址"
//5、指定api server的ip地址
KUBELET_API_SERVER="--api-servers=http://127.0.0.1:8080"
修改为
KUBELET_API_SERVER="--api-servers=http://master节点的ip地址:8080"
//6、修改pod infrastructure container的镜像下载地址
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
修改为
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=192.168.198.145:5000/rhel7/pod-infrastructure:latest"
//7、设置service-node-port的端口范围(默认范围是:30000-32767)
KUBELET_ARGS=""
修改为
KUBELET_ARGS="--service-node-port-range=30000-50000"
3、编辑config配置文件
//1、编辑config配置文件
vim /etc/kubernetes/config
//2、修改kubernetes master统一的管理入口ip地址
KUBE_MASTER="--master=http://127.0.0.1:8080"
修改为
KUBE_MASTER="--master=http://master节点的ip地址:8080"
4、启动kubelet 和 kube-proxy服务,并加入到开机启动
//1、启动kubelet服务,并设置开机启动
systemctl start kubelet
systemctl enable kubelet
//2、启动kube-proxy服务,并设置开机启动
systemctl start kube-proxy
systemctl enable kube-proxy
1、安装flannel组件
yum install -y flannel
2、编辑flanneld配置文件
//1、编辑flanneld配置文件
vim /etc/sysconfig/flanneld
//2、修改flanneld服务读取etcd数据库的ip地址
FLANNEL_ETCD_ENDPOINTS="http://127.0.0.1:2379"
修改为
FLANNEL_ETCD_ENDPOINTS="http://master节点的ip地址:2379"
4、启动flanneld服务,并加入到开机启动
//1、启动flanneld服务
systemctl start flanneld
//2、设置开机启动
systemctl enable flanneld
//1、进入到docker目录下
cd /etc/docker/
//2、编辑daemon.json配置文件
vim daemon.json
//3、配置阿里云镜像加速器 和 添加镜像仓库地址
{
"registry-mirrors": ["你的阿里云镜像加速器地址"],
"insecure-registries": ["master节点的ip地址:镜像仓库端口"]
}
获取阿里云镜像加速地址,注意
:"registry-mirrors"一行末尾有逗号,
//重新加载daemon.json配置文件
systemctl daemon-reload
//重启服务器
systemctl restart docker
kubectl get nodes
/**
* 1、测试之前需要修改 所有Node节点上的 iptables规则,将FORWARD规则(默认为DROP) 改为 ACCEPT,否则Node节点之间将无法进行通信
* 2、修改的iptables规则 再重启Node节点之后将会失效,所以每次重启Node节点都需要重新设置一遍 FORWARD规则
**/
iptables -L -n //查看iptables规则
iptables -P FORWARD ACCEPT //修改FORWARD规则为 ACCEPT
注意
:修改的iptables规则 再重启Node节点之后将会失效,所以每次重启Node节点都需要重新设置一遍 FORWARD规则
以Node1节点为例,修改iptables规则,将FORWARD规则(默认为DROP) 改为 ACCEPT
//1、拉取busybox镜像
docker pull busybox
//2、运行busybox镜像 并进入到容器内部
docker run -it busybox
//3、查看其IP地址
ifconfig
2、执行ping命令,测试Node1节点能否跨主机通信
当看到如下信息时,则表示Node1节点能够跨主机通信
--- 172.17.81.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.645/2.744/6.515 ms
3、执行ping命令,测试Node2节点能否跨主机通信
当看到如下信息时,则表示Node2节点能够跨主机通信
--- 172.17.13.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.501/0.648/0.900 ms
Kubernetes入门到实践系列文章列表:
Kubernetes入门到实践 (一) Kubernetes介绍 与 yum安装Kubernetes集群
Kubernetes入门到实践 (二) Kubeadm安装Kubernetes集群
如果有遇到不懂或者有问题时,可以扫描下方二维码,欢迎进群交流与分享,希望能够跟大家交流学习!