Kubernetes概述

首先

这是一个关于Kubernetes的初学者总结和我的笔记。请注意,本文章依据技术书籍《Docker/Kubernetes 实践容器开发入门》的内容。

Kubernetes 是什么

Kubernetes是由Google主导开发的容器编排系统,旨在自动化容器的操作。它是一个集成化的系统,可以实现和管理容器编排,并提供相应的API和CLI工具供操作使用。

Kubernetes概念

在Kubernetes中运行的应用程序通过与各种资源协同工作来运行。Kubernetes的资源就像是构成应用程序部署配置的组件,有如下几种类型。

リソース名用途NodeKubernetesクラスタで実行するコンテナを配置するためのサーバNamespaceKubernetesクラスタ内で作る仮想的なクラスタPodコンテナ集合体の単位で、コンテナを実行する方法を定義するReplicaSet同じ仕様のPodを複数生成・管理するDeploymentReplicaSetの世代を管理するServicePodの集合にアクセスするための経路を定義するIngressServiceをKubernetesクラスタの外に公開するConfigMap設定情報を定義し、Podに供給するPersistentVolumePodが利用するストレージのサイズや種別を定義するPersistentVolumeClaimPersistentVolumeを動的に確保するStorageClassPersistentVolumeが確保するストレージの種類を定義するStatefulSet同じ仕様で一貫性のあるPodを複数生成・管理するJob常駐目的ではない複数のPodを作成し、正常終了することを保証するCronJobcron記法でスケジューリングして実行されるJobSecret認証情報等の機密データを定義するRoleNamespace内で操作可能なKubernetesリソースのルールを定義するRoleBindingRoleとKubernetesリソースを利用するユーザーを紐づけるClusterRoleCluster全体で操作可能なKubernetesリソースのルールを定義するClusterRoleBindingClusterRoleとKubernetesリソースを利用するユーザーを紐づけるServiceAccountPodにKubernetesリソースを操作させる際に利用するユーザー

Kubernetes集群和节点

Kubernetes 集群是指管理 Kubernetes 的各种资源的集合体。Node 是已注册在 Kubernetes 集群中的 Docker 主机,用于在 Kubernetes 上部署容器。Kubernetes 集群由主节点和节点组成,如下所示。

図1.png

在Master Node上部署的组件的角色如下所示。

コンポーネント名役割kube apiserverKubernetesのAPIを公開するコンポーネント。kubectlからのリソース操作を受け付けるetcd高可用性を備えた分散キーバリューストアでKubernetesクラスタのバッキングストアとして利用されるkube schedulerNodeを監視し、コンテナを配置する最適なNodeを選択するkube controller managerリソースを制御するコントローラーを実行する

命名空间

Kubernetes可以创建嵌套在集群中的虚拟集群,这就是Namespace的概念。构建集群时会预先准备default、docker、kube-public和kube-system这些Namespace。每个Namespace都可以设置操作权限,从而实现更为健壮和细致的权限控制。

播放器

Pod的概述

Pod是容器的集合单元,至少包含一个容器。Pod被配置在任何一个Node上,可以将同一个Pod配置在多个Node上,也可以将多个Pod配置在一个Node上。

図2.png

创建Pod

使用yaml文件(也称为清单文件)来定义创建Pod所需的内容。在这个示例中,我们将定义一个由具有代理功能的Nginx和一个名为echo的应用程序组成的Pod。(假设镜像已经创建完成)

apiVersion: v1
kind: Pod    # リソースの種類の指定
metadate:
  name: echo    # リソース名
spec:    # kind属性の値次第でspec以下のスキーマが変わる
  containers:    # コンテナ郡の指定
  - name: nginx    # コンテナ名
    image: example/nginx:latest    # イメージ保存先
    env:    # 環境変数の指定
    - name: BACKEND_HOST
      value: localhost:8080
    ports:    # EXPOSEするポートの指定
    - containerPort: 80
  - name: echo
    image: example/echo:latest
    ports:
    - containerPort: 8080

