42、Kubernetes 资源管理:Secrets、命名与命名空间

Kubernetes 资源管理:Secrets、命名与命名空间

1. 管理 Kubernetes 中的 Secrets

1.1 Secrets 概述

Kubernetes 的 Secrets 以键值对的形式管理信息,其中值是经过编码的。使用 Secrets 可以避免在配置文件中设置敏感值或在命令行中输入它们,从而降低凭证泄露的风险,并使资源配置更加有序。目前,Secrets 有三种类型:
- Opaque:默认类型,数据不会显示。
- Service account token
- Docker authentication

1.2 使用 Secrets 前的准备

  • 大小限制 :每个 Secret 有 1 MB 的大小限制,虽然可以在单个 Secret 中定义多个键值对,但总大小不能超过 1 MB。
  • 创建顺序 :由于 Secret 对于容器来说就像一个卷,因此需要在依赖它的 Pod 之前创建 Secret。

1.3 创建 Secret

只能使用配置文件来生成 Secret。以下是一个简单的示例:

// A simple file for configuring secret
# cat secret-test.json
{
  "kind": "Secret",
  "apiVersion": "v1",
  "metadata": {
    "name": "secret-test"
  },
  "type": "Opaque",
  "data": {
    "username": "YW15Cg==",
    "password": " UGEkJHcwcmQhCg=="
  }
}

可以通过以下命令对值进行 Base64 编码:

# echo "amy" | base64
YW15Cg==

使用以下命令创建 Secret 并检查其状态:

# kubectl create -f secret-test.json
secret "secret-test" created
# kubectl get secret
NAME          TYPE      DATA      AGE
secret-test   Opaque    2         39s
# kubectl describe secret secret-test
Name:    secret-test
Namespace:  default
Labels:    <none>
Annotations:  <none>
Type:  Opaque
Data
====
password:  10 bytes
username:  4 bytes

1.4 在容器中使用 Secret

为了让 Pod 获取 Secret 信息,需要将 Secret 数据作为文件挂载到容器中。以下是一个示例配置文件:

# cat pod-secret.json
{
  "kind": "Pod",
  "apiVersion": "v1",
  "metadata": {
    "name": "pod-with-secret"
  },
  "spec": {
    "volumes": [
      {
        "name": "secret-volume",
        "secret": {
          "secretName": "secret-test"
        }
      }
    ],
    "containers": [
      {
        "name": "secret-test-pod",
        "image": "nginx",
        "volumeMounts": [
          {
            "name": "secret-volume",
            "readOnly": true,
            "mountPath": "/tmp/secret-volume"
          }
        ]
      }
    ]
  }
}

验证容器中 Secret 内容是否已解密:

// login to node and enable bash process with new tty
# docker exec -it <CONTAINER_ID> bash
root@pod-with-secret:/# ls /tmp/secrets/
password  username
root@pod-with-secret:/# cat /tmp/secrets/password
Pa$$w0rd!
root@pod-with-secret:/# cat /tmp/secrets/username
amy

1.5 删除 Secret

可以使用以下命令删除 Secret:

# kubectl delete -f secret-test.json
secret "secret-test" deleted

1.6 Secrets 的工作原理

为了降低 Secret 内容泄露的风险,Kubernetes 系统不会将 Secret 数据保存在磁盘上,而是存储在内存中。Kubernetes API 服务器会将 Secret 推送到运行所需容器的节点上,节点将数据存储在 tmpfs 中,当容器被销毁时,tmpfs 中的数据会被清除。

1.7 其他注意事项

  • 避免创建大尺寸或大量小尺寸的 Secret :由于 Secret 存储在节点的内存中,减少 Secret 的总大小有助于节省资源并保持良好的性能。
  • 服务账户 :可以通过创建不同的服务账户来实现不同的身份验证。以下是创建服务账户的示例:
# example of service account creation
$ cat serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-account
# create service account named test-account
$ kubectl create -f serviceaccount.yaml
serviceaccount "test-account" created

可以使用以下命令查看和删除服务账户:

$ kubectl get serviceaccounts
NAME           SECRETS   AGE
default        0         18d
test-account   0         37s
$ kubectl delete serviceaccount test-account
serviceaccount "test-account" deleted

