k8s プラクティス | configmap&secret&pv&pvc

configmap&secret&pv&pvc

1 つ、configMap

アプリケーションを kubernetes にデプロイするとき、データベース アドレス、ユーザー名、パスワードなど、いくつかの構成をアプリケーションに渡す必要があることがよくあります。これを行うには、次のような多くのオプションがあります。

  • イメージをパッケージ化するときにアプリケーション構成ファイルに直接書き込むことができますが、この方法の欠点は明らかであり、非常に明白です。
  • 構成ファイルで env 環境変数を渡すことができますが、この場合、env を変更する場合は、yaml ファイルを変更する必要があり、すべてのコンテナーを再起動する必要があります。
  • アプリケーションの起動時に、データベースまたは特定の場所に移動して取得できます。問題ありません! しかし、1 つ目は実装が面倒なこと、2 つ目は構成場所が変わったらどうするかということです。

もちろん、他の解決策もありますが、それぞれの解決策には独自の問題があります。

さらに、もう 1 つの問題があります.私の構成の 1 つを複数のアプリケーションで使用する必要がある場合、3 番目の解決策を除いて、構成を共有する方法はありません.つまり、構成を変更したい場合は、構成を変更する必要があります.手動で 1 つずつ変更します。100 個のアプリケーションがある場合、100 個の構成を変更する必要があります...

Kubernetes は、ConfigMap と Secret を使用して、この問題に対する優れたソリューションを提供します。

ConfigMap 関数は、kubernetes のバージョン 1.2 で導入されました. 多くのアプリケーションは、構成ファイル、コマンド ライン パラメータ、または環境変数から構成情報を読み取ります. ConfigAPI は、構成情報をコンテナに注入するメカニズムを提供します. ConfigMap を使用して、単一のプロパティを保存できます構成ファイル全体または JSON blob を保持するためにも使用できます。

ConfigMap对像是一系列配置的集合,k8s会将这一集合注入到对应的Pod对像中,并为容器成功启动使用。注入的方式一般有两种,一种是挂载存储卷,一种是传递变量。ConfigMap被引用之前必须存在,属于名称空间级别,不能跨名称空间使用,内容明文显示。ConfigMap内容修改后,对应的pod必须重启或者重新加载配置(支持热更新的应用,不需要重启)。
Secret类似于ConfigMap,是用Base64加密,密文显示,一般存放敏感数据。一般有两种创建方式,一种是使用kubectl create创建,一种是用Secret配置文件。

1.適用シナリオ

アプリケーション シナリオ: 多くの場合、ミラーリングはアプリケーションの基礎であり、リソースの消費、ログの場所のレベルなど、カスタマイズする必要がある多くのパラメーターまたは構成があります。ミラーリングまたは Kubernetes Configmap は、コンテナーに構成ファイルまたは環境変数を提供してさまざまな構成を実現するために提供されます。これにより、イメージ構成がイメージ自体から分離され、コンテナー アプリケーションが環境構成に依存しなくなります。

我们经常都需要为我们的应用程序配置一些特殊的数据,比如密钥、Token 、数据库连接地址或者其他私密的信息。你的应用可能会使用一些特定的配置文件进行配置,比如settings.py文件,或者我们可以在应用的业务逻辑中读取环境变量或者某些标志来处理配置信息。
我们要做到这个,有好多种方案,比如:
1.我们可以直接在打包镜像的时候写在应用配置文件里面,但是这种方式的坏处显而易见而且非常明显。
2.我们可以在配置文件里面通过 env 环境变量传入,但是这样的话我们要修改 env 就必须去修改 yaml 文件,而且需要重启所有的 container 才行。
3.我们可以在应用启动的时候去数据库或者某个特定的地方拿,没问题!但是第一,实现起来麻烦;第二,如果配置的地方变了怎么办?

