Files
kuboard-press/t/cka/daily/009.md
huanqing.shao b2402cde7d 010
2019-12-03 22:41:44 +08:00

14 KiB
Raw Blame History

vssueId, sharingTitle, description, meta
vssueId sharingTitle description meta
170 CKA备考打卡 - 每日一题 - Day 9 CKA备考打卡 - 每日一题 - Day 9
name content
keywords Kubernetes,K8S,CKA,Certified Kubernetes Administrator

CKA每日一题 --- Day 9

::: tip 考题

创建 Secret 名为 cka1127-secret内含有 password 字段,值为 cka1127然后在名为 cka1127-01 的 Pod1 里使用ENV进行调用名为cka1127-02的 Pod2 里使用 Volume 挂载在 /data 下;

注意提交评论包含命令和yaml以及注意点。可分多次评论。

:::

答案及解析

答案

创建secret方式一 cka1127-secret.yaml可以是以下这样

apiVersion: v1
kind: Secret
metadata:
  name: cka1127-secret
type: Opaque
stringData:
  cka1127-password: cka1127

创建

[root@liabio test]# kubectl apply -f  cka-1127-secret.yaml 
secret/cka1127-secret created

创建secret方式二

kubectl create secret generic cka1127-secret --from-literal=password=cka1127

名为cka1127-01的Pod yaml

apiVersion: v1
kind: Pod
metadata:
  name: cka1127-01
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: pwd
      mountPath: /data/password
      readOnly: true
  volumes:
  - name: pwd
    secret:
      secretName: cka1127-secret

名为cka1127-02的Pod yaml

apiVersion: v1
kind: Pod
metadata:
  name: cka1127-02
spec:
  containers:
  - image: nginx
    name: nginx
    env:
    - name: PASSWORD
      valueFrom:
        secretKeyRef:
          name: cka1127-secret
          key: password

volume形式验证保证/data/password/下有password文件文件内容为明文cka1127

[root@liabio ~]# kubectl exec -ti cka1127-01 sh
# 
# ls -l /data/password
total 0
lrwxrwxrwx 1 root root 15 Nov 28 00:40 password -> ..data/password
# cat /data/password/password
cka1127# 
# 

环境变量形式验证保证env能查到name为PASSWORD的环境变量

[root@liabio test]# kubectl exec -ti cka1127-02  bash
root@cka1127-02:/# 
root@cka1127-02:/# echo $PASSWORD
cka1127
root@cka1127-02:/#

解析

secret官方文档 https://kubernetes.io/docs/concepts/configuration/secret/

中文文档:https://kuboard.cn/learning/k8s-intermediate/config/secrets/

secret简介

Kubernetes中的Secret资源可以用来存储密码、Token、秘钥等敏感数据 将这些敏感信息保存在Secret中相对于暴露到Pod、镜像中更加的安全和灵活。

