1. 应用部署方式演变
1). 传统部署
优点:简单,不需要其他技术的参与;
缺点:不能为应用程序定义资源使用边界,很难合理分配计算资源,而且程序之间容易产生影响;
2). 虚拟化部署
优点:程序环境不会互相影响,提供一定程度的安全性;
缺点:增加了操作系统,浪费了部分资源;
3). 容器化部署(与虚拟化类似,但是共享操作系统)
优点:可以保证每个容器都有自己的文件系统、CPU、内存、进程空间等;运行应用程序需要的资源被容器包装,并和底层基础架构解耦;容器化的应用程序可以跨云服务商、跨Linux操作系统发行版进行部署;
缺点:如:一个容器故障停机,如何让另一个容器立刻启动去替补停机的容器;当并发访问量变大,如果做到横向扩展容器数量;这些问题被称为容器编排问题;
Swarm:Docker公司的容器编排工具;
Mesos:Apache的资源统一管控工具,需要和Marathon结合使用;
Kubernetes:Google开源的容器编排工具;
2. Kubernetes介绍
Kubernetes是全新的基于容器技术的分布式架构领先方案;Kubernetes本质是一组服务器集群,可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。它的目的是实现资源管理的自动化,主要提供以下的功能:
自我修复:一旦某个容器崩溃,可以在1s左右迅速启动新的容器;
弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整;
服务发现:服务可以通过自动发现的形式找到它所依赖的服务;
负载均衡:如果一个服务启动多个容器,能够自动实现请求的负载均衡;
版本回退:发现新发布的程序版本有问题,可以立刻回退到原来的版本;
存储编排:根据容器自身的需求自动创建存储卷;
3. Kubernetes组件
一个Kubernetes集群主要由控制节点master和工作节点node组成,每个节点上都会安装不同的组件;
master:集群的控制平面,负责集群的决策;
ApiServer:资源操作的唯一入口,接收用户的输入命令,提供认证、授权、API注册和发现等机制;
Scheduler:负责集群资源的调度,按照预定的调度策略将Pod调度到相应的node节点上;
ControllerManager:负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等;
Etcd:负责存储集群中各种资源对象的信息;
node:集群的数据平面,负责为容器提供运行环境;
Kubelet:负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器;
KubeProxy:负责提供集群内部的服务发现和负载均衡;
Docker:负责节点上容器的各种操作;

