《Kubernetes权威指南》笔记1 Hello K8s

Hello K8s

  1. 创建集群 kind create cluster
  2. kubectl apply -f mysql-deploy.yaml
  3. k create -f mysql-svc.yaml
  4. k get svc mysql 获取 CLUSTER-IP
  5. k apply -f myweb-deploy.yaml 连接 CLUSTER-IP
  6. k create -f myweb-svc.yaml 指定 nodePort
  7. k get nodes -o wide 获取 node 的 INTERNAL-IP,简称 nodeIP
  8. curl -vL http://<nodeIP>:<nodePort>/demo/

其他命令

1
2
3
4
sql复制代码k get pods
k get nodes
k get scv
k describe node <name>

集群 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容器并启动。

图1.6 Pod、容器与Node的关系

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资源对象所要解决的问题。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%