2. Kubernetes 中的命名规则

2.1 命名概述

在创建 Kubernetes 对象(如 Pod、Replication Controller 和 Service)时,可以为其分配名称。Kubernetes 中的名称在空间上是唯一的,即在同一 Pod 中不能使用相同的名称。

2.2 命名限制

  • 名称长度最多为 253 个字符。
  • 只能包含小写字母、数字。
  • 中间可以包含特殊字符,但只能是连字符 (-) 和点 (.)。

2.3 命名示例

2.3.1 成功创建 Pod
# cat my-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
# kubectl create -f my-pod.yaml 
pod "my-pod" created
# kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
my-pod    0/1       Running   0          4s
# kubectl describe pod my-pod
Name:        my-pod
Namespace:      default
Image(s):      nginx
Node:        ip-10-96-219-25/10.96.219.25
Start Time:      Wed, 16 Dec 2015 00:46:33 +0000
Labels:        <none>
Status:        Running
Reason:        
Message:      
IP:        192.168.34.35
Replication Controllers:  <none>
Containers:
  my-container:
    Container ID:  docker://5501d115703e334ae44c1541b990a7e22ce4f310226ea
fea206594e4c85c90d9
    Image:    nginx
    Image ID:    docker://6ffc02088cb870652eca9ccd4c4fb582f75b29af2879792
ed09bb46fd1c898ef
    State:    Running
      Started:    Wed, 16 Dec 2015 00:46:34 +0000
    Ready:    True
    Restart Count:  0
    Environment Variables:
2.3.2 命名冲突导致创建失败
# cat duplicate.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: nginx
  - name: my-container
    image: centos
    command: ["/bin/sh", "-c", "while : ;do curl http://localhost:80/; 
sleep 3; done"]
# kubectl create -f duplicate.yaml 
The Pod "my-pod" is invalid.
spec.containers[1].name: duplicate value 'my-container'
You can add the -validate flag
For example: kubectl create -f duplicate.yaml -validate
Use a schema to validate the input before sending it
2.3.3 不同类型对象使用相同名称
# cat nginx.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: my-nginx
spec:
  replicas: 2
  selector:
      sel : my-selector
  template:
    metadata:
        labels:
          sel : my-selector
    spec:
      containers:
      - name: my-container
        image: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
spec:
  ports:
    - protocol: TCP
      port: 80
      nodePort: 30080
  type: NodePort
  selector:
     sel: my-selector
# kubectl create -f nginx.yaml 
replicationcontroller "my-nginx" created
service "my-nginx" created
# kubectl get rc
CONTROLLER   CONTAINER(S)   IMAGE(S)   SELECTOR          REPLICAS   AGE
my-nginx     my-container   nginx      sel=my-selector   2          8s
# kubectl get service
NAME         CLUSTER_IP       EXTERNAL_IP   PORT(S)   SELECTOR          
AGE
kubernetes   192.168.0.1      <none>        443/TCP   <none>            
6d
my-nginx     192.168.38.134   nodes         80/TCP    sel=my-selector   
14s

2.4 命名建议

  • 建议使用能够方便查找和识别容器镜像的命名方式,如 memcached-pod1 haproxy.us-west my-project1.mysql
  • 避免使用包含大写字母、下划线或点在最后的名称,如 Memcache-pod1 haproxy.us_west my-project1.mysql.
  • 如果需要分配环境、版本或应用角色等信息,可以使用标签(Label)。
  • 如果只需要分配应用名称,可以使用命名空间(Namespace)。

3. Kubernetes 中的命名空间管理

3.1 命名空间概述

在 Kubernetes 集群中,资源的名称在命名空间内是唯一的。使用 Kubernetes 命名空间可以在同一集群中为不同环境隔离命名空间,从而灵活地创建隔离环境并将资源分配给不同的项目和团队。

3.2 准备工作

  • 默认情况下,Kubernetes 会创建一个名为 default 的命名空间,未指定命名空间创建的对象将被放入该命名空间。
  • Kubernetes 还会创建一个名为 kube-system 的初始命名空间,用于存放 Kubernetes 系统对象。
  • 命名空间的名称必须是 DNS 标签,且满足以下规则:
  • 最多 63 个字符。
  • 匹配正则表达式 [a-z0-9]([-a-z0-9]*[a-z0-9])

3.3 创建命名空间

# cat newNamespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: new-namespace
# kubectl create -f newNamespace.yaml

3.4 查看命名空间

# kubectl get namespaces
NAME            LABELS    STATUS    AGE
default         <none>    Active    8d
new-namespace   <none>    Active    12m

3.5 在命名空间中运行资源

# kubectl run nginx --image=nginx --namespace=new-namespace

查看 Pod 时,如果不指定命名空间,可能看不到新命名空间中的 Pod:

# kubectl get pods
NAME                                    READY     STATUS        
RESTARTS   AGE

使用 --all-namespaces 或指定命名空间查看 Pod:

# kubectl get pods --all-namespaces
NAMESPACE      NAME          READY     STATUS    RESTARTS   AGE
new-namespace  nginx-ns0ig   1/1       Running   0          17m
# kubectl get pods --namespace=new-namespace
NAME          READY     STATUS    RESTARTS   AGE
nginx-ns0ig   1/1       Running   0          18m

3.6 指定命名空间创建资源

使用配置文件创建资源时,可以通过 --namespace 参数指定命名空间:

# kubectl create -f myResource.yaml --namespace=new-namespace

3.7 更改默认命名空间

3.7.1 查找当前上下文
# kubectl config view | grep current-context
current-context: ""
3.7.2 设置新的上下文
# kubectl config set-context <current context or new context name> 
--namespace=new-namespace
3.7.3 查看当前配置
# kubectl config view
apiVersion: v1
clusters: []
contexts:
- context:
    cluster: ""
    namespace: new-namespace
    user: ""
  name: new-context
current-context: ""
kind: Config
preferences: {}
users: []
3.7.4 切换上下文
# kubectl config use-context new-context
3.7.5 验证当前上下文
# kubectl config view | grep current-context
current-context: new-context
3.7.6 查看 Pod
# kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
nginx-ns0ig   1/1       Running   0          54m

3.8 删除命名空间

# kubectl delete namespaces new-namespace
namespace "new-namespace" deleted

删除命名空间后,该命名空间下的所有资源都会被删除。如果尝试在已删除的命名空间中创建资源,会出现错误:

# kubectl run nginx --image=nginx
Error from server: namespaces "new-namespace" not found

可以将默认命名空间切换回 default

# kubectl config set-context new-context --namespace=""
context "new-context" set.
# kubectl run nginx --image=nginx
replicationcontroller "nginx" created
# kubectl describe pods nginx-ymqeh
Name:        nginx-ymqeh
Namespace:      default
Image(s):      nginx
Node:        ip-10-96-219-156/10.96.219.156
Start Time:      Sun, 20 Dec 2015 16:13:33 +0000
Labels:        run=nginx
Status:        Running
...

3.9 资源配额限制

有时需要通过命名空间来限制每个团队的资源配额。默认情况下,资源配额和限制未设置。在设置限制之前,需要启用 Kubernetes API 服务器中的 LimitRanger

# kube-apiserver --admission-control=LimitRanger

或在配置文件中设置:

# cat /etc/kubernetes/apiserver
...
# default admission control policies
KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceE
xists,LimitRanger,SecurityContextDeny,ResourceQuota"
...

以下是在命名空间中创建限制的示例:

# cat limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limits
  namespace: new-namespace
spec:
  limits:
  - max:
      cpu: "2"
      memory: 1Gi
    min:
      cpu: 200m
      memory: 6Mi
    type: Pod
  - default:
      cpu: 300m
      memory: 200Mi
    defaultRequest:
      cpu: 200m
      memory: 100Mi
    max:
      cpu: "2"
      memory: 1Gi
    min:
      cpu: 100m
      memory: 3Mi
    type: Container
# kubectl create -f limits.yaml
limitrange "limits" created
# kubectl get LimitRange --namespace=new-namespace
NAME      AGE
limits    22m
# kubectl describe namespace new-namespace
Name:  new-namespace
Labels:  <none>
Status:  Active
No resource quota.
Resource Limits
 Type      Resource  Min   Max   Request  Limit   Limit/Request
 ----      --------  ---     ---    -------  -----   -------------
 Pod      memory    6Mi      1Gi  -         -      -
 Pod      cpu       200m   2     -         -      -
 Container  cpu       100m   2     200m      300m   -
 Container  memory    3Mi      1Gi  100Mi      200Mi   -

在该命名空间中创建的所有 Pod 和容器都必须遵循这些资源限制,否则会抛出验证错误。

总结

本文详细介绍了 Kubernetes 中 Secrets、命名和命名空间的使用方法。通过合理使用这些功能,可以提高 Kubernetes 集群的安全性、可管理性和资源利用率。在实际应用中,需要根据具体需求和场景,灵活运用这些特性,以实现高效的资源管理。

流程图:创建 Secret 流程

graph LR
    A[准备配置文件] --> B[检查大小限制]
    B --> C[创建 Secret]
    C --> D[验证 Secret 状态]
    D --> E[挂载到容器]
    E --> F[验证容器中 Secret 内容]

表格:命名规则总结

规则 详情 示例
长度 最多 253 个字符
字符 小写字母、数字
特殊字符 中间可包含连字符 (-) 和点 (.) memcached-pod1
冲突 同一 Pod 中不能使用相同名称
不同类型对象 不同类型对象可使用相同名称 my-nginx (Replication Controller 和 Service)

流程图:命名空间操作流程

graph LR
    A[创建命名空间] --> B[查看命名空间]
    B --> C[在命名空间中运行资源]
    C --> D[查看资源]
    D --> E{是否需要切换默认命名空间}
    E -- 是 --> F[切换默认命名空间]
    E -- 否 --> G[删除命名空间]
    F --> D
    G --> H[验证删除结果]

表格:命名空间资源配额限制总结

资源类型 最小限制 最大限制 默认请求 默认限制
Pod - CPU 200m 2 - -
Pod - 内存 6Mi 1Gi - -
Container - CPU 100m 2 200m 300m
Container - 内存 3Mi 1Gi 100Mi 200Mi

4. 综合应用案例与最佳实践

4.1 综合应用案例

假设我们要部署一个简单的 Web 应用,该应用需要访问数据库,并且我们希望通过 Kubernetes 的资源管理功能来保证安全性和资源的合理分配。

4.1.1 创建 Secret 存储数据库凭证

首先,我们创建一个 Secret 来存储数据库的用户名和密码。

// database-secret.json
{
  "kind": "Secret",
  "apiVersion": "v1",
  "metadata": {
    "name": "database-secret"
  },
  "type": "Opaque",
  "data": {
    "db-username": "c29tZV91c2VybmFtZQ==",
    "db-password": "c29tZV9wYXNzd29yZA=="
  }
}
# 对值进行 Base64 编码
echo "some_username" | base64
echo "some_password" | base64
# 创建 Secret
kubectl create -f database-secret.json
4.1.2 创建命名空间

为了隔离这个 Web 应用的资源,我们创建一个新的命名空间。

# web-app-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: web-app-namespace
kubectl create -f web-app-namespace.yaml
4.1.3 在命名空间中部署应用

创建一个 Deployment 来部署 Web 应用,并将 Secret 挂载到容器中。

# web-app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-deployment
  namespace: web-app-namespace
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app-container
        image: web-app-image:latest
        volumeMounts:
        - name: secret-volume
          readOnly: true
          mountPath: "/etc/secrets"
      volumes:
      - name: secret-volume
        secret:
          secretName: database-secret
kubectl create -f web-app-deployment.yaml --namespace=web-app-namespace
4.1.4 设置资源配额限制

在命名空间中设置资源配额限制,确保应用不会过度消耗资源。

# web-app-limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: web-app-limits
  namespace: web-app-namespace
spec:
  limits:
  - max:
      cpu: "1"
      memory: 512Mi
    min:
      cpu: 100m
      memory: 64Mi
    type: Pod
  - default:
      cpu: 200m
      memory: 128Mi
    defaultRequest:
      cpu: 100m
      memory: 64Mi
    max:
      cpu: "1"
      memory: 512Mi
    min:
      cpu: 100m
      memory: 64Mi
    type: Container
kubectl create -f web-app-limits.yaml --namespace=web-app-namespace
4.2 最佳实践
4.2.1 Secrets 最佳实践
  • 最小化 Secret 大小 :避免创建大尺寸的 Secret,因为它们存储在节点的内存中,大尺寸的 Secret 会占用过多资源。
  • 定期更新 Secret :定期更换敏感信息,如数据库密码,以提高安全性。
  • 使用 Secret 版本控制 :可以通过版本控制工具(如 Git)管理 Secret 的配置文件,方便追溯和回滚。
4.2.2 命名最佳实践
  • 使用有意义的名称 :名称应该能够清晰地表达对象的用途,如 web-app-pod database-service 等。
  • 遵循命名规范 :严格遵守 Kubernetes 的命名限制,避免因命名问题导致创建失败。
4.2.3 命名空间最佳实践
  • 合理划分命名空间 :根据不同的项目、环境(如开发、测试、生产)或团队划分命名空间,提高资源的隔离性和可管理性。
  • 设置资源配额 :在每个命名空间中设置合理的资源配额,确保资源的合理分配。

5. 常见问题与解决方案

5.1 Secrets 相关问题
5.1.1 Secret 大小超过限制

如果创建 Secret 时超过了 1 MB 的大小限制,会导致创建失败。解决方案是将大的 Secret 拆分成多个小的 Secret,或者重新评估是否真的需要存储这么多信息。

5.1.2 容器无法访问 Secret

如果容器无法访问挂载的 Secret,可能是由于以下原因:
- Secret 名称或挂载路径配置错误:检查 Pod 配置文件中 Secret 的名称和挂载路径是否正确。
- Secret 未正确创建:使用 kubectl get secret 命令检查 Secret 是否存在。

5.2 命名相关问题
5.2.1 命名冲突

如果在同一 Pod 中使用了相同的名称,会导致创建失败。解决方案是检查配置文件,确保每个容器的名称唯一。

5.2.2 不符合命名规则

如果名称不符合 Kubernetes 的命名规则,如包含大写字母、下划线等,会导致创建失败。解决方案是修改名称,使其符合规则。

5.3 命名空间相关问题
5.3.1 找不到命名空间

如果在删除命名空间后,尝试在该命名空间中创建资源,会出现找不到命名空间的错误。解决方案是切换默认命名空间或指定正确的命名空间。

5.3.2 资源配额限制导致创建失败

如果在命名空间中设置了资源配额限制,而创建的资源超出了限制,会导致创建失败。解决方案是调整资源请求和限制,或者修改资源配额设置。

6. 总结与展望

6.1 总结

本文全面介绍了 Kubernetes 中 Secrets、命名和命名空间的使用方法、最佳实践以及常见问题的解决方案。通过合理使用这些功能,可以提高 Kubernetes 集群的安全性、可管理性和资源利用率。

6.2 展望

随着 Kubernetes 的不断发展,资源管理功能也将不断完善。未来,可能会出现更强大的 Secret 管理工具、更灵活的命名规则和更精细的命名空间管理功能。我们需要持续关注这些变化,不断学习和实践,以更好地应对复杂的应用场景。

流程图:综合应用案例部署流程

graph LR
    A[创建 Secret] --> B[创建命名空间]
    B --> C[部署应用到命名空间]
    C --> D[设置资源配额限制]
    D --> E[验证应用运行状态]

表格:常见问题与解决方案总结

问题类型 问题描述 解决方案
Secrets Secret 大小超过限制 拆分 Secret 或重新评估信息
Secrets 容器无法访问 Secret 检查配置和 Secret 状态
命名 命名冲突 确保每个容器名称唯一
命名 不符合命名规则 修改名称使其符合规则
命名空间 找不到命名空间 切换默认命名空间或指定正确命名空间
命名空间 资源配额限制导致创建失败 调整资源请求和限制或修改配额设置
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值