Secret概述
Secret解决了密码、token、秘钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。
用户可以创建 secret,同时系统也创建了一些 secret。
要使用 secret,pod 需要引用 secret。Pod 可以用两种方式使用 secret:作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里,或者当 kubelet 为 pod 拉取镜像时使用。
Secret类型
- Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中。
- Opaque:base64编码格式的Secret,用来存储密码、秘钥等。
- kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
Service Account通过kube-proxy查看- [root@k8s-master01 ~]# kubectl get pod -A | grep "kube-proxy"
- kube-system kube-proxy-5jt9d 1/1 Running 6 22d
- kube-system kube-proxy-r4dx5 1/1 Running 6 22d
- [root@k8s-master01 ~]# kubectl exec -it -n kube-system kube-proxy-5jt9d -- /bin/sh
- # ls -l /run/secrets/kubernetes.io/serviceaccount
- total 0
- lrwxrwxrwx 1 root root 13 Apr 27 12:55 ca.crt -> ..data/ca.crt
- lrwxrwxrwx 1 root root 16 Apr 27 12:55 namespace -> ..data/namespace
- lrwxrwxrwx 1 root root 12 Apr 27 12:55 token -> ..data/token
 Opaque Secret创建secret手动加密,基于base64加密
 yaml文件[root@k8s-master01 ~]# echo "admin" | base64 YWRtaW4K [root@k8s-master01 ~]# echo -n '1f2d1e2e67df' | base64 MWYyZDFlMmU2N2Rm
 或者通过如下命令行创建【secret名称故意设置不一样,以方便查看对比】,生成secret后会自动加密,而非明文存储。[root@k8s-master01 secret]# pwd /root/k8s_practice/secret [root@k8s-master01 secret]# cat secret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4K password: MWYyZDFlMmU2N2Rm
 生成secret,并查看状态 ```shell [root@k8s-master01 secret]# kubectl apply -f secret.yaml secret/mysecret createdkubectl create secret generic db-user-pass --from-literal=username=admin --from-literal=password=1f2d1e2e67df
[root@k8s-master01 secret]# kubectl get secret ### 查看默认名称空间的secret简要信息 NAME TYPE DATA AGE db-user-pass Opaque 2 53s default-token-k2f44 kubernetes.io/service-account-token 3 22d mysecret Opaque 2 21s
[root@k8s-master01 secret]# kubectl get secret mysecret -o yaml ### 查看mysecret详细信息 apiVersion: v1 data: password: MWYyZDFlMmU2N2Rm username: YWRtaW4K kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {“apiVersion”:”v1”,”data”:{“password”:”MWYyZDFlMmU2N2Rm”,”username”:”YWRtaW4K”},”kind”:”Secret”,”metadata”:{“annotations”:{},”name”:”mysecret”,”namespace”:”default”},”type”:”Opaque”} creationTimestamp: “2021-04-27T23:49:37Z” name: mysecret namespace: default resourceVersion: “149397” selfLink: /api/v1/namespaces/default/secrets/mysecret uid: 70cfe6e0-6347-4efd-9333-5f896d14e6b8 type: Opaque
[root@k8s-master01 secret]# kubectl describe secret mysecret     ### 查看描述信息
Name:         mysecret
Namespace:    default
Labels:       
Type:         Opaque
Data
password: 12 bytes username: 6 bytes
<a name="csEBW"></a>
## 将Secret挂载到Volume中
yaml文件
```shell
[root@k8s-master01 secret]# pwd
/root/k8s_practice/secret
[root@k8s-master01 secret]# cat pod_secret_volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-volume
spec:
  containers:
  - name: myapp
    image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secret
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: mysecret
启动pod并查看状态
[root@k8s-master01 secret]# kubectl apply -f pod_secret_volume.yaml
pod/pod-secret-volume created
[root@k8s-master01 secret]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE    IP               NODE         NOMINATED NODE   READINESS GATES
daemonset-example-5sjhf   1/1     Running   0          10h    192.168.85.244   k8s-node01   <none>           <none>
frontend-4crh5            1/1     Running   0          10h    192.168.85.239   k8s-node01   <none>           <none>
frontend-n4z6w            1/1     Running   0          10h    192.168.85.213   k8s-node01   <none>           <none>
frontend-pmcrm            1/1     Running   0          10h    192.168.85.235   k8s-node01   <none>           <none>
nginx-configmap           1/1     Running   0          119m   192.168.85.238   k8s-node01   <none>           <none>
pod-secret-volume         1/1     Running   0          41s    192.168.85.229   k8s-node01   <none>           <none>
查看secret信息
[root@k8s-master01 secret]#  kubectl exec -it pod-secret-volume -- /bin/sh
/ # cd /etc/secret/
/etc/secret # ls
password  username
/etc/secret # cat username 
admin
/etc/secret # cat password 
1f2d1e2e67df
将Secret导入到环境变量中
yaml文件
[root@k8s-master01 secret]# pwd
/root/k8s_practice/secret
[root@k8s-master01 secret]# cat pod_secret_env.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-env
spec:
  containers:
  - name: myapp
    image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
    env:
    - name: SECRET_USERNAME
      valueFrom:
        secretKeyRef:
          name: mysecret
          key: username
    - name: SECRET_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysecret
          key: password
  restartPolicy: Never