要将在这个文件中定义的Pod应用到Kubernetes集群中,请执行以下命令。

$ kubectl apply -f echo.yaml
pod "echo" created

你还可以使用相同的命令来添加之后要介绍的资源。

使用Pod

检查Pod的状态

通过执行以下命令,您可以获取到Pod的状态列表。如果STATUS为Running,这表示Pod内的所有容器都已处于运行状态。READY的分母表示Pod定义的容器数,分子表示已经处于运行状态的容器数。

$ kubectl get pod
NAME         READY      STATUS     RESTARTS     AGE
echo         2/2        Running    0            11m

在容器内执行命令

您可以使用以下命令在容器内执行命令。

# kubectl exec -it Pod名 コマンド -c コンテナ名
$ kubectl exec -it echo sh -c nginx
#

容器的标准输出显示

# kubectl logs -f Pod名 -c コンテナ名
$ kubectl logs -f echo -c echo

删除Pod

# kubectl delete pod Pod名
$ kubectl delete pod echo
# kubectl delete -f マニフェストファイル名
$ kubectl delete -f echo.yaml

Pod and the address of the Pod’s internal container.

每个Pod都分配了一个独特的虚拟IP地址。被分配给Pod的虚拟IP地址将与Pod内的所有容器共享。

図3.png

副本集 jí)

ReplicaSet 是用于生成和管理具有相同规格的 Pod 的资源。以下是一个描述 ReplicaSet 的清单文件 echo-replicaset.yaml 的示例。

apiVersion: apps/v1
kind: ReplicaSet    # リソースの種類の指定
metadate:
  name: echo    # リソース名
  labels:
    app: echo
spec:    # kind属性の値次第でspec以下のスキーマが変わる
  replicas: 3    # Pod数
  selector:
    matchLabels:
      app: echo
  template:
    metadate:
      labels:
        app: echo
    spec:
      containers:    # コンテナ郡の指定
      - name: nginx    # コンテナ名
        image: example/nginx:latest    # イメージ保存先
        env:    # 環境変数の指定
        - name: BACKEND_HOST
          value: localhost:8080
        ports:    # EXPOSEするポートの指定
        - containerPort: 80
      - name: echo
        image: example/echo:latest
        ports:
        - containerPort: 8080

操作ReplicaSet以减少Pod数量时,减少的Pod将被删除。无法恢复已删除的Pod。因此,适合使用具有无状态特性的Pod,如Web应用程序。

部署

在 ReplicaSet 之上有一个资源称为 Deployment。Deployment 是应用程序部署的基本单元。它是为了管理和操作 ReplicaSet 而提供的资源。以下是描述 Deployment 的清单文件 echo-deployment.yaml 的示例。

apiVersion: apps/v1
kind: Deployment    # リソースの種類の指定
metadate:
  name: echo    # リソース名
  labels:
    app: echo
spec:    # kind属性の値次第でspec以下のスキーマが変わる
  replicas: 3    # Pod数
  selector:
    matchLabels:
      app: echo
  template:
    metadate:
      labels:
        app: echo
    spec:
      containers:    # コンテナ郡の指定
      - name: nginx    # コンテナ名
        image: example/nginx:latest    # イメージ保存先
        env:    # 環境変数の指定
        - name: BACKEND_HOST
          value: localhost:8080
        ports:    # EXPOSEするポートの指定
        - containerPort: 80
      - name: echo
        image: example/echo:latest
        ports:
        - containerPort: 8080

Deployment的定义与ReplicaSet并没有太大的差异。不同之处在于Deployment使得对ReplicaSet的版本管理成为可能。可以使用以下命令来确认Deployment的修订版本。

$ kubectl rollout history deployment echo
deployments "echo"
REVISION   CHANGE-CASE
1          kubectl apply --filename=echo-deployment.yaml --record=true

