Docker集群Kubernetes开源架构及实践

作者:孙鑫

更新时间: 11 March 2017

版权所有,转载请联系admin@cloudbin.cn

 

Kubernetes介绍

1.1 Kubernetes的定义

Kubernetes是Google开源的容器集群管理系统,实现基于Docker构建容器,利用Kubernetes能很方面管理多台Docker主机中的容器。

1.2 Kubernetes主要功能

  • 将多台Docker主机抽象为一个资源,以集群方式管理容器,包括任务调度、资源管理、弹性伸缩、滚动升级等功能。
  • 使用编排系统(YAML File)快速构建容器集群,提供负载均衡,解决容器直接关联及通信问题
  • 自动管理和修复容器,简单说,比如创建一个集群,里面有十个容器,如果某个容器异常关闭,那么,会尝试重启或重新分配容器,始终保证会有十个容器在运行,反而杀死多余的。

Kubernetes架构:

Kubernetes以RESTFul形式开放接口,用户可操作的REST对象有三个:Pod,Service和RC (Replication).

2.1 Kubernetes的操作对象

2.1.1  Pod

Pod是kubernetes的操作调度的最小单位,,一个Pod可以由一个或多个容器组成。逻辑上表示某种应用的一个实例,比如一个web站点应用由前端、后端及数据库构建而成,这三个组件将运行在各自的容器中,那么我们可以创建包含三个container的Pod。

同一个Pod只能运行在同一个主机上,共享相同的volumes、network、namespace。

Pod运行于Node节点上,若干相关容器的组合。Pod内包含的容器运行在同一宿主机上,使用相同的网络命名空间、IP地址和端口,能够通过localhost进行通。Pod是Kurbernetes进行创建、调度和管理的最小单位,它提供了比容器更高层次的抽象,使得部署和管理更加灵活。

2.1.2  Service

Service定义了一个Pod逻辑集合的抽象资源,是Pod的路由代理抽象,用于解决Pod之间的服务发现问题。因为Pod的运行状态可动态变化(比如切换机器了、缩容过程中被终止了等),所以访问端不能以写死IP的方式去访问该Pod提供的服务。当创建一个Service后,会分配一个Cluster IP,这个IP与定义的端口提供这个Pod集合一个统一的访问接口,并且实现负载均衡。

Service的引入旨在保证Pod的动态变化对访问端透明,访问端只需要知道Service的地址,由Service来提供代理.

2.1.3  Replication Controller(RC)

RC是用来管理Pod的抽象资源。一个RC可以由一个或多个Pod组成,用于解决Pod的扩容缩容问题。通常,分布式应用为了性能或高可用性的考虑,需要复制多份资源,并且根据负载情况动态伸缩。通过Replication Controller,我们可以指定一个应用需要几份复制,Replication Controller将为每份复制创建一个Pod,并且保证实际运行Pod数量总是与该复制数量相等(例如,当前某个Pod宕机时,自动创建新的Pod来替换)。

在RC被创建后,系统会根据定义好的副本数来创建Pod数量。在运行过程中,如果Pod数量小于定义的,就会重启停止的或重新分配Pod,反之则杀死多余的。当然,也可以动态伸缩运行的Pods规模。

 

另外可以看到,Service和Replication Controller只是建立在Pod之上的抽象,最终是要作用于Pod的,那么它们如何跟Pod联系起来呢?这就要引入label的概念:label其实很好理解,就是为Pod加上可用于搜索或关联的一组key/value标签,而Service和Replication Controller正是通过label来与Pod关联的。

如下图所示,有三个Pod都有label为”app=backend”,创建Service和Replication Controller时可以指定同样的label:”app=backend”,再通过label selector机制,就将它们与这三个Pod关联起来了。例如,当有其他frontend Pod访问该Service时,自动会转发到其中的一个backend Pod。

2.2 Kubernetes功能组件

如下图所示是kubernetes官方文档里的kubernetes集群架构图,是个典型的master/slave模型。

2.2.1 Master节点

Master上运行kubernetes的三个组件:

2.2.1.1  apiserver

apiserver作为kubernetes系统的入口,封装了核心对象的增删改查操作,以RESTFul接口方式提供给外部客户和内部组件调用。它维护的REST对象将持久化到etcd(一个分布式强一致性的key/value存储)。

2.2.1.2  Scheduler

Scheduler负责集群的资源调度,为新建的Pod分配机器。这部分工作分出来变成一个组件,意味着可以很方便地替换成其他的调度器。

2.2.1.3  Controller-manager

