Kubernetes(K8S v1.1版本) 集群管理Docker容器之部署篇
什么是Kubernetes? Kubernetes是Google开源的容器集群管理系统,实现基于Docker构建容器,利用Kubernetes能很方面管理多台Docker主机中的容器。 主要功能如下: 1)将多台Docker主机抽象为一个资源,以集群方式管理容器,包括任务调度、资源管理、弹性伸缩、滚动升级等功能。 2)使用编排系统(YAML File)快速构建容器集群,提供负载均衡,解决容器直接关联及通信问题 3)自动管理和修复容器,简单说,比如创建一个集群,里面有十个容器,如果某个容器异常关闭,那么,会尝试重启或重新分配容器,始终保证会有十个容器在运行,反而杀死多余的。 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 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访问服务了。 基本部署步骤: 1)minion节点安装docker 2)minion节点配置跨主机容器通信 3)master节点部署并启动etcd、kube-apiserver、kube-controller-manager和kube-scheduler组件 4)minion节点部署并启动kubelet、kube-proxy组件 注意:如果minion主机没有安装docker,启动kubelet时会报如下错误: [size=1em][size=1em]1
[size=1em]2
[size=1em]3
| [size=1em][size=1em]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.
[size=1em]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.
[size=1em]I0116 23:36:24.205817 2589 plugins.go:71] No cloud provider specified.
|
实验环境: 操作系统: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、添加docker源秘钥 $ sudo apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D 2、添加docker源 注意:通过命令lsb_release -cs查看上面对应的版本,不要都添加上 $ sudo vi /etc/apt/sources.list.d/docker.list # Ubuntu Precise # Ubuntu Trusty # Ubuntu Vivid # Ubuntu Wily 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 4f080650-d408-457b-81bd-9de64d199120 Bridge "obr0" Port "gre0" Interface "gre0" type: gre options: {remote_ip="192.168.18.17"} Port "obr0" Interface "obr0" type: internal ovs_version: "2.0.1" 5、添加docker网桥 $ sudo brctl addbr kbr0 6、将obr0网桥加入kbr0网桥,并启动 $ sudo brctl addif kbr0 obr0 $ sudo ip link set dev kbr0 up 7、查看网桥信息 $ sudo brctl show bridge name bridge id STP enabled interfaces kbr0 8000.56d3df8c8e40 no obr0 8、添加docker网桥配置信息(18.17宿主机按照这种方式配置自己) $ vi /etc/network/interfaces [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
[size=1em]7
[size=1em]8
[size=1em]9
[size=1em]10
[size=1em]11
[size=1em]12
| [size=1em][size=1em]auto eth0
[size=1em]iface eth0 inet static
[size=1em] address 192.168.18.16
[size=1em] netmask 255.255.255.0
[size=1em] gateway 192.168.18.1
[size=1em] dns-nameservers 192.168.18.1
[size=1em]auto kbr0
[size=1em]iface kbr0 inet static
[size=1em] address 172.17.1.1
[size=1em] netmask 255.255.255.0
[size=1em] gateway 172.17.1.0
[size=1em] bridge_ports obr0
|
9、删除默认docker网桥 $ sudo ip link set dev docker0 down $ sudo ip link delete dev docker0 10、修改docker默认桥接网桥,并重启 $ sudo vi /etc/default/docker DOCKER_OPTS="-b=kbr0" $ sudo service docker restart 11、关键一点,添加路由条目,否则无法通讯(同样在18.17上面这样添加路由,写对端IP) # via从哪个网关出去,写对端IP。dev由哪个设备出去 $ sudo ip route add 172.17.2.0/24 via 192.168.18.17 dev eth0 跨主机容器互联配置完成,并可以相互通信,接下来部署kubernetes集群!
先下载好相关的二进制包: 没有VPN的网友可以在这个地址下载:
三、Master节点部署etcd、kube-apiserver、kube-controller-manager和kube-scheduler组件 1、部署与配置存储系统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="\ --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 :作为分布式的客户端连接端口,如果不写这个参数会出现以下报错。 [size=1em] | [size=1em][size=1em]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'.
[size=1em]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" 配置完成后,启动组件: [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
| [size=1em][size=1em]# service etcd start
[size=1em]etcd start/running, process 30585
[size=1em]注意:如果etcd启动后进程不存在,尝试去掉/etc/init.d/etcd第64行的 >> $ETCD_LOGFILE 2>&1追加日志这部分再启动试试。
[size=1em]# service kube-apiserver start
[size=1em] * Kube-Apiserver is managed via upstart, try using service kube-apiserver start
|
启动方式不对!为啥呢? 先看下/etcd/init.d/kube-apiserver脚本这段怎么执行的,可以看到两个条件都是成立的,当然会输出这句话了,看下IT论坛启动脚本也一样,为啥etcd能启动呢?再看下/etcd/init.d/etcd的启动脚本,原来压根都没执行这个判断,难道是kubernetes官方漏写了?先不管了,IT论坛脚本都也改为etcd这样吧! 再启动就成功了,呵呵! [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
[size=1em]6
| [size=1em][size=1em]# service kube-apiserver start
[size=1em] * Starting Kube-Apiserver: kube-apiserver [ OK ]
[size=1em]# service kube-scheduler start
[size=1em] * Starting Kube-Scheduler: kube-scheduler [ OK ]
[size=1em]# service kube-controller-manager start
[size=1em] * 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 注意:ubuntu默认禁止root远程登录,需要配置允许ssh登录,也可以先将二进制包拷贝到minion服务器能ssh登录的用户,然后再sudo移动到/opt/bin目录 拷贝相关组件启动脚本到/etc/init.d目录: # cd kubernetes/cluster/ubuntu/minion/init_scripts 配置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 [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
[size=1em]5
| [size=1em][size=1em]E1230 19:33:33.171758 24488 server.go:357] Not trying iptables proxy: can't get Node "minion2": node "minion2" not found
[size=1em]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
[size=1em]Try `iptables -h' or 'iptables --help' for more information.
[size=1em]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
[size=1em]Try `iptables -h' or 'iptables --help' for more information.
|
配置完成后,启动组件: [size=1em][size=1em]1
[size=1em]2
[size=1em]3
[size=1em]4
| [size=1em][size=1em]# service kube-proxy start
[size=1em] * Starting Kube-Proxy: kube-proxy [ OK ]
[size=1em]# service kubelet start
[size=1em] * 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服务有没有正常启动了!
至此,kubernetes集群就部署成功了,想了解更贴近业务系统使用,请继续关注! Kubernetes(K8S v1.1版本) 集群管理Docker容器之部署篇
http://blog.51cto.com/lizhenliang/1736572
|