Kubernetes使用集群联邦实现多集群管理

本文来自10月24日有容云Docker微信群分享整理

分享嘉宾:有容云系统工程师  吕龙

 

以下是分享正文:

 

Kubernetes在1.3版本之后,增加了“集群联邦”Federation的功能。这个功能使企业能够快速有效的、低成本的跨区跨域、甚至在不同的云平台上运行集群。这个功能可以按照地理位置创建一个复制机制,将多个kubernetes集群进行复制,即使遇到某个区域连接中断或某个数据中心故障,也会保持最关键的服务运行。在1.7版以后支持本地多个集群联邦管理,不需要使用依赖云平台

 

 

Kubernetes集群联邦介绍

 

1、管理多個kubernetes集群

 

 “集群联邦”在架构上同kubernetes集群很相似。有一个“集群联邦”的API server提供一个标准的Kubernetes API,并且通过etcd来存储状态。不同的是,一个通常的Kubernetes只是管理节点计算,而“集群联邦”管理所有的kubernetes集群。

 

 

2、跨集群服务发现

 

Kubernetes有一个标准的插件:kube-dns,这个插件可以在集群内部提供DNS服务,通过DNS解析service名字来访问kubernetes服务。Kubernetes服务是由一组kubernetesPOD组成的,这些POD是一些已经容器化了的应用,这些POD前面使用到了负载均衡器。假如我们有一个kubernetes集群,这个集群裡面有一个服务叫做mysql,这个服务是由一组mysql POD组成的。在这个kubernetes集群中,其他应用可以通过DNS来访问这个mysql服务。

   

集群联邦federation/v1beta1API扩展基于DNS服务发现的功能。利用DNS,让POD可以跨集群、透明的解析服务。

 

3、跨集群调度

 

为了追求高可用性和更高的性能,集群联邦能够把不同POD指定给不同的Kubernetes集群中。集群联邦调度器将决定如何在不同kubernetes集群中分配工作负载。

  

通过跨集群调度,我们可以:

 

  • 跨kubernetes集群均匀的调度任务负载

 

  • 将各个kubernetes集群的工作负载进行最大化,如果当前kubernetes集群超出了承受能力,那麽将额外的工作负载路由到另一个比较空闲的kubernetes集群中

 

  • 根据应用地理区域需求,调度工作负载到不同的kubernetes集群中,对于不同的终端用户,提供更高的带宽和更低的延迟。


4、集群高可用,故障自动迁移

 

集群联邦可以跨集群冗馀部署,当某个集群所在区域出现故障时,并不影响整个服务。集群联邦还可以检测集群是否为不可用状态,如果发现某个集群为不可用状态时,可以将失败的任务重新分配给集群联邦中其他可用状态的集群上。

 

 

Kubernetes使用集群联邦实现多集群管理

 

 

1、系统环境及初始化

  

 1.1 系统环境

 

功能组件

系统组件

系统版本

推荐配置

设备数量

备注

联邦集群控制平面

K8S+Federation

CentOS 7.2

4核/8G/80G

2台

联邦集群控制平面

K8s集群01

Kubernetes master+node

CentOS 7.2

4核/8G/80G

2台

联邦集群节点

K8s集群02

Kubernetes master+node

CentOS 7.2

4核/8G/80G

2台

联邦集群节点

 

 

1.2 安装前准备

     

1.2.1 准备kubernetes组件镜像

 

Kubernetes1.7版本的集群与联邦集群功能的安装方式均为镜像安装,所有组件功能都使用官方提供的镜像来实现,由于官方镜像国内无法正常下载,需要提前准备好镜像或科学上网,具体镜像列表如下。

 

序号

Kubernetes镜像

版本

1

gcr.io/google_containers/kube-proxy-amd64

v1.7.0

2

gcr.io/google_containers/kube-apiserver-amd64

v1.7.0

3

gcr.io/google_containers/kube-controller-manager-amd64

v1.7.0

4

gcr.io/google_containers/kube-scheduler-amd64

v1.7.0

5

gcr.io/google_containers/kube-aggregator

v1.7.0

6

gcr.io/google_containers/k8s-dns-sidecar-amd64

1.14.4

7

