Kubernetes是一个可轻便的,可拓展的开源平台,为管理容器与服务提供便利的配置以及自动化.现已有着很庞大以及快速增长的生态系统.
Kubernetes还有一个重要的思想就是一切皆容器.
k8s是kubernetes的简称,8代指是ubernete.
关键概念
node
一个节点可以是VM虚拟机或者物理机,部署service运行pod.由Master组件管理.
pod
在K8s当中能够被创建以及调度的最小单元,并不是单个容器,一个Pod是由若干个容器组成.Pod容器内共享Network space.
- IP等网络资源分配的单位的基本单位.
- 共享Volume
- 同一个pod内的容器可以功能性IPC(消息队列等),共享主机名.
service
service其实就是一组pods的集合抽象定义.
service可以由Label Selector选出pods.
pod的IP地址会随着pod生命周期消亡而变更,但service的IP不会产生变更,这样可以很好的标识一个服务.
其实通过概念可以看出Service其实不是真正提供服务的因此,他需要将TCP/UDP的流量转发到实际的Endpoints(实际是由Service的selector选择出的Pod).
还有一点是Service可以直接通过设置ExternalIP(公网IP)访问到内部应用服务.
网络
Docker Mode
Docker中同一主机内容器通过虚拟桥接进行通信,默认情况下这个网络是host-private(私有网络).因此Docker容器在各个节点互不相同.
如果需要进行跨节点进行通信,需要在每台主机上开启端口,Docker代理并转发这个端口的流量到容器中,从而实现跨节点通信.
Kubernetes实现
Kubernetes网络实现概念:
1.所有的容器可以不基于NAT互相通信
2.所有的节点可以和容器进行不基于NAT通信
3.IP地址对容器内外都是一致
NAT:网络地址转换.
pod当中的容器位于同一个NetworkNamespace,因此它们是共享IP的,同一个pod可以通过localhost进行访问.这个是通过Docker的--net=--net=container:<id>
实现.
KubeProxy
用于流量转发每个节点都会存在KubeProxy.为每个服务生成一个虚拟的IP,并由三种(IPVS,iptables,usersapce)方式转发到Pods中.
IPVS还是beta版,这里先只介绍一下两种方式:
- iptables:默认模式,kubeproxy不参与真正的流量转发,实时监听endpoints与service的变化控制iptables的转发规则.实际流量的转发是由iptables进行.因此相比与userspace模式速度更快,流量的转发只是在内核.
- userspace:将实际service中cluster的IP通过iptables转发到kube-proxy代理的端口中然后kube-proxy在转到对应的pod当中.
MASTER组件
MASTER组件可以运行到任集群的何节点,也可以实现高可用.运行这些组件的节点成为主节点.
这些组件为集群提供控制层.这些主要组件做一些主要的决策例如调度,发现和响应集群事件.
- kube-apiserver
位于MASTER节点,暴露K8s的接口 - etcd
提供一致性和高可用的持久化的键值存储服务. - kube-scheduler
观察是否有新的pod创建,如果有新的pod创建并且没有分配节点,为pod分配节点并运行. - kube-controller-manager
- Node Controller:当节点停止时发送通知和进行响应.
- Replication Controller:维护pod在节点设置的正确运行的副本数量.可以用于灰度发布,滚动更新,多版本追踪等
- Endpoints Controller:用于维护Services与endpoint的关系.
- Service Account & Token Controllers:为新的命名空间创建下默认的账户与API的access token.
Node Component
Node Component运行在每一个节点之上,维护运行的pods,以及k8s的环境.
- Kubelet
集群当中每个节点的代理,确保在一个pod中的容器处于运行状态. - kube-proxy
能够让k8s通过维护在主机的网络规则以及连接代理进行服务抽象. - Container Runtime
是承担容器运行的软件
Addons
附加组件都属于kube-system命名空间,不是必须组件,但是这里只介绍一个DNS组件.
DNS
Cluster DNS是一个集群的DNS服务.容器启动时在DNS查询之时会使用DNS服务.
Namespaces
使用不同的命名空间是为了分割资源,使用标签来区分资源在同一命名空间下.
可以在多个命名空间存在相同的名字,但是在单个命名空间下只能存在一个.
Label 与 Selector
Label使用键值存储,关键做用是用于区分不同的对象.可以用来选择区分不同的对象.
命名规则
Label的key分为前缀以及名字.
Key 规则如下:
1.名字必须不超过63个字符,且以字母开头,可由[\.-_a-zA-Z0-9]
构成.
2.前缀必须是域名加/
,不超过253个字符.
3.如果前缀不存在那么k8s会假设这个Key是这个用户私有.
Value规则:
不超过63个字符且以字母开头可由[\.-_a-zA-Z0-9]
构成.
进行选择
目前只支持基于集合和基于相等,并列条件可以在每个选择条件之间加入,
表示逻辑&&
.
基于集合
支持的字符:in not in exists not exists
exists
的语法是直接写Key的名称,下述例子是查找env为qa,dev,prod,且包含partition的key,且不包含notincluded的key.
env in (qa, dev, prod),partition,!notincluded
基于相等
支持的字符:= != ==
.
=
与==
是等价的都表示相等条件.
使用示例:
选出pods当中label中的key为env,value为prod
kubectl get pods -l 'env=prod,partition in (1)'
deployment
主要为了操作部署replicaset与pod.
功能:可以进行横向扩展,蓝绿发布,金丝雀发布,灰度发布,多版本发布等.
除此之外可已根据对应的发布版本的历史记录进行回滚.
当然我们也可以设置自己的策略,当我们部署的pods或者需要更新pods没有正常执行而异常退出,deployment controller会根据设置的策略对部署的pods进行重新部署.
配置示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
#指定副本数量
replicas: 3
selector:
matchLabels:
app: nginx
#pod的模板信息
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
replicaset
主要作用:确保当前运行数量的pods.
官方不推荐直接使用replicaset进行操作,而推荐使用deployment.
其与replication controller最主要的区别是replicaset中selector支持集合操作.
Jobs
一个Job创建一个或者多个pods确保明确的运行数量成功运行.
主要存在下述三种类型:
1.非平行工作:通常启动一个pod,当pod成功退出,任务就被完成.
2.固定执行任务数的平行工作:指定了.spec.completions
非0正数值,当运行成功的pod满足了.spec.completions
的值时,那么任务就会被完成
3.平行工作:每个pod都在运行job,只要有任一一个job中的工作完成,那么其他的pod也会终止job.
CronJob
CronJob是类似于Crond服务的计划工作模式.
配置要求:
1.Kubernetes版本大于1.8
2.对于小于1.8版本的需要在启动时增加--runtime-config=batch/v2alpha1=true
配置项
简单的配置要求
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
Volume
k8s支持很多种类型的Volume.这里简单介绍几种Volume.
Volume声明是在pod当中,因此pod的内的容器共享Volume.
pod中进程看到容器的内的文件系统由两部分组成:
1.Docker镜像文件系统
2.若干个Volume
ConfigMap
ConfigMap可以用于存储一些配置数据,变量等.不适合存储大型文件.
示例:
apiVersion: v1
data:
allowed: '"true"'
enemies: aliens
lives: "3"
kind: ConfigMap
metadata:
creationTimestamp: 2017-12-27T18:36:28Z
name: game-config-env-file
namespace: default
resourceVersion: "809965"
selfLink: /api/v1/namespaces/default/configmaps/game-config-env-file
uid: d9d1ca5b-eb34-11e7-887b-42010a8002b8
secret
secret 可用于存储一些加密的信息以文件的形式传给pod.
persistentVolume
持久化volume,独立于pod的生命周期.指定资源类型,大小,存储类型等等.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
persistentVolumeClaim
对于PersistentVolume的资源请求(分配),被用于挂载persistentVolume到pod上,不需要关心底层的存储环境无论是GCE或者是ISCSI.
通过多个pod使用供用的PVC我们可以实现,不同的之间共享数据.
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
pod使用emptDir类型Volume使用示例
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}