注意:

将密钥与 Oracle Cloud Native Environment 结合使用

简介

许多应用程序具有仅授权用户应访问的信息,例如密码。在这种情况下,Kubernetes Secrets 可以提供帮助。它们提供了一种安全地管理敏感数据(如密码、SSH 和 API 密钥)的方法。使用密钥可以将机密数据与应用程序的代码分离,从而降低在 Pod 工作流中暴露或修改敏感数据的风险。

在开始之前,了解有关 Kubernetes 密钥的一些基本详细信息会很有帮助:

重要提示:默认情况下,Kubernetes 密钥不加密,因为它们只有 Base64 编码并且未加密存储在 etcd 中。因此,任何可以访问 etcd 的人都可以查看或更改密钥。使用 Kubernetes 密钥可以通过以下任何方法实现安全:

本教程介绍了 Kubernetes 密钥的基础知识,并演示了一个简单的用例。

有关 Oracle Cloud Native Environment 2 的更多信息,请参阅当前 Release Documentation 站点。

目标

在本教程中,您将学习:

先决条件

配置 Oracle Cloud Native Environment

注:如果在您自己的租户中运行,请在部署实验环境之前阅读 linux-virt-labs GitHub 项目 README.md 并完成先决条件。

  1. 在 Luna Desktop 上打开一个终端。

  2. 克隆 linux-virt-labs GitHub 项目。

    git clone https://github.com/oracle-devrel/linux-virt-labs.git
    
  3. 转到工作目录。

    cd linux-virt-labs/ocne2
    
  4. 安装所需集合。

    ansible-galaxy collection install -r requirements.yml
    
  5. 部署实验室环境。

    ansible-playbook create_instance.yml -e localhost_python_interpreter="/usr/bin/python3.6" -e install_ocne_rpm=true -e create_ocne_cluster=true -e "ocne_cluster_node_options='-n 1 -w 1'"
    

    免费的实验环境需要额外的变量 local_python_interpreter,该变量为在 localhost 上运行的播放设置 ansible_python_interpreter。此变量是必需的,因为环境安装了适用于 Python 的 Oracle Cloud Infrastructure SDK 的 RPM 程序包,该程序包位于 python3.6 模块下。

    默认部署配置使用 AMD CPU 和 Oracle Linux 8。要使用 Intel CPU 或 Oracle Linux 9,请将 -e instance_shape="VM.Standard3.Flex"-e os_version="9" 添加到部署命令。

    重要提示:等待手册成功运行并到达暂停任务。在手册的这一阶段,Oracle CNE 安装已完成,实例已准备就绪。记下之前的剧集,其中输出其部署的节点的公共和专用 IP 地址,以及运行实验时所需的任何其他部署信息。

访问 Kubernetes 集群

  1. 打开终端并通过 SSH 连接到 ocne 实例。

    ssh oracle@<ip_address_of_instance>
    
  2. 等待群集稳定下来,并且所有 pod 都报告为正在运行状态。

    watch kubectl get pods -A
    

    当所有 pod 显示 STATUSRunning 时,键入 ctrl-c 以退出 watch 命令。

  3. 确认存在多少个节点。

    kubectl get nodes
    

创建秘密

有三种方法可以创建 Kubernetes 密钥,这些方法包括:

直接从命令行使用 Kubectl

Kubectl 以两种方式之一创建秘密:

  1. 使用直接从命令行传递的文字值创建密钥。

    kubectl create secret generic my-literal-secret --from-literal=username=my-user --from-literal=password=my-password
    

    注:使用单引号 '' 对字符串值中包含的特殊字符(如 $\$&=!)进行转义。否则,命令 shell 将对其进行解释。

    输出示例:

    [oracle@ocne ~]$ kubectl create secret generic my-literal-secret --from-literal=username=my-user --from-literal=password=my-password
    secret/my-literal-secret created
    

将 Kubectl 与存储的身份证明文件结合使用

文件的内容变为 VALUE ,文件名变为 KEY

  1. 创建身份证明文件。

    echo -n 'admin' > ./username.txt
    echo -n 'S!B\*d$zDsb=' > ./password.txt
    
  2. 使用保存的文件创建密钥。

    kubectl create secret generic my-file-secret \
     --from-file=username=./username.txt \
     --from-file=password=./password.txt
    

    注:缺省行为使用文件名作为 KEY 值来显示如何覆盖缺省行为,并使用 --from-file=[key]=[path to file] 方法直接从命令行声明 KEY 名称 - 值。

    额外信息:

    或者,您可以从存储在子目录中的多个文件创建密钥。

    1. 创建子目录。

      mkdir secrets
      
    2. 创建身份证明文件。

      echo -n 'user1' > ./secrets/username.txt
      echo -n 'my-super-secret-password' > ./secrets/password.txt
      
    3. 使用子目录中的身份证明文件创建密钥。

      kubectl create secret generic my-secret --from-file=./secrets/
      

      注:此方法使用每个文件名作为 KEY 值,并将文件的内容用作 VALUE