gcr.io/google_containers/k8s-dns-kube-dns-amd64

1.14.4

8

gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64

1.14.4

9

gcr.io/google_containers/etcd-amd64

3.0.17

10

quay.io/coreos/flannel

v0.7.1-amd64

11

gcr.io/google_containers/pause-amd64

3.0

联邦集群镜像

1

gcr.io/google_containers/hyperkube-amd64

v1.7.0

2

docker.io/coredns/coredns

006

3

gcr.io/kubernetes-helm/tiller

v2.1.3

1.2.2 安装Docker 1.12

 

 

Kubernetes 1.7还没有针对docker 1.13上做测试和验证,所以这里安装Kubernetes官方推荐的Docker 1.12版本。

 

1.2.3 修改系统配置

 

创建/etc/sysctl.d/k8s.conf文件,添加如下内容:

 

net.bridge.bridge-nf-call-ip6tables= 1

net.bridge.bridge-nf-call-iptables= 1

 

执行sysctl -p /etc/sysctl.d/k8s.conf使修改生效。

 

在/etc/hostname中修改各节点的hostname,在/etc/hosts设置hostname对应ip:

 

192.168.5.13test01.example.com

192.168.5.14test02.example.com

 

关闭防火墙服务与禁用开机启动项

 

systemctl stopfirewalld

systemctl disable firewalld关闭SELINUX选项

 

关闭SELINUX选项

 

setenforce 0

sed -i's/SELINUX=enforcing/SELINUX=disabled/g'/etc/sysconfig/selinux


1.2.4 安装Kuberadm与Kubelet

 

注意:该yum源需要科学才能正常安装

 

在每个节点安装kubeadm和kubelet:

 

cat< /etc/yum.repos.d/kubernetes.repo

[kubernetes]

name=Kubernetes

baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64

enabled=1

gpgcheck=1

repo_gpgcheck=1

gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg

       https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg

EOF

 

安装kubeadm, kubelet, kubectl, kubernets-cni

 

yum install -ykubelet kubeadm kubectl kubernetes-cni

 

Kubelet服务设置开机启动

 

systemctl enablekubelet.service

 

安装完成后初始化环境准备完成

 

2、安装kubernetes集群

 

首先在一个节点上安装kubernetes作为master节点,将master节点参与集群调度.然后在该节点上安装联邦集群功能,作为联邦集群的控制平面。

 

2.1 初始化集群

 

 

使用kubeadm初始化集群,选择node1作为Master,在node1上执行下面的命令:

注:因为我们选择flannel作为Pod网络插件,所以命令指定--pod-network-cidr=10.240.0.0/16

 

kubeadm init--kubernetes-version=v1.7.0 --pod-network-cidr=10.240.0.0/16--apiserver-advertise-address=192.168.5.13

 

 kubeadm init执行成功后输出下面的信息:

注:请保存好该信息,后续节点加入集群需要使用该命令.

 

You can now join anynumber of machines by running the following on each node

as root:

kubeadm join --tokene7986d.e440de5882342711 192.168.5.13:6443

 

为了使用kubectl访问apiserver,在~/.bash_profile中追加下面的环境变量:

 

echo "exportKUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile

source /etc/profile

 

此时kubectl命令在master node上就好用了,查看一下当前机器中的Node:

 

kubectl get nodes

  NAME      STATUS    AGE       VERSION

 node0     Ready     3m        v1.7.0

 

2.2 安装Pod网络组件

 

接下来安装flannelnetwork add-on:

 

wgethttps://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel-rbac.yml

wgethttps://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

 

目前需要在kube-flannel.yml中使用--iface参数指定集群主机内网网卡的名称,否则可能会出现dns无法解析。需要将kube-flannel.yml下载到本地,flanneld启动参数加上--iface=

 

vi kube-flannel.yml

   command: [ "/opt/bin/flanneld","--ip-masq", "--kube-subnet-mgr", "--iface=eth1"]   //改为本机网卡名称

 

部署网络组件:

 

kubectlcreate -f kube-flannel-rbac.yml

kubectlapply -f kube-flannel.yml

 

 确保所有的Pod都处于Running状态。

 

kubectlget pod --all-namespaces -o wide

 

 

