Hello K8s
- 创建集群
kind create cluster
kubectl apply -f mysql-deploy.yaml
k create -f mysql-svc.yaml
k get svc mysql
获取 CLUSTER-IPk apply -f myweb-deploy.yaml
连接 CLUSTER-IPk create -f myweb-svc.yaml
指定 nodePortk get nodes -o wide
获取 node 的 INTERNAL-IP,简称 nodeIPcurl -vL http://<nodeIP>:<nodePort>/demo/
其他命令
1 | sql复制代码k get pods |
集群 Cluster
Cluster 包含一个 Master 和 N 个 Node(N>=0)。
Master 上的关键进程
- kube-apiserver:提供 HTTP RESTful API接口的主要服务,是Kubernetes里对所有资源进行增、删、改、查等操作的唯一入口,也是集群控制的入口进程。
- kube-controller-manager:Kubernetes 里所有资源对象的自动化控制中心
- kube-scheduler:负责资源调度(Pod 调度)的进程
- etcd
Node 上的关键进程
- kubelet:负责 Pod 对应容器的创建、启停等任务,同时与 Master 密切协作,实现集群管理的基本功能。
- kube-proxy:实现 Kubernetes Service 的通信与负载均衡机制的服务。
- 容器运行时(如 Docker):负责本机的容器创建和管理。
Service
一般说来,Service指的是无状态服务,通常由多个程序副本提供服务,在特殊情况下也可以是有状态的单实例服务,比如MySQL这种数据存储类的服务。
系统最终由多个提供不同业务能力而又彼此独立的微服务单元组成,服务之间通过TCP/IP进行通信,从而形成强大又灵活的弹性网格。
Pod
Pod里的多个业务容器共享Pause容器的IP,共享Pause容器挂接的Volume,这样既简化了密切关联的业务容器之间的通信问题,也很好地解决了它们之间的文件共享问题。
Kubernetes为每个Pod都分配了唯一的IP地址,称之为Pod IP,一个Pod里的多个容器共享Pod IP地址。Kubernetes要求底层网络支持集群内任意两个Pod之间的TCP/IP直接通信,因此我们需要牢记一点:在Kubernetes里,一个Pod里的容器与另外主机上的Pod容器能够直接通信。
普通的Pod(不普通的Pod是指静态Pod)一旦被创建,就会被放入etcd中存储,随后被Kubernetes Master调度到某个具体的Node上并绑定(Binding),该Pod被对应的Node上的kubelet进程实例化成一组相关的Docker容器并启动。
Kubernetes 内部在每个 Node 上都运行了一套全局的虚拟负载均衡器,自动注入并自动实时更新集群中所有 Service 的路由表,通过 iptables 或者 IPVS 机制,把对 Service 的请求转发到其后端对应的某个 Pod 实例上,并在内部实现服务的负载均衡与会话保持机制。
Label
一个 Label 是一个 key=value 的键值对,可以被附加到各种资源对象上,例如 Node、Pod、Service、Deployment 等。
一些常用的Label示例如下:
版本标签:release:stable和release:canary。
- 环境标签:
environment:dev | qa | production
。 - 架构标签:
tier:frontend | backend | middleware
。 - 分区标签:
partition:customerA | customerB
。 - 质量管控标签:
track:daily | weekly
。
可以通过 Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,如
name=redis-slave
env!=production
name in (redis-master,redis-slave)
name not in (php-frontend)
name=redis-slave, env!=production
我们几乎见不到没有 Label 的 Pod。
Deployment
Deployment 资源根据我们指定的模板自动创建指定数量的Pod实例。
ClusterIP
Pod 的 Endpoint(即 IP + 端口)地址会随着 Pod 的销毁和重新创建而发生改变,因为新 Pod 的 IP 地址与旧 Pod 的不同。
而 Service 一旦被创建,Kubernetes 就会自动为它分配一个全局唯一的虚拟IP——ClusterIP,而且在 Service 的整个生命周期内,其 ClusterIP 地址不会发生改变,这样一来,每个服务就变成了具备唯一 IP 的通信节点,远程服务之间的通信问题就变成了基础的 TCP 网络通信问题。
因为没有一个“实体网络对象”来响应,所以 ClusterIP 无法被 ping 通。ClusterIP 只能与Service Port 组成一个具体的服务访问端点,单独的 ClusterIP 不具备 TCP/IP 通信的基础。
只要在 Service 的定义中设置了clusterIP:None,就定义了一个 Headless Service,它与普通 Service 的关键区别在于它没有 ClusterIP,如果解析 Headless Service 的 DNS 域名,则返回的是该 Service 对应的全部 Pod 的 Endpoint 列表,这意味着客户端是直接与后端的Pod建立TCP/IP连接进行通信的,没有通过虚拟 ClusterIP 地址进行转发,因此通信性能最高,等同于“原生网络通信”。
三种 IP
Node IP、Pod IP 和 Service IP。
Node IP 是集群中每个节点的物理网卡的 IP,是一个真实存在的物理网络 IP。这也表明集群之外的节点访问集群内的某个节点或者服务时,都必须通过 Node IP 通信。
Pod IP 是每个 Pod 的 IP,在使用 Docker 作为容器支持引擎的情况下,它是 Docker Engine 根据 docker0 网桥的 IP 段进行分配的,通常是一个虚拟二层网络。Kubernetes 要求位于不同 Node 上的 Pod 都能够彼此直接通信,所以 Kubernetes 中一个 Pod 里的容器访问另外一个 Pod 里的容器时,就是通过 Pod IP 所在的虚拟二层网络进行通信的。
Service 的 ClusterIP 地址属于集群内的地址,无法在集群外直接使用。为了解决这个问题,Kubernetes 引入了NodePort。
但 NodePort 还没有完全解决外部访问 Service 的所有问题,比如负载均衡问题。于是Kubernetes 提供了自动化的解决方案,如果我们的集群运行在谷歌的公有云 GCE 上,那么只要把Service的 “type=NodePort” 改为 “type=LoadBalancer”,Kubernetes 就会自动创建一个对应的负载均衡器实例并返回它的 IP 供外部客户端使用。
端口是有限的物理资源,那能不能让多个 Service 共用一个对外端口呢?这就是后来增加的 Ingress资源对象所要解决的问题。
本文转载自: 掘金