K8S概念

为何使用K8S

由于大型单体应用转变成微服务架构,因为微服务能独立开发、部署、升级、伸缩,更加灵活。但由于微服务组件越来越多,使得配置、管理并保持系统的正常运行越来越困难,所以K8S提供了对它们的自动调度、配置、监管和故障处理的功能。开发者可以自主部署应用,选择回退版本、多版本部署、控制部署的频率。

Pod

Pod是容器组。一个Pod下的所有容器共享相同的主机名和网络,能够在内部通过回环地址与其他容器互相通信,所以注意同个pod下的容器不能绑定相同的端口号,否则会导致端口冲突。不同Pod下的容器永远不会遇到端口冲突。同一Pod中的各容器是共享一些资源的,其实就是namespace是打通了共享的资源。Pod有如下状态:

  • pending(挂起) 例如没有适合的节点运行pod
  • running (运行)
  • failed (失败)
  • succeeded(成功)
  • unknown

同一pod下的共享资源有如下:
PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID;
网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围;
IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信;
UTS命名空间:Pod中的多个容器共享一个主机名;
Volumes(共享存储卷):Pod中的各个容器可以访问在Pod级别定义的Volumes

Node

Node是Pod真正运行的主机,可以是物理机,也可以是虚拟机。为了管理Pod,每个Node节点上至少要运行container runtime(例如docker)、kubelet和kube-proxy服务,Node有如下状态:

  • Ready:节点正常
  • NotReady: 节点断开

Namespace

相同Namespace的服务可以相互通讯,反之相互隔离。此Namespace与pod中的命名空间是不一样的,k8s 中的Namespace指的是提供了一个作用域,而Pod中命名空间是linux内核提供的命名空间(主机名、网络、文件系统、进程等各个维度)。所谓的作用域,例如通过建立Service访问Pod时,如果Service的Namespace不正确,那么就无法正常关联到Pod。k8s中的集群默认会有一个叫default的Namespace。主要是2个:

  • default:App默认被创建于此。
  • kube-system:kubernetes系统组件使用。

这个默认(default)的Namespace并没什么特别,但你不能删除它。这很适合刚刚开始使用k8s和一些小的服务的系统。但不建议应用于大型生产系统。因为在复杂系统中,团队会非常容易意外地或者无意识地重写或者中断其他服务Service。相反,请创建多个命名空间来把你的服务Service分割成更容易管理的块。

kubectl get ns 查看命名空间列表

--通过文件创建--
$ cat my-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: new-namespace

$ kubectl create -f ./my-namespace.yaml
--或者使用apply--更新
--删除,注意会删除该空间下所有资源--
$ kubectl delete namespaces new-namespace

注意删除一个Namespace后,会把此Namespace下的所有资源删除,还有可能会出现Terminating状态的namespace,这里不细讲
kubectl delete ns 名称 --force --grace-period=0

Deployment

ReplicationController现在已经过时了,建议使用Deployment 配合ReplicaSet。ReplicationController的主要功能是保证Pod的数量、健康,弹性收缩等。但是Deployment除了有这些功能之外,还增加了回滚功能(当升级 pod 镜像或者相关参数的时候,如果有错误,可以回滚到上一个稳定版本),版本记录(每一次对 Deployment 的操作都能保存下来)。暂停和启动(升级的时候,能随时暂停和启动)。虽然ReplicaSets可以独立使用,但是它主要被作为协调作用的Pod创建,删除和更新的机制。在k8s中,有一个叫做kube-controller-manager的组件。这个组件,是一系列控制器的集合,我们创建的Controller按定义的配置进行容器编排

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox-deployment-v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: busybox-v1
  template:
    metadata:
      labels:
        app: busybox-v1
    spec:
      containers:
      - name: busybox-host
        image: busybox:1.31.1
        command: ["sleep"]
        args: ["1000"]

Labels

spec.selector.matchLablesspec.template.metadata.lables的区别。正确的Deployment书写方式,是要让这2个值完全匹配,这样才不会报错。matchLables是必须的。例如app:nginx表示用app=nginx的标签来创建pod实例

StatefulSet

Deployment不足以覆盖所有的应用编排问题,因为在它看来,一个应用的所有Pod是完全一样的,所以它们之间就没有顺序,也无所谓运行在哪台宿主机上。需要时,Deployment就通过Pod模板创建新的Pod,不需要时,就"杀掉"任意一个Pod。但是在实际场景中,并不是所有应用都满足这样的要求。比如:主从关系、主备关系、还有就是数据存储类的多个实例通常会在本地磁盘上保存一份数据,而这些实例一旦被杀掉,即使重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。这种实例之间有不对等关系,或者有依赖关系的应用,被称为“有状态应用(Stateful Application)”,为了支持这种,Kubernetes在Deployment基础上扩展出了StatefulSet。这块功能可以用其他方式解决,对于公用的基础依赖,应该单独抽离出来,配合Deployment也可以落地实现