你可能会觉得secret一般不会用到实际上在创建Pod时Kubernetes会自动创建包含用于访问API的凭据的secret(由kube-controller-managerservice account token controller控制并且它会自动修改Pod以使用这种类型的secret这个由Admission Controller来控制

k8s每个namespace都会有一个Service Account当我们创建namespace时service account controller会监听namespace的创建会在该namespace中创建一个名为default的Service Account同时service account token controller会监听Service Account的创建创建对应的secret并将这个secret绑定到Service Account。

[root@liabio test]# kubectl create ns cka
namespace/cka created
[root@liabio test]# 
[root@liabio test]# kubectl get sa -n cka
NAME      SECRETS   AGE
default   1         11s
[root@liabio test]# kubectl get secrets -n cka
NAME                  TYPE                                  DATA   AGE
default-token-r77xn   kubernetes.io/service-account-token   3      18s
[root@liabio test]# 

CKA每日一题_Day9

当我们创建Pod时如果未指定Service Account则默认会在同一命令空间namespace中自动为其分配Service Account。则可以看到该spec.serviceAccountName字段已被自动设置。

CKA每日一题_Day9

您可以使用自动添加的Service Account凭据从Pod内部访问APIService Account的API权限取决于所使用的授权插件和策略。

有关Service Account如何工作的更多信息请参见文档 https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

Secret的类型

--type指定创建的秘密类型Kubernetes内置了三种类型的Secret

kubernetes.io/service-account-token Secret

上面我们已经讲到为了能从Pod内部访问Kubernetes APIKubernetes提供了Service Account资源。Service Account会自动创建和挂载访问Kubernetes API的Secret会挂载到Pod的 /var/run/secrets/kubernetes.io/serviceaccount目录中。namespace创建时自动创建的Service Account用到的Secret就是这种类型的。

CKA每日一题_Day9在这里插入图片描述

Opaque Secret

Opaque类型的Secret是一个map结构(key-value)其中vlaue要求以base64格式编码以下示例中基本都为Opaque类型的Secret。

kubernetes.io/dockerconfigjson Secret

kubernetes.io/dockercfg类型的Secret用于存放私有Docker Registry的认证信息。当Kubernetes在创建Pod并且需要从私有Docker Registry pull镜像时需要使用认证信息就会用到kubernetes.io/dockercfg类型的Secret。

kubectl create secret docker-registry cka-regsecret \
--docker-server=coderaction \
--docker-username=admin \
--docker-password=123456 \
--docker-email=837448191@qq.com

CKA每日一题_Day9

在创建Pod时需要在Pod的spec中按如下形式使用

apiVersion: v1
kind: Pod
metadata:
  name: cka-private-reg
spec:
  containers:
    - name: cka-private-reg-container
      image: nginx
  imagePullSecrets:
    - name: cka-regsecret

可以参考官方文档: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod

中文文档: 使用私有仓库中的镜像

给分区默认的ServiceAccount添加imagePullSecrets以至于创建的所有Pod可以自动添加spec.imagePullSecrets详情参考官方文档 https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account

secret创建

kubectl创建secret

kubectl创建seccret官方文档 https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-secret-em-

格式:

kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run]

--from-literal指定要插入的键和文字值即mykey = somevaluevalue为明文值创建后会被base64编码 --from-file可以使用密钥文件的文件路径指定密钥文件在这种情况下将为它们指定默认名称或者可以选择使用指定目录这样将迭代该目录中的每个有效文件密钥。 --type创建的秘密类型上面已经介绍过三种类型 --dry-run如果为true则仅打印将要向APIServer发送创建的对象而不发送它。默认false

使用--from-file创建

[root@liabio cka]# echo -n 'admin' > ./username
[root@liabio cka]# echo -n 'test123' > ./password
[root@liabio cka]# echo -n 'shanghai' > ./city
[root@liabio cka]# ll
total 12
-rw-r--r-- 1 root root 9 Nov 28 20:44 city
-rw-r--r-- 1 root root 8 Nov 28 20:43 password
-rw-r--r-- 1 root root 6 Nov 28 20:43 username
[root@liabio cka]# kubectl create secret generic test-cka1127-01 --from-file=./username --from-file=./password
secret/test-cka1127-01 created
[root@liabio cka]# kubectl create secret generic test-cka1127-02 --from-file=./
secret/test-cka1127-02 created
[root@liabio cka]# 

以指定目录创建的secret查看到目录下所有文件都被加到data下

kubectl get secrets test-cka1127-02 -oyaml
apiVersion: v1
data:
  city: c2hhbmdoYWkK
  password: dGVzdDEyMwo=
  username: YWRtaW4K
kind: Secret
metadata:
  creationTimestamp: "2019-11-28T12:44:57Z"
  name: test-cka1127-02
  namespace: default
  resourceVersion: "14636360"
  selfLink: /api/v1/namespaces/default/secrets/test-cka1127-02
  uid: 4a3a1a5d-09e6-4bf9-bbe3-3300db1ddf7a
type: Opaque

指定username和password创建的secret

kubectl get secrets test-cka1127-01 -oyaml
apiVersion: v1
data:
  password: dGVzdDEyMwo=
  username: YWRtaW4K