Controller-manager负责执行各种控制器,目前有两类:

  • endpoint-controller:定期关联Service和Pod(关联信息由endpoint对象维护),保证Service到Pod的映射总是最新的。
  • replication-controller:定期关联Replication Controller和Pod,保证Replication Controller定义的复制数量与实际运行Pod的数量总是一致的。

 

2.2.2  Slave节点

Slave(称作minion)上运行两个组件:

2.2.2.1  kubelet

kubelet负责管控docker容器,如启动/停止、监控运行状态等。它会定期从etcd获取分配到本机的Pod,并根据Pod信息启动或停止相应的容器。同时,它也会接收apiserver的HTTP请求,汇报Pod的运行状态。

2.2.2.2  Proxy

Proxy负责为Pod提供代理。它会定期从etcd获取所有的Service,并根据Service信息创建代理。当某个客户Pod要访问其他Pod时,访问请求会经过本机proxy做转发。

2.2.3 具体软件模块

1)kubectl

客户端命令行工具,将接受的命令格式化后发送给kube-apiserver,作为整个系统的操作入口。

2)kube-apiserver

作为整个系统的控制入口,以REST API服务提供接口。

3)kube-controller-manager

用来执行整个系统中的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。

4)kube-scheduler

负责节点资源管理,接受来自kube-apiserver创建Pods任务,并分配到某个节点。

5)etcd

负责节点间的服务发现和配置共享(一个分布式强一致性的key/value存储)。

6)kube-proxy

运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到Service信息来做相应的策略。

7)kubelet

运行在每个计算节点上,作为agent,接受分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver。

8)DNS

一个可选的DNS服务,用于为每个Service对象创建DNS记录,这样所有的Pod就可以通过DNS访问服务了。

Kubernetes集群安装部署实现

3.1 Kubernetes集群组件

– etcd 一个高可用的K/V键值对存储和服务发现系统
– flannel 实现夸主机的容器网络的通信
– kube-apiserver 提供kubernetes集群的API调用
– kube-controller-manager 确保集群服务
– kube-scheduler 调度容器,分配到Node
– kubelet 在Node节点上按照配置文件中定义的容器规格启动容器
– kube-proxy 提供网络代理服务

3.2 Kubernetes集群示意图

Kubernetes工作模式server-client,Kubenetes Master提供集中化管理Minions。部署1台Kubernetes Master节点和4台Minion节点,
示意图如下:

3.3 Kubernetes集群安装部署步骤

3.3.1 先决条件

如下操作在所有安装CentOS的机器执行

1.确保系统已经安装epel-release源

# yum -y install epel-release

2.关闭防火墙服务,避免与docker容器的防火墙规则冲突(一定要关闭,否则后面会失败)。

# systemctl stop firewalld

# systemctl disable firewalld

 

3.3.2 安装配置Kubernetes Master

如下操作在master上执行
1.使用yum安装etcd和kubernetes-master

# yum -y install etcd kubernetes-master

2.编辑/etc/etcd/etcd.conf文件

ETCD_NAME=default

ETCD_DATA_DIR=”/var/lib/etcd/default.etcd”

ETCD_LISTEN_CLIENT_URLS=”http://0.0.0.0:2379″

ETCD_ADVERTISE_CLIENT_URLS=”http://localhost:2379″

 

3.编辑/etc/kubernetes/apiserver文件

KUBE_API_ADDRESS=”–insecure-bind-address=0.0.0.0″

KUBE_API_PORT=”–port=8080″

KUBELET_PORT=”–kubelet-port=10250″

KUBE_ETCD_SERVERS=”–etcd-servers=http://127.0.0.1:2379″

KUBE_SERVICE_ADDRESSES=”–Service-cluster-ip-range=10.254.0.0/16″

KUBE_ADMISSION_CONTROL=”–admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota”

KUBE_API_ARGS=””

 

4.启动etcd、kube-apiserver、kube-controller-manager、kube-scheduler等服务,并设置开机启动。

# for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do systemctl restart $SERVICES;systemctl enable $SERVICES;systemctl status $SERVICES ; done

5.在etcd中定义flannel网络

# etcdctl mk /atomic.io/network/config ‘{“Network”:”172.17.0.0/16″}’

 

3.3.3 安装配置Kubernetes Slaver

如下操作在node1、node2、node3、node4上执行
1.使用yum安装flannel和kubernetes-node

# yum -y install flannel kubernetes-node

2.为flannel网络指定etcd服务,修改/etc/sysconfig/flanneld文件

FLANNEL_ETCD=”http://192.168.30.20:2379″

FLANNEL_ETCD_KEY=”/atomic.io/network”

 

3.修改/etc/kubernetes/config文件

