Kubernetes介绍及使用

1. 概念

Pod :Kubernetes 中的最小部署单元,它可以包含一个或多个容器(通常是一个),容器在同一个 Pod 中共享网络和存储资源
Deployment :Pod 的生命周期管理、调度和扩缩容。
Service :定义了一种访问 Pod 的方式,通常提供负载均衡
StatefulSet :管理有状态的应用,并保证了 Pod 的部署顺序和唯一性。
ConfigMap: 用于存储配置信息。
Secret: 用于存储敏感信息,如密码和密钥,Secret 在 API 中以加密形式存储,以提供更安全的数据管理。
Volume: 提供了一种存储机制,允许数据在 Pod 中的容器之间共享和持久化。
Namespace: 是 Kubernetes 中的一种隔离机制,用于将集群资源划分为多个逻辑分区。

  1. 创建一个名为 namespace.yaml 的文件,文件内容如下:
apiVersion: v1
kind: Namespace
metadata:
  name: <namespace-name>
  1. 应用这个文件
kubectl apply -f namespace.yaml
  1. 设置 kubectl 的默认命名空间
kubectl config set-context --current --namespace=<namespace-name>
  1. 在特定命名空间中运行 kubectl 命令
kubectl get pods -n <namespace-name>

2. 架构和工作原理

Kubernetes 的主要组件,集群由控制平面(Control Plane)组件和工作节点(Worker Nodes)组件组成

1. Control Plane

  • etcd: 分布式键值数据库,保存了整个集群的所有数据。
  • API Server: 集群的管理中心,提供了 Kubernetes API 服务。
  • Scheduler: 负责调度 Pod 到合适的节点上。
  • Controller Manager: 运行控制器进程,如节点控制器、副本控制器等。

2. Work Nodes

  • Kubelet: 在每个节点上运行,负责启动和管理容器的运行状态。
  • Kube-proxy: 管理节点上的网络代理,运行在每个节点上,维护节点网络规则,实现服务发现和负载均衡。

3. 插件和附加组件

  • Ingress Controller:集群外部访问的一个入口。将外部的请求转发到不同的 Server 上,其实就相当于 Nginx、Haproxy 等负载均衡。Ingress调度的是后端的service而不是pod。

3. Kubernetes相关问题

1. Kubernetes 的网络模型

Kubernetes 要求所有 Pod 能够直接通信,不需要网络地址转换(NAT),且每个 Pod 都分配有一个唯一的 IP 地址。

  • 查看Pod IP地址命令
kubectl get pods -o wide
  • 特定 Pod 的详细信息
kubectl describe pod <pod-name>
2. Kubernetes 管理资源配额和限制

Kubernetes 使用 ResourceQuota 对象来定义和限制每个 Namespace 可以消耗的资源量,同时可以使用 LimitRange 来约束每个 Pod 或容器可以使用的资源。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-resource-quota
  namespace: mynamespace
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    pods: "10"
    services: "5"
    replicationcontrollers: "5"
    resourcequotas: "1"
    persistentvolumeclaims: "10"
    secrets: "10"
    configmaps: "10"
    services.loadbalancers: "2"
    services.nodeports: "2"

在这个示例中,针对的是特定命名空间’mynamespace’进行资源限制:

  • requests.cpu 和 requests.memory 分别限制了 Pod 可以请求的 CPU 和内存资源的总量。
  • limits.cpu 和 limits.memory 分别限制了 Pod 可以设置的 CPU 和内存资源的最大限制的总量。
  • pods, services, replicationcontrollers 等字段限制了这些资源对象的数量。
3. 解释 Kubernetes 的自动扩缩容功能

自动扩缩容通过 HorizontalPodAutoscaler (HPA) 实现,它自动调整 Pod 的数量基于 CPU 或其他监控指标。
创建hpa.yaml的yaml文件

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: my-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-deployment
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