服务 (fú wù)

Service是Kubernetes集群中为一组Pod(主要是ReplicaSet)提供路径和服务发现功能的资源。以下是一个示例,描述了两个ReplicaSet的清单文件echo-ReplicaSet-with-label.yaml。

apiVersion: apps/v1
kind: ReplicaSet    # リソースの種類の指定
metadate:
  name: echo    # リソース名
  labels:
    app: echo
    release: spring    # ラベル
spec:    # kind属性の値次第でspec以下のスキーマが変わる
  replicas: 1    # Pod数
  selector:
    matchLabels:
      app: echo
      release: spring
  template:
    metadate:
      labels:
        app: echo
        release: spring
    spec:
      containers:    # コンテナ郡の指定
      - name: nginx    # コンテナ名
        image: example/nginx:latest    # イメージ保存先
        env:    # 環境変数の指定
        - name: BACKEND_HOST
          value: localhost:8080
        ports:    # EXPOSEするポートの指定
        - containerPort: 80
      - name: echo
        image: example/echo:latest
        ports:
        - containerPort: 8080

---
apiVersion: apps/v1
kind: ReplicaSet    # リソースの種類の指定
metadate:
  name: echo    # リソース名
  labels:
    app: echo
    release: summer    # ラベル
spec:    # kind属性の値次第でspec以下のスキーマが変わる
  replicas: 2    # Pod数
  selector:
    matchLabels:
      app: echo
      release: summer
  template:
    metadate:
      labels:
        app: echo
        release: summer
    spec:
      containers:    # コンテナ郡の指定
      - name: nginx    # コンテナ名
        image: example/nginx:latest    # イメージ保存先
        env:    # 環境変数の指定
        - name: BACKEND_HOST
          value: localhost:8080
        ports:    # EXPOSEするポートの指定
        - containerPort: 80
      - name: echo
        image: example/echo:latest
        ports:
        - containerPort: 8080

创建以下的清单文件来定义一个只能访问具有release=summer的Pod的Service。

apiVersion: v1
kind: Service
metadate:
  name: echo
spec:
  selector:
    app: echo
    release: summer
  ports:
    - name: http
      port: 80

这个图表代表了Service与具有标签的Pod之间的关系。

図4.png

挤入

可通过在Kubernetes集群外使用NodePort方式将Service公开到Kubernetes集群之外,但该方法仅能处理L4层级,无法进行L7层级的控制,例如基于路径切换转发到目标Service的控制。为了解决这个问题,我们引入了Ingress资源。Ingress可以实现将Service公开到Kubernetes集群外部,并同时支持基于路径的高级HTTP路由。我们可以考虑以下示例Service。

apiService: v1
kind: Service
metadata:
  name: echo
spec:
  selector:
    app: echo
  ports:
    - name: http
      port: 80

可以通过以下方式定义Ingress,将此Service公开到Kubernetes集群的外部。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echo
spec:
  rules:
  - host: example.local
    http:
      paths:
      - path: /
        backend:
          serviceName: echo
          servicePort: 80

持久卷 和 持久卷索取

在Kubernetes中,为了保证存储,提供了PersistentVolume和PersistentVolumeClaim这两个资源。这些资源用于创建与集群所提供的平台n相对应的持久卷。PersistentVolume代表存储的实体(在GCP中是GCEPersistentDisk),而PersistentVolumeClaim可以动态地分配所需的存储容量给PersistentVolume。下面是PersistentVolumeClaim清单文件的示例图像。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-example
spec:
  accessModes:    # ストレージへのマウントポリシー
    - ReadWriteOnce
  storageClassName: ssd    # StorageClassリソースの名前
  resources:
    requests:
      storage: 4Gi

存储类

StorageClass是一种可以定义由PersistentVolume提供的存储类型的资源。下面是一个类似于StorageClass清单文件的示例图像。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ssd
  annotation:
    storageclass.kubernetes.io/is-default-class: "false"
  labels:
    kubernetes.io/cluster-service: "true"