KUBE_LOGTOSTDERR=”–logtostderr=true”

KUBE_LOG_LEVEL=”–v=0″

KUBE_ALLOW_PRIV=”–allow-privileged=false”

KUBE_MASTER=”–master=http://192.168.30.20:8080″

4.按照如下内容修改对应node的配置文件/etc/kubernetes/kubelet

node1:

KUBELET_ADDRESS=”–address=0.0.0.0″

KUBELET_PORT=”–port=10250″

KUBELET_HOSTNAME=”–hostname-override=192.168.30.21″ #修改成对应Node的IP

KUBELET_API_SERVER=”–api-servers=http://192.168.30.20:8080″ #指定Master节点的API Server

KUBELET_POD_INFRA_CONTAINER=”–Pod-infra-container-image=registry.access.redhat.com/rhel7/Pod-infrastructure:latest”

KUBELET_ARGS=””

 

node2:

KUBELET_ADDRESS=”–address=0.0.0.0″

KUBELET_PORT=”–port=10250″

KUBELET_HOSTNAME=”–hostname-override=192.168.30.22″

KUBELET_API_SERVER=”–api-servers=http://192.168.30.20:8080″

KUBELET_POD_INFRA_CONTAINER=”–Pod-infra-container-image=registry.access.redhat.com/rhel7/Pod-infrastructure:latest”

KUBELET_ARGS=””

 

node3:

KUBELET_ADDRESS=”–address=0.0.0.0″

KUBELET_PORT=”–port=10250″

KUBELET_HOSTNAME=”–hostname-override=192.168.30.23″

KUBELET_API_SERVER=”–api-servers=http://192.168.30.20:8080″

KUBELET_POD_INFRA_CONTAINER=”–Pod-infra-container-image=registry.access.redhat.com/rhel7/Pod-infrastructure:latest”

KUBELET_ARGS=””

 

node4:

KUBELET_ADDRESS=”–address=0.0.0.0″

KUBELET_PORT=”–port=10250″

KUBELET_HOSTNAME=”–hostname-override=192.168.30.24″

KUBELET_API_SERVER=”–api-servers=http://192.168.30.20:8080″

KUBELET_POD_INFRA_CONTAINER=”–Pod-infra-container-image=registry.access.redhat.com/rhel7/Pod-infrastructure:latest”

KUBELET_ARGS=””

 

5.在所有Node节点上启动kube-proxy,kubelet,docker,flanneld等服务,并设置开机启动。

# for SERVICES in kube-proxy kubelet docker flanneld;do systemctl restart $SERVICES;systemctl enable $SERVICES;systemctl status $SERVICES; done

 

3.3.4  验证集群是否安装成功

在master上执行如下命令

[root@master ~]# kubectl get node

NAME            STATUS    AGE

192.168.30.21   Ready     1m

192.168.30.22   Ready     1m

192.168.30.23   Ready     1m

192.168.30.24   Ready     1m

3.3.5 安装图形化管理界面Kube-ui

kube-ui是kubernetes提供的web管理界面,可以展示节点的内存、CPU、磁盘、Pod、RC、SVC等信息。

1.编辑kube-dashboard-rc.yml定义文件
[root@master kube-dashboard]# cat kubernetes-dashboard-rc.yml

 

kind: Replication Controller

apiVersion: v1

metadata:

labels:

app: kubernetes-dashboard

name: kubernetes-dashboard

namespace: kube-system

spec:

replicas: 1

selector:

app: kubernetes-dashboard

template:

metadata:

labels:

app: kubernetes-dashboard

spec:

containers:

– name: kubernetes-dashboard

image: docker.gaoxiaobang.com/kubernetes/kube-ui:v5

imagePullPolicy: Always

ports:

– containerPort: 8080

 

  • 创建Pod

[root@master kube-dashboard]# kubectl create –f kubernetes-dashboard-rc.yml

 

2.编辑kube-dashboard-svc.yml定义文件
[root@master kube-dashboard]# cat kubernetes-dashboard-svc.yml

 

kind: Service

apiVersion: v1

metadata:

labels:

app: kubernetes-dashboard

name: kubernetes-dashboard

namespace: kube-system

spec:

type: NodePort

ports:

– port: 80

targetPort: 8080

selector:

app: kubernetes-dashboard

 

  1. 创建Service

[root@master kube-dashboard]# kubectl create -f kubernetes-dashboard-svc.yml

 

4.访问192.168.30.20:8080/ui(也就是master节点),会自动跳转到http://192.168.30.20:8080/api/v1/proxy/namespaces/kube-system/Services/kubernetes-dashboard/#/dashboard/,效果如下图

 

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据