kubernetes1.4简介和安装部署
Posted @路痴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kubernetes1.4简介和安装部署相关的知识,希望对你有一定的参考价值。
项目需要了解kubernetes,所以自学了几天,仅提供给新手…写该博客一是希望能够帮助像我这样刚入门的小白,二是加深自己的印象,如果忘了也可以再看看,有些片段是从其他博客、文档和书籍学习来的,但都是自己理解的,一些没有理解的或者不确定的就没有写出来,如有问题希望大家能够批评指正,由衷的表示感谢。
注:学习kubernetes需要了解容器技术,之前写过一篇docker容器的文章可以参考下:
kubernetes简介
1、k8s简介
Kubernetes(k8s)是Google开源的容器集群管理系统,是一个完备集群管理能力的分布式系统支撑平台。
先简单概览下官方master/slave集群架构图:
假设图中是我们的三台“主机”,其中右侧两台是放我们应用的服务器,也就是k8s中的Node,在k8s中通过左侧的Master来管理我们的Node。
先说Master:kubectl是k8s中的命令行操作工具,类似docker命令;Authentication是k8s的认证,Authorization是k8s的授权;API Server提供了集群管理的API接口和负责集群内功能模块的数据交互和通信;Kubernetes以RESTFul形式开放接口;Scheduler是集群中的调度器,负责Pod在集群中节点的调度分配;controller manager是k8s的管理控制中心;etcd是一个高可用的键值存储系统,在k8s中用于存储集群中所有的资源对象的信息并被监控。
再说Node:Node是Kubernetes集群中相对Master而言的工作主机,可以是一台物理机、虚拟机或者云服务器;kubelet负责本Node上的Pod创建、修改、监控和删除等全生命周期管理,同时定时上报本Node的状态信息;Proxy实现Service的代理及软件模式的负载均衡;cAdvisor是一个用于监控容器运行状态的开源软件,k8s中默认被集成到kubelet组件中。
2、基本概念和术语
Kubernetes中Service、Pod、Master、Node、RC、label等概念都可以看作一种资源对象,通过Kubernetes提供的Kubectl工具或API调用进行操作,并保存在etcd中。
Node:
是Kubernetes集群中相对Master而言的工作主机。Node包含的信息:Node的地址(“主机”ip地址)或者Node ID、Node运行状态、Node系统容量描述、Node可用的系统资源、还包括实例信息等,在Node上运行的服务进程包括Kubelet、Kube-proxy和docker daemon。
Pod:
是Kubernetes的最基本操作单元,Pod在Node上被创建、启动或销毁,通过Yaml或者Json格式的配置文件来定义。一个Pod包含一个或多个容器,Pod中的多个容器应用通常是紧耦合的。创建Pod的原因是由于Docker容器之间的通信受到Docker网络机制的限制,虽然容器之间可以通过link的方式访问,但是通过Pod的概念可以将一个Pod当做一个“虚拟机”,Pod中的容器就是这台“虚拟机”中的所有应用,也就是说可以将Node当做我们的“物理机”,然后在我们的“物理机”中创建一个“虚拟机”,“虚拟机”内当然可以通过localhost实现通信,也方便管理,一个Pod中的应用容器可以看到其他应用程序的进程ID。
以下是简单的Master、Node、Pod和container的关系图:
图中Master管理多个Node,Node中包含多个Pod,Pod中包含多个容器。
Lable:
是Kubernetes系统中的一个核心概念。Lable以key/value键值对的形式附加到各种资源对象上,如Pod、Service、RC、Node等,并且每个对象可以具有多个Lable,在为“对象”定义好Lable后,其他“对象”就可以使用Lable Selector来定义其作用的对象了。Lable Selector分为基于等式或者基于集合的形式,类似sql中的“=”、“!=”、“in”、“not in”语句,或者js中的name标签。
Replication Controller(RC):
是Kubernates系统中的核心概念,可以通过yaml或json格式的配置文件定义Pod副本的数量,并且可以手动修改,在Master内,Controller Manager进程通过RC的定义和Node的上的某个程序(如Kubelet或Docker)来完成Pod的创建、监控、启停等操作,如果运行了过多的Pod,RC会停掉一些Pod,如果运行了Pod数过少,则RC会启动相应数量的Pod,如果需要删除所有Pod,可以将Pod的数量修改为0,也就是RC可以控制Kubernetes的扩容缩容。
Job:
job类似RC,只是RC是持续管理pod,而Job是一次性创建后就完成结束,删除job会清理掉该job创建的pod。
Daemon Set:
如果需要所有节点(或部分)节点都运行某一个pod(比如日志、监控)可以创建Daemon Set,当这些节点添加到集群中时pod也会被添加,如果某个节点从集群中删除,则这些节点的pod会被垃圾回收,删除Daemon Set将清理它创建的pod。
Replica Set(RS):
是下一代“RC”Replica Set和Replication Controller的区别是,它支持基于集合的选择器要求,而RC仅支持基于等式的选择器。虽然Replica Set可以单独存在管理pod,但是它主要的功能是配合Deployments来进行管理pod。
Deployment:
对pod和Replica Set进行声明和更新。典型的实例:创建部署得到Replica Set和Pods;检查部署的状态,以查看其是否成功;更新该部署以重新创建Pod(例如,使用新的镜像);如果当前部署不稳定,回滚到早期的部署版本;暂停和恢复部署。
Service:
是一个虚拟概念,逻辑上代理后端pod,可以看作一组提供相同服务的Pod对外访问接口,拥有一个唯一的指定的名字,一个虚拟IP或端口号,能够提供某种远程服务能力,可以通过Lable Selector来定义Service作用于哪些Pod。如果外部需要访问,可以对外提供Service的type定义:NodePort端口映射和LoadBalancer自定义负载,这样即使运行在不同Node上面相同Lable的Pod,也可以定义Service的Lable Selector和port让外部通过port来访问任何一个该Lable的Pod。如果一个Service需要对外暴露多个端口,可给每个port定义不同的name来区分。
kube-proxy:
每个工作节点都会运行一个kube-proxy服务进程,通过kube-proxy实现流量从service到pod的转发,kube-proxy还可以实现简单的负载均衡功能。kube-proxy有多种代理模式,kube-proxy在工作节点上为每一个服务创建一个临时端口,service的ip:port过来的流量转发到这个临时端口上,kube-proxy会用内部的负载均衡机制(默认是轮寻)选择一个后端pod,然后建立iptables,把流量导入到某个pod里。Kubernetes 支持两种服务发现模式,分别是环境变量和dns。使用环境变量的时候会在pod创建的时候,服务的ip和port信息以环境变量的形式注入到pod里,比如服务ip地址是192.168.1.1,port是8080,则会把下面一系列环境变量注入到pod里,通过这些环境变量获取服务的ip和port。Kubernetes集群内会内置一个dns服务器,service创建成功后,会在dns服务器里导入一些记录,想要访问某个服务,通过dns服务器解析出对应的ip和port,从而实现服务访问。
结合Lable概念说明:
图中每个Pod有两个标签,如果在Service的配置中定义Lable Selector属性为name:tomcat,并且ip地址为192.168.1.216,端口号为8080,那么我们可以通过192.168.1.216:8080同时访问Pod1和Pod3;如果在Service的配置中定义Lable Selector属性为version:1,ip地址为192.168.1.216,端口号为80,那么我们可以通过192.168.1.216:80同时访问Pod1和Pod2。
Pod的概念让我们方便在同一个Pod中通过localhost加端口号来访问不同的容器,而Service让我们方便在同一个Node或外部通过ip地址加端口号来访问不同的“服务器”。
Volume:
是Pod中能够被多个容器访问的共享目录,类似Docker的Volume,只是Pod的Volume生命周期与Pod相同,于容器不相干,并且一个Pod可以有多个Volume。Kubernetes提供两种Volume类型:EmptyDir初始内容为空,同一个Pod中的容器可以读写EmptyDir中的相同文件,如果Pod从Node上移除EmptyDir中的数据也会永远删除;hostPath是在Pod上挂载宿主机上的文件或目录;还可以使用其他存储设备、网络上的永久磁盘或文件系统等作为Volume。
Namespace:
简单的说namespace的定义是为了限制集群范围内的资源访问,即使是同一个用户也不能跨namespace访问资源。
3、服务组件
- Master:
Etcd:是一个高可用的键值存储系统,在k8s中用于持续化集群中所有的资源对象并被监控。
API server:提供了资源对象的唯一操作入口,其他组件都必须通过它提供的API来操作资源数据。
Controller Manager:集群内部的管理控制中心,其主要目的是实现Kubernetes集群的故障检测和恢复的自动化工作。
Scheduler:集群中的调度器,将待调度的Pod按照特定的调度算法和调度策略绑定到集群中某个合适的Node上。
- Node:
kubelet:每个Node上都会启动一个Kubelet服务进程,负责本Node节点上管理监控本Node和本Node上的Pod和容器。
Proxy:实现了Service的代理及软件模式的负载均衡器。
- 创建基本对象流程
kubernetes中基本的对象为Pod、Replication Controller和Service。
Create Pod:
简单说明下Create Pod的过程:
首先用户通过命令行工具(kubecfg也是命令行工具,在新版Kubernetes中,所有的操作命令都整合至kubectl,包括kubecfg、kubectl.sh、kubecfg.sh等)向apiserver提交创建Pod的请求,apiserver将请求的Pod信息对象存储到etcd中;然后scheduler周期性的通过apiserver访问etcd中需要创建的Pod的信息,并且通过调度算法和策略给需要创建的Pod分配Node;最后kubelet周期性的访问etcd需要创建的Pod的信息,通过docker创建并且启动一个容器。
Create ReplicationController:
Create Service:
安装部署
1、资源准备
master(centos 3.10.0-327.el7.x86_64): 192.168.1.187
node(centos 3.10.0-327.el7.x86_64): 192.168.1.107
node(centos 3.10.0-327.el7.x86_64): 192.168.1.105
docker(1.12.3)
kubernetes(1.4.1)
2、修改对应主机名、关闭防火墙和selinux
hostnamectl set-hostname master-187
hostnamectl set-hostname node-107
hostnamectl set-hostname node-105
3、所有主机添加docker的yum源
tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
4、所有主机安装启动docker
yum install -y docker-engine
systemctl enable docker
systemctl start docker
5、所有主机添加kubernetes1.4的(国内)yum源
cat <<EOF> /etc/yum.repos.d/k8s.repo
[kubelet]
name=kubelet
baseurl=http://files.rm-rf.ca/rpms/kubelet/
enabled=1
gpgcheck=0
EOF
6、master主机资源准备
- 下载镜像(版本号不能变,否则创建集群的时候可能导致镜像检查失败不能初始化):
docker pull mritd/kube-proxy-amd64:v1.4.1
docker pull mritd/kube-discovery-amd64:1.0
docker pull mritd/kubedns-amd64:1.7
docker pull mritd/kube-scheduler-amd64:v1.4.1
docker pull mritd/kube-controller-manager-amd64:v1.4.1
docker pull mritd/kube-apiserver-amd64:v1.4.1
docker pull mritd/etcd-amd64:2.2.5
docker pull mritd/kube-dnsmasq-amd64:1.3
docker pull mritd/exechealthz-amd64:1.1
docker pull mritd/pause-amd64:3.0
- 打标镜像:
docker tag mritd/kube-proxy-amd64:v1.4.1 gcr.io/google_containers/kube-proxy-amd64:v1.4.1
docker tag mritd/kube-discovery-amd64:1.0 gcr.io/google_containers/kube-discovery-amd64:1.0
docker tag mritd/kubedns-amd64:1.7 gcr.io/google_containers/kubedns-amd64:1.7
docker tag mritd/kube-scheduler-amd64:v1.4.1 gcr.io/google_containers/kube-scheduler-amd64:v1.4.1
docker tag mritd/kube-controller-manager-amd64:v1.4.1 gcr.io/google_containers/kube-controller-manager-amd64:v1.4.1
docker tag mritd/kube-apiserver-amd64:v1.4.1 gcr.io/google_containers/kube-apiserver-amd64:v1.4.1
docker tag mritd/etcd-amd64:2.2.5 gcr.io/google_containers/etcd-amd64:2.2.5
docker tag mritd/kube-dnsmasq-amd64:1.3 gcr.io/google_containers/kube-dnsmasq-amd64:1.3
docker tag mritd/exechealthz-amd64:1.1 gcr.io/google_containers/exechealthz-amd64:1.1
docker tag mritd/pause-amd64:3.0 gcr.io/google_containers/pause-amd64:3.0
- 删除多余镜像:
docker rmi mritd/kube-proxy-amd64:v1.4.1
docker rmi mritd/kube-discovery-amd64:1.0
docker rmi mritd/kubedns-amd64:1.7
docker rmi mritd/kube-scheduler-amd64:v1.4.1
docker rmi mritd/kube-controller-manager-amd64:v1.4.1
docker rmi mritd/kube-apiserver-amd64:v1.4.1
docker rmi mritd/etcd-amd64:2.2.5
docker rmi mritd/kube-dnsmasq-amd64:1.3
docker rmi mritd/exechealthz-amd64:1.1
docker rmi mritd/pause-amd64:3.0
- 或者编辑镜像更新脚本:
images=(kube-proxy-amd64:v1.4.1 kube-discovery-amd64:1.0 kubedns-amd64:1.7 kube-scheduler-amd64:v1.4.1 kube-controller-manager-amd64:v1.4.1 kube-apiserver-amd64:v1.4.1 etcd-amd64:2.2.5 kube-dnsmasq-amd64:1.3 exechealthz-amd64:1.1 pause-amd64:3.0)
for imageName in $images[@] ; do
docker pull mritd/$imageName
docker tag mritd/$imageName gcr.io/google_containers/$imageName
docker rmi mritd/$imageName
done
- 安装kubernetes相关组件:
yum install -y kubelet kubeadm kubectl kubernetes-cni ebtables
systemctl enable kubelet
systemctl start kubelet
- 编辑/etc/hosts文件:
master创建的pod是运行在node上的,如果不加入节点的ip会按照节点名找节点,会提示no such host。
7、node主机资源准备
- 镜像准备(只需要kube-proxy-amd64和kube-proxy-amd64):
docker pull mritd/kube-proxy-amd64:v1.4.1
docker pull mritd/pause-amd64:3.0
docker tag mritd/kube-proxy-amd64:v1.4.1 gcr.io/google_containers/kube-proxy-amd64:v1.4.1
docker tag mritd/pause-amd64:3.0 gcr.io/google_containers/pause-amd64:3.0
docker rmi mritd/kube-proxy-amd64:v1.4.1
docker rmi mritd/pause-amd64:3.0
- 安装kubernetes相关组件:
yum install -y kubelet kubeadm
systemctl enable kubelet
systemctl start kubelet
8、创建集群
- 初始化集群:
kubeadm init --api-advertise-addresses=192.168.1.187
集群创建成功后会显示如下图:
如果显示到:
<master/apiclient> created API client, waiting for the control plane to become ready
很久也没有往下进行很可能是镜像的版本不匹配,需要重新下载不匹配的镜像。最后的显示的是加入集群的命令,需要记一下,暂时没有找到该token存储的位置。
kubeadm join --token=f1bfac.5df27d2c6aebf2cc 192.168.1.187
- 重置集群
如果集群出现问题可以重置集群,重新init,以下是官网简化的命令:
kubeadm reset
但是重置的时候会停掉所有运行的docker镜像,需要注意。
- 节点加入
kubeadm join --token=f1bfac.5df27d2c6aebf2cc 192.168.1.187
节点加入成功后会显示如下图:
如果提示:
<node/bootstrap> endpoint check failed [failed to connect to https://192.168.1.187:6443[Get https://192.168.1.187:6443/version: x509: certificate has expired or is not yet valid]]<node/bootstrap> trying to connect to endpoint https://192.168.1.187:6443
类似的信息,是你的docker证书过期,使用date命令检查下系统时间是否和当前时间一致,如果不一致需要更新系统时间。
yum -y install ntp
ntpdate cn.pool.ntp.org
如果显示找不到主机的路由是因为没有关闭防火墙。
集群加入成功可以在master上检查下:
kubectl get node
- master主机创建weave网络
如果master主机没有配置weave网络,dns是不会启动的,查看系统默认启动的pod:
kubectl get pod --namespace=kube-system
查看该pod的详细信息(pod后面跟的是你自己的pod名称不要写错):
kubectl describe pod kube-dns-2247936740-0xx49 --namespace=kube-system
提示无法设置网络,无法分配ip,这时候需要创建weave网络:
kubectl create -f https://git.io/weave-kube
weave创建成功显示如下:
该创建过程可能会很慢因为创建weave网络的时候需要在每个主机上下载
weaveworks/weave-npc:1.8.1和weaveworks/weave-kube:1.8.1两个镜像,可以提前下载好,重新查看下dns的pod信息:
9、创建pod
- 创建一个简单的pod示例
先编辑一个busybox.yaml作为pod的yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
hostname: busybox-1
subdomain: default
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox
创建pod:
kubectl create -f busybox.yaml
如果node节点没有busybox的镜像会先下载,所以过程需要等一下,创建后显示:
kubectl get pod
查看pod的详情:
kubectl describe pod busybox
Node属性后面显示的就是该pod被创建的node节点名称和ip,可以107节点上查看是否下载了相关镜像:
- 创建多个跨主机通信的pod示例(借用kubernetes权威指南示例,略微修改 )
首先创建一个mysql的RC:
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql
spec:
replicas: 1
selector:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: '123456'
RC中定义需要运行一个pod,再创建一个mysql的service用于外部通信:
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
service中定义访问接口是3306, 再创建一个应用的RC:
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 5
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
RC中定义需要运行五个pod,使用一个自定义的tomcat镜像,再创建一个应用的service用于外部通信:
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
service中定义对外暴露的接口是30001访问接口是8080,在这个应用镜像中定义了一些mysql的环境变量,用于访问mysql,如果节点主机没有相应镜像可能会有点慢,运行结果如下:
查看应用中的环境变量:
可以使用describe或logs来查看某个pod的详情和日志,如果运行成功在浏览器通过master主机ip加30001访问tomcat,加demo可以访问我们应用的示例:
以上是关于kubernetes1.4简介和安装部署的主要内容,如果未能解决你的问题,请参考以下文章