当然还有别的方案,但是各种方案都有各自的问题。
而且,还有一个问题就是,如果说我的一个配置,是要多个应用一起使用的,以上除了第三种方案,都没办法进行配置的共享,就是说我如果要改配置的话,那得一个一个手动改。假如我们有 100 个应用,就得改 100 份配置,以此类推……

kubernetes 对这个问题提供了一个很好的解决方案,就是用 ConfigMap 和 Secret。    

パラメータをコンテナに渡します。

ドッカー Kubernetes 説明
エントリーポイント 指図 コンテナ内の実行可能ファイル
CMD 引数 実行可能ファイルに渡す必要がある引数

コンテナーにパラメーターを渡す必要がある場合は、Yaml ファイルでコマンドと引数または環境変数を使用できます。

apiVersion: v1
kind: Pod
metadata:
  name: print-greeting
spec:
  containers:
  - name: env-print-demo
    image: hub.kaikeba.com/java12/bash:v1
    env:
    - name: GREETING
      value: "Warm greetings to"
    - name: HONORIFIC
      value: "The Most Honorable"
    - name: NAME
      value: "Kubernetes"
    command: ["echo"]
    args: ["$(GREETING) $(HONORIFIC) $(NAME)"]
    
    # 创建后,命令 echo Warm greetings to The Most Honorable Kubernetes 将在容器中运行,也就是环境变量中的值被传递到了容器中。
    # 查看pod就可以看出
    kubectl logs podname 

2. configMap を作成する

2.1、ヘルプドキュメント

[root@k8s-master-155-221 configmap]# kubectl create  configmap --help
......
Aliases:
configmap, cm  #可以使用cm替代

Examples:
  # Create a new configmap named my-config based on folder bar
  kubectl create configmap my-config --from-file=path/to/bar  #从目录创建  文件名称为键  文件内容为值?
  
  # Create a new configmap named my-config with specified keys instead of file basenames on disk
  kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt #从文件创建 key1为键 文件内容为值
  
  # Create a new configmap named my-config with key1=config1 and key2=config2
  kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2   #直接命令行给定,键为key1 值为config1
  
  # Create a new configmap named my-config from the key=value pairs in the file
  kubectl create configmap my-config --from-file=path/to/bar   #从文件创建 文件名为键 文件内容为值
  
  # Create a new configmap named my-config from an env file
  kubectl create configmap my-config --from-env-file=path/to/bar.env

2.2、ディレクトリを使用して作成する



# 指定目录
ls /docs/user-guide/configmap
#创建game.properties,ui.properties,game.cnf ui.conf ,game.yaml
# game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

# ui.propertes
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice

#创建configmap ,指令
# game-config :configmap的名称
# --from-file:指定一个目录,目录下的所有内容都会被创建出来。以键值对的形式
# --from-file指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容
kubectl create configmap game-config --from-file=docs/user-guide/configmap

# 查看configmap文件
kubectl get cm 

# 查看详细信息
kubectl get cm game-config -o yaml   

kubectl describe cm

2.3. ファイルに従って作成

ファイルとして指定するだけで、単一のファイルから ConfigMap を作成できます。

# 指定创建的文件即可
kubectl create configmap game-config-2 --from-file=/docs/user-guide/configmap/game.propertes

#查看
kubectl get configmaps game-config-2 -o yaml

–from-file This parameter can be used multiple times, you can specify game.properties, ui.propertes each. 効果は、ディレクトリ全体を指定するのと同じです。

2.4、テキスト作成

# 使用--from-literal 方式直接创建configmap
# Create the ConfigMap
$ kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2
configmap "my-config" created 

# Get the ConfigMap Details for my-config
$ kubectl get configmaps my-config -o yaml
apiVersion: v1
data:
  key1: value1
  key2: value2
kind: ConfigMap
metadata:
  creationTimestamp: 2017-05-31T07:21:55Z
  name: my-config
  namespace: default
  resourceVersion: "241345"
  selfLink: /api/v1/namespaces/default/configmaps/my-config
  uid: d35f0a3d-45d1-11e7-9e62-080027a46057
  