以部署Nginx服务为例,说明Kubernetes各组件的调用关系:
1). 首先明确,一旦Kubernetes环境启动,则会将master和node节点的信息存储到etcd数据库中;
2). 一个Nginx服务的安装请求会首先发送给master节点的apiServer组件;
3). apiServer组件则会调用Scheduler组件来决定将服务安装到哪个node节点;此时,会从etcd中读取个节点的信息,然后按照一定的算法进行选择,将结果告知apiServer;
4). apiServer调用controller-manager去调度Node节点安装Nginx服务;
5). Kubelet接收到指令后,会通知docker,然后由docker启动nginx的pod,pod是kubernetes操作的最小单元,容器必须跑在pod中,一个pod可以包含一个或多个容器;
6). 如果需要访问Nginx,则需要通过kube-proxy来对pod产生访问的代理;
4. Kubernetes概念
Controller:实现对pod的管理,如启动pod、停止pod、伸缩pod等等;
Service:pod对外服务的统一入口,下面可以维护同一类的多个pod,实现负载均衡的效果;
Label:用于对pod进行分类,同一类pod会拥有相同的标签;
Namespace:命名空间,用来隔离pod运行环境;
5. 集群环境规划
集群类型:
Kubernetes集群大体上分为两类:一主多从和多主多从;
一主多从:一台master节点和多台Node节点,搭建简单,存在单机故障风险,适合测试环境;
多主多从:多台master节点和多台Node节点,搭建麻烦,安全性高,适合生产环境;
安装方式:
Kubernetes有多种部署方式,目前主流的方式有kubeadm、minikube、二进制包;
minikube:快速搭建单节点kubernetes工具;
kubeadm:快速搭建kubernetes集群的工具;
二进制包:从官网下载每个组件二进制包,依次去安装;
主机规划:
| Master | Centos | 2颗CPU 2G内存 50G硬盘 | 192.168.75.100 |
| Node1 | Centos | 2颗CPU 2G内存 50G硬盘 | 192.168.75.101 |
| Node2 | Centos | 2颗CPU 2G内存 50G硬盘 | 192.168.75.102 |
6. 环境搭建
6.1 主机安装
6.2 环境初始化
- 检查操作系统的版本:cat /etc/redhat-release;Kubernetes集群要求Centos版本在7.5或以上;
- 主机名解析 编辑/etc/hosts;
- 时间同步 Kubernetes要求集群中的节点时间必须精确一致,使用chronyd从网络同步时间;
systemctl start chronyd;systemctl enable chronyd;
- 禁用iptables和firewalld服务;(Kubernetes和docker在运行中会产生大量的iptables规则,为了不让系统规则跟他们混淆,直接关闭系统的规则;)
systemctl stop firewalld.service; systemctl disable firewalld.service;
systemctl stop iptables; systemctl disable iptables;
- 禁用selinux;/etc/selinux/config文件中,修改SELINUX的值为disabled;修改完毕后重启Linux服务;
- 禁用swap分区;Kubernetes要求每个节点都要禁用swap设备;/etc/fstab,注释掉swap分区一行;
- 修改Linux内核参数;添加网桥过滤和地址转发功能;/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
- 配置ipvs功能;Kubernetes中的service有两种代理模型,一种是基于iptables,一种则是基于ipvs,两者比较ipvs性能更高;ipvs模块需要手动载入;
# 安装ipset和ipvsadm;
#Centos8系统需要切换至Centos-Vault源;
sudo sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-*
sudo sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-* yum install ipset ipvsadm -y # 添加需要加载的模块写入脚本文件 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 EOF # 为脚本文件添加执行权限 chmod +x /etc/sysconfig/modules/ipvs.modules # 执行脚本文件 /bin/bash /etc/sysconfig/modules/ipvs.modules # 查看对应模块是否加载成功 lsmod | grep -e ip_vs -e nf_conntrack
- 重启服务器;
6.3 集群所需组件安装
组件:docker、kubeadm、kubelet、kubectl程序;
安装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=obsoletes=0,否则yum会自动安装更高版本; yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm yum install docker-ce --nobest #为docker添加配置文件 mkdir /etc/docker cat <<EOF > /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": ["https://kn0t2bca.mirror.aliyuncs.com"] } EOF #启动docker | 设置开启自启动 systemctl start docker systemctl enable docker # 检查docker状态和版本 docker version
安装kubernetes;
# 编辑/etc/yum.repos.d/kubernetes.repo,添加如下配置; [kubernetes] name = Kubernetes baseurl = https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg exclude = kube* # 安装kubeadm、kubelet、kubectl; yum install -y conntrack ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git yum install -y --nogpgcheck kubelet kubeadm kubectl --disableexcludes=kubernetes # 配置kubelet的cgroup,编辑/etc/sysconfig/kubelet,添加下面配置; KUBELET_CGROUP_ARGS="--cgroup-driver=systemd" KUBE_PROXY_MODE="ipvs" # 设置kubelet开机自启 systemctl enable kubelet;
安装集群镜像;
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
集群初始化;只需要在master节点上执行;
kubeadm init --kubernetes-version=v1.17.4 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --apiserver-advertise-address=192.168.75.100 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config kubectl get nodes
网络插件的安装;
kubernetes支持的网络插件:flannel、calico、canal;
操作只需要在master节点上执行即可,插件使用的是DaemonSet的控制器,它会在每个节点上运行;
# 获取fannel配置文件; wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 修改文件中quay.io仓库为quay-mirror.qiniu.com # 使用配置文件启动fannel; kubectl apply -f kube-flannel.yml
查看网络插件是否安装成功;
kubectl get nodes;

服务部署测试;
# 部署Nginx kubectl create deployment nginx --image=nginx:1.14-alpine # 暴露端口 kubectl expose deployment nginx --port=80 --type=NodePort # 查看服务状态 kubectl get pod,service
浙公网安备 33010602011771号