启动pod并查看状态
[root@k8s-master01 secret]# kubectl apply -f pod_secret_env.yaml
pod/pod-secret-env created
[root@k8s-master01 secret]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP               NODE         NOMINATED NODE   READINESS GATES
daemonset-example-5sjhf   1/1     Running   0          11h     192.168.85.244   k8s-node01   <none>           <none>
frontend-4crh5            1/1     Running   0          11h     192.168.85.239   k8s-node01   <none>           <none>
frontend-n4z6w            1/1     Running   0          11h     192.168.85.213   k8s-node01   <none>           <none>
frontend-pmcrm            1/1     Running   0          11h     192.168.85.235   k8s-node01   <none>           <none>
nginx-configmap           1/1     Running   0          126m    192.168.85.238   k8s-node01   <none>           <none>
pod-secret-env            1/1     Running   0          19s     192.168.85.240   k8s-node01   <none>           <none>
查看secret信息
[root@k8s-master01 secret]# kubectl exec -it pod-secret-env -- /bin/sh
/ # env
MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156
MYAPP_SERVICE_PORT_HTTP=80
KUBERNETES_PORT=tcp://10.20.0.1:443
KUBERNETES_SERVICE_PORT=443
MYAPP_SVC_PORT_80_TCP_PORT=80
HOSTNAME=pod-secret-env
SHLVL=1
MYAPP_SVC_PORT_80_TCP_PROTO=tcp
HOME=/root
MYAPP_SERVICE_HOST=10.20.179.180
SECRET_PASSWORD=1f2d1e2e67df
MYAPP_SVC_PORT_80_TCP=tcp://10.98.57.156:80
MYAPP_SERVICE_PORT=80
MYAPP_PORT=tcp://10.20.179.180:80
TERM=xterm
NGINX_VERSION=1.12.2
KUBERNETES_PORT_443_TCP_ADDR=10.20.0.1
MYAPP_PORT_80_TCP_ADDR=10.20.179.180
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
MYAPP_PORT_80_TCP_PORT=80
MYAPP_PORT_80_TCP_PROTO=tcp
MYAPP_SVC_SERVICE_HOST=10.98.57.156
SECRET_USERNAME=admin
KUBERNETES_PORT_443_TCP=tcp://10.20.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
MYAPP_PORT_80_TCP=tcp://10.20.179.180:80
KUBERNETES_SERVICE_HOST=10.20.0.1
MYAPP_SVC_SERVICE_PORT=80
MYAPP_SVC_PORT=tcp://10.98.57.156:80
docker-registry Secret
harbor镜像仓库
首先使用harbor搭建镜像仓库,搭建部署过程参考:「Harbor企业级私有Docker镜像仓库部署」
harbor部分配置文件信息
[root@linux harbor]# pwd
/root/harbor/harbor
[root@linux harbor]# cat harbor.yml
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 192.168.18.131
# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 5000
# https related config
https:
  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  certificate: /etc/harbor/cert/httpd.crt
  private_key: /etc/harbor/cert/httpd.key
# # Uncomment following will enable tls communication between all harbor components
# internal_tls:
#   # set enabled to true means internal tls is enabled
#   enabled: true
#   # put your cert and key files on dir
#   dir: /etc/harbor/tls/internal
# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433
# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345
# Harbor DB configuration
database:
  # The password for the root user of Harbor DB. Change this before any production use.
  password: root123
  # The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
  max_idle_conns: 50
  # The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections.
  # Note: the default number of connections is 1024 for postgres of harbor.
  max_open_conns: 1000
