1.kubernetes是什么?
它是一个全新的基于容器技术的分布式系统支撑平台。
kubernetes具有完备的集群管理能力。
包括:
1:多层次的安全防护和准入机制
2:多租户应用支撑能力
3:透明的服务注册和服务发现机制
4:内建的智能负载均衡器
5:强大的故障发现和自我修复能力
6:服务滚动升级和在线扩容能力
7:可扩展的资源自动调度机制
8:多粒度的资源调度配额管理能力
9:完善的管理工具,这些工具涵盖了包括:(开发,部署测试,运维监控在的各个环节)
2.为什么要用kubernets?
1:可以“轻装上阵”地开发复杂系统。之前需要多人协作才能设计,实现和运维的分布式系统,现在只需少量人员就可以轻松实现。
2:可以随时将系统整体搬迁到公有云上。这跟k8s的底层设计有关!
3:kubernetes内在的服务弹性扩容机制可以让我们轻松应对突发流量
3.kubernets基本架构
4.Kubernetes主要由以下几个核心组件组成:
- etcd保存了整个集群的状态;
- apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
- controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
- kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
- Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
- kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
除了核心组件,还有一些推荐的Add-ons:
- kube-dns负责为整个集群提供DNS服务
- Ingress Controller为服务提供外网入口
- Heapster提供资源监控
- Dashboard提供GUI
- Federation提供跨可用区的集群
- Fluentd-elasticsearch提供集群日志采集、存储与查询
k8s各组件间工作流程:
①运维人员向kube-apiserver发出指令(我想干什么,我期望事情是什么状态)(以下kube-apiserver简称apiserver、kube-controller-manager简称controller、kube-scheduler简称scheduler)
②api响应命令,通过一系列认证授权,把pod数据存储到etcd,创建deployment资源并初始化。(期望状态)
③controller通过list-watch机制,监测发现新的deployment,将该资源加入到内部工作队列,发现该资源没有关联的pod和replicaset,启用deployment controller创建replicaset资源,再启用replicaset controller创建pod。
④所有controller被创建完成后.将deployment,replicaset,pod资源更新存储到etcd。
⑤scheduler通过list-watch机制,监测发现新的pod,经过主机过滤、主机打分规则,将pod绑定(binding)到合适的主机。
⑥将绑定结果存储到etcd。
⑦kubelet每隔 20s(可以自定义)向apiserver通过NodeName 获取自身Node上所要运行的pod清单.通过与自己的内部缓存进行比较,新增加pod。
⑧kubelet创建pod。
⑨kube-proxy为新创建的pod注册动态DNS到CoreOS。给pod的service添加iptables/ipvs规则,用于服务发现和负载均衡。
⑩controller通过control loop(控制循环)将当前pod状态与用户所期望的状态做对比,如果当前状态与用户期望状态不同,则controller会将pod修改为用户期望状态,实在不行会将此pod删掉,然后重新创建pod。
5.kubernetes的基本概念和术语:
master
指的是k8s集群控制节点。负责整个集群的管理和控制。所有的控制命令都是在master上运行。
master上运行着以下关键进程
1: kube-apiserver
提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
2:kube-controller-manager
负责维护集群的状态,比如故障检测、自动扩展、滚动更新等.是所有资源对象的自动化控制中心,可以理解为资源对象的“”大总管“”
3:kube-scheduler
负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上
node
除了master,k8s集群中的其他机器别成为node。每个node都会被master 分配一些工作负载(docker容器)
node上运行着以下进程
1:kubelet
负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理.与master密切协作,实现集群管理的基本功能
2:kube-proxy
负责为Service提供cluster内部的服务发现和负载均衡
3:docker engine
负载本机的容器创建和管理工作
pod
pod是一组紧密相关的容器,是一起运行在同一个工作节点上,以及同一个Linux命名空间中。
每个pod就像是一个独立的逻辑机器,拥有自己的IP、主机名、进程等,运行一个独立的应用程序。
pod是逻辑主机,一个pod的所有容器都运行在同一个逻辑机器上。
一个pod包含多个容器时,这些容器总是运行在同一个工作节点上,一个pod绝不可能跨多个工作节点。
pod的管理对象(或者调度策略)有:
1:面向无状态的服务
RC,replicas set,Deployment,DaemonSet
2:面向有状态的服务
StatfulSet
label
一个lable是一个key=value的键值对,key和value都是由用户自己定义。
我们可以通过给指定的资源对象绑定一个或多个不同的lable来实现多维度的资源分组管理功能,
以便灵活,方便的进行资源分配,调度,配置,部署等管理工作
================= Pod调度策略相关概念 =======================
Replication Controller
用来声明某种pod的副本数量在任意时刻都符合某个预期值。因此 RC的定义包括:
1:Pod期待的副本数量
2:用于筛选目标Pod的Lale selector
3:当Pod的副本数量小于预期数量时,用于创建新Pod的Pod模板(template)
Deloyment
是RC的升级版,用于更好的解决Pod的编排问题,我们可以随时知道当前Pod“部署”的进度
Horizontal Pod Autoscaler
用来实现Pod横向自动扩容
StatefulSet
用于部署和扩展有状态应用的pod资源,确保他们的运行顺序及每个pod资源的唯一性
Job
负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束
CronJob
是基于调度的Job执行将会自动产生多个job,调度格式参考Linux的cron系统
================= Pod调度策略相关概念 =======================
Service
Service可以看作是一组提供相同服务的Pod对外的访问接口。
借助Service,应用可以方便地实现服务发现和负载均衡。
Volume
kubernetes中的volume被定于在pod上,是Pod中能够被多个容器访问的共享目录。
volume类型分为(详细介绍):
1: emptyDir
2: hsotPath
3: gcePersistentDisk
4: awsElasticBlockStore
5: NFS
Peristent Volume
一种网络共享存储,不属于 任何node,但可以再任何node上访问,由管理员创建和配置
Persistent Volume Claim
pvc是用户对网络存储资源的一个“申请”。就像创建Pods需要消耗一定的Nodes的资源。pvc能够消费 pv资源
Anotation
与label类似,也使用key、value 键值对的形式进行定义。
主要用于用户任意定义的附加信息,以便于外部工具查找。
ConfigMap
ConfigMap顾名思义,是用于保存配置数据的键值对,可以用来保存单个属性,也可以保存配置文件。
对于一些非敏感数据,比如应用的配置信息,则可以使用ConfigMap
6.例子:
使用kubernetes实现基于tomcat的web服务
此应用需要启动两个容器:tomcat容器和mysql容器,并且tmcat容器需要访问mysql容器。
1 环境准备
使用kuberadm快速安装一个kubernetes集群
2 启动mysql服务
2.1 为mysql服务创建一个RC定义文件mysql-rc.yaml
apiVersion: v1
kind: ReplicationController #资源对象类型:RC
metadata:
name: mysql #RC的名称,全局唯一
spec:
replicas: 1 #pod副本的期待数量
selector: #监控和管理拥有这些标签的pod实例
app: mysql
template: #根据此模板穿件pod的副本(实例)
metadata:
labels:
app: mysql #pod副本拥有的标签,对应RC的selector
spec: #pod内容器的定义部分
containers:
- name: mysql #容器的名称
image: mysql:5.7 # 容器对应的docker镜像
ports:
- containerPort: 3306 # 容器应用监听的端口号
env: # 注入容器内的环境变量
- name: MYSQL_ROOT_PASSWORD
value: "123456"
2.2 发布到kuberntes集群中
[root@k8s-master ~]# kubectl create -f mysql-rc.yaml
replicationcontroller/mysql created
2.3 查看刚刚创建的RC
[root@k8s-master ~]# kubectl get rc
NAME DESIRED CURRENT READY AGE
mysql 1 1 1 17m
2.4 查看pod 创建情况
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-jft2w 1/1 Running 0 42s
2.5 docker 指令查看正在运行的容器
[root@k8s-node1 ~]# docker ps -a|grep mysql
f3f0f36a3de7 mysql "docker-entrypoint.s…" 18 minutes ago Up 18 minutes k8s_mysql_mysql-jft2w_default_51cdaa93-e129-47e3-85ee-07a6d61f8080_0
0c031c2d45d0 registry.aliyuncs.com/google_containers/pause:3.1 "/pause" 19 minutes ago Up 19 minutes k8s_POD_mysql-jft2w_default_51cdaa93-e129-47e3-85ee-07a6d61f8080_0
pause 容器时pod的“”根容器“”
2.6 创建一个与之关联的kubernets Service: mysql-svc.yaml
apiVersion: v1
kind: Service #资源类型为Service
metadata:
name: mysql #service的全局唯一名称
spec:
ports:
- port: 3306 # service提供服务的端口号
selector: #service 对应的pod拥有这里定义的标签
app: mysql
2.7 创建Service
[root@k8s-master ~]# kubectl create -f mysql-svc.yaml
service/mysql created
2.8 查看刚刚创建的Service
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39d
mysql ClusterIP 10.96.228.88 <none> 3306/TCP 3m49s
可以看到 mysql服务被分配了一个值为10.96.228.88的cluster ip地址。
可以通过service的cluster ip端口号3306来访问它了
3 启动tomcat应用
3.1 创建对应的RC文件 :myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
value: 10.96.228.88
3.2 创建RC
[root@k8s-master ~]# kubectl create -f myweb-rc.yaml
replicationcontroller/myweb created
3.3 创建对应的Service myweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
type+NodePort 和nodePort=30001 表明此Service开启了NodePort方式外网访问模式。
可以通过浏览器+30001端口访问myweb
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39d
mysql ClusterIP 10.96.228.88 <none> 3306/TCP 28m
myweb NodePort 10.96.21.149 <none> 8080:30001/TCP 3m56s
3.4 创建 Service
[root@k8s-master ~]# kubectl create -f myweb-svc.yaml
service/myweb created
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39d
mysql ClusterIP 10.96.228.88 <none> 3306/TCP 28m
myweb NodePort 10.96.21.149 <none> 8080:30001/TCP 3m56s
4 通过浏览器访问