使用下面的命令使MasterNode参与工作负载

 

kubectltaint nodes --all node-role.kubernetes.io/master-

 

3、安装联邦集群组件

 

3.1安装前配置修改

 

修改前先停止kubelet服务

 

vi/etc/kubernetes/manifests/etcd.yaml

   - --listen-client-urls=http://0.0.0.0:2379

   ---advertise-client-urls=http://0.0.0.0:2379

vi/etc/kubernetes/manifests/kube-apiserver.yaml

   ---insecure-port=8080

   ---insecure-bind-address=0.0.0.0

 

重启kubelet服务让etcd与apiserver监听端口生效

 

systemctl restart kubelet

 

3.2安装helm工具部署Coredns

 

curlhttps://raw.githubusercontent.com/kubernetes/helm/master/scripts/get >get_helm.sh

chmod 700 get_helm.sh

./get_helm.sh

 

修改RBAC临时访问权限

 

kubectl create clusterrolebinding add-on-cluster-admin--clusterrole=cluster-admin --serviceaccount=kube-system:default

 

创建coredns键值文件

 

cat < /opt/Values.yaml

isClusterService: false

serviceType: "NodePort"

middleware:

 kubernetes:

   enabled: false

  etcd:

   enabled: true

    zones:

    -"example.com."

   endpoint: "http://192.168.5.13:2379"

EOF

 

初始化helm,并使用helm安装coredns组件

 

helm init

helm install --namespace default --name coredns-f /opt/Values.yaml stable/coredns

   

新建coredns配置文件

 

vi /root/coredns-provider.conf

[Global]

etcd-endpoints = http://192.168.0.51:2379

zones = example.com.

 

3.3添加kubernetes从节点

 

 在kubernetes工作节点上初始安装后执行以下命令

 

kubeadmjoin --token e7986d.e440de5882342711 192.168.5.13:6443

  

在master节点查看节点状态

 

kubectlget nodes

   

重复上述步骤创建多个kubernetes集群,为联邦集群添加集群节点做准备。

   

 3.4初始化联邦集群

 

kubefed init fellowship \

   --host-cluster-context=kubernetes-admin@kubernetes \

    --dns-provider="coredns" \

    --dns-zone-name="example.com." \

   --dns-provider-config="/root/coredns-provider.conf" \

    --apiserver-enable-basic-auth=true \

    --apiserver-enable-token-auth=true \

   --apiserver-arg-overrides="--anonymous-auth=false,--v=4" \

   --api-server-service-type="NodePort" \

   --api-server-advertise-address="192.168.5.13" \

--etcd-persistent-storage=false

 

初始化完成后集群联邦会在federation-system命名空间中创建两个POD

 

 

3.5其他kubernetes集群加入联邦集群

 

选择集群的context

 

 

kubectlconfig use-context fellowship   //fellowship为联邦初始化时创建

 

添加联邦集群文件

 

cat /home/tmp/c1.yaml

   apiVersion: federation/v1beta1

   kind: Cluster

   metadata:

 name: c1

   spec:

 serverAddressByClientCIDRs:

 - clientCIDR: 0.0.0.0/0

   serverAddress: http://192.168.15.53:8080

 

   cat /home/tmp/c2.yaml

   apiVersion: federation/v1beta1

   kind: Cluster

   metadata:

 name: c2

   spec:

serverAddressByClientCIDRs:

- clientCIDR: 0.0.0.0/0

 serverAddress: http://192.168.8.12:8080

 

添加集群到联邦

 

cat /home/tmp/c1.yaml

   apiVersion: federation/v1beta1

   kind: Cluster

   metadata:

 name: c1

   spec:

 serverAddressByClientCIDRs:

 - clientCIDR: 0.0.0.0/0

   serverAddress: http://192.168.15.53:8080

 

   cat /home/tmp/c2.yaml

   apiVersion: federation/v1beta1

   kind: Cluster

   metadata:

 name: c2

   spec:

serverAddressByClientCIDRs:

- clientCIDR: 0.0.0.0/0

 serverAddress: http://192.168.8.12:8080

 

添加集群到联邦

 

kubectlcreate -f c1.yaml

kubectlcreate -f c2.yaml

  

查看联邦集群状态

 