# The default data volume
data_volume: /data
启动harbor后客户端http设置
集群所有机器都要操作
所有客户端都需要添加这个配置,然后重启 docker 服务。
[root@k8s-master01 ~]# vim /etc/docker/daemon.json
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "100m"
    },
    "storage-driver": "overlay2",
    "registry-mirrors":[
        "https://kfwkfulq.mirror.aliyuncs.com",
        "https://2lqq34jg.mirror.aliyuncs.com",
        "https://pee6w651.mirror.aliyuncs.com",
        "http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://registry.docker-cn.com"
    ],
    "insecure-registries": ["192.168.18.131:5000"]
}
添加了 “insecure-registries”: [“192.168.18.131:5000”] 这行,其中192.168.18.131为内网IP地址。该文件必须符合 json 规范,否则 Docker 将不能启动。
systemctl daemon-reload
systemctl restart docker
如果在Harbor所在的机器重启了docker服务,记得要重新启动Harbor。
创建「私有」仓库
镜像上传
docker pull registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
docker tag registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 192.168.18.131:5000/k8s-secret/myapp:v1
# 登录
docker login 192.168.18.131:5000 -u admin -p Harbor12345
# 上传
docker push 192.168.18.131:5000/k8s-secret/myapp:v1

退出登录
之后在操作机上退出harbor登录,便于后面演示
### 退出harbor登录
[root@k8s-node02 ~]# docker logout 192.168.18.131:5000  
Removing login credentials for 192.168.18.131:5000
### 拉取失败,需要先登录。表明完成准备工作
[root@k8s-master secret]# docker pull 192.168.18.131:5000/k8s-secret/myapp:v1
Error response from daemon: unauthorized: unauthorized to access repository: k8s-secret/myapp, action: pull: unauthorized to access repository: k8s-secret/myapp, action: pull
pod直接下载镜像
在yaml文件中指定image后,直接启动pod
[root@k8s-master01 secret]# pwd
/root/k8s_practice/secret
[root@k8s-master01 secret]# cat pod_secret_registry.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-registry
spec:
  containers:
  - name: myapp
    image: 192.168.18.131:5000/k8s-secret/myapp:v1