Service

通过Service来访问Pod,外部的Service可以通过其他的Service的ClusterIP来访问Pod。每个PodIP由网络插件动态随机分配(Pod重启后IP地址会改变)。ClusterIP只在集群内部可访问

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
  selector:  #service通过selector和pod建立关联
    app: nginx

不设置type,这种Service查看详情会发现
spec:clusterIP=None,这种被称为headless serivces,通过这种方式selector选择的pod可以直接从service的endpoints暴露的ip端口进行连接,而不是通过service的CLUSTER-IP间接访问pod

kubectl describe svc myservice查看详情

ClusterIP类型

当使用ClusterIP类型,可以使用以下方式访问,这种方式的负载均衡已经确定,可以使用Istio组件来替换默认的负载均衡

$ kubectl proxy --port=8080 
curl http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/

NodePort类型

当使用NodePort类型,在所有Node上开放一个特定端口,任何发送到该端口的流量都被转发到对应服务。NodePort 服务主要有两点区别于普通的“ClusterIP”服务。第一,它的类型是“NodePort”。有一个额外的端口,称为 nodePort,它指定节点上开放的端口值 。如果你不指定这个端口,系统将选择一个随机端口。大多数时候我们应该让 Kubernetes 来选择端口,让开发者自己来选择可用端口比较麻烦。这种方式每个端口只能是一种服务,而且端口范围只能是 30000-32767。不建议在生产环境上用这种方式暴露服务。如果你运行的服务不要求一直可用,或者对成本比较敏感,你可以使用这种方法。这样的应用的最佳例子是 demo 应用,或者某些临时应用

apiVersion: v1 
kind: Service 
metadata:   
  name: my-nodeport-service 
selector:     
  app: my-app 
spec: 
  type: NodePort 
  ports:   
  - name: http 
    port: 80 
    targetPort: 80 
    nodePort: 30036 
    protocol: TCP 

LoadBalancer类型

使用LoadBalancer类型。这个方式的最大缺点是每一个用 LoadBalancer 暴露的服务都会有它自己的实际的IP地址,用在公有云上,不允考虑

Endpoints

Endpoints把k8s外部应用或服务的address和port发布到k8s,作为内部Service的依赖。如果endpoints和service是同一个名字,那么就自动关联

apiVersion: v1
kind: Endpoints
metadata:
  name: mysql-process
  namespace: mysql
subsets:
  # k8s外部服务的地址和端口
  - addresses:
      - ip: 10.0.0.82
    ports:
      - port: 3306

内部虚拟IP,只有k8s内部的控制器可连接

apiVersion: v1
    kind: Service
    metadata:
      name: mysql-process
      namespace: mysql
    spec:
      ports:
        - port: 3306

Ingress

Ingress是对service的更高层次的抽象,service是工作在tcp/ip层,基于ip和port的,那么ingress是针对http 7层路由机制,将客户端的请求直接转发到service对应的后端pod服务上
使用Ingress类型。最强大的,最灵活。Nginx ingress是k8s所推荐的默认的ingress。缺点:当路由配置非常大的时候,Nginx reload 会耗时非常久,可以达到几秒甚至十几秒,Nginx ingress的插件能力和可扩展性比较差

apiVersion: extensions/v1beta1 
kind: Ingress 
metadata: 
  name: my-ingress 
spec: 
  backend: 
    serviceName: other 
    servicePort: 8080 
  rules: 
  - host: foo.mydomain.com 
    http: 
      paths: 
      - backend: 
          serviceName: foo 
          servicePort: 8080 
  - host: mydomain.com 
    http: 
      paths: 
      - path: /bar/* 
        backend: 
          serviceName: bar 
          servicePort: 8080 

发布文件配置说明

appVersion
1.extensions/v1beta1是用于kubernetes版本在1.6之前
2.apps/v1beta1是用于1.6-1.9版本之间
3.apps/v1是1.9版本以后使用
目前使用的是1.16.3版本可以正常使用apps/v1,使用下面命令查看是否支持某项声明

kubectl api-versions
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,783评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,396评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,834评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,036评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,035评论 5 362
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,242评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,727评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,376评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,415评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,463评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,140评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,734评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,809评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,028评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,521评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,119评论 2 341

推荐阅读更多精彩内容