[root@test01~]# kubectl get cluster

NAME      STATUS     AGE

c1        Ready     2d

c2        Ready     2d

 

3.6通过联邦集群部署应用

 

 

通过联邦集群部署应用,需要在联邦集群控制平面的节点上,切换到联邦的context

 

kubectlconfig use-context fellowship   //fellowship为联邦初始化时创建

 

配置应用在分布在2个集群中

 

vi tomcat.yaml

apiVersion: exensions/v1beta1

kind: ReplicaSet

metadata:

  name:tomcat

  lables:

    app:tomcat

 annotaions:

   federation.kubernetes.io/replica-set-preferences:

        {

           "rebalance": true,

           "clusters": {

             "c1": {

            "weight": 1

          },

             "c2": {

            "weight": 1

          }

        }

    }

spec:

  replicas:4

  template:

   metadata:

     labels:

       #region: tomcat

    app:tomcat

    spec:

     containers:

        -name: fed-tomcat

      image:192.168.18.250:5002/admin/tomcat:v0.0.5

      resourcces:

        requests:

          cpu: 200M

          memory: 500Mi

      ports:

     - containerPort: 80

 

通过联邦创建应用,应用的4个实例按比例分布到2个集群中

 

[root@test01 ~]# kubectl create namespace default

namespace"default" created

 

[root@test01 ~]#kubectl create -f tomcat.yaml

replicaset"tomcat" created

 

[root@test01 ~]#kubectl get rs

NAME      DESIRED     CURRENT       AGE

tomcat    4           4            

 

[root@test01 ~]#kubectl -s 192.168.15.53:8080 get pod

NAME           READY     STATUS       RESTARTS   AGE

tomcat-juywx  1/1      Running      0           33s

tomcat-siidb  1/1      Running      0           33s

 

[root@test01 ~]#kubectl -s 192.168.8.12:8080 get pod

NAME           READY     STATUS       RESTARTS   AGE

tomcat-sw437  1/1      Running      0           33s

tomcat-n7z74  1/1      Running      0           33s

 

集群联邦只支持以下几种类型资源的创建:

 

Cluster

ConfigMap

DaemonSets

Deployment

Events

Ingress

Namespaces

ReplicaSets

Secrets

Services

 

 

Q&A

 

Q1 :node机器推荐命名规则与生成使用经验

A :推荐使用“地理位置+机房编号+机柜号+应用名称”的缩写字母来命名,这样便于运维人员后续的管理和维护。

 

Q2 :为什么要修改etcd与apiserver的监听端口?

A :修改etcd监听IP为0.0.0.0是为了防止出现监听了lo网卡的127.0.0.1的IP,出现不能连接的情况。apiserver则是开启8080端口用于接收http请求,这样是为了测试时方便不用使用CA证书认证。

 

Q3 :请问docker 源怎么弄,国内一般不好连接,下载不了?另外还有1.6要升级到1.7怎么做?

A建议使用科学上网方式,这样就不需要改动配置。1.6升级到1.7,先停止kubelet服务,然后下载1.7版本的kubernetes-server-linux-amd64.tar.gz包,解压替换/usr/bin目录下的同名文件,然后再把kubelet服务启动

 

Q4 :在联邦集群中部署服务,可以将服务只部署在一个集群中么?

A :可以只部署服务在一个集群中,通过编排文件中federation.kubernetes.io/replica-set-preference来控制副本分布在哪个集群。

 

Q5 :联邦集群的几个组件现在有支持高可用么?没有的话,我们应该怎么避免联邦组件的bug导致的服务不可用?

A :联邦集群的Federation组目录没有支持高可用,但联邦功能主要是为了调度管理k8s集群的,所以联邦集群Federation组件出现故障时并不会直接影响到下面各个集群自身的已经在运行的服务。

 

Q6 :根据应用地理区域需求,调度工作负载到不同的kubernetes集群中,对于不同的终端用户,提供更高的带宽和更低的延迟. 这个调度到不同的集群,是k8s根据地理位置调度吗?是k8s自己调度吗?

A :工作负载k8s可以自己调度到比较空闲的集群上,地理位置调度这个需要通过编排文件控制应用的容器分配到更合适的区域机房。

 

