跳转至

kubernetes 教程

1. Kubernetes 基础概念

1.1 什么是 Kubernetes?

Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它由 Google 开发,后来成为 CNCF(Cloud Native Computing Foundation)的一部分。Kubernetes 旨在简化容器的管理,使得部署和管理大规模容器化应用变得更加高效和可靠。

1.2 Kubernetes 架构

Kubernetes 的架构主要包括两个部分:控制平面节点

  • 控制平面(Control Plane):负责管理整个 Kubernetes 集群,调度 Pods 和管理集群状态。控制平面通常由以下组件组成:
  • API Server:Kubernetes 的 API 入口点,所有对集群的操作都是通过 API Server 进行的。
  • Controller Manager:监控集群的状态,并负责处理控制循环,如确保 Pods 数量符合预期。
  • Scheduler:负责将 Pods 调度到合适的节点上。
  • etcd:分布式键值存储,用于保存集群状态和配置数据。

  • 节点(Nodes):集群中的工作机器,每个节点运行一个或多个 Pods。节点主要包括:

  • Kubelet:管理容器的生命周期,确保容器按预期运行。
  • Kube Proxy:维护网络规则,确保服务的网络通信。
  • Container Runtime:运行容器的工具,如 Docker、containerd 等。

1.3 核心概念

  • Pod:Kubernetes 中的基本运行单元,一个 Pod 可以包含一个或多个容器,它们共享网络、存储等资源。
  • Service:定义访问 Pods 的方法,提供负载均衡和服务发现功能。
  • Deployment:管理 Pods 和 ReplicaSets,实现应用的部署和滚动更新。
  • ReplicaSet:确保指定数量的 Pods 副本在集群中运行。
  • Namespace:用于组织和隔离集群资源,支持多租户环境。
  • ConfigMap:管理非敏感配置数据。
  • Secret:管理敏感数据,如密码和密钥。
  • Volume:用于持久化数据存储。

2. Kubernetes 核心对象

2.1 Pod

Pod 是 Kubernetes 中最小的调度单元,包含一个或多个容器。这些容器共享网络、存储等资源,通常一起部署和管理。

Pod 的配置示例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  containers:
  - name: my-container
    image: nginx:latest
    ports:
    - containerPort: 80
  restartPolicy: Always
  • metadata:Pod 的元数据,包括名称和标签。
  • spec:Pod 的规范,包括容器配置和重启策略。
  • containers:Pod 中的容器列表,每个容器包括名称、镜像、暴露的端口等信息。

操作命令

kubectl apply -f pod.yaml
kubectl get pods
kubectl describe pod my-pod
kubectl delete pod my-pod

2.2 Service

Service 提供稳定的访问点来访问一组 Pods,支持负载均衡和服务发现。

Service 的配置示例

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  • type:指定 Service 的类型(ClusterIP、NodePort、LoadBalancer、ExternalName)。
  • selector:选择与 Service 匹配的 Pods。
  • ports:指定 Service 的端口和目标端口。

操作命令

kubectl apply -f service.yaml
kubectl get services
kubectl describe service my-service
kubectl delete service my-service

2.3 Deployment

Deployment 用于声明式地管理 Pods 和 ReplicaSets,实现应用的部署和更新。

Deployment 的配置示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest
        ports:
        - containerPort: 80
  • replicas:指定 Pod 副本的数量。
  • selector:选择与 Deployment 匹配的 Pods。
  • template:Pod 模板,包括 Pod 的规范。

操作命令

kubectl apply -f deployment.yaml
kubectl get deployments
kubectl describe deployment my-deployment
kubectl rollout status deployment/my-deployment
kubectl set image deployment/my-deployment my-container=nginx:latest
kubectl rollout undo deployment/my-deployment
kubectl delete deployment my-deployment

2.4 ReplicaSet

ReplicaSet 确保指定数量的 Pod 副本在集群中运行。通常不直接创建 ReplicaSet,而是通过 Deployment 管理。

ReplicaSet 的配置示例

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest
        ports:
        - containerPort: 80

操作命令

kubectl apply -f replicaset.yaml
kubectl get replicasets
kubectl describe replicaset my-replicaset
kubectl delete replicaset my-replicaset

2.5 Namespace

Namespace 用于将集群中的资源分隔到逻辑上不同的区域中。

Namespace 的配置示例

apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace

操作命令

kubectl apply -f namespace.yaml
kubectl get namespaces
kubectl describe namespace my-namespace
kubectl delete namespace my-namespace