使用 Kubectl 应用 YAML 配置文件

  1. 创建密钥 YAML 定义文件。

    cat << EOF | tee db-credentials.yaml > /dev/null
    apiVersion: v1
    kind: Secret
    metadata:
      name: db-credentials
      # immutable: true
    type: Opaque
    data:
      username: "bXktdXNlcg=="
      password: "bXktcGFzc3dvcmQ="
    EOF
    

    注: YAML 文件中的密钥值必须为 BASE64 编码。

  2. 应用密钥。

    kubectl apply -f db-credentials.yaml
    

将 Kustomize 与 kustomization.yaml 文件结合使用

使用 Kustomize 创建密钥需要 kustomization.yaml 文件。该文件应使用以下方法之一定义 secretGenerator

使用 Kustomize 时,上述所有内容都不要求对密钥值进行 Base64 编码。Kustomize 使用的 YAML 文件的名称必须kustomization.yamlkustomization.yml

此示例说明如何使用文字值创建密钥。

  1. 创建 secretGenerator 文件。

    cat << EOF | tee kustomization.yaml > /dev/null
    secretGenerator:
    - name: database-credentials
      literals:
      - username=admin
      - password=password
    EOF
    
  2. 使用 Kustomize 生成密钥。

    kubectl -n default apply -k .
    

    输出示例:

    [oracle@ocne ~]$ kubectl -n default apply -k .
    secret/database-credentials-fd8288cb7g created
    

管理 Kubernetes 密钥

您可以将 Kubernetes 密钥存储在不同的名称空间中。因此,您需要使用 -n 选项从特定名称空间检索密钥,或者使用 --all-namespaces-A 从所有名称空间检索密钥。如果不指定名称空间,则 kubectl 命令将使用 default 名称空间。创建 Kubernetes 密钥时也适用相同的行为。

列出现有 Kubernetes 密钥

  1. 列出新创建的密钥。

    kubectl get secrets
    

    输出示例:

    NAME                              TYPE     DATA   AGE
    database-credentials-fd8288cb7g   Opaque   2      34s
    db-credentials                    Opaque   2      2m16s
    my-file-secret                    Opaque   2      2m40s
    my-literal-secret                 Opaque   2      2m51s
    
  2. 获取有关新创建的密钥的更多详细信息。

    kubectl describe secrets
    

    输出示例:

    [oracle@ocne ~]$ kubectl describe secrets
    Name:         database-credentials-fd8288cb7g
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Type:  Opaque
    
    Data
    ====
    password:  8 bytes
    username:  5 bytes
    
    
    Name:         db-credentials
    Namespace:    default
    ...
    ...
    
    Name:         my-literal-secret
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Type:  Opaque
    
    Data
    ====
    username:  7 bytes
    password:  11 bytes
    

    请注意,kubectl getkubectl describe 命令不显示 secret 的内容,以防止意外暴露或包含在日志文件中。

  3. 查看其中一个密钥的信息。

    kubectl -n default describe secret db-credentials
    

    输出示例:

    [oracle@ocne ~]$ kubectl -n default describe secret db-credentials
    Name:         db-credentials
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    
    Type:  Opaque
    
    Data
    ====
    password:  11 bytes
    username:  7 bytes
    

解码 Kubernetes 密钥

  1. 查看其中一个密钥的存储数据。

    kubectl -n default get secret db-credentials -o jsonpath='{.data}'
    

    输出示例:

    [oracle@ocne ~]$ kubectl -n default get secret db-credentials -o jsonpath='{.data}'
    {"password":"bXktcGFzc3dvcmQ=","username":"bXktdXNlcg=="}[oracle@ocne ~]$ 
    

    输出显示密钥数据的编码密钥:值对。值数据是 base64 编码的。

  2. 解码编码的 Key:Value 数据。

    echo <BASE64-VALUE-FOR-PASSWORD> | base64 --decode
    

    输出示例:

    [oracle@ocne ~]$ echo bXktc3VwZXItc2VjcmV0LXBhc3Nvd3Jk | base64 --decode
    my-password[oracle@ocne ~]$ 
    

    警告:这些步骤可能会导致在 shell 历史记录中记录密钥数据。通过组合两个步骤来避免这种情况,如下一步所示。

  3. 解码编码 Key:Value 数据的更安全方法。

    kubectl -n default get secret db-credentials -o jsonpath='{.data.password}' | base64 --decode
    

    输出示例:

    [oracle@ocne ~]$ kubectl -n default get secret db-credentials -o jsonpath='{.data.password}' | base64 --decode
    my-password[oracle@ocne ~]$ 
    

编辑密钥