# 文字方式
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm

#查看
kubectlget configmaps special-config -o yaml 

テキストを使用して作成し、 --from-literal パラメーターを使用して構成情報を渡し、パラメーターを変更すると、複数回使用できます。

2.5. 直接法


# 直接通过配置文件的方式创建  
# 耦合方式创建
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  name: game-config
  namespace: default

2.6. Pod でのアプリケーション

# 创建configMap,   special.how: very   键名:键值
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
  
# 创建第二个configMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO

# 第一种方式: 在pod中使用configmap配置,使用ConfigMap来替代环境变量
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: hub.kaikeba.com/library/myapp:v1 
      command: ["/bin/sh", "-c", "env"]
      env:
        - name: SPECIAL_LEVEL_KEY 
          valueFrom:
            configMapKeyRef: 
              name: special-config  # 第一种导入方式:在env中导入
              key: special.how              
        - name: SPECIAL_TYPE_KEY
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.type 
      envFrom:                      # 第二种导入方式,直接使用envFrom导入
        - configMapRef: 
            name: env-config 
  restartPolicy: Never
  
# 查看日志可以发现,环境变量注入到了容器中了,打印env就结束了
kubectl  logs  test-pod 
...
SPECIAL_TYPE_KEY=charm
SPECIAL_LEVEL_KEY=very
log_level=INFO
  
  
#第二种方式:用ConfigMap设置命令行参数
#用作命令行参数,将 ConfigMap 用作命令行参数时,需要先把 ConfigMap 的数据保存在环境变量中,然后通过 $(VAR_NAME) 的方式引用环境变量.
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: hub.kaikeba.com/library/myapp:v1
      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] 
      env:
        - name: SPECIAL_LEVEL_KEY 
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.how 
        - name: SPECIAL_TYPE_KEY 
          valueFrom: 
            configMapKeyRef: 
              name: special-config 
              key: special.type 
  restartPolicy: Never
  
  
# 第三种方式:通过数据卷插件使用ConfigMap
#在数据卷里面使用这个ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容

apiversion: v1
kind: Pod
metadata:
  name: test-pod3
spec:
  containers:
    - name: test-container
      image: hub.kaikeba.com/library/myapp:v1
      command: [ "/bin/sh", "-c", "sleep 600s" ] 
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config # 表示把conifg-volume挂载卷挂载到容器的/etc/config目录下
  volumes:    # 开启挂载外部configmap
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never
  
  # 登录容器查看/etc/config目录下是否挂载成功
  

2.7. ホットアップデート

# ConfigMap的热更新
apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
  namespace: default
data:
  log_level:INFO
---
apiVersion: extensions/v1beta1 
kind: Deployment 
metadata: 
  name: my-nginx 
spec:
  replicas: 1
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
        - name: my-nginx
          image: hub.kaikeba.com/java12/myapp:v1 
          ports:
            - containerPort: 80 
          volumeMounts:
            - name: config-volume 
              mountPath: /etc/config 
      volumes:
        - name: config-volume 
          configMap:
            name: log-config

# 获取值
kubectl exec my-nginx-7b55868ff4-wqh2q -it -- cat /etc/config/log_level
#输出
INFO

修改ConfigMap

$ kubectl edit configmap log-config
修改log-level的值为DEBUG等待大概10秒钟时间,再次查看环境变量的值

二、secret

Secret オブジェクトがデータを保存する方法は、キー値の形式でデータを保存することです. Pod リソースで Secret を呼び出す方法は、環境変数またはストレージ ボリュームを介してデータにアクセスすることです.これにより、パスワード、トークンなどの機密データの構成の問題が解決されます. 、およびキー。これらの機密データを画像や Pod 仕様に公開する必要はありません。

