跳到主要内容

3 篇博文 含有标签「k8s」

查看所有标签

K8S Services解释

· 阅读需 2 分钟

前言

从我个人角度来看,service 是 k8s 最容易出问题的地方。网络不通是最常见的问题,想要排查网络,就要对 service 有一个深入的理解。

ClusterIP Service

clusterIP工作场景

ClusterIP 是 service 的一种类型,负责管内部的网络通信。k8s 中,每个 pod 都有独立的 ip,但是 pod 是非稳定的,很容易创建销毁,ip 地址也随之改变。clusterIP 的 service 就是通过 selector 确定请求转发到哪种 pod,还有 targetPort 属性确定 pod 的 port。targetPort 必须和容器监听的 port 相同。

Headless Service

headless 工作场景

ClusterIP 有自己的 ip,Headless 就是不分配 ip 的服务。上图中,两个 mongo-db 节点中的 pod 想要相互通信(比如主从数据同步),就要通过 headless service。

nodePort Service

NodePort工作场景

nodePort 是节点机器上的一个端口, nodePort 可以直接被 Ingress 或者外部请求访问到。它的数值范围是 30000-32767. nodePort 被创建,同时意味着有一个内部的 clusterIP service 被创建。

loadBalancer Service

loadBalancer工作场景

等于是在 nodePort service 之外又套了一个 loadBalancer,意味着创建了 loadBalancer,同时也创建了 nodePort 和 ClusterIP。

17190658904841719065889152.png

在生产环境中,出于安全考虑,应该用 Ingress 或者 loadBalancer service 处理外部请求,而不是 nodePort。

minikube的使用记录

· 阅读需 5 分钟

前言

k8s 一直以概念繁杂著称。在容器编排这个领域,它是统治级的存在,可以说它就代表了这个领域内的几乎所有知识。因为我对这个领域并不熟悉,所以很难记住这些概念。只能一次次地翻看基础教程。

k8s 的背景是容器化部署盛行,加上微服务要求,一个系统的容器数量成百上千,这样,必须有一个专门的编排工具,达到高可用、可伸缩等目的。

在之前写的k8s 入门中,介绍了两个在线平台运行 k8s 命令。其实,本地也可以运行 minikube 这个精简版。下面记录一下它的使用过程。

安装

minikube架构

简而言之,一个节点中包含了控制进程和工作进程,因此一台笔记本也能模拟 k8s 集群。


minikube 文档 https://minikube.sigs.k8s.io/docs/


minikube 的默认启动命令是minikube start,命令行启动界面:

minikube启动界面

可以看出,我本机上的 minikube 版本号为 1.32.0,且使用到了预装的 docker 和 kubectl,k8s 的版本号为 1.28.3. 启动后,docker desktop 显示多了一个 minikube 容器,是为 node。

kubectl


kubectl cheat sheet https://spacelift.io/blog/kubernetes-cheat-sheet


kubectl 是一个命令行工具,需要单独安装。通过它,操控 k8s 的各级资源。

yaml 文件编写

yaml 文件的四个必要部分:apiversion, kind, metadata, spec

  • apiVersion: 指定资源的 API 版本,例如 v1。
  • kind: 指定资源的类型,例如 Pod、Service、Deployment 等。
  • metadata: 提供资源的元数据,例如名称、命名空间、标签等。
  • spec: 指定资源的具体配置,内容根据资源类型的不同而有所不同。

一份示例 yaml 文件:

apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
app: myapp
spec:
containers:
- name: mycontainer
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: mycontainer
image: nginx:latest
ports:
- containerPort: 80

一般 yaml 文件不要求从头写,而是从模板复制:


kubernetes 官方文档 https://kubernetes.io/zh-cn/docs/concepts


运行 yaml 文件的命令:kubectl apply -f test.yaml

spec 下的 replicas 字段指 pod 数量,不论 kind 是 deployment 或者 replicaset。

另外,yaml 文件还有一个实时更新的部分:status。它记录了当前状态和 yaml 文件的目标状态之间的差异。

labels 作用:template 下的 labels 是给一种 pod 打上相同的标签;selector 下的 matchLabels 则是告诉 Deployment,replicas 是使用该标签下的 pod。

service 下的 port/targetport/nodePort

可以把 service 想象为一台完整的机器。既有接受外部请求的端口(port),又有内部的容器(pod)监听的端口(targetPort)。

port:这是 Service 本身暴露给集群内其他 Pod 或外部用户的端口号。当其他应用程序或服务想要与 Service 通信时,它们将使用该端口。例如,如果你有一个 Web 应用程序,你可能会将端口设置为 80(HTTP)或 443(HTTPS)。