provisioner: kubernetes.io/gce-pd    # GCPの永続ストレージであるGCEPersistentDiskに対応したVolumePlugin
parameters:
  type: pd-ssd

有状态集

Deployment是根据定义的Pod规范创建Pod的资源,适用于部署唯一标识的Pod或无需持久化数据的stateless应用。相比之下,StatefulSet是用于管理持久化数据的stateful应用的资源,例如数据存储。Deployment会为Pod分配随机的标识符,而StatefulSet会按顺序分配唯一的标识符(例如pod-0,pod-1,pod-2)来创建Pod。配置文件定义与ReplicaSet几乎相同。

工作

Job 是用来管理创建一个或多个 Pod,直到指定数量的 Pod 正常完成的资源。即使 Job 下的所有 Pod 都正常结束,Pod 也不会被删除而是会被保留,因此可以在结束后分析 Pod 的日志和执行结果。因此,Job 适用于大规模计算和批处理型应用程序,而不适用于 Web 应用程序等常驻型应用程序。Job 的清单文件示例如下:

apiVersion: batch/v1
kind: Job
metadata:
  name: pingpong
  labels:
    app: pingpong
spec:
  parallelism: 3    # 同時に実行するPod数
  template:
    metadata:
      labels:
        app: pingpong
    spec:
      containers:
      - name: pingpong
        image: example/alpine:bash
        command: ["/bin/sh"]
        args:
          - "-c"
          - |
            echo ['date'] ping!
            sleep 10
            echo ['date'] pong!
      restartPolicy: Never    # Pod終了時の再実行の設定

当确认Pod的状态时,已经完成的Pod将显示为”STATUS=Completed”。

计划任务

使用CronJob资源可以进行定期调度并周期性地执行Pod,而Job只能执行一次。下面是CronJob配置文件的样例。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: pingpong
spec:
  schedule: "*/1 * * * *"    # Jobのスケジュール(cron記法)
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: pingpong
        spec:
          containers:
          - name: pingpong
            image: example/alpine:bash
            command: ["/bin/sh"]
            args:
              - "-c"
              - |
                echo ['date'] ping!
                sleep 10
                echo ['date'] pong!
          restartPolicy: OnFailure    # Pod終了時の再実行の設定

秘密

在Kubernetes中,定义密钥资源后,可以以Base64编码的形式处理机密信息字符串。下面是Secret清单文件的示例图像。

apiVersion: v1
kind: Secret
matadata:
  name: example-secret
type: Opaque
data:
  .htpasswd: Base64エンコードした機密情報の文字列

在查看Secret资源时,您可以从仪表盘上以解码Base64的文件形式来确认其内容。

(集群)角色和(集群)角色绑定

Kubernetes中的RBAC机制。

RBAC中的权限控制由两个要素构成:角色定义了在Kubernetes API上可以执行的操作,而身份验证用户、组、ServiceAccount和角色之间的关系是另一个要素。这两个要素的关系可以用下面的图表示出来。

図5.png

为了实现对RBAC的权限控制,Kubernetes提供了以下类型的资源。

リソース名内容RoleKubernetes APIへの操作許可のルールを定義し、指定のNamespace内でのみ有効RoleBinding認証ユーザー・グループ・ServiceAccountとRoleの紐付けを定義するClusterRoleKubernetes APIへの操作許可のルールを定義し、クラスタ全体で有効ClusterRoleBinding認証ユーザー・グループ・ServiceAccountとClusterRoleの紐付けを定義する

清单文件

ClusterRole和ClusterRoleBinding的清单文件应按照以下方式编写。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-reader-binding
subjects:    # Roleを紐付ける対象の認証ユーザー
- kind: ServiceAccount
  name: user
  namespace: default
roleRef:    # Role
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
广告
将在 10 秒后关闭
bannerAds