Q7 :是先建立3个k8s集群,然后在1个集群的master上kubefed init fellowship是吗?

A :是的,在其中1个集群的master上安装Federation组件,然后把3个K8s集群加进来管理。

 

Q8 ;其他集群加入到联邦的时候执行kubectl config use-context fellowship,但这时候其集群上还没有fellowship,他怎么config的?

A :kubectl config use-context fellowship是在安装了联邦Federation组件的那个集群master上执行的,通过联邦控制平面将其他集群加入进来。

 

Q9 :添加联邦集群文件时,里面的serverAddress是什么地址?

A :serverAddress就是k8s集群的API server的IP和端口,c1.yaml里面的serverAddress就是集群01的API server的IP和端口,c2.yaml里面的serverAddress就是集群02的API server的IP和端口

node机器推荐命名规则与生成使用经验

A :推荐使用“地理位置+机房编号+机柜号+应用名称”的缩写字母来命名,这样便于运维人员后续的管理和维护。

 

Q10 :为什么要修改etcd与apiserver的监听端口?

A :修改etcd监听IP为0.0.0.0是为了防止出现监听了lo网卡的127.0.0.1的IP,出现不能连接的情况。apiserver则是开启8080端口用于接收http请求,这样是为了测试时方便不用使用CA证书认证。

 

Q11 :请问docker 源怎么弄,国内一般不好连接,下载不了?另外还有1.6要升级到1.7怎么做?

A :建议使用科学上网方式,这样就不需要改动配置。1.6升级到1.7,先停止kubelet服务,然后下载1.7版本的kubernetes-server-linux-amd64.tar.gz包,解压替换/usr/bin目录下的同名文件,然后再把kubelet服务启动

 

Q12 :在联邦集群中部署服务,可以将服务只部署在一个集群中么?

A :可以只部署服务在一个集群中,通过编排文件中federation.kubernetes.io/replica-set-preference来控制副本分布在哪个集群。

 

Q13 :联邦集群的几个组件现在有支持高可用么?没有的话,我们应该怎么避免联邦组件的bug导致的服务不可用?

A :联邦集群的Federation组目录没有支持高可用,但联邦功能主要是为了调度管理k8s集群的,所以联邦集群Federation组件出现故障时并不会直接影响到下面各个集群自身的已经在运行的服务。

 

Q14 :根据应用地理区域需求,调度工作负载到不同的kubernetes集群中,对于不同的终端用户,提供更高的带宽和更低的延迟. 这个调度到不同的集群,是k8s根据地理位置调度吗?是k8s自己调度吗?

A :工作负载k8s可以自己调度到比较空闲的集群上,地理位置调度这个需要通过编排文件控制应用的容器分配到更合适的区域机房。

 

Q15 :是先建立3个k8s集群,然后在1个集群的master上kubefed init fellowship是吗?

A :是的,在其中1个集群的master上安装Federation组件,然后把3个K8s集群加进来管理。

 

Q16 :其他集群加入到联邦的时候执行kubectl config use-context fellowship,但这时候其集群上还没有fellowship,他怎么config的?

A ;kubectl config use-context fellowship是在安装了联邦Federation组件的那个集群master上执行的,通过联邦控制平面将其他集群加入进来。

 

Q17:添加联邦集群文件时,里面的serverAddress是什么地址?

A :serverAddress就是k8s集群的API server的IP和端口,c1.yaml里面的serverAddress就是集群01的API server的IP和端口,c2.yaml里面的serverAddress就是集群02的API server的IP和端口

 

                                 -END-

 

分享:Kubernetes使用集群联邦实现多集群管理

有容云-构筑企业容器云 www.youruncloud.com

温馨提示

对Docker容器技术或容器生产实施感兴趣的朋友欢迎加群讨论。我们汇集了Docker容器技术落地实施团队精英及业内技术派高人,在线为您分享Docker技术干货。我们的宗旨是为了大家拥有更专业的平台交流Docker实战技术,我们将定期邀请嘉宾做各类话题分享及回顾,共同实践研究Docker容器生态圈。

加微信群方法:

1.关注【有容云】公众号

2.留言”我要加群”

QQ群号:454565480

有容云微信二维码