在这个示例中:

  • scaleTargetRef 指定了要扩缩容的目标,通常是一个 Deployment。
  • minReplicas 和 maxReplicas 分别指定了副本数量的最小值和最大值。
  • targetCPUUtilizationPercentage 设置了目标 CPU 使用率的阈值,当超过这个阈值时,HPA 会增加副本数量;当低于这个阈值时,HPA 会减少副本数量。

执行hpa.yaml文件

kubectl apply -f hpa.yaml

Note: 确保你的 Pods 和 Deployment 配置了资源请求。HPA 使用这些请求来计算 Pod 的 CPU 使用率。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: my-container
        image: nginx
        resources:
          requests:
            cpu: "100m"       # 请求 100 millicpu
            memory: "200Mi"   # 请求 200 MiB 内存
          limits:
            cpu: "200m"       # 设置 CPU 使用上限为 200 millicpu
            memory: "400Mi"   # 设置内存使用上限为 400 MiB

在这个例子中,resources.requests.cpu 和 resources.requests.memory 定义了每个 Pod 的 CPU 和内存请求。这些值是 HPA 用来计算使用率并进行扩缩容决策的基础。

4. Ingress 是什么,它如何工作

Ingress 是一个 API 对象,它管理外部访问集群中的服务,可以提供负载均衡、SSL 终端和基于名称的虚拟托管。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

注意事项

  • 注解:Ingress 控制器可以使用注解来启用或配置额外的功能,如 SSL 重定向、负载均衡策略等。
  • TLS/SSL:如果你需要为 Ingress 启用 TLS/SSL,你需要在 Ingress 资源中指定一个 tls 部分,并引用 Kubernetes Secret,其中包含了 TLS 证书和私钥。
  • 域名:你需要确保 DNS 记录指向了 Ingress 控制器的外部 IP 地址。
5. 如何在 Kubernetes 中实现蓝绿部署和滚动更新

蓝绿部署通常通过创建两个版本的 Deployment 实现,然后通过切换 Service 指向不同的 Deployment 来切换流量。

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
    version: blue
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

当准备好将流量切换到绿色部署时,更新 Service 的选择器:

spec:
  selector:
    app: myapp
    version: green

滚动更新是 Kubernetes Deployment 的默认策略,更新 Deployment 的配置(例如,更新应用的镜像版本)。它逐渐替换旧版本的 Pod。

  • 监控更新的进展
kubectl rollout status
  • 如果更新出现问题,回滚到上一个版本
kubectl rollout undo
6. 如何在 Kubernetes 中管理应用的配置

应用配置可以通过 ConfigMap 和 Secrets 管理,它们可以作为环境变量、命令行参数或配置文件挂载到 Pod 中。

7. Kubernetes 的service发现是如何工作的

Kubernetes 中的服务发现是指在集群内部定位和连接到服务的过程。Kubernetes 提供了几种机制来实现服务发现,主要通过 Service 资源和 DNS。

Service 资源

当你在 Kubernetes 中创建一个 Service 时,它会自动获得一个与之关联的内部 DNS 名称。这个名称可以在集群的所有 Pod 中使用,允许它们通过服务名称发现并连接到服务。

  • ClusterIP:每个 Service 都会被分配一个内部 IP 地址(称为 ClusterIP)。这个地址在集群内部是可达的,允许集群内的其他 Pod 通过 IP 地址连接到服务。

  • DNS 解析:Kubernetes 集群通常运行一个内部 DNS 服务(如 CoreDNS),它为每个 Service 自动创建 DNS 记录。Pod 可以通过服务的名称解析这个 DNS 记录,从而获得服务的 IP 地址。

例如,如果有一个名为 “my-service” 的 Service 在 “my-namespace” 命名空间中,那么在同一命名空间中的 Pod 可以通过 my-service 访问该服务,而在其他命名空间中的 Pod 可以通过 my-service.my-namespace 访问。

环境变量

当 Pod 启动时,Kubernetes 也会为每个活动的 Service 设置一组环境变量。这些环境变量包括服务的名称和 ClusterIP。Pod 可以使用这些环境变量来发现和连接到服务。

Endpoints 对象