2.6 ConfigMap 和 Secret

ConfigMapSecret 用于管理配置数据和敏感数据。

ConfigMap 的配置示例

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  key1: value1
  key2: value2

Secret 的配置示例

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  password: cGFzc3dvcmQ=  # base64 编码的密码

操作命令

kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
kubectl get configmaps
kubectl get secrets
kubectl describe configmap my-config
kubectl describe secret my-secret
kubectl delete configmap my-config
kubectl delete secret my-secret

2.7 Volume

Volume 用于存储数据并在 Pod 之间共享数据。

PersistentVolume 和 PersistentVolumeClaim 的配置示例

PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /mnt/data

PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

在 Pod 中使用 PVC

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: my-storage
  volumes:
  - name: my-storage
    persistentVolumeClaim:
      claimName: my-pvc

操作命令

kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
kubectl apply -f pod.yaml
kubectl get persistentvolumes
kubectl get persistentvolumeclaims

3. 高级配置

3.1 网络配置

NetworkPolicy 用于控制 Pods 之间的网络通信。

NetworkPolicy 的配置示例

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-network-policy
spec:
  podSelector:
    matchLabels:
      app: my-app
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: my-namespace

操作命令

kubectl apply -f networkpolicy.yaml
kubectl get networkpolicies
kubectl describe networkpolicy my-network-policy

3.2 Ingress

Ingress 提供 HTTP 和 HTTPS 访问到集群内部的服务,并支持 URL 路径和主机名的路由。

Ingress 的配置示例

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: my-app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

操作命令

kubectl apply -f ingress.yaml
kubectl get ingress
kubectl describe ingress my-ingress

3.3 Horizontal Pod Autoscaler

Horizontal Pod Autoscaler 根据 CPU 使用率或其他指标自动扩展 Pods。

Horizontal Pod Autoscaler 的配置示例

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

操作命令

kubectl apply -f hpa.yaml
kubectl get hpa
kubectl describe hpa my-hpa

3.4 Cluster Autoscaler

Cluster Autoscaler 自动调整集群中节点的数量以适应负载需求。

部署 Cluster Autoscaler 的配置示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cluster-autoscaler
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cluster-autoscaler
  template:
    metadata:
      labels:
        app: cluster-autoscaler
    spec:
      containers:
      - name: cluster-autoscaler
        image: k8s.gcr.io/cluster-autoscaler:v1.21.0
        command:
        - ./cluster-autoscaler
        - --v=4
        - --cloud-provider=aws
        - --cluster-name=my-cluster
        - --namespace=kube-system

操作命令

kubectl apply -f cluster-autoscaler.yaml
kubectl get deployments -n kube-system
kubectl describe deployment cluster-autoscaler -n kube-system

3.5 监控和日志

  • Prometheus 和 Grafana 用于集群和应用程序的监控和可视化。

部署 Prometheus

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:latest
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        volumeMounts:
        - name: config-volume
          mountPath: /etc/prometheus
      volumes:
      - name: config-volume
        configMap:
          name: prometheus-config

部署 Grafana

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:latest
        ports:
        - containerPort: 3000

部署 ELK Stack(Elasticsearch, Logstash, Kibana)用于日志管理和分析。

部署 Elasticsearch

apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
  namespace: logging
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1
        env:
        - name: discovery.type
          value: single-node
        ports:
        - containerPort: 9200

好的,我们继续深入探讨 Kubernetes 的更多高级主题,包括集群管理、调度策略、网络插件以及一些实际操作示例。


4. Kubernetes 高级主题

4.1 Kubernetes 调度策略

Kubernetes 提供了多种调度策略来管理 Pod 的调度和分配。理解这些策略可以帮助你优化集群的资源利用和性能。

4.1.1 Pod 的调度

调度是 Kubernetes 将 Pod 分配到集群中适当节点上的过程。默认情况下,Kubernetes 会选择资源足够且负载最少的节点来运行 Pod。可以通过以下几种方式影响调度策略:

  • 节点选择器(Node Selector):通过标签选择特定的节点来运行 Pod。
  • 节点亲和性(Node Affinity):通过更复杂的规则指定 Pod 应该或必须调度到的节点。
  • Pod 亲和性与反亲和性(Pod Affinity & Anti-Affinity):控制 Pod 与其他 Pods 的调度关系。

4.1.2 节点选择器