kind: Secret
metadata:
  creationTimestamp: "2019-11-28T12:44:47Z"
  name: test-cka1127-01
  namespace: default
  resourceVersion: "14636347"
  selfLink: /api/v1/namespaces/default/secrets/test-cka1127-01
  uid: 766516a2-34be-4a18-b4e2-83751a6cd2b7
type: Opaque

默认情况下kubectl describe 命令能避免显示文件的内容。这可以防止将 secret 中的内容暴露给从终端日志记录中刻意寻找它们的人。

特殊字符,例如不能识别此Latex公式: \*,和!需要逃逸。在大多数常见的shell中最简单的转义密码方法是用单引号'引起来。例如如果您的实际密码是S!B*dzDsb则应以这种方式执行命令

kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B*d$zDsb' 您无需从文件(--from-file中转义密码中的特殊字符。

手动创建Secret

还可以先在文件中以json或yaml格式创建一个Secret然后创建该对象。该secret包含两种data和是stringData是。data字段用于存储使用base64编码的任意数据。提供stringData字段是为了方便起见它允许提供未编码的字符串。

例如要使用data将两个字符串存储在Secret中请按如下所示将它们转换为base64

echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm

注意在转base64编码时一定记得加-n参数否则可能会遇到坑。

然后创建以下yaml最终kubectl apply

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

如果用以下yaml创建注意到用了stringDatauser的值为coderaction明文。

apiVersion: v1
kind: Secret
metadata:
  name: cka1127-secret-02
type: Opaque
stringData:
  user: coderaction

执行 kubectl apply 后查看:

apiVersion: v1
data:
  user: Y29kZXJhY3Rpb24=
kind: Secret
metadata:
  name: cka1127-secret-02
type: Opaque

Y29kZXJhY3Rpb24=解码为coderaction

[root@liabio cka]# echo Y29kZXJhY3Rpb24= | base64 -d
coderaction

data和stringData的键必须由字母数字字符“-”,“ _”或“。”组成。

编码注意secret数据的序列化JSON和YAML值被编码为base64字符串。换行符在这些字符串中无效因此必须省略。base64在Darwin/macOS上使用该实用程序时用户应避免使用该-b选项来分隔长行。相反如果选项不可用Linux用户应将选项添加-w 0到base64命令或管道中。base64 | tr -d '\n'-w

从生成器创建Secret

从1.14开始Kubectl支持使用Kustomize管理对象。使用此新功能您还可以从生成器创建一个Secret然后将其应用于在Apiserver上创建对象。

使用Kuboard界面创建Secret

参考文档 使用Kuboard界面创建Secret

使用Secret

将secret所有内容挂载为Pod里的文件

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

这样Pod中的/etc/foo目录下会生成mysecret中的所有映射文件。

将密钥投影到特定路径

我们还可以控制secret映射到卷中的路径。您可以使用.spec.volumes[].secret.items更改每个键的目标路径

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username

这样Pod中username存储在/etc/foo/my-group/my-username文件而非/etc/foo/username而且没有password的映射文件。

secret文件权限

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: nginx
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: cka1127-secret
      defaultMode: 256

然后Secret将被挂载到/etc/foo并且由Secret卷挂载创建的所有文件权限为0400

请注意JSON规范不支持八进制表示法因此对于0400权限请使用值256。如果您使用yaml而不是json描述Pod则可以使用八进制表示法以更自然的方式指定权限。

也可以像前面的示例一样使用映射,并为不同的文件指定不同的权限,如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: mypod-1
spec:
  containers:
  - name: mypod
    image: nginx
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: cka1127-secret-02
      items:
      - key: user
        path: my-group/my-username
        mode: 511

mode值511为十进制在这种情况下生成的文件的/etc/foo/my-group/my-username许可权值为八进制0777。由于JSON的限制您必须以十进制表示法指定mode。

请注意,如果稍后阅读此权限值,则可能会以十进制表示法显示。

环境变量

Pod中通过环境变量引用Secret和题目答案一样不做累述

以上事例来自于官方文档。方便大家学习。

CKA 考试每日一题系列,全部内容由 我的小碗汤 创作,本站仅做转载