启动pod并查看状态
[root@k8s-master01 secret]# kubectl apply -f pod_secret_registry.yaml 
pod/pod-secret-registry created
[root@k8s-master01 secret]# kubectl get pod -o wide     ### 可见镜像下载失败
NAME                      READY   STATUS             RESTARTS   AGE    IP               NODE         NOMINATED NODE   READINESS GATES
daemonset-example-5sjhf   1/1     Running            1          11h    192.168.85.233   k8s-node01   <none>           <none>
frontend-4crh5            1/1     Running            1          11h    192.168.85.216   k8s-node01   <none>           <none>
frontend-n4z6w            1/1     Running            1          11h    192.168.85.227   k8s-node01   <none>           <none>
frontend-pmcrm            1/1     Running            1          11h    192.168.85.236   k8s-node01   <none>           <none>
nginx-configmap           1/1     Running            1          147m   192.168.85.247   k8s-node01   <none>           <none>
pod-secret-env            0/1     Completed          0          21m    192.168.85.240   k8s-node01   <none>           <none>
pod-secret-registry       0/1     ImagePullBackOff   0          12s    192.168.85.245   k8s-node01   <none>           <none>
pod-secret-volume         1/1     Running            1          28m    192.168.85.237   k8s-node01   <none>           <none>
[root@k8s-master01 secret]# kubectl describe pod pod-secret-registry     ### 查看pod详情
Name:         pod-secret-registry
Namespace:    default
Priority:     0
Node:         k8s-node01/192.168.18.130
Start Time:   Wed, 28 Apr 2021 08:21:36 +0800
Labels:       <none>
Annotations:  cni.projectcalico.org/podIP: 192.168.85.245/32
              kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"pod-secret-registry","namespace":"default"},"spec":{"containers":[{"i...
Status:       Pending
IP:           192.168.85.245
IPs:
  IP:  192.168.85.245
Containers:
  myapp:
    Container ID:   
    Image:          192.168.18.131:5000/k8s-secret/myapp:v1
    Image ID:       
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ImagePullBackOff
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-k2f44 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  default-token-k2f44:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-k2f44
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                From                 Message
  ----     ------     ----               ----                 -------
  Normal   Scheduled  <unknown>          default-scheduler    Successfully assigned default/pod-secret-registry to k8s-node01
  Normal   BackOff    21s (x2 over 22s)  kubelet, k8s-node01  Back-off pulling image "192.168.18.131:5000/k8s-secret/myapp:v1"
  Warning  Failed     21s (x2 over 22s)  kubelet, k8s-node01  Error: ImagePullBackOff
  Normal   Pulling    5s (x2 over 22s)   kubelet, k8s-node01  Pulling image "192.168.18.131:5000/k8s-secret/myapp:v1"
  Warning  Failed     5s (x2 over 22s)   kubelet, k8s-node01  Failed to pull image "192.168.18.131:5000/k8s-secret/myapp:v1": rpc error: code = Unknown desc = Error response from daemon: unauthorized: unauthorized to access repository: k8s-secret/myapp, action: pull: unauthorized to access repository: k8s-secret/myapp, action: pull
  Warning  Failed     5s (x2 over 22s)   kubelet, k8s-node01  Error: ErrImagePul
pod通过Secret下载镜像
通过命令行创建Secret,并查看其描述信息
[root@k8s-master01 secret]# kubectl create secret docker-registry myregistrysecret --docker-server='192.168.18.131:5000' --docker-username='admin' --docker-password='Harbor12345' 
secret/myregistrysecret created
[root@k8s-master01 secret]# kubectl get secret 
NAME                  TYPE                                  DATA   AGE
db-user-pass          Opaque                                2      35m
default-token-k2f44   kubernetes.io/service-account-token   3      22d
myregistrysecret      kubernetes.io/dockerconfigjson        1      25s
mysecret              Opaque                                2      34m
[root@k8s-master01 secret]# kubectl get secret myregistrysecret -o yaml     ### 查看详细信息
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyIxOTIuMTY4LjE4LjEzMTo1MDAwIjp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IkhhcmJvcjEyMzQ1IiwiYXV0aCI6IllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSJ9fX0=
kind: Secret
metadata:
  creationTimestamp: "2021-04-28T00:24:03Z"
  name: myregistrysecret
  namespace: default
  resourceVersion: "154358"
  selfLink: /api/v1/namespaces/default/secrets/myregistrysecret
  uid: 317d6799-337e-4eda-9002-23707c13f8e4
type: kubernetes.io/dockerconfigjson
[root@k8s-master01 secret]# kubectl describe secret myregistrysecret     ### 查看描述信息
Name:         myregistrysecret
Namespace:    default
Labels:       <none>
Annotations:  <none>
Type:  kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson:  113 bytes
修改之前的yaml文件
[root@k8s-master01 secret]# cat pod_secret_registry.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-registry
spec:
  containers:
  - name: myapp
    image: 192.168.18.131:5000/k8s-secret/myapp:v1
  imagePullSecrets:
    - name: myregistrysecret
启动pod并查看状态
[root@k8s-master01 secret]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES
daemonset-example-mvptr   1/1     Running   0          79s   192.168.85.255   k8s-node01   <none>           <none>
frontend-6jpsr            1/1     Running   0          97s   192.168.85.200   k8s-node01   <none>           <none>
frontend-6tzs6            1/1     Running   0          97s   192.168.85.250   k8s-node01   <none>           <none>
frontend-lvsdl            1/1     Running   0          97s   192.168.85.253   k8s-node01   <none>           <none>
pod-secret-registry       1/1     Running   0          31s   192.168.85.202   k8s-node01   <none>           <none>
[root@k8s-master01 secret]# kubectl describe pod pod-secret-registry
Name:         pod-secret-registry
Namespace:    default
Priority:     0
Node:         k8s-node01/192.168.18.130
Start Time:   Wed, 28 Apr 2021 08:29:06 +0800
Labels:       <none>
Annotations:  cni.projectcalico.org/podIP: 192.168.85.202/32
              kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"pod-secret-registry","namespace":"default"},"spec":{"containers":[{"i...
Status:       Running
IP:           192.168.85.202
IPs:
  IP:  192.168.85.202
Containers:
  myapp:
    Container ID:   docker://a86ddde7e21a47110ae8117c5f359ab160de9fd67cea5cc4e9254c7355ef7efa
    Image:          192.168.18.131:5000/k8s-secret/myapp:v1
    Image ID:       docker-pullable://192.168.18.131:5000/k8s-secret/myapp@sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 28 Apr 2021 08:29:07 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-k2f44 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-k2f44:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-k2f44
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From                 Message
  ----    ------     ----       ----                 -------
  Normal  Scheduled  <unknown>  default-scheduler    Successfully assigned default/pod-secret-registry to k8s-node01
  Normal  Pulling    40s        kubelet, k8s-node01  Pulling image "192.168.18.131:5000/k8s-secret/myapp:v1"
  Normal  Pulled     40s        kubelet, k8s-node01  Successfully pulled image "192.168.18.131:5000/k8s-secret/myapp:v1"
  Normal  Created    40s        kubelet, k8s-node01  Created container myapp
  Normal  Started    40s        kubelet, k8s-node01  Started container myapp
由上可见,通过secret认证后pod拉取私有镜像是可以的。
 
                         
                                