节点选择器是一种简单的调度策略,允许你指定 Pod 只能调度到具有特定标签的节点上。

示例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest
  nodeSelector:
    disktype: ssd

这个示例中的 Pod 只会调度到带有 disktype=ssd 标签的节点上。

4.1.3 节点亲和性

节点亲和性提供了比节点选择器更灵活的调度策略。它允许你指定软性和硬性要求。

示例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: region
            operator: In
            values:
            - us-east-1

在这个示例中,Pod 必须调度到 disktype=ssd 的节点上,并且优先选择 region=us-east-1 的节点。

4.1.4 Pod 亲和性与反亲和性

Pod 亲和性用于将一个 Pod 调度到与某些指定 Pod 位于同一节点或不同节点上。

示例

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx:latest
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - my-app
        topologyKey: "kubernetes.io/hostname"
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - another-app
        topologyKey: "kubernetes.io/hostname"

这个示例表示 Pod 需要与 app=my-app 的 Pod 位于同一节点,但不与 app=another-app 的 Pod 位于同一节点。

4.2 Kubernetes 网络插件

Kubernetes 网络模型允许每个 Pod 拥有一个独立的 IP 地址,并且不同 Pod 之间可以相互通信。网络插件(CNI 插件)用于实现这种网络模型。以下是一些常见的网络插件:

  • Flannel:一个简单的网络插件,适合小型集群,提供基本的网络功能。
  • Calico:支持网络策略、BGP 路由等高级功能,适合大规模集群。
  • Weave:支持跨数据中心的网络通信,适合分布式集群。
  • Cilium:基于 eBPF 的网络插件,提供高性能的网络策略和安全性功能。

4.2.1 Flannel

Flannel 是一个简单的覆盖网络插件,适合小型集群。它通过 VXLAN 技术实现跨节点的容器网络。

安装 Flannel

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

4.2.2 Calico

Calico 提供了强大的网络策略和安全功能,适合大规模集群。

安装 Calico

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

4.3 Kubernetes 存储

Kubernetes 支持多种存储方案,满足不同应用的数据持久化需求。以下是一些常见的存储类型:

  • PersistentVolume(PV)和 PersistentVolumeClaim(PVC):PV 是集群管理员配置的存储资源,PVC 是用户申请使用这些资源的请求。PV 与 PVC 的绑定是持久存储的基础。
  • StorageClass:用于定义动态创建 PV 的策略,支持不同的存储后端,如 NFS、Ceph、AWS EBS 等。

4.3.1 PersistentVolume 和 PersistentVolumeClaim

PV 是集群中的实际存储资源,PVC 是用户对存储的请求。以下是一个创建 PV 和 PVC 的示例:

PersistentVolume 示例

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /mnt/data
    server: nfs-server.example.com

PersistentVolumeClaim 示例

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

4.3.2 StorageClass

StorageClass 定义了动态创建 PV 的存储策略。

StorageClass 示例

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  fsType: ext4

4.4 Kubernetes 安全

安全性是 Kubernetes 中的一个重要方面,涉及到认证、授权、网络策略等多个层面。

4.4.1 认证与授权

  • 认证(Authentication):Kubernetes 支持多种认证方式,包括 X.509 客户端证书、Bearer Token、OpenID Connect 等。
  • 授权(Authorization):Kubernetes 使用 RBAC(基于角色的访问控制)来管理对资源的访问权限。

RBAC 示例

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: "jane"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

4.4.2 网络策略

NetworkPolicy 用于控制 Pods 之间的网络流量。

NetworkPolicy 示例

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-http
spec:
  podSelector:
    matchLabels:
      app: my-app
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 80

4.5 Kubernetes 日志与监控

监控和日志管理是 Kubernetes 运营的重要部分。

4.5.1 Prometheus 与 Grafana

Prometheus 是一个用于监控和报警的系统,Grafana 是一个用于数据可视化的工具。二者结合可实现强大的监控和可视化功能。

Prometheus 部署示例

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
      - job_name: 'kubernetes-apiservers'
        kubernetes_sd_configs:
          - role: endpoints

Grafana 部署示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:latest
        ports:
        - containerPort: 3000

4.5.2 日志管理

Kubernetes 日志管理通常使用 ELK Stack(Elasticsearch, Logstash, Kibana)。它可以实现集中式日志管理和分析。

Elasticsearch 部署示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
  namespace: logging
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:7.10.1
        env:
        - name: discovery.type
          value: single-node
        ports:
        - containerPort: 9200