targetPort:这是 Service 用来连接后端 Pod 的端口号。当 Service 接收到来自外部的请求时,它将流量路由到目标端口上。这个端口对应于 Service 所指向的后端 Pod 中运行的应用程序的端口。例如,如果你的后端应用程序在容器中监听 3000 端口,你会将 targetPort 设置为 3000。

最后,nodePort 只存在于 external service 中,表示暴露给 k8s 外的 client 的端口。

Nana 教程中 mongo-express 例子最后的坑

在例子的最后,命令行执行minikube service mongo-express-service后,有如下日志:

命令行输出

下面那行才是本机浏览器可访问的地址。只是还需要账号密码。nana 的视频并不需要输入账号密码。在 stackoverflow 上找到答案,这里的账号密码是 mongo-express 要求提供的,默认是 admin:pass

k8s 入门

· 阅读需 6 分钟

前言

我没想到有一天我会去学 k8s,但这是新公司要求的,现在我觉得我即将入职的岗位可能是 devops(development+operation, 开发+运维)。

首先,k8s 是 kubernetes 的简称,因为 k 和 s 之间有八个字母。我之前一直以为 8 来自 b,是国人的专属简称,哈哈。还有,orchestration, 编排,字面意义就是对容器的管理。

安装的话,我在笔记本的 windows 上和云主机的 centos7 上都安装失败了。笔记本上是想着按照虚拟机的方案模拟集群,但是 vmware 的 player 非常难用,换成基于 ubuntu 的轻量虚拟机 multipass 也失败了。最后发现,还是在线环境适合这种大型软件的学习。一共两个可选项:


killerconda https://killercoda.com/playgrounds/scenario/kubernetes



play-with-k8s https://labs.play-with-k8s.com/


play-with-k8s 的网页命令行不能执行复制粘贴,killercoda 不仅可以粘贴命令,而且是已经设置好集群了(包含控制平面和一个工作节点)。所以,推荐 killercoda。

基础概念

node(节点),一个集群至少包含一个控制平面和一个节点。一个节点通常映射到一个物理服务器或一个虚拟机。节点上的组件包括 kubelet、 容器运行时以及 kube-proxy。

k8s 能操作的最小单元是 pod,大多数应用场景下,一个 Pod 只包含一个容器。

Deplyment 下的 replica 属性规定了 pod 的集合内容器。有了 deployment,意味着应用容器挂掉可以马上转到新的一模一样的容器中,而没有任何 downtime.

statefulset 类似于 deployment,但是针对于有状态的应用(如数据库)。deployment 只记录了无状态应用的 blueprint,而 statefulset 还保存了有状态应用的状态信息。(注:如果数据库只有单节点而非集群,也可以用 deployment 管理,只需要配置好 volumn 即可)

Service 是将运行在一个或一组 Pod (一组内的 pod 应该具有相同的功能)上的网络应用程序公开为网络服务的方法。具体而言,Service 提供了三个功能:标签选择器(Label Selector)、稳定的网络标识、负载均衡。其中,稳定的网络标识是核心。Service 为其选择的一组 Pods 提供一个稳定的 IP 地址和 DNS 名称。无论 Pod 的 IP 地址如何变化,客户端都可以通过 Service 的 IP 地址或 DNS 名称来访问这些 Pods。

Ingress 是指在访问域名而非 ip 地址时,需要先经过 Ingress(DNS?)

configMap: 明文配置;secret: 不方便给外界看的配置。

k8s 架构

k8s集群架构

每个工作节点内部必须有三个进程:

  • kubelet 负责 pod 的创建
  • kube proxy 负责 pod 请求的转发
  • 容器运行时

控制节点也可以不止一个。控制平面管理集群中的所有操作。主要组件包括:

  • API Server:集群的入口,接收和处理所有的 REST 请求。
  • etcd:一个高可用的键值存储,用于存储集群的所有数据。
  • Controller Manager:运行控制器,确保集群的期望状态和实际状态一致。
  • Scheduler:负责将新创建的 Pod 分配到适当的工作节点上。

作为一个如此复杂的工具,我们应该知道什么东西是需要人来配置,什么东西是工具自己来调节操控的。Deployment 以下的,都是 k8s 自主调节。

从头开始

说了这么多,有必要把一个应用是如何由原来的直接部署或者 docker 部署迁移到 k8s 上的完整流程叙述一遍。首先,把手头上拥有的机器资源做个清点,划分出控制节点和工作节点。然后,在每台机器上都装上 Kubeadm, Kubelet 和 Kubectl。在控制节点上执行kubeadm init初始化集群;在工作节点上执行kubeadm join加入集群。验证集群是否成立。最后就是编写 yaml 文件,在任意一个节点上执行kubectl apply -f执行 yaml 配置(无论哪个节点,kubectl 都会到控制节点的 api-server 中)。