Docker集群部署管理
1、什么是Kubernetes?Kubernetes是Google开源的容器集群管理系统,是目前比较火的集群式部署管理系统:Kubernetes(简称k8s),它是基于Docker技术的nat网络模式构建和Docker构建容器,利用Kubernetes能很方面管理多台Docker主机中的容器。2、优势和劣势(1)部署和管理。优势:以管理者的角度看,因为k8s的集群环境相较于实际生产环境,算是比较纯
1、什么是Kubernetes?
Kubernetes是Google开源的容器集群管理系统,是目前比较火的集群式部署管理系统:Kubernetes(简称k8s),它是基于Docker技术的nat网络模式构建和Docker构建容器,利用Kubernetes能很方面管理多台Docker主机中的容器。
2、优势和劣势
(1)部署和管理。
优势:以管理者的角度看,因为k8s的集群环境相较于实际生产环境,算是比较纯粹干净(特别是业务线比较长的公司),且使用的nat模式,横向扩展可以很方便,可以轻易的扩展部署和迁移,结合docker快速上下线的技术特性,使得动态调整部署很方便,是一套比较不错的高效部署管理系统;
劣势:k8s架构本身基于三角稳固体系,且中间有嵌套,逻辑比较重,为了连贯整套体系,保证服务质量,架构中间的辅助性支撑节点偏多,使得k8s要维护本身的框架所消耗的资源成本偏高,简单举例:k8s架构基于三个基本的管理对象(pod、service、replicationController),典型的三角稳定模型,相互关系类似于我们熟知的执法、立法、司法,其中pod对象也是有自己的架构,也是基于三角模型的管理对象(container、kubelet、proxy),通过这套集群管理系统接入一个业务,整套流程下来,至少要经过两趟嵌套式的管理架构,最后才能实现真正的docker container的落地使用,如果业务体系本身的架构比较轻可以支撑,但是一旦业务本身的架构比较重,假设分接入、逻辑和存储,各层次中间还有均衡容灾,用k8s部署管理,会导致这整套体系中间的支撑逻辑会非常重,架构成本会很高;
(2)与实际生产环境的兼容结合
优势:纯粹干净的集群环境,适合新的业务部署,结合镜像的使用方式,可以将开发、发布、部署封装成一条龙流程,实现高效快速的开发迭代和发布部署;
劣势:相较于大部分公司的业务系统都是基于IP为状态做的发布、部署、管理、监控,基于nat无状态模式运营管理k8s其实很难兼容铺开使用,它更强调依赖底层单纯干净的集群资源环境,它有一套自己的发布、部署、管理、监控的体系,与大部分公司已有的体系比较难融合,如果是小公司还比较好,业务范围不广,运营压力不大,从开发、发布到运维的整条生产线,直接迁移到nat模式或许可以接受,但是如果公司业务比较多,业务架构比较重,要迁过去或做兼容成本是非常大的,甚至可能是颠覆性的改革,而且改革结果是不确定性的,很多公司其实是很难接受的,简单举例:假设A公司已有一套基于IP为状态比较完善的业务系统,上游的发布工具、中游的资源管理和部署调度系统、下游的监控告警系统,整套流程都比较好用,如果让k8s支撑这套业务,需要把这套东西都改为支持nat模式,所有的流程中间都必须有一层nat转换,上层无法得知映射后面具体的IP,就算知道了,IP也是复用不唯一,会导致之前基于以IP为状态做的管理、调度、监控、告警会全部瘫痪掉,简直就像武侠小说里说的欲练此功必先自宫,代价太大;
(2)成本
优势:如果公司打造了一套纯粹的基于k8s 集群部署环境,能快速的批量扩缩容,集群本身弹性扩展比较方便,能很高效的实现运维人员追求的部署流程傻瓜自动化,从人力角度来评价,还是很省成本的,很高效;
劣势:如果从设备资源的角度考虑,由于相较于其他模式的管理集群,对容器的使用方式都一样,k8s本身不能提供更高级的可智能学习迭代优化机制,而且也没基于系统层级对硬件使用做优化策略,所以在容器对资源使用这块不会有成本优势,相反,由于nat模式本身就耗设备性能,如果一台机器部署几台容器,当业务请求都上来的时候,性能下降肯定比线性更严重,另外,由于k8s本身架构繁重,为支撑并保证集群稳定运行,还会耗用一些资源,且集群越大,成本越高,可拓展性预期比较差;
3、主要功能如下:
1)将多台Docker主机抽象为一个资源,以集群方式管理容器,包括任务调度、资源管理、弹性伸缩、滚动升级等功能。
2)使用编排系统(YAML File)快速构建容器集群,提供负载均衡,解决容器直接关联及通信问题
3)自动管理和修复容器,简单说,比如创建一个集群,里面有十个容器,如果某个容器异常关闭,那么,会尝试重启或重新分配容器,始终保证会有十个容器在运行,反而杀死多余的。
4、kubernetes角色组成:
1)Pod
Pod是kubernetes的最小操作单元,一个Pod可以由一个或多个容器组成;
同一个Pod只能运行在同一个主机上,共享相同的volumes、network、namespace;
2)ReplicationController(RC)
RC用来管理Pod,一个RC可以由一个或多个Pod组成,在RC被创建后,系统会根据定义好的副本数来创建Pod数量。在运行过程中,如果Pod数量小于定义的,就会重启停止的或重新分配Pod,反之则杀死多余的。当然,也可以动态伸缩运行的Pods规模或熟悉。
RC通过label关联对应的Pods,在滚动升级中,RC采用一个一个替换要更新的整个Pods中的Pod。
3)Service
Service定义了一个Pod逻辑集合的抽象资源,Pod集合中的容器提供相同的功能。集合根据定义的Label和selector完成,当创建一个Service后,会分配一个Cluster IP,这个IP与定义的端口提供这个集合一个统一的访问接口,并且实现负载均衡。
4)Label
5、Label是用于区分Pod、Service、RC的key/value键值对;
Pod、Service、RC可以有多个label,但是每个label的key只能对应一个;
主要是将Service的请求通过lable转发给后端提供服务的Pod集合;
kubernetes组件组成:
1)kubectl
客户端命令行工具,将接受的命令格式化后发送给kube-apiserver,作为整个系统的操作入口。
2)kube-apiserver
作为整个系统的控制入口,以REST API服务提供接口。
3)kube-controller-manager
用来执行整个系统中的后台任务,包括节点状态状况、Pod个数、Pods和Service的关联等。
4)kube-scheduler
负责节点资源管理,接受来自kube-apiserver创建Pods任务,并分配到某个节点。
5)etcd
负责节点间的服务发现和配置共享。
6)kube-proxy
运行在每个计算节点上,负责Pod网络代理。定时从etcd获取到service信息来做相应的策略。
7)kubelet
运行在每个计算节点上,作为agent,接受分配该节点的Pods任务及管理容器,周期性获取容器状态,反馈给kube-apiserver。
8)DNS
一个可选的DNS服务,用于为每个Service对象创建DNS记录,这样所有的Pod就可以通过DNS访问服务了。
6、基本部署步骤:
1)minion节点安装docker
2)minion节点配置跨主机容器通信
3)master节点部署etcd、kube-apiserver、kube-controller-manager和kube-scheduler组件
4)minion节点部署kubelet、kube-proxy组件
注意:如果minion主机没有安装docker,启动kubelet时会报如下错误:
W0116 23:36:24.205672 2589 server.go:585] Could not load kubeconfig file /var/lib/kubelet/kubeconfig: stat /var/lib/kubelet/kubeconfig: no such file or directory. Trying auth path instead.
W0116 23:36:24.205751 2589 server.go:547] Could not load kubernetes auth path /var/lib/kubelet/kubernetes_auth: stat /var/lib/kubelet/kubernetes_auth: no such file or directory. Continuing with defaults.
I0116 23:36:24.205817 2589 plugins.go:71] No cloud provider specified.
7、实验环境:
操作系统:ubuntu14.04_x64
master:192.168.18.15
minion01 : 192.168.18.16 容器网段:172.17.1.0/24
minion02 : 192.168.18.17 容器网段:172.17.2.0/24
一、minion节点安装docker
1、添加秘钥
$ sudo apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
2、添加docker源
$ sudo vi /etc/apt/sources.list.d/docker.list
# Ubuntu Precise
deb https://apt.dockerproject.org/repo ubuntu-precise main
# Ubuntu Trusty
deb https://apt.dockerproject.org/repo ubuntu-trusty main
# Ubuntu Vivid
deb https://apt.dockerproject.org/repo ubuntu-vivid main
# Ubuntu Wily
deb https://apt.dockerproject.org/repo ubuntu-wily main
注意:通过命令lsb_release -cs查看上面对应的版本,不要都添加上
3、更新索引
$ sudo apt-get update
4、安装docker
$ sudo apt-get install docker-engine -y
二、minion节点配置跨主机容器互联(也可以使用自带的flannel组件)
由于docker自身还未支持跨主机容器通信,需要借助docker网络开源解决方案实现。这里利用OpenVSwich即开放式虚拟交换机实现容器跨主机通信。
什么是OpenVSwich?
OpenVSwich是一种开源软件,通过软件的方式实现二层交换机功能,专门管理多租赁云计算网络环境,提供虚拟网络中的访问策略、网络隔离、流量监控等。
既然是虚拟交换机,自然与传统的物理交换机有着相同的特性,操作中可以按照理解物理交换机的方式去操作,有助于对虚拟交换机的认识。
开始创建网络环境(两台宿主机做相同的操作,部分要适当修改,已注明):
1、安装openvswitch
$ sudo apt-get install openvswitch-switch bridge-utils
2、添加网桥obr0(理解为添加了一个交换机)
$ sudo ovs-vsctl add-br obr0
3、将gre0接口加入到网桥obr0, 远程IP写对端IP(创建一个GRE隧道并添加到网桥中)
$ sudo ovs-vsctl add-port obr0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.18.17
4、查看ovs信息
$ sudo ovs-vsctl show
5、添加docker网桥
$ sudo brctl addbr kbr0
6、将obr0网桥加入kbr0网桥,并启动
$ sudo brctl addif kbr0 obr0
$ sudo ip link dev kbr0 up
$ sudo ip link set dev kbr0 up
7、查看网桥信息
$ sudo brctl show
8、添加docker网桥配置信息(18.17宿主机按照这种方式配置自己)
$ vi /etc/network/interfaces
auto eth0
iface eth0 inet static
address 192.168.18.16
netmask 255.255.255.0
gateway 192.168.18.1
dns-nameservers 192.168.18.1
auto kbr0
iface kbr0 inet static
address 172.17.1.1
netmask 255.255.255.0
gateway 172.17.1.0
9、删除默认docker网桥
$ sudo ip link set dev docker0 down
$ sudo ip link delete dev docker0
10、关键一点,添加路由条目,否则无法通讯(同样在18.17上面这样添加路由,写对端IP)
# via从哪个网关出去,写对端IP。dev由哪个设备出去
$ sudo ip route add 172.17.2.0/24 via 192.168.18.17 dev eth0
跨主机容器互联配置完成,并可以相互通信,接下来部署kubernetes集群!
先下载好相关的二进制包:
https://storage.googleapis.com/kubernetes-release/release/v1.1.3/kubernetes.tar.gz
https://github.com/coreos/etcd/releases/download/v2.2.2/etcd-v2.2.2-linux-amd64.tar.gz
三、master节点部署etcd、kube-apiserver、kube-controller-manager和kube-scheduler组件
1、安装配置k8s存储系统etcd
etcd是一个开源的用于配置共享和服务发现的高性能的键值存储系统。
# tar zxvf etcd-v2.2.2-linux-amd64.tar.gz
# cd etcd-v2.2.2-linux-amd64
注意: 创建存放所有组件二进制文件目录,最好是/opt/bin目录,因为启动脚本里面写的就是这个目录。
# mkdir /opt/bin
# cp etcd etcdctl /opt/bin
配置etcd启动选项:
# vi /etc/default/etcd
ETCD_OPTS="\
--listen-client-urls http://0.0.0.0:4001 \
--advertise-client-urls http://0.0.0.0:4001 \
--data-dir /var/lib/etcd/default.etcd"
选项说明:
--listen-peer-urls :etcd作为分布式节点通信端口,默认指定端口7001,我们这里做的是单节点,这个参数可以不写,需要知道的是v2版本中改变为2380,7001仍可用
--listen-client-urls :客户端操作etcd API的端口,默认指定端口4001,v2中改变为2379,在k8s中我们要使用4001端口
--data-dir :指定数据存放目录
--advertise-client-urls :作为分布式的客户端连接端口,如果不写这个参数会出现以下报错。
2016-01-15 16:04:20.469486 E | etcdmain: error verifying flags, -advertise-client-urls is required when -listen-client-urls is set explicitly. See 'etcd --help'.
2016-01-15 16:04:20.469717 E | etcdmain: When listening on specific address(es), this etcd process must advertise accessible url(s) to each connected client.
etcd服务配置好后先不启动,待会用下面kubernetes提供的启动脚本启动!~
2、启动etcd,安装配置kube-apiserver、kube-scheduler和kube-controller-manager
# tar zxvf kubernetes.tar.gz
# cd kubernetes/server
# tar zxvf kubernetes-server-linux-amd64.tar.gz
拷贝master端相关组件到/opt/bin目录:
# cd kubernetes/server/kubernetes/server/bin
# cp kube-apiserver kube-scheduler kube-controller-manager /opt/bin/
拷贝相关组件启动脚本到/etc/init.d目录:
# cd kubernetes/cluster/ubuntu/master/init_scripts
# cp etcd kube-* /etc/init.d/
配置apiserver启动选项:
# vi /etc/default/kube-apiserver
KUBE_APISERVER_OPTS="\
--insecure-bind-address=0.0.0.0 \
--insecure-port=8080 \
--service-cluster-ip-range=10.0.0.0/16 \
--etcd_servers=http://127.0.0.1:4001 \
--logtostderr=true"
选项说明:
--insecure-bind-address:api监听地址
--insecure-port:api监听端口
--service-cluster-ip-range:上面说到service角色是定义集群中一个pod集合,这个pod中容器提供一种服务,当创建service时会分配一个CLUSTER_IP提供统一的访问入口,那么,这个选项就是指定分配的IP范围
--etcd_servers:指定etcd连接地址
配置controller-manager启动选项:
# vi /etc/default/kube-controller-manager
KUBE_CONTROLLER_MANAGER_OPTS="\
--master=127.0.0.1:8080 \
--logtostderr=true"
配置scheduler启动选项:
# vi /etc/default/kube-scheduler
KUBE_SCHEDULER_OPTS="\
--master=127.0.0.1:8080 \
--logtostderr=true"
配置完成后,启动组件:
# service etcd start
etcd start/running, process 30585
# service kube-apiserver start
* Kube-Apiserver is managed via upstart, try using service kube-apiserver start
启动方式不对!为啥呢?
先看下脚本这段怎么执行的,可以看到两个条件都是成立的,当然会输出这句话了,看下其他启动脚本也一样,为啥etcd能启动呢?再看下etcd的启动脚本,原来压根都没执行这个判断,难道是kubernetes漏写了,先不管了,其他脚本都改为etcd这样吧!
再启动就成功了,呵呵!
# service kube-apiserver start
* Starting Kube-Apiserver: kube-apiserver [ OK ]
# service kube-scheduler start
* Starting Kube-Scheduler: kube-scheduler [ OK ]
# service kube-controller-manager start
* Starting Kube-Controller-Manager: kube-controller-manager [ OK ]
可以通过etcdctl查看到etcd存储着关于集群的各种信息:
# /opt/bin/etcdctl ls /registry
/registry/controllers
/registry/pods
/registry/ranges
/registry/namespaces
/registry/services
/registry/serviceaccounts
/registry/events
/registry/minions
四、minion节点部署kubelet、kube-proxy组件
在master端将minion相关组件拷贝到minion:
# cd kubernetes/server/kubernetes/server/bin
# scp kubelet kube-proxy root@192.168.18.16:/opt/bin
# scp kubelet kube-proxy root@192.168.18.17:/opt/bin
注意: ubuntu默认禁止root远程登录,需要配置允许ssh登录,也可以先将二进制包拷贝到minion服务器能ssh登录的用户,然后再sudo移动到/opt/bin目录
拷贝相关组件启动脚本到/etc/init.d目录:
# cd kubernetes/cluster/ubuntu/minion/init_scripts
# scp kubelet kube-proxy root@192.168.18.16:/etc/init.d/
# scp kubelet kube-proxy root@192.168.18.17:/etc/init.d/
配置kubelet启动选项:
# vi /etc/default/kubelet
KUBELET_OPTS="\
--address=0.0.0.0 \
--port=10250 \
--hostname_override=192.168.18.16 \
--api_servers=http://192.168.18.15:8080 \
--pod-infra-container-image=docker.io/kubernetes/pause:latest \
--logtostderr=true"
重要选项说明:
--hostname_override:在master端显示的节点名称,对应的minion主机修改对应的IP
--pod-infra-container-image:创建pod时下载镜像地址,默认是gcr.io/google_containers/pause:0.8.0,需要翻墙才能访问,所以指定了官方镜像下载源
配置kube-proxy启动选项:
# vi /etc/default/kube-proxy
KUBE_PROXY_OPTS="\
--master=http://192.168.18.15:8080 \
--proxy-mode=iptables \
--logtostderr=true"
重要选项说明:--proxy-mode,代理模式,默认使用userspace,会如下报错,我们需要修改为iptables做网络转发
# tail /var/log/kube-proxy.log
E1230 19:33:33.171758 24488 server.go:357] Not trying iptables proxy: can't get Node "minion2": node "minion2" not found
E1230 19:33:33.203271 24488 proxier.go:193] Error removing pure-iptables proxy rule: error checking rule: exit status 2: iptables v1.4.21: Couldn't load target `KUBE-SERVICES':No such file or directory
Try `iptables -h' or 'iptables --help' for more information.
E1230 19:33:33.204572 24488 proxier.go:197] Error removing pure-iptables proxy rule: error checking rule: exit status 2: iptables v1.4.21: Couldn't load target `KUBE-SERVICES':No such file or directory
Try `iptables -h' or 'iptables --help' for more information.
配置完成后,启动组件:
# service kube-proxy start
* Starting Kube-Proxy: kube-proxy [ OK ]
# service kubelet start
* Starting Kubelet: kubelet [ OK ]
注意:启动之前为了避免出现启动方式不对,先修改下启动脚本中这段代码false来跳过。
到这kubernetes就配置完了,查看下集群节点:
pods是空的,还没有创建,接下来创建一个吧!
先设置下命令变量,方便使用:
# vi /etc/profile
export PATH=$PATH:/opt/bin
# source /etc/profile
命令启动一个nginx:
# kubectl run --image=nginx nginx-test
replicationcontroller "nginx-test" created
初次创建要下载镜像,需等待数分钟,查看集群pods:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-test-8p7it 1/1 Running 0 14s
yaml文件启动一个nginx:
READY是kebernetes检查服务健康状态,1表示服务可用。
查看下创建的nginx信息:
知道了我们创建的pods分配到了18.17节点,也知道了容器的ip,那么,就到18.17节点上测试nginx服务有没有正常启动了!
原文:http://blog.csdn.net/ztsinghua/article/details/52329622、http://blog.csdn.net/hfeng101/article/details/48016401
更多推荐
所有评论(0)