当 Service 被创建时,Kubernetes 会创建一个同名的 Endpoints 对象。这个对象包含了与 Service 的选择器匹配的所有 Pod 的 IP 地址和端口信息。当 Pod 状态改变时,Endpoints 对象会相应地更新,从而保证服务发现的准确性。

使用 Service 发现

在应用代码中,你通常会通过服务的名称(DNS 解析)或环境变量来连接到其他服务。例如,如果一个微服务需要连接到名为 “database-service” 的数据库服务,它可以简单地连接到 database-service,DNS 解析会自动将这个名称转换为相应的 IP 地址。
总之,Kubernetes 的服务发现机制提供了一个简单且一致的方式来在集群内部定位和通信服务,无论后端 Pod 的实际 IP 地址如何变化。

安全性和隔离

1. Kubernetes 的安全特性

Kubernetes 的安全特性包括:RBAC 授权、Pod Security Policies、网络策略、TLS 证书和 Secret 管理等。

2. 什么是 Role-Based Access Control (RBAC)

RBAC 是一种基于角色的访问控制,它使用 Role 和 RoleBinding 对象为 Kubernetes API 定义权限和授权。

3. 如何在 Kubernetes 中配置网络策略?

网络策略通过 NetworkPolicy 资源定义,它允许你控制 Pod 间的网络访问规则。

4. Pod Security Policy (PSP) 是什么

PSP 是一种集群级别的安全特性,它定义了 Pod 运行所需的条件,以减少潜在的安全风险。

监控和日志

1. Kubernetes 中如何监控 Pod 的健康状况

Pod 的健康状况通过 Liveness 和 Readiness 探针进行监控。
Liveness Probes 确定何时需要重启容器。例如,如果应用程序处于死锁状态,无法对外提供服务,liveness probe 将检测到这种状态,并重启出现问题的容器,以恢复正常服务。
Readiness Probes 判断容器何时准备好开始接受流量。只有当容器的 readiness probe 成功时,流量才会被路由到该容器。这对于在容器启动期间依赖于外部资源的应用程序特别有用,确保服务不会开始接收请求,直到它真正准备好。

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: myimage
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 3
      periodSeconds: 3
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5

在这个例子中:

  • Liveness probe 通过在容器的 8080 端口上的 /healthz 路径上进行 HTTP GET 请求来工作。kubelet 在容器启动后 3 秒开始检查,并每 3 秒检查一次。
  • Readiness probe 使用 TCP 检查,看端口 8080 是否开放。kubelet 在容器启动后 5 秒开始检查,并每 5 秒检查一次。
    注意事项
  • 探针的 initialDelaySeconds 参数对于避免在容器启动阶段错误地判断状态至关重要。
  • 合理设置 periodSeconds(探针检查间隔)和 timeoutSeconds(探针超时时间),以确保系统稳定性和准确性。
  • 确保 readiness 和 liveness 探针的检查路径是轻量级的,以避免对应用程序性能产生负面影响。
    通过正确配置 liveness 和 readiness 探针,你可以提高应用的可靠性和可用性,确保 Kubernetes 能够及时响应容器故障和服务不可用的情况。
2. Kubernetes 中的日志管理是怎样的

Kubernetes 本身不存储日志,但可以使用 kubectl logs 命令获取容器日志。对于长期日志存储,通常需要集成外部日志记录解决方案,如 ELK 栈或 Fluentd。

3. 使用哪些工具来监控 Kubernetes 集群

常用工具包括 Prometheus 用于指标收集,Grafana 用于数据可视化,以及 Alertmanager 用于警报。

4. Kubernetes 上部署应用程序的过程

包括编写 Dockerfile 构建应用的容器镜像、推送到容器镜像仓库、编写 Kubernetes 配置文件(如 Deployment 和 Service),然后使用 kubectl apply 将配置应用到 Kubernetes 集群。