さらに、Secret オブジェクトのデータ ストレージと印刷形式は Base64 でエンコードされた文字列であるため、ユーザーは Secret オブジェクトを作成するときに、このタイプのエンコード形式でデータを提供する必要もあります。コンテナー内で環境変数またはストレージ ボリュームとしてアクセスすると、自動的にプレーンテキスト形式にデコードされます。マスター ノード上にある場合、Secret オブジェクトは暗号化されていない形式で etcd に格納されるため、etcd の管理と権限を厳密に制御する必要があることに注意してください。
シークレットには 4 つのタイプがあります。

  • サービス アカウント: Kubernetes API にアクセスするために使用され、Kubernetes によって自動的に作成され、Pod の /run/secrets/kubernetes.io/serviceaccount ディレクトリに自動的にマウントされます。
  • 不透明: パスワード、キー、情報、証明書などを格納するために使用される base64 エンコーディング形式のシークレットであり、タイプ識別子は一般的です。
  • kubernetes.io/dockerconfigjson : プライベート Docker レジストリの認証情報を格納するために使用され、タイプは docker-registry として識別されます。
  • kubernetes.io/tls: SSL 通信モードの証明書と秘密鍵ファイルを格納するために使用され、必須の作成タイプは tls として識別されます。

1、サービスアカウント

サービス アカウントは、Kubernetes によって自動的に作成された kubernetes API にアクセスするために使用され、Pod の /run/secrets/kubernetes.io/serviceaccount ディレクトリに自動的にマウントされます。

サービス アカウントは自分で管理する必要はありません. この証明書は kubernetes 自体によって維持および管理されます.

# 创建pod
kubectl run my-nginx --image=hub.kaikeba.com/java12/nginx:v1 

# 查看证书
kubctl exec -it podName -- sh
# 进入证书目录/run/secrets/kubernetes.io/serviceaccount查看即可
ca
namespace
token

2、不透明な秘密

2.1. 例を作成する

不透明型データはマップ型であり、値は base64 エンコード形式である必要があります

# base64对用户名,密码加密效果演示
echo -n "admin" | base64
YWRtaW4=

echo -n "abcdefgh" | base64
YWJjZGVmZ2g=


# secret.yaml配置文件方式
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
 password: YWJjZGVmZ2g=
 username: YWRtaW4=

2.2. 使い方

# 将secret挂载到volume中
apiVersion: v1
kind: pod
metadata:
 name: secret-test
 labels:
   name: secret-test
spec:
  volumes:
  - name: secrets
    secret:
      secretName: mysecret
  containers:
  - image: hub.kaikeba.com/java12/myapp:v1
    name: db
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
   


# 将secret导出到环境变量中
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: secret-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: pod-deployment
    spec:
      containers:
      - name: pod-1
        image: hub.kaikeba.com/java12/myapp:v1
        ports:
        - containerPort: 80
        env:
        - name: TEST_USER
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: TEST_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password

3. k8s-ボリューム

1. ボリュームは何を使用すればよいですか?

k8s のコンテナー内のディスクのライフサイクルは短く、一連の問題を引き起こします

  1. コンテナが破損した場合、kubelet はコンテナを再起動しますが、コンテナ内のファイルは失われます - コンテナはクリーンな状態で再起動します
  2. 多くのコンテナーが同じポッドで実行される場合、データ ファイルの共有が必要になることがよくあります
  3. ではk8s、異なるノードに分散されているためpod、異なるノード間での永続データの共有を実現できず、ノードに障害が発生すると、永続的なデータ損失が発生する可能性があります。

ボリュームは上記の問題を解決するために使用されます

ボリュームのライフ サイクルはコンテナーとは無関係です。Pod 内のコンテナーは破棄されて再構築される場合がありますが、ボリュームは保持されます。

注: docker ディスク マッピングのデータは保持されます。これは kubernetes とは多少異なります。

2.ボリュームとは?

