seo网站关键词优化哪家好,互联网推广优化,python做网站入门,网站运行方案一、Kubernetes系列之介绍篇
1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建#xff0c;到处运行 - 容器的快速轻量 - 完整的生态环境
2.什么是kubernetes 首先#xff0c;他是一个全新的基于容器技术的分布式架构领先方案。Kubernetes(k8…一、Kubernetes系列之介绍篇
1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建到处运行 - 容器的快速轻量 - 完整的生态环境
2.什么是kubernetes 首先他是一个全新的基于容器技术的分布式架构领先方案。Kubernetes(k8s)是Google开源的容器集群管理系统谷歌内部:Borg。在Docker技术的基础上为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能提高了大规模容器集群管理的便捷性。 Kubernetes是一个完备的分布式系统支撑平台具有完备的集群管理能力多扩多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。同时Kubernetes提供完善的管理工具涵盖了包括开发、部署测试、运维监控在内的各个环节。
Kubernetes中Service是分布式集群架构的核心一个Service对象拥有如下关键特征 拥有一个唯一指定的名字 拥有一个虚拟IPCluster IP、Service IP、或VIP和端口号 能够一统某种远程服务能力 被映射到了提供这种服务能力的一组容器应用上 Service的服务进程目前都是基于Socket通信方式对外提供服务比如Redis、Memcache、MySQL、Web Server或者是实现了某个具体业务的一个特定的TCP Server进程虽然一个Service通常由多个相关的服务进程来提供服务每个服务进程都有一个独立的EndpointIPPort访问点但Kubernetes能够让我们通过服务连接到指定的Service上。有了Kubernetes内建的透明负载均衡和故障恢复机制不管后端有多少服务进程也不管某个服务进程是否会由于发生故障而重新部署到其他机器都不会影响我们对服务的正常调用更重要的是这个Service本身一旦创建就不会发生变化意味着在Kubernetes集群中我们不用为了服务的IP地址的变化问题而头疼了。 容器提供了强大的隔离功能所有有必要把为Service提供服务的这组进程放入容器中进行隔离。为此Kubernetes设计了Pod对象将每个服务进程包装到相对应的Pod中使其成为Pod中运行的一个容器。为了建立Service与Pod间的关联管理Kubernetes给每个Pod贴上一个标签Label比如运行MySQL的Pod贴上namemysql标签给运行PHP的Pod贴上namephp标签然后给相应的Service定义标签选择器Label Selector这样就能巧妙的解决了Service于Pod的关联问题。 在集群管理方面Kubernetes将集群中的机器划分为一个Master节点和一群工作节点Node其中在Master节点运行着集群管理相关的一组进程kube-apiserver、kube-controller-manager和kube-scheduler这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理能力并且都是全自动完成的。Node作为集群中的工作节点运行真正的应用程序在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy服务进程这些服务进程负责Pod的创建、启动、监控、重启、销毁以及实现软件模式的负载均衡器。 在Kubernetes集群中它解决了传统IT系统中服务扩容和升级的两大难题。你只需为需要扩容的Service关联的Pod创建一个Replication Controller简称RC则该Service的扩容及后续的升级等问题将迎刃而解。在一个RC定义文件中包括以下3个关键信息。
·目标Pod的定义
·目标Pod需要运行的副本数量Replicas
·要监控的目标Pod标签Label 在创建好RC后Kubernetes会通过RC中定义的的Label筛选出对应Pod实例并实时监控其状态和数量如果实例数量少于定义的副本数量则会根据RC中定义的Pod模板来创建一个新的Pod然后将新Pod调度到合适的Node上启动运行直到Pod实例的数量达到预定目标这个过程完全是自动化。 Kubernetes优势 - 容器编排 - 轻量级 - 开源 - 弹性伸缩 - 负载均衡
3.Kubernetes的核心概念
1Master k8s集群的管理节点负责管理集群提供集群的资源数据访问入口。拥有Etcd存储服务可选运行Api Server进程Controller Manager服务进程及Scheduler服务进程关联工作节点Node。Kubernetes API server提供HTTP Rest接口的关键服务进程是Kubernetes里所有资源的增、删、改、查等操作的唯一入口也是集群控制的入口进程Kubernetes Controller Manager是Kubernetes所有资源对象的自动化控制中心Kubernetes Schedule是负责资源调度Pod调度的进程
2Node Node是Kubernetes集群架构中运行Pod的服务节点亦叫agent或minion。Node是Kubernetes集群操作的单元用来承载被分配Pod的运行是Pod运行的宿主机。关联Master管理节点拥有名称和IP、系统资源信息。运行docker eninge服务守护进程kunelet及负载均衡器kube-proxy。每个Node节点都运行着以下一组关键进程。
kubelet负责对Pod对于的容器的创建、启停等任务
kube-proxy实现Kubernetes Service的通信与负载均衡机制的重要组件
Docker EngineDockerDocker引擎负责本机容器的创建和管理工作 Node节点可以在运行期间动态增加到Kubernetes集群中默认情况下kubelet会想master注册自己这也是Kubernetes推荐的Node管理方式kubelet进程会定时向Master汇报自身情况如操作系统、Docker版本、CPU和内存以及有哪些Pod在运行等等这样Master可以获知每个Node节点的资源使用情况并实现高效均衡的资源调度策略。
3Pod 运行于Node节点上若干相关容器的组合。Pod内包含的容器运行在同一宿主机上使用相同的网络命名空间、IP地址和端口能够通过localhost进行通。Pod是Kurbernetes进行创建、调度和管理的最小单位它提供了比容器更高层次的抽象使得部署和管理更加灵活。一个Pod可以包含一个容器或者多个相关容器。 Pod其实有两种类型普通Pod和静态Pod后者比较特殊它并不存在Kubernetes的etcd存储中而是存放在某个具体的Node上的一个具体文件中并且只在此Node上启动。普通Pod一旦被创建就会被放入etcd存储中随后会被Kubernetes Master调度到某个具体的Node上进行绑定随后该Pod被对应的Node上的kubelet进程实例化成一组相关的Docker容器并启动起来。在默认情况下当Pod里的某个容器停止时Kubernetes会自动检测到这个问题并且重启这个Pod重启Pod里的所有容器如果Pod所在的Node宕机则会将这个Node上的所有Pod重新调度到其他节点上。
4Replication Controller Replication Controller用来管理Pod的副本保证集群中存在指定数量的Pod副本。集群中副本的数量大于指定数量则会停止指定数量之外的多余容器数量反之则会启动少于指定数量个数的容器保证数量不变。Replication Controller是实现弹性伸缩、动态扩容和滚动升级的核心。
5Service Service定义了Pod的逻辑集合和访问该集合的策略是真实服务的抽象。Service提供了一个统一的服务访问入口以及服务代理和发现机制关联多个相同Label的Pod用户不需要了解后台Pod是如何运行。
外部系统访问Service的问题首先需要弄明白Kubernetes的三种IP Node IPNode节点的IP地址 Pod IP Pod的IP地址 Cluster IPService的IP地址 Node IP是Kubernetes集群中节点的物理网卡IP地址所有属于这个网络的服务器之间都能通过这个网络直接通信。这也表明Kubernetes集群之外的节点访问Kubernetes集群之内的某个节点或者TCP/IP服务的时候必须通过Node IP进行通信 Pod IP是每个Pod的IP地址他是Docker Engine根据docker0网桥的IP地址段进行分配的通常是一个虚拟的二层网络。 Cluster IP是一个虚拟的IP但更像是一个伪造的IP网络原因有以下几点 1. Cluster IP仅仅作用于Kubernetes Service这个对象并由Kubernetes管理和分配P地址 2. Cluster IP无法被ping他没有一个“实体网络对象”来响应 3. Cluster IP只能结合Service Port组成一个具体的通信端口单独的Cluster IP不具备通信的基础并且他们属于Kubernetes集群这样一个封闭的空间。
Kubernetes集群之内Node IP网、Pod IP网与Cluster IP网之间的通信采用的是Kubernetes自己设计的一种编程方式的特殊路由规则。
6Label Kubernetes中的任意API对象都是通过Label进行标识Label的实质是一系列的Key/Value键值对其中key和value由用户自己指定。Label可以附加在各种资源对象上如Node、Pod、Service、RC等一个资源对象可以定义任意数量的Label同一个Label也可以被添加到任意数量的资源对象上去。Label是Replication Controller和Service运行的基础二者通过Label来进行关联Node上运行的Pod。
我们可以通过给指定的资源对象捆绑一个或者多个不同的Label来实现多维度的资源分组管理功能以便于灵活、方便的进行资源分配、调度、配置等管理工作。
一些常用的Label如下
版本标签release:stable,release:canary...... 环境标签environment:dev,environment:qa,environment:production 架构标签tier:frontend,tier:backend,tier:middleware 分区标签partition:customerA,partition:customerB 质量管控标签track:daily,track:weekly
给某个资源对象定义一个Label就相当于给它打了一个标签随后可以通过Label Selector标签选择器查询和筛选拥有某些Label的资源对象Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制。
Label Selector在Kubernetes中重要使用场景如下 1. kube-Controller进程通过资源对象RC上定义Label Selector来筛选要监控的Pod副本的数量从而实现副本数量始终符合预期设定的全自动控制流程 2. kube-proxy进程通过Service的Label Selector来选择对应的Pod自动建立起每个Service到对应Pod的请求转发路由表从而实现Service的智能负载均衡 3. 通过对某些Node定义特定的Label并且在Pod定义文件中使用Nodeselector这种标签调度策略kuber-scheduler进程可以实现Pod”定向调度“的特性
7kubelet kubelet 是 kubernetes 工作节点上的一个代理组件运行在每个节点上。 kubelet是工作节点上的主要服务定期从kube-apiserver组件接收新的或修改的Pod规范并确保Pod及其容器在期望规范下运行。同时该组件作为工作节点的监控组件向kube-apiserver汇报主机的运行状况。
更多kubectl参考kubelet | Kubernetes
8kubeadm 一个搭建kubernetes环境一个工具用于初始化cluster
9kubectl kubectl控制Kubernetes集群管理器使用Kubernetes命令行工具kubectl在Kubernetes上部署和管理应用程序。使用kubectl您可以检查群集资源; 创建删除和更新组件; 看看你的新集群; 并提出示例应用程序。
更多kubectl参考kubectl| Kubernetes
4.Kubernetes架构和组件
- 服务分组小集群多集群 - 服务分组大集群单集群
1Master控制组件调度管理整个系统集群包含如下组件 1.Kubernetes API Server 作为Kubernetes系统的入口其封装了核心对象的增删改查操作以RESTful API接口方式提供给外部客户和内部组件调用。维护的REST对象持久化到Etcd中存储。 2.Kubernetes Scheduler 为新建立的Pod进行节点(node)选择(即分配机器)负责集群的资源调度。组件抽离可以方便替换成其他调度器。 3.Kubernetes Controller 负责执行各种控制器目前已经提供了很多控制器来保证Kubernetes的正常运行。 4. Replication Controller 管理维护Replication Controller关联Replication Controller和Pod保证Replication Controller定义的副本数量与实际运行Pod数量一致。 5. Node Controller 管理维护Node定期检查Node的健康状态标识出失效或未失效的Node节点。 6. Namespace Controller 管理维护Namespace定期清理无效的Namespace包括Namesapce下的API对象比如Pod、Service等。 7. Service Controller 管理维护Service提供负载以及服务代理。 8.EndPoints Controller 管理维护Endpoints关联Service和Pod创建Endpoints为Service的后端当Pod发生变化时实时更新Endpoints。 9. Service Account Controller 管理维护Service Account为每个Namespace创建默认的Service Account同时为Service Account创建Service Account Secret。 10. Persistent Volume Controller 管理维护Persistent Volume和Persistent Volume Claim为新的Persistent Volume Claim分配Persistent Volume进行绑定为释放的Persistent Volume执行清理回收。 11. Daemon Set Controller 管理维护Daemon Set负责创建Daemon Pod保证指定的Node上正常运行Daemon Pod。 12. Deployment Controller 管理维护Deployment关联Deployment和Replication Controller保证运行指定数量的Pod。当Deployment更新时控制实现Replication Controller和 Pod的更新。 13.Job Controller 管理维护Job为Jod创建一次性任务Pod保证完成Job指定完成的任务数目 14. Pod Autoscaler Controller 实现Pod的自动伸缩定时获取监控数据进行策略匹配当满足条件时执行Pod的伸缩动作。
2Node运行节点组件运行管理业务容器包含如下组件 1.Kubelet 负责管控容器Kubelet会从Kubernetes API Server接收Pod的创建请求启动和停止容器监控容器运行状态并汇报给Kubernetes API Server。 2.Kubernetes Proxy 负责为Pod创建代理服务Kubernetes Proxy会从Kubernetes API Server获取所有的Service信息并根据Service的信息创建代理服务实现Service到Pod的请求路由和转发从而实现Kubernetes层级的虚拟转发网络。 3.Docker Node上需要运行容器服务即k8s的运行时软件之一。
二、基于kubernetes构建Docker集群环境实战
kubernetes是google公司基于docker所做的一个分布式集群有以下组件组成
1.Kubernetes组成组件 etcd: 高可用存储共享配置和服务发现作为与minion机器上的flannel配套使用作用是使每台minion上运行的docker拥有不同的ip段最终目的是使不同minion上正在运行的docker containner都有一个与别的任意一个containner别的minion上运行的docker containner不一样的IP地址。 flannel: 网络结构支持 kube-apiserver: 不论通过kubectl还是使用remote api 直接控制都要经过apiserver kube-controller-manager: 对replication controller, endpoints controller, namespace controller, and serviceaccounts controller的循环控制与kube-apiserver交互保证这些controller工作 kube-scheduler: Kubernetes scheduler的作用就是根据特定的调度算法将pod调度到指定的工作节点minion上这一过程也叫绑定bind) kubelet: Kubelet运行在Kubernetes Minion Node上.它是container agent的逻辑继任者 kube-proxy: kube-proxy是kubernetes 里运行在minion节点上的一个组件, 它起的作用是一个服务代理的角色
图为GITJenkinsKubernetesDockerEtcdconfdNginxGlusterfs架构如下
2.构建K8S环境
centos7系统机器三台 10.0.0.81: 用来安装kubernetes master 10.0.0.82: 用作kubernetes minionminion1 10.0.0.83: 用作kubbernetes minion (minion2)
3.关闭防火墙及selinux
1如果系统开启了防火墙则按如下步骤关闭防火墙所有机器
# systemctl stop firewalld
# systemctl disable firewalld
2关闭selinux #setenforce 0 #sed -i /^SELINUX/cSELINUXdisabled /etc/sysconfig/selinux 4.MASTER安装配置 1安装并配置Kubernetes master(yum 方式) # yum -y install etcd kubernetes 配置etcd确保列出的这些项都配置正确并且没有被注释掉下面的配置都是如此 # vim /etc/etcd/etcd.conf ETCD_NAMEdefault ETCD_DATA_DIR/var/lib/etcd/default.etcd ETCD_LISTEN_CLIENT_URLShttp://0.0.0.0:2379 ETCD_ADVERTISE_CLIENT_URLShttp://localhost:2379 配置kubernetes # vim /etc/kubernetes/apiserver KUBE_API_ADDRESS--address0.0.0.0KUBE_API_PORT--port8080 KUBELET_PORT--kubelet_port10250 KUBE_ETCD_SERVERS--etcd_servershttp://127.0.0.1:2379 KUBE_SERVICE_ADDRESSES--service-cluster-ip-range10.254.0.0/16 KUBE_ADMISSION_CONTROL--admission_controlNamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota KUBE_API_ARGS 2启动服务 # for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do systemctl restart $SERVICES systemctl enable $SERVICES systemctl status $SERVICES done 3设置etcd网络 #etcdctl -C 10.0.0.81:2379 set /atomic.io/network/config {Network:10.1.0.0/16} 4master配置完成验证
运行kubectl get nodes可以查看有多少minion在运行及其状态。这里我们的minion还都没有开始安装配置所以运行之后结果为空 # kubectl get nodes NAME LABELS STATUS 5.MINION安装配置
每台minion机器都按如下安装配置
1环境安装和配置 # yum -y install flannel kubernetes 配置kubernetes连接的服务端IP #vim /etc/kubernetes/config KUBE_MASTER--masterhttp://10.0.0.81:8080 KUBE_ETCD_SERVERS--etcd_servershttp://10.0.0.81:2379 配置kubernetes请使用每台minion自己的IP地址比如10.0.0.82代替下面的$LOCALIP #vim /etc/kubernetes/kubeletbrKUBELET_ADDRESS--address0.0.0.0 KUBELET_PORT--port10250 # change the hostname to this host’s IP address KUBELET_HOSTNAME--hostname_override$LOCALIP KUBELET_API_SERVER--api_servershttp://10.0.0.81:8080 KUBELET_ARGS 2docker服务启动准备工作
如果本来机器上已经运行过docker的请看过来没有运行过的请忽略此步骤运行ifconfig查看机器的网络配置情况有docker0 # ifconfig docker0 Link encap:Ethernet HWaddr 02:42:B2:75:2E:67 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) warning:在运行过docker的机器上可以看到有docker0这里在启动服务之前需要删掉docker0配置 # sudo ip link delete docker0 3配置flannel网络 # vim /etc/sysconfig/flanneld FLANNEL_ETCD_ENDPOINTShttp://10.0.0.81:2379 FLANNEL_ETCD_PREFIX/atomic.io/network PS其中atomic.io与上面etcd中的Network对应
4启动服务 # for SERVICES in flanneld kube-proxy kubelet docker; do systemctl restart $SERVICES systemctl enable $SERVICES systemctl status $SERVICES done 5配置完成验证
确定两台minion(10.0.0.82和10.0.0.83)和一台master10.0.0.81都已经成功的安装配置并且服务都已经启动切换到master机器上 # kubectl get nodes NAME STATUS AGE 10.0.0.82 Ready 1m 10.0.0.83 Ready 1m 可以看到配置的两台minion已经在master的node列表中了。如果想要更多的node只需要按照minion的配置配置更多的机器就可以了。
三、Kubernetes之深入了解Pod
1.yaml格式的Pod配置文件内容及注解
深入Pod之前首先我们来了解下Pod的yaml整体文件内容及功能注解。
# yaml格式的pod定义文件完整内容
apiVersion: v1 #必选版本号例如v1
kind: Pod #必选Pod
metadata: #必选元数据name: string #必选Pod名称namespace: string #必选Pod所属的命名空间labels: #自定义标签- name: string #自定义标签名字annotations: #自定义注释列表- name: string
spec: #必选Pod中容器的详细定义containers: #必选Pod中容器列表- name: string #必选容器名称image: string #必选容器的镜像名称imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像否则下载镜像Nerver表示仅使用本地镜像command: [string] #容器的启动命令列表如不指定使用打包时使用的启动命令args: [string] #容器的启动命令参数列表workingDir: string #容器的工作目录volumeMounts: #挂载到容器内部的存储卷配置- name: string #引用pod定义的共享存储卷的名称需用volumes[]部分定义的的卷名mountPath: string #存储卷在容器内mount的绝对路径应少于512字符readOnly: boolean #是否为只读模式ports: #需要暴露的端口库号列表- name: string #端口号名称containerPort: int #容器需要监听的端口号hostPort: int #容器所在主机需要监听的端口号默认与Container相同protocol: string #端口协议支持TCP和UDP默认TCPenv: #容器运行前需设置的环境变量列表- name: string #环境变量名称value: string #环境变量的值resources: #资源限制和请求的设置limits: #资源限制的设置cpu: string #Cpu的限制单位为core数将用于docker run --cpu-shares参数memory: string #内存限制单位可以为Mib/Gib将用于docker run --memory参数requests: #资源请求的设置cpu: string #Cpu请求容器启动的初始可用数量memory: string #内存清楚容器启动的初始可用数量livenessProbe: #对Pod内个容器健康检查的设置当探测无响应几次后将自动重启该容器检查方法有exec、httpGet和tcpSocket对一个容器只需设置其中一种方法即可exec: #对Pod容器内检查方式设置为exec方式command: [string] #exec方式需要制定的命令或脚本httpGet: #对Pod内个容器健康检查方法设置为HttpGet需要制定Path、portpath: stringport: numberhost: stringscheme: stringHttpHeaders:- name: stringvalue: stringtcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式port: numberinitialDelaySeconds: 0 #容器启动完成后首次探测的时间单位为秒timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间单位秒默认1秒periodSeconds: 0 #对容器监控检查的定期探测时间设置单位秒默认10秒一次successThreshold: 0failureThreshold: 0securityContext:privileged:falserestartPolicy: [Always | Never | OnFailure]#Pod的重启策略Always表示一旦不管以何种方式终止运行kubelet都将重启OnFailure表示只有Pod以非0退出码退出才重启Nerver表示不再重启该PodnodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上以keyvalue的格式指定imagePullSecrets: #Pull镜像时使用的secret名称以keysecretkey格式指定- name: stringhostNetwork:false #是否使用主机网络模式默认为false如果设置为true表示使用宿主机网络volumes: #在该pod上定义共享存储卷列表- name: string #共享存储卷名称 volumes类型有很多种emptyDir: {} #类型为emtyDir的存储卷与Pod同生命周期的一个临时目录。为空值hostPath: string #类型为hostPath的存储卷表示挂载Pod所在宿主机的目录path: string #Pod所在宿主机的目录将被用于同期中mount的目录secret: #类型为secret的存储卷挂载集群与定义的secre对象到容器内部scretname: string items: - key: stringpath: stringconfigMap: #类型为configMap的存储卷挂载预定义的configMap对象到容器内部name: stringitems:- key: stringpath: string 2.Pod基本用法 在使用docker时我们可以使用docker run命令创建并启动一个容器而在Kubernetes系统中对长时间运行的容器要求是其主程序需要一直在前台运行。如果我们创建的docker镜像的启动命令是后台执行程序例如Linux脚本
nohup ./startup.sh
则kubelet创建包含这个容器的pod后运行完该命令即认为Pod执行结束之后根据RC中定义的pod的replicas副本数量生产一个新的pod而一旦创建出新的pod将在执行完命令后陷入无限循环的过程中这就是Kubernetes需要我们创建的docker镜像以一个前台命令作为启动命令的原因。 对于无法改造为前台执行的应用也可以使用开源工具supervisor辅助进行前台运行的功能。
****Pod可以由一个或多个容器组合而成
例如两个容器应用的前端frontend和redis为紧耦合的关系应该组合成一个整体对外提供服务则应该将这两个打包为一个pod.
配置文件frontend-localredis-pod.yaml如下 apiVersion:v1 kind: Pod metadata: name: redis-php label: name: redis-php spec: containers: - name: frontend image: kubeguide/guestbook-php-frontend:localredis ports: - containersPort: 80 - name: redis-php image:kubeguide/redis-master ports: - containersPort: 6379 属于一个Pod的多个容器应用之间相互访问只需要通过localhost就可以通信这一组容器被绑定在一个环境中。
使用kubectl create创建该Pod后get Pod信息可以看到如下 #kubectl get gods NAME READY STATUS RESTATS AGE redis-php 2/2Running 0 10m 可以看到READY信息为2/2表示Pod中的两个容器都成功运行了。
查看pod的详细信息可以看到两个容器的定义和创建过程 [rootkubernetes-master ~]# kubectl describe redis-php the server doesnt have a resourcetype redis-php [rootkubernetes-master ~]# kubectl describe pod redis-php Name: redis-php Namespace: default Node: kubernetes-minion/10.0.0.23 Start Time: Wed, 12 Apr 2017 09:14:58 0800 Labels: nameredis-php Status: Running IP: 10.1.24.2 Controllers: none Containers: nginx: Container ID: docker://d05b743c200dff7cf3b60b7373a45666be2ebb48b7b8b31ce0ece9be4546ce77 Image: nginx Image ID: docker-pullable://docker.io/nginxsha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582 Port: 80/TCP State: Running Started: Wed, 12 Apr 2017 09:19:31 0800 3.静态Pod 静态pod是由kubelet进行管理的仅存在于特定Node的Pod上他们不能通过API Server进行管理无法与ReplicationController、Deployment或者DaemonSet进行关联并且kubelet无法对他们进行健康检查。静态Pod总是由kubelet进行创建并且总是在kubelet所在的Node上运行。
创建静态Pod有两种方式配置文件或者HTTP方式
1配置文件方式 首先需要设置kubelet的启动参数--config指定kubelet需要监控的配置文件所在的目录kubelet会定期扫描该目录并根据目录中的 .yaml或 .json文件进行创建操作。
假设配置目录为/etc/kubelet.d/配置启动参数:--config/etc/kubelet.d/然后重启kubelet服务在宿主机上用docker ps或者在Kubernetes Master上都可以看到指定的容器在列表中
由于静态pod无法通过API Server直接管理所以在master节点尝试删除该pod会将其变为pending状态也不会被删除 #kubetctl delete pod static-web-node1 pod static-web-node1deleted #kubectl get pods NAME READY STATUS RESTARTS AGE static-web-node1 0/1Pending 0 1s 要删除该pod只能在其所在的Node上操作将其定义的.yaml文件从/etc/kubelet.d/目录下删除 # rm -f /etc/kubelet.d/static-web.yaml # docker ps 4.Pod容器共享Volume Volume类型包括emtyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、gitRepo、secret、nfs、scsi、glusterfs、persistentVolumeClaim、rbd、flexVolume、cinder、cephfs、flocker、downwardAPI、fc、azureFile、configMap、vsphereVolume等等可以定义多个Volume每个Volume的name保持唯一。在同一个pod中的多个容器能够共享pod级别的存储卷Volume。Volume可以定义为各种类型多个容器各自进行挂载操作将一个Volume挂载为容器内需要的目录。如下图 上图中的Pod中包含两个容器tomcat和busybox在pod级别设置Volume “app-logs”用于tomcat向其中写日志文件busybox读日志文件。
配置文件如下 apiVersion:v1 kind: Pod metadata: name: redis-php label: name: volume-pod spec: containers: - name: tomcat image: tomcat ports: - containersPort: 8080 volumeMounts: - name: app-logs mountPath:/usr/local/tomcat/logs - name: busybox image:busybox command: [sh,-C,tail -f /logs/catalina*.log] volumes: - name: app-logs emptyDir:{} busybox容器可以通过kubectl logs查看输出内容 # kubectl logs volume-pod -c busybox tomcat容器生成的日志文件可以登录容器查看 # kubectl exec -ti volume-pod -c tomcat -- ls /usr/local/tomcat/logs 5.Pod的配置管理 应用部署的一个最佳实践是将应用所需的配置信息与程序进行分离这样可以使得应用程序被更好的复用通过不同配置文件也能实现更灵活的功能。将应用打包为容器镜像后可以通过环境变量或外挂文件的方式在创建容器时进行配置注入。ConfigMap是Kubernetes v1.2版本开始提供的一种统一集群配置管理方案。
1ConfigMap容器应用的配置管理
容器使用ConfigMap的典型用法如下
1生产为容器的环境变量。
2设置容器启动命令的启动参数需设置为环境变量。
3以Volume的形式挂载为容器内部的文件或目录。 ConfigMap以一个或多个key:value的形式保存在Kubernetes系统中共应用使用既可以用于表示一个变量的值也可以表示一个完整的配置文件内容。
通过yaml配置文件或者直接使用kubelet create configmap 命令的方式来创建ConfigMap
2ConfigMap的创建
举个小例子cm-appvars.yaml来描述将几个应用所需的变量定义为ConfigMap的用法 # vim cm-appvars.yaml apiVersion: v1 kind: ConfigMap metadata: name: cm-appvars data: apploglevel: info appdatadir:/var/data 执行kubectl create命令创建该ConfigMap # kubectl create -f cm-appvars.yaml configmap cm-appvars.yamlcreated 查看建立好的ConfigMap #kubectl get configmap NAME DATA AGE cm-appvars 2 3s [rootkubernetes-master ~]# kubectl describe configmap cm-appvars Name: cm-appvars Namespace: default Labels: none Annotations: none Data appdatadir: 9 bytes apploglevel: 4 bytes [rootkubernetes-master ~]# kubectl get configmap cm-appvars -o yaml apiVersion: v1 data: appdatadir: /var/data apploglevel: info kind: ConfigMap metadata: creationTimestamp: 2017-04-14T06:03:36Z name: cm-appvars namespace: default resourceVersion:571221 selfLink: /api/v1/namespaces/default/configmaps/cm-appvars uid: 190323cb-20d8-11e7-94ec-000c29ac8d83 另创建一个cm-appconfigfile.yaml描述将两个配置文件server.xml和logging.properties定义为configmap的用法设置key为配置文件的别名value则是配置文件的文本内容 apiVersion: v1 kind: ConfigMap metadata: name: cm-appvars data: key-serverxml: ?xml Version1.0encodingutf-8? Server port8005shutdownSHUTDOWN ..... /service /Server key-loggingproperties: handlerslcatalina.org.apache.juli.FileHandler, .... 在pod cm-test-app定义中将configmap cm-appconfigfile中的内容以文件形式mount到容器内部configfiles目录中。
Pod配置文件cm-test-app.yaml内容如下 # vim cm-test-app.yaml apiVersion: v1 kind: Pod metadata: name: cm-test-app spec: containers: - name: cm-test-app image: tomcat-app:v1 ports: - containerPort: 8080 volumeMounts: - name: serverxml #引用volume名 mountPath:/configfiles #挂载到容器内部目录 configMap: name: cm-test-appconfigfile #使用configmap定义的的cm-appconfigfile items: - key: key-serverxml #将keykey-serverxml path: server.xml #value将server.xml文件名进行挂载 - key: key-loggingproperties #将keykey-loggingproperties path: logging.properties #value将logging.properties文件名进行挂载 创建该Pod # kubectl create -f cm-test-app.yaml Pod cm-test-appcreated 登录容器查看configfiles目录下的server.xml和logging.properties文件他们的内容就是configmap “cm-appconfigfile”中定义的两个key的内容 # kubectl exec -ti cm-test-app -- bash # cat /configfiles/server.xml # cat /configfiles/logging.properties 3使用ConfigMap的条件限制
使用configmap的限制条件如下 configmap必须在pod之间创建 configmap也可以定义为属于某个Namespace只有处于相同namespaces中的pod可以引用 configmap中配额管理还未能实现 kubelet只支持被api server管理的pod使用configmap静态pod无法引用 在pod对configmap进行挂载操作时容器内部职能挂载为目录无法挂载文件。
6.Pod生命周期和重启策略 Pod在整个生命周期过程中被定义为各种状态熟悉Pod的各种状态有助于理解如何设置Pod的调度策略、重启策略
Pod的状态包含以下几种如图 Pod的重启策略RestartPolicy应用于Pod内所有的容器并且仅在Pod所处的Node上由kubelet进行判断和重启操作。当某哥容器异常退出或者健康检查失败时kubelet将根据RestartPolicy的设置进行相应的操作 Pod的重启策略包括Always、OnFailure及Nerver默认值为Always。 kubelet重启失效容器的时间间隔以sync-frequency乘以2n来计算例如1、2、4、8倍等最长延时5分钟并且成功重启后的10分钟后重置该事件。 Pod的重启策略和控制方式息息相关当前可用于管理Pod的控制器宝库ReplicationController、Job、DaemonSet及直接通过kubelet管理静态Pod每种控制器对Pod的重启策略要求如下
o RC和DaemonSet必须设置为Always需要保证该容器持续运行
o JobOnFailure或Nerver确保容器执行完成后不再重启
o kubelet在Pod失效时重启他不论RestartPolicy设置什么值并且也不会对Pod进行健康检查
7.Pod健康检查
对Pod的健康检查可以通过两类探针来检查LivenessProbe和ReadinessProbe
o LivenessProbe探针用于判断容器是否存活running状态如果LivenessProbe探针探测到容器不健康则kubelet杀掉该容器并根据容器的重启策略做响应处理
o ReadinessProbe探针用于判断容器是否启动完成ready状态可以接受请求。如果ReadinessProbe探针探测失败则Pod的状态被修改。Endpoint Controller将从service的Endpoint中删除包含该容器所在的Pod的Endpoint。
kubelet定制执行LivenessProbe探针来诊断容器的健康状况。LivenessProbe有三种事项方式。
1ExecAction在容器内部执行一个命令如果该命令的返回值为0则表示容器健康例 apiVersion:v1 kind: Pod metadata: name: liveness-exec label: name: liveness spec: containers: - name: tomcat image: grc.io/google_containers/tomcat args: -/bin/sh - -c -echo ok /tmp.health;sleep10; rm -fr /tmp/health;sleep600 livenessProbe: exec: command: -cat -/tmp/health initianDelaySeconds:15 timeoutSeconds:1 2TCPSocketAction通过容器ip地址和端口号执行TCP检查如果能够建立tcp连接表明容器健康例 kind: Pod metadata: name: pod-with-healthcheck spec: containers: - name: nginx image: nginx livenessProbe: tcpSocket: port: 80 initianDelaySeconds:30 timeoutSeconds:1 3HTTPGetAction通过容器Ip地址、端口号及路径调用http get方法如果响应的状态码大于200且小于400则认为容器健康例 apiVersion:v1 kind: Pod metadata: name: pod-with-healthcheck spec: containers: - name: nginx image: nginx livenessProbe: httpGet: path:/_status/healthz port: 80 initianDelaySeconds:30 timeoutSeconds:1 对于每种探针方式都需要设置initialDelaySeconds和timeoutSeconds两个参数它们含义如下
·initialDelaySeconds启动容器后首次监控检查的等待时间单位秒
·timeouSeconds健康检查发送请求后等待响应的超时时间单位秒。当发生超时就被认为容器无法提供服务无该容器将被重启
8.玩转Pod调度 在Kubernetes系统中Pod在大部分场景下都只是容器的载体而已通常需要通过RC、Deployment、DaemonSet、Job等对象来完成Pod的调度和自动控制功能。
1RC、Deployment全自动调度 RC的主要功能之一就是自动部署容器应用的多份副本以及持续监控副本的数量在集群内始终维护用户指定的副本数量。
在调度策略上除了使用系统内置的调度算法选择合适的Node进行调度也可以在Pod的定义中使用NodeSelector或NodeAffinity来指定满足条件的Node进行调度。
1NodeSelector:定向调度 Kubernetes Master上的scheduler服务kube-Scheduler进程负责实现Pod的调度整个过程通过一系列复杂的算法最终为每个Pod计算出一个最佳的目标节点通常我们无法知道Pod最终会被调度到哪个节点上。实际情况中我们需要将Pod调度到我们指定的节点上可以通过Node的标签和pod的nodeSelector属性相匹配来达到目的。
首先通过kubectl label命令给目标Node打上标签
kubectl label nodes node-name label-keylabel-value # kubectllabel nodes k8s-node-1 zonenorth 然后在Pod定义中加上nodeSelector的设置例 apiVersion:v1 kind: Pod metadata: name: redis-master label: name: redis-master spec: replicas: 1 selector: name: redis-master template: metadata: labels: name: redis-master spec: containers: - name: redis-master images: kubeguide/redis-master ports: - containerPort: 6379 nodeSelector: zone: north 运行kubectl create -f命令创建Podscheduler就会将该Pod调度到拥有zonenorth标签的Node上。 如果多个Node拥有该标签则会根据调度算法在该组Node上选一个可用的进行Pod调度。
需要注意的是如果集群中没有拥有该标签的Node则这个Pod也无法被成功调度。
2NodeAffinity亲和性调度
该调度策略是将来替换NodeSelector的新一代调度策略。由于NodeSelector通过Node的Label进行精确匹配所有NodeAffinity增加了In、NotIn、Exists、DoesNotexist、Gt、Lt等操作符来选择Node。调度侧露更加灵活。
2DaemonSet特定场景调度
DaemonSet用于管理集群中每个Node上仅运行一份Pod的副本实例如图 这种用法适合一些有下列需求的应用
·在每个Node上运行个以GlusterFS存储或者ceph存储的daemon进程
·在每个Node上运行一个日志采集程序例如fluentd或者logstach
·在每个Node上运行一个健康程序采集Node的性能数据。
DaemonSet的Pod调度策略类似于RC除了使用系统内置的算法在每台Node上进行调度也可以在Pod的定义中使用NodeSelector或NodeAffinity来指定满足条件的Node范围来进行调度。
3批处理调度
9.Pod的扩容和缩容 在实际生产环境中我们经常遇到某个服务需要扩容的场景也有可能因为资源精确需要缩减资源而需要减少服务实例数量此时我们可以Kubernetes中RC提供scale机制来完成这些工作。
以redis-slave RC为例已定义的最初副本数量为2通过kubectl scale命令可以将Pod副本数量重新调整 #kubectl scale rc redis-slave --replicas3 ReplicationControllerredis-slave scaled #kubectl get pods NAME READY STATUS RESTARTS AGE redis-slave-1sf23 1/1Running 0 1h redis-slave-54wfk 1/1Running 0 1h redis-slave-3da5y 1/1Running 0 1h 除了可以手工通过kubectl scale命令完成Pod的扩容和缩容操作以外新版本新增加了Horizontal Podautoscaler(HPA)的控制器用于实现基于CPU使用路进行启动Pod扩容缩容的功能。该控制器基于Mastger的kube-controller-manager服务启动参数 --horizontal-pod-autoscler-sync-period定义的时长默认30秒周期性监控目标Pod的Cpu使用率并在满足条件时对ReplicationController或Deployment中的Pod副本数量进行调整以符合用户定义的平均Pod Cpu使用率Pod Cpu使用率来源于heapster组件所以需预先安装好heapster。
10. Pod的滚动升级 当集群中的某个服务需要升级时我们需要停止目前与该服务相关的所有Pod然后重新拉取镜像并启动。如果集群规模较大因服务全部停止后升级的方式将导致长时间的服务不可用。由此Kubernetes提供了rolling-update滚动升级功能来解决该问题。
滚动升级通过执行kubectl rolling-update命令一键完成该命令创建一个新的RC然后自动控制旧版本的Pod数量逐渐减少到0同时新的RC中的Pod副本数量从0逐步增加到目标值最终实现Pod的升级。需要注意的是系统要求新的RC需要与旧的RC在相同的Namespace内即不能把别人的资产转到到自家名下。
例将redis-master从1.0版本升级到2.0 apiVersion: v1 kind: replicationController metadata: name: redis-master-v2 labels: name: redis-master Version: v2 spec: replicas: 1 selector: name: redis-master Version: v2 template: labels: name: redis-master Version: v2 spec: containers: - name: master images: kubeguide/redis-master:2.0 ports: - containerPort: 6379 需要注意的点
1RC的name不能与旧的RC名字相同
2在Selector中应至少有一个label与旧的RC的label不同以标识为新的RC。本例中新增了一个名为version的label与旧的RC区分
运行kubectl rolling-update来完成Pod的滚动升级 #kubectl rolling-update redis-master -f redis-master-controller-v2.yaml 另一种方法就是不使用配置文件直接用kubectl rolling-update加上--image参数指定新版镜像名来完成Pod的滚动升级 #kubectl rolling-update redis-master --imageredis-master:2.0 与使用配置文件的方式不同的是执行的结果是旧的RC被删除新的RC仍然使用旧RC的名字。
如果在更新过程总发现配置有误则用户可以中断更新操作并通过执行kubectl rolling-update-rollback完成Pod版本的回滚。 --------------------- 作者Yonself 来源CSDN 原文https://blog.csdn.net/qq_25518029/article/details/120215350 版权声明本文为作者原创文章转载请附上博文链接 内容解析ByCSDN,CNBLOG博客文章一键转载插件