准备应用的 Docker 镜像
  1. 创建 Dockerfile:
    为你的应用编写一个 Dockerfile。这是一个包含了构建应用 Docker 镜像所需所有命令的文本文件。
  2. 构建镜像:
    使用 docker build 命令构建你的 Docker 镜像。
    例如:docker build -t myapp:v1 .
  3. 推送镜像到镜像仓库:
    将镜像推送到 Docker Hub 或其他容器镜像仓库。
    例如:docker push myapp:v1
创建 Kubernetes 配置文件
  1. 编写配置文件:
    编写一个或多个 Kubernetes 配置文件(YAML 格式),定义你的应用部署(Deployment)、服务(Service)等。
    例如,创建一个名为 deployment.yaml 的文件来定义你的应用部署。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1
        ports:
        - containerPort: 80

例如,创建一个名为 service.yaml 的文件。

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: myapp
部署应用到 Kubernetes 集群
  1. 应用配置文件:
    使用 kubectl apply 命令将你的配置应用到 Kubernetes 集群。
    例如:kubectl apply -f deployment.yaml 和 kubectl apply -f service.yaml
  2. 验证部署:
    使用 kubectl get deployments 检查部署状态。
    使用 kubectl get pods 查看 Pod 的状态。
  3. 访问应用:
    如果你创建了类型为 LoadBalancer 的服务,等待外部 IP 地址被分配。
    使用分配的外部 IP 地址访问你的应用。
监控和维护
  • 监控:
    使用 Kubernetes Dashboard 或其他监控工具监控应用状态和性能。
  • 更新应用:
    更新应用时,更改 Docker 镜像版本并重新应用配置文件。
  • 扩缩容:
    根据需要增加或减少 Pod 的副本数。
    注意事项
    确保 Kubernetes 集群已经准备好,并且你有足够的权限来部署应用。
    在部署之前在本地或开发环境中测试你的应用和配置。
    考虑应用的安全性、存储需求、日志管理和备份策略。
5. 如何调试 Kubernetes 集群中的问题

调试 Kubernetes 的问题可以通过检查 Pod 状态、查看日志、执行 kubectl describe 来获取更多信息,以及进入 Pod 内部进行检查。

6. 处理 Kubernetes 升级和回滚

升级可以通过更新 Kubernetes 集群的版本或更改应用的配置和镜像版本实现。回滚可以使用 Deployment 的历史版本来进行,通过 kubectl rollout 命令。

7. Kubernetes 集群规划和配置持久化存储

规划持久化存储通常涉及选择合适的存储类型(如 PersistentVolumes 和 StorageClasses)和确定存储的大小、性能和备份策略。

8. 如何根据应用需求选择合适的 Kubernetes 对象

根据应用是否有状态、更新模式、访问模式等因素选择合适的对象,如 Deployment、StatefulSet 或 DaemonSet。

9. 在设计大规模 Kubernetes 集群时需要考虑哪些因素

考虑的因素包括集群的扩展性、多租户和资源隔离、网络设计、存储和持久化需求、监控和日志、安全性和合规性以及灾难恢复策略。

10. 如果 Pod 没有正常启动,你会如何排查问题?

检查 Pod 的状态和事件,查看日志,检查是否有资源限制、错误的镜像名或配置错误。

10. 描述一个 Kubernetes 网络问题的排查过程。

查看 Service 和 Ingress 配置是否正确,检查网络策略,确保 Pod 之间的通信不受限制,以及查看相关的日志和指标。

11. 如果应用性能下降,如何使用 Kubernetes 工具进行故障排查?

可以使用 kubectl top 查看资源使用情况,检查是否有资源瓶颈,通过指标和日志确定性能瓶颈的位置,以及可能需要调整的资源请求和限制。

场景应用

目标用户和用途:面向中到大型生产环境,是一个功能强大的容器编排系统。

可伸缩性和复杂性:设计用于处理大规模、高可用性和跨多主机的容器部署。

功能范围:包括自动部署、扩展和管理容器化应用程序的复杂功能。

使用场景:适用于需要高度可伸缩性和复杂容器管理的大型项目和企业级部署。

你可能感兴趣的:(kubernetes,容器,云原生)