与许多 Kubernetes 对象一样,您可以编辑 Kubernetes 密钥。唯一的例外是将密钥声明为 immutable

  1. 编辑密钥。

    kubectl edit secrets my-literal-secret
    

    默认编辑器将打开(默认情况下为 vi),以允许您更新 data: 字段中的 Base64 编码密钥值。

    输出示例:

    # Please edit the object below. Lines beginning with a '#' will be ignored,
    # and an empty file will abort the edit. If an error occurs while saving this file will be
    # reopened with the relevant failures.
    #
    apiVersion: v1
    data:
      password: bXktcGFzc3dvcmQ=
      username: bXktdXNlcg==
    kind: Secret
    metadata:
      creationTimestamp: "2025-05-09T10:56:14Z"
      name: my-literal-secret
      namespace: default
      resourceVersion: "1689"
      uid: 394dfda3-025a-417d-bbfe-c4851a6b6cff
    type: Opaque
    ~                                                                                                                                       
    ~                                                                                                                                             
    ~                                                                                                                                       
    ~                                                                                                                                             
    "/tmp/kubectl-edit-1267071353.yaml" 16L, 480C
    
  2. 退出编辑器而不保存,方法是按 Esc 键,后跟 :q! 键。

    输出示例:

    [oracle@ocne ~]$ kubectl edit secrets my-literal-secret
    Edit cancelled, no changes made.
    

删除私钥

可以使用 kubectl -n <NAMESPACE> delete 命令删除密钥。

  1. 删除密钥。

    kubectl -n default delete secret my-file-secret my-literal-secret
    

    输出示例:

    [oracle@ocne ~]$ kubectl -n default delete secret my-file-secret  my-literal-secret
    secret "my-file-secret" deleted
    secret "my-literal-secret" deleted
    

    注:您可以通过对多个密钥进行空格分隔来删除它们。

将密钥与部署结合使用

接下来,您将使用创建的 Kubernetes 密钥数据创建部署。

  1. 列出 default 名称空间中的所有密钥。

    kubectl get secrets -n default
    

    输出示例:

    [oracle@ocne ~]$ kubectl get secrets -n default
    NAME                              TYPE     DATA   AGE
    database-credentials-fd8288cb7g   Opaque   2      10m
    db-credentials                    Opaque   2      8m
    
  2. 创建部署 YAML 文件。

    cat << EOF | tee echo-deployment.yaml > /dev/null
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: echo
      template:
        metadata:
          labels:
            app: echo
        spec:
          containers:
          - name: echo
            image: ghcr.io/oracle/oraclelinux:9
            command: ["/bin/bash", "-c"]
            args: ["echo 'Username: $USER' 'Password: $PASSWORD'; sleep infinity"]
            env:
            - name: USER
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: username
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-credentials
                  key: password
          restartPolicy: Always
    EOF
    
  3. 创建部署

    kubectl -n default apply -f echo-deployment.yaml
    
  4. 确认部署。

    kubectl get deployments
    

    您可能需要在部署时重新查询几次。

    输出示例:

    [oracle@ocne ~]$ kubectl get deployments 
    NAME              READY   UP-TO-DATE   AVAILABLE   AGE
    echo-deployment   1/1     1            1           4m
    
  5. 获取已部署 Pod 的名称。

    kubectl get pods
    

    输出示例:

    [oracle@ocne ~]$ kubectl get pods
    NAME                               READY   STATUS    RESTARTS   AGE
    echo-deployment-59bff74847-9nnkq   1/1     Running   0          6m
    

    注意:您的云池的名称将不同。

  6. 验证部署的 Pod 是否使用了密钥。

    kubectl -n default describe pod <POD-NAME>
    

    其中:

    • <POD-NAME> - 部署中的 Pod 名称。

    输出示例:

    [oracle@ocne ~]$ kubectl -n default describe pod echo-deployment-59bff74847-9nnkq
    Name:             echo-deployment-59bff74847-9nnkq
    Namespace:        default
    Priority:         0
    Service Account:  default
    Node:             ocne-worker-1/192.168.122.77
    Start Time:       Mon, 12 May 2025 13:42:25 +0000
    ...
    ...
        Ready:          True
        Restart Count:  0
        Environment:
          USER:      <set to the key 'username' in secret 'db-credentials'>  Optional: false
          PASSWORD:  <set to the key 'password' in secret 'db-credentials'>  Optional: false
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-5fp4d (ro)
    Conditions:
      Type                        Status
      PodReadyToStartContainers   True 
      Initialized                 True
    ...
    ..
    QoS Class:                   BestEffort
    Node-Selectors:              <none>
    Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    Events:                      <none>
    [oracle@ocne ~]$ 
    

    注:检查 Environment: 部分是否确认存在 $USER$PASSWORD 变量。

  7. 确认部署的云池中存在环境变量。

    kubectl exec -it <POD-NAME> -- printenv USER PASSWORD
    

    其中:

    • <POD-NAME> - 部署中的 Pod 名称。

    输出示例:

    [oracle@ocne ~]$ kubectl exec -it echo-deployment-59bff74847-9nnkq -- printenv USER PASSWORD
    my-user
    my-password
    

    输出确认您已成功在部署的云池中将 Kubernetes 密钥用作环境变量。

后续步骤

本教程演示了如何创建和使用 Kubernetes 密钥来限制对敏感信息的未经授权的访问。然而,这只是开始。有关其他教程和内容,请查看 Oracle Linux 培训站。

更多学习资源

通过 docs.oracle.com/learn 浏览其他实验室,或者通过 Oracle Learning YouTube 频道访问更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。

有关产品文档,请访问 Oracle 帮助中心