ボリュームは、コンテナーのデータをマウントし、コンテナーの実行時に必要なデータを格納するために使用されます。実際にコンテナーを再作成したところ、ボリューム マウントされたボリュームが変更されていないことがわかりました。

kubernetes のボリュームには、それをカプセル化するポッドと同じ寿命が定義されています。したがって、ボリュームの寿命は Pod 内のすべてのコンテナーよりも長く、コンテナーが再起動されてもデータは保持されます。

もちろん、ポッドが存在しなくなると、ボリュームも存在しなくなります。おそらくもっと重要なのは、kubernetes が複数のタイプのボリュームをサポートし、ポッドが同時に任意の数のボリュームを使用できることです。

[外部リンクの画像転送に失敗しました。ソース サイトにアンチリーチング メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-oacvq1xO-1679666378136)(assets/image-20200511204534341.png)]

3. ボリュームタイプ

kubenetes ボリュームのタイプ:

[外部リンクの画像転送に失敗しました。ソース サイトにリーチング防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-vT8zWo1N-1679666378138)(assets/image-20200511111331467.png)]

1つ目はローカルボリューム

dockerでのhostPath型やbindマウント型と同じく、ホストファイルに直接マウントする型で、
emptyDirはボリューム型と同様のローカルボリュームで、
どちらもノードにバインドされます。ノード。

2 つ目は、ネットワーク データ量です。

たとえば、Nfs、ClusterFs、Ceph は、k8s にマウントできる外部ストレージです。

3つ目はクラウドディスク

AWS、Microsoft (azuredisk) など

4番目はk8s自体のリソースです

secret、configmap、downwardAPI など

4・空のディレクトリ

最初にローカル ボリュームを見てみましょう
. EmptyDir は Docker のボリュームに似ています. Docker がコンテナを削除すると、データ ボリュームはまだ存在しますが、emptyDir がコンテナを削除すると、データ ボリュームも失われます. 通常、これは一時的なデータ ボリュームとして使用されます。

空のボリュームを作成し、Pod 内のコンテナーにマウントします。ボリュームを削除する Pod も削除されます。

アプリケーション シナリオ: Pod 内のコンテナー間のデータ共有

Pod がノードに割り当てられると、最初に emptyDir ボリュームが作成され、Pod がそのノードで実行されている限り存在します。ボリュームの名前が示すように、最初は空で、ポッド内のコンテナーは emptyDir ボリューム内の同じファイルを読み書きできますが、ボリュームは各コンテナー内の同じパスまたは異なるパスにマウントできます。何らかの理由で Pod がノードから削除されると、emptyDir のデータは完全に削除されます

注: コンテナーがクラッシュしても Pod はノードから削除されないため、emptyDir ボリューム内のデータはコンテナーのクラッシュから保護されます

[外部リンクの画像転送に失敗しました。ソース サイトには盗難防止リンク機構がある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-xquYaKw6-1679666378139)(assets/image-20200511205218768.png)]

emptyDir の使用法

1、暂存空间,例如用于基于磁盘的合并排序
2、用作长时间计算崩溃恢复时候的检查点
3、web服务器容器提供数据时,保存内容管理器容器提取的文件

5. 例

apiVersion: v1
kind: Pod
metadata:
  name: test-pod1
spec:
  containers:
  - image: hub.kaikeba.com/library/myapp:v1
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {
    
    }
    

---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod2
spec:
  containers:
  - image: hub.kaikeba.com/library/myapp:v1
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  - name: test-1
    image: hub.kaikeba.com/library/busybox:v1
    command: ["/bin/sh","-c","sleep 3600s"]
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir: {
    
    }

6、ホストパス

Node ファイル システム上のファイルまたはディレクトリを Pod 内のコンテナーにマウントします。

アプリケーション シナリオ: Pod 内のコンテナーは、ホスト ファイルにアクセスする必要があります。

7. 例

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - image: hub.kaikeba.com/library/myapp:v1
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    hostPath:
      path: /data
      type: Directory

ここで作成されるデータは、自分が割り当てられたノード node のデータと同じで、作成されたデータが更新されます. コンテナを削除しても、データボリュームのデータは削除されません.

タイプ タイプ

必要なパス属性の位置に加えて、ユーザーは hostPath ボリュームのタイプも指定できます。

画像-20200511114734100

8. NFS ネットワーク ストレージ

Kubernetes の高度な PersistentVolume 静的プロビジョニングにより、NFS ネットワーク ストレージを実現

NFSは非常に初期のテクノロジーです.スタンドアロンストレージはサーバーに関してはまだ非常に主流ですが,nfsの唯一の欠点はクラスタバージョンがないことです.クラスタリングはまだ比較的面倒であり,ファイルシステムは実行できません.これは.非常に大きな問題です. 大きな欠点は、大規模な場合、分散ストレージを選択する必要があることです. nfs はネットワーク ファイル ストレージ サーバーです. nfs をインストールした後、ディレクトリを共有し、他のサーバーはこのディレクトリを介してローカルにマウントできます.このディレクトリ内のファイルは、リモート サーバーに同期されて、複数の Web サーバーなどのデータの共有ストレージに一般的に使用される共有ストレージ機能を実装します.これらの Web のデータの一貫性を確保することは間違いなく必要ですnfs が複数の Web サーバーにマウントされている場合、Web サイトのルート ディレクトリの下に、Web サイト プログラムが nfs サーバーに配置されます。すべての Web サイトとすべての Web プログラムは、このディレクトリを読み取り、一貫したデータを持つことができるため、複数のノードが一貫したプログラムを提供することが保証されます。

1) 別のサーバーを nfs サーバーとして使用する. ここではまず、Web ページのルート ディレクトリを格納する NFS サーバーを構築します。

yum install nfs-utils -y

2) ディレクトリを公開して、他のサーバーがこのディレクトリをマウントできるようにします。

mkdir /opt/k8s
vim /etc/exports
/opt/k8s 192.168.30.0/24(rw,no_root_squash)

このネットワーク セグメントに、読み取りおよび書き込み可能なアクセス許可を追加します

[root@nfs ~]# systemctl start nfs

マウントしてテストするノードを見つけます。このディレクトリを共有している限り、このクライアントをインストールする必要があります

#其他节点也需要安装nfs
yum install nfs-utils -y
mount -t nfs 192.168.30.27:/opt/k8s /mnt
cd /mnt
df -h
192.168.30.27:/opt/k8s    36G  5.8G   30G   17% /mnt
touch a.txt

サーバーに移動して、データが共有されていることを確認します

nfs サーバーのデータを削除すると、それも削除されます.
次に、K8s の使用方法.
Web ページのすべてのディレクトリをこのディレクトリに配置します。

# mkdir wwwroot
# vim nfs.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nfs
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: hub.kaikeba.com/library/myapp:v1
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot
        nfs:
          server: 192.168.66.13
          path: /opt/k8s/wwwroot
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: NodePort

ソース ポッドの Web ディレクトリにデータを書き込み、nfs サーバー ディレクトリでも共有されることを確認します。

4. PV&PVC

1. pv&pvcの説明

管理存储と管理计算には明確な違いがあります。PersistentVolumeユーザーと管理者に一連の API を提供し、存储方法を抽象化します提供和消耗的细节PersistentVolume(简称PV)ここでは、と の2 つの新しい API リソースを紹介しますPersistentVolumeClaim(简称PVC)

  • PersistentVolume (Persistent Volume、PV と呼ばれる) は、クラスター内の管理者によって提供されるネットワーク ストレージの一部です。クラスター内のノードと同様に、PV もクラスター内のリソースです。Volume のようなボリューム プラグインでもありますが、そのライフ サイクルはそれを使用する Pod とは無関係です。PV は、NFS、iSCSI、またはその他のクラウド ストレージ システムなどの実装の詳細をキャプチャする API オブジェクトです。
  • PersistentVolumeClaim (Persistent Volume Claim、略して PVC) は、ユーザーからのストレージ要求です。Pod と同様に、Pod は Node リソースを消費し、PVC は PV リソースを消費します。Pod は、特定のリソース (CPU やメモリなど) を要求できます。PVC は、指定されたサイズとアクセス モードを要求できます (1 回限りの読み取り/書き込みまたは複数の読み取り専用としてマップできます)。

PVC を使用すると、ユーザーは抽象的なストレージ リソースを消費できます。また、ユーザーは多くの場合、さまざまな属性 (パフォーマンスなど) の PV を必要とします。クラスター管理者は、ボリュームの実装方法の詳細をユーザーに公開することなく、さまざまなサイズとさまざまなアクセス モードのさまざまな PV を提供する必要があります。この必要性のために、リソースが生まれますStorageClass

StorageClass管理者が提供するストレージのレベルを説明する方法を提供します。クラスタ管理者は、さまざまなレベルをさまざまなサービス レベルおよびさまざまなバックエンド ポリシーにマッピングできます。

ストレージの配置はK8s、
コンテナストレージの配置は主にpv/pvcと呼ばれるデータ永続ボリュームのPersistentVolumeを使用

• PersistentVolume (PV): ストレージ リソースの作成と使用を抽象化したもので、クラスタ内のリソース管理 PV としてのストレージは、
運用と保守によって考慮され、外部ストレージの管理に使用されます。

• 静的: 事前に pv を作成します。たとえば、100G pv、200G pv を作成し、必要な人に使用させます。つまり、pvc は pv に接続されています。つまり、作成された pv の数、どのようにどれだけのスペースが作られ、その作品の名前がどれだけ、ある程度の一致性があるか

• ダイナミック

• PersistentVolumeClaim (PVC): ユーザーが特定のボリューム実装の詳細を定義するために使用される容量を気にする必要がないように
. たとえば、10 G を使用するためにサービスを開発および展開する必要がある場合、リソース オブジェクト pvc を使用できます。 10 G の使用を定義するために使用されます。他のことは気にしないでください。

pv&pvcの違い

PersistentVolume(持久卷)と は、PersistentVolumeClaim(持久卷申请)ストレージの詳細を抽象化するために k8s によって提供される 2 つの API リソースです。

管理者は、ユーザーがどのように使用するかに注意を払うことなく、pv を介してストレージ機能を提供する方法に焦点を当てます. 同様に、ユーザーは、ストレージ ボリュームを実装するために使用されるテクノロジに注意を払うことなく、コンテナーに pvc をマウントするだけで済みます.

pvc と pv の関係はポッドとノードの関係と似ており、前者は後者のリソースを消費します。PVC は、指定されたサイズのストレージ リソースを PV に適用し、アクセス モードを設定して、Provision -> Claim を通じてストレージ リソースを制御できます。

2.ライフサイクル

ボリュームとクレームのライフ サイクル。PV はクラスター内のリソース、PVC はこれらのリソースの要求であり、これらのリソースの「抽出証明書」でもあります。PV と PVC 間の相互作用は、次のライフ サイクルに従います。

  • 供給

    PV を提供するには、静的と動的の 2 つの方法があります。

  • 静的

    クラスター管理者は、クラスター ユーザーが利用できる実際のストレージの詳細を保持する複数の PV を作成します。これらは Kubernetes API に存在し、ストレージで使用できます。

  • 動的

    管理者によって作成された静的 PV のいずれもユーザーの PVC と一致しない場合、クラスターはボリュームを PVC に排他的にプロビジョニングしようとする場合があります。プロビジョニングは StorageClass に基づいています。PVC はそのようなクラスを要求する必要があり、管理者はこの動的なプロビジョニングを行うためにそのようなクラスを作成して構成しておく必要があります。クラス "" で構成された PVC を要求すると、それ自体の動的プロビジョニング機能が実質的に無効になります。

  • 縛る

    ユーザーは、必要なストレージ サイズとアクセス モードを指定して、PVC を作成します (または動的プロビジョニング用に以前に作成しました)。マスターには、新しい PVC を監視し、一致する PV (存在する場合) を見つけ、PVC を PV にバインドする制御ループがあります。PV が新しい PVC に動的にプロビジョニングされた場合、ループは常に PV を PVC にバインドします。さらに、ユーザーは常に少なくとも要求したストレージを取得しますが、ボリュームが要求を超える場合があります。バインドされると、バインド モードに関係なく、PVC バインドは排他的になります。

    一致する PV が見つからない場合、PVC は無期限に unbound unbound 状態になり、PV が使用可能になると、PVC は再びバインドされます。たとえば、PV クラスターが多くの 50G を提供する場合、100G を必要とする PVC とは一致しません。100G PV がクラスターに追加されるまで、PVC はバインドされません。

  • 使用

    Pod はボリュームと同様に PVC を使用します。クラスターは PVC をチェックし、バインドされた PV を見つけて、PV を Pod にマップします。複数のアクセス モードをサポートする PV の場合、ユーザーは使用するモードを指定できます。ユーザーが PVC を所有し、PVC がバインドされると、ユーザーが必要とする限り、PV は常にユーザーに属します。ユーザーは Pod のボリューム ブロックに PVC を含めることで、Pod をスケジュールし、PV にアクセスします。

  • 解放された

    ユーザーが PV の使用を終了すると、API を介して PVC オブジェクトを削除できます。PVC が削除されると、対応する PV は「解放された」と見なされますが、別の PVC で使用することはできません。以前の PVC の所有権はこの PV にまだ存在しており、ポリシーに従って処分する必要があります。

  • リサイクル

    PV の再利用ポリシーは、PV が解放された後に PV をどう処理するかをクラスターに指示します。現在、PV は保持、リサイクル、または削除できます。Reserved を使用すると、リソースを手動で再度宣言できます。削除操作をサポートする PV ボリュームの場合、削除操作は、対応する外部ストレージ (AWS EBS、GCE PD、Azure ディスク、または Cinder ボリュームなど) だけでなく、Kubernetes から PV オブジェクトを削除します。動的にプロビジョニングされたボリュームは常に削除されます。

3、ポッド&PVC

最初にコンテナ アプリケーションを作成します

#vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
    containers:
    - name: nginx
      image: nginx:latest
      ports:
      - containerPort: 80
      volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc

ボリュームには yaml が必要で、ここの名前は一致している必要があります. 通常、2 つのファイルは 1 つにまとめられます

# vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

次のステップは運用と保守、事前に pv を作成します

# vim pv1.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/k8s/demo1
    server: 192.168.66.13

事前に pv を作成し、ディレクトリをマウントします

別のpvを作成し、事前にnfsサーバーにディレクトリを作成し、名前を変更します

# vim pv2.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv2
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/k8s/demo2
    server: 192.168.66.13

次に、ポッドと pvc を作成します。ここでは、それらをまとめて記述します。

# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
      - name: www
        mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

es:
- ReadWriteMany
nfs:
パス: /opt/k8s/demo1
サーバー: 192.168.66.13


提前创建好pv,以及挂载目录

我再创建一个pv,在nfs服务器提前把目录创建好,名称修改一下

```yaml
# vim pv2.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv2
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/k8s/demo2
    server: 192.168.66.13

次に、ポッドと pvc を作成します。ここでは、それらをまとめて記述します。

# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
      - name: www
        mountPath: /usr/share/nginx/html
  volumes:
    - name: www
      persistentVolumeClaim:
        claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

おすすめ

転載: blog.csdn.net/qq_58360406/article/details/129759462