《kubernetes 1.8.0 测试环境安装部署》
时间:2017-12-15
secrets
是用来保存类似于密码、token、key等敏感信息的。将这些敏感信息放在secrets
里比直接放在pod
或者docker镜像
中更安全和灵活。
创建:用户能够创建secrets
,同时系统也会自动创建一些secrets
(内建secrets)
使用:一个secrets
能够被两种方式使用: 通过volume
挂载到一个或者多个容器中,或者在kubelet pull docker
镜像的时候使用(需要login的docker仓库)
Build-in Secrets
(内建secrets):
这个主要是关联Service Account
使用,当创建一个SA
的时候将自动关联一个secrets
,如果想通过某个sa
账户访问apiserver
可通过该secrets
进行验证;
kubectl create secret
创建secrets
:要是一些pod需要访问数据库,用户名和密码保存在本机的./username.txt
和 ./password.txt
文件中
创建所需的文件:
$ mkdir ~/secret-examle
$ cd ~/secret-examle
$ echo -n "admin" > ./username.txt
$ echo -n "1f2d1e2e67df" > ./password.txt
使用kubectl create secret
打包这些文件到secrets
$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
generic
:表明从本地文件,目录,或者键值对创建,还可以使用docker-registry
以及tls
查看:
[root@node-131 secret-examle]# kubectl get secrets
NAME TYPE DATA AGE
...
db-user-pass Opaque 2 15s
...
[root@node-131 secret-examle]# kubectl describe secrets db-user-pass
Name: db-user-pass
Namespace: default
Labels:
Annotations:
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
手工创建一个secrets
能够通过yaml或者json文件创建secrets
先获取username和password的base64编码:
$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "1f2d1e2e67df" | base64
MWYyZDFlMmU2N2Rm
创建secrets的yaml:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
应用yaml:
$ kubectl create -f ./secret.yaml
secret "mysecret" created
查看:
[root@node-131 secret-examle]# kubectl get secret mysecret -o yaml
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: 2017-12-15T06:49:21Z
name: mysecret
namespace: default
resourceVersion: "3418648"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: 14c9804b-e164-11e7-8e94-005056bc80ed
type: Opaque
decode:
$ echo "MWYyZDFlMmU2N2Rm" | base64 --decode
1f2d1e2e67df
secrets能够被以data volume的方式挂载或者以环境变量的方式暴露在pod中的container。也可以用在系统的其他方面,比如可以保存用于系统其他部分的交互证书;
以文件的方式在pod中使用secrets:
spec.volumes[]
部分添加,名字任意,配置spec.volumes[].secret.secretName
为 对应secrets
对象的名字secrets
的container
添加spec.containers[].volumeMounts[]
部分, 注明spec.containers[].volumeMounts[].readOnly = true
以及注明spec.containers[].volumeMounts[].mountPath
到一个想防止secrets以及未使用的目录名.例子1:挂载secrets到一个volume:
mysecret.yaml
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
spec.volumes
volumeMounts
,而每个secrets只需要一个spec.volumes
应用并查看:
[root@node-131 secret-examle]# kubectl create -f mysecret.yaml
pod "mypod" created
[root@node-131 secret-examle]# kubectl exec mypod ls /etc/foo/
password username
[root@node-131 secret-examle]# kubectl exec mypod cat /etc/foo/password
1f2d1e2e67df
[root@node-131 secret-examle]# kubectl exec mypod cat /etc/foo/username
admin
将secrets的key映射至指定路径:
mysecret.yaml
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
username
:这个key将被存放在/etc/foo/my-group/my-username
目录下password
:这个key将不会被映射spec.volumes[].secret.items
部分,所有想要被映射的key都必须列出来,否则将不比被挂载到指定的目录下应用并查看:
[root@node-131 secret-examle]# kubectl delete pod mypod
pod "mypod" deleted
##terminating后
[root@node-131 secret-examle]# kubectl create -f mysecret.yaml
pod "mypod" created
[root@node-131 secret-examle]# kubectl exec mypod ls /etc/foo/
my-group
[root@node-131 secret-examle]# kubectl exec mypod cat /etc/foo/my-group/my-username
admin
设置secrets文件的权限
可以单独设置secrets的权限mode bit,如果没有特别设置,缺省权限为0644,json不支持八进制,所以用256 表示 0400.511表示 0777以此类推;
mysecret.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 256
0400
应用并查看:
[root@node-131 secret-examle]# kubectl exec -ti mypod -- ls -l /etc/foo/
total 0
lrwxrwxrwx 1 root root 15 Dec 15 09:06 password -> ..data/password
lrwxrwxrwx 1 root root 15 Dec 15 09:06 username -> ..data/username
[root@node-131 secret-examle]# kubectl exec -ti mypod -- ls -l /etc/foo/..data/username
-r-------- 1 root root 5 Dec 15 09:06 /etc/foo/..data/username
..data/
下mysecret.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
mode: 511
查看:
[root@node-131 secret-examle]# kubectl exec -ti mypod -- ls -l /etc/foo/..data/my-group/my-username
-rwxrwxrwx 1 root root 5 Dec 15 09:36 /etc/foo/..data/my-group/my-username
以环境变量的方式在pod中使用secrets:
通过修改env[].valueFrom.secretKeyRef
将secrets映射至pod中的环境变量
mysecret.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
env.name
:变量名env[].valueFrom.secretKeyRef.name
:secret名env[].valueFrom.secretKeyRef.name
:secret的data中的哪个key应用并查看:
[root@node-131 secret-examle]# kubectl exec -ti secret-env-pod bash
root@secret-env-pod:/data# echo $SECRET_USERNAME
admin
root@secret-env-pod:/data# echo $SECRET_PASSWORD
1f2d1e2e67df
创建用来imagepull的 secrets:
$ kubectl create secret docker-registry myregistrykey \
--docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER \
--docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret "myregistrykey" created.
首先本地用docker login进行登录,登录成功后,将在当前用户的宿主目录下创建~/.docker/config.json
用base64将~/.docker/config.json
加密
[root@node-131 secret-examle]# cat ~/.docker/config.json | base64 -w 0
ewoJImFJImF1dGgiOiAiWVdSdGFXNDZRV3hoWkdsdV.....S4wLWNlIChsaW51eCkiCgl9Cn0=
编辑yaml文件
myregistrykey.yaml
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
namespace: default
data:
.dockerconfigjson: ewoJImFJImF1dGgiOiAiWVdSdGFXNDZRV3hoWkdsdV.....S4wLWNlIChsaW51eCkiCgl9Cn0=
type: kubernetes.io/dockerconfigjson
.dockerconfigjson
:将base64加密后的那串东西填到这里创建并查看:
[root@node-131 secret-examle]# kubectl create -f myregistrykey.yaml
secret "myregistrykey" created
[root@node-131 secret-examle]# kubectl describe secret myregistrykey
Name: myregistrykey
Namespace: default
Labels:
Annotations:
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 155 bytes
创建一个pod测试
foo.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: default
spec:
containers:
- name: foo
image: 172.18.169.134/elk/elasticsearch:v5.6.4
imagePullSecrets:
- name: myregistrykey
image: 172.18.169.134/elk/elasticsearch:v5.6.4
:根据自己的环境修改前提条件是做了私有仓库,并设置项目为私有,即必须通过登录才能够pull;
应用yaml并查看:
[root@node-131 secret-examle]# kubectl describe pod foo
Name: foo
Namespace: default
Node: node.131/172.18.169.131
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 6s default-scheduler Successfully assigned foo to node.131
Normal SuccessfulMountVolume 6s kubelet, node.131 MountVolume.SetUp succeeded for volume "default-token-t8j7k"
Normal Pulling 5s kubelet, node.131 pulling image "172.18.169.134/elk/elasticsearch:v5.6.4"
Normal Pulled 5s kubelet, node.131 Successfully pulled image "172.18.169.134/elk/elasticsearch:v5.6.4"
Normal Created 5s kubelet, node.131 Created container
Normal Started 5s kubelet, node.131 Started container
其他一些细节:
* secrets 必须在所应用的pod之前先创建
* secrets 必须和所应用的pod在同一个namespace
* secrets 大小必须效益1MB
用例:带有ssh key的pod
创建一个secret 包含本机的ssh key:
[root@node-131 secret-examle]# kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/root/.ssh/id_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub
secret "ssh-key-secret" created
创建pod
secret-test-pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: redis
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
应用并测试:
[root@node-131 secret-examle]# kubectl exec secret-test-pod cat /etc/secret-volume/ssh-publickey
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOB8IMzTYPcRb9h2pVoMNBI2Fy5EYPjXOEg11FyI1ffeo+C... root@node-131
[root@node-131 secret-examle]# kubectl exec secret-test-pod cat /etc/secret-volume/ssh-privatekey
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAzgfCDM02D3EW/YdqVaDDQSNhcuRGD41zhINdRciNX33qPglK
Npks8CIresIAbPdBDc4P6FO0MncuVAoXZVOE4xOUYTcmnXkncwHp6amATMtJNFTc
OSzejJIokVQn9e7nmREU2bCTSUtlnR6804XNm78Tmh9P7dyI863OWEVdGdBKZFFz
G...
后续这个container可以用这个建立与宿主机的ssh链接
用例:使用区分正式环境和测试环境认证信息的pod
这个例子说明了其中一个pod使用正式的认证信息,另一个pod使用测试环境的认证信息:
$ kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret "prod-db-secret" created
$ kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
secret "test-db-secret" created
创建pod:
apiVersion: v1
kind: List
items:
- kind: Pod
apiVersion: v1
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: prod-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- kind: Pod
apiVersion: v1
metadata:
name: test-db-client-pod
labels:
name: test-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: test-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
预期的效果是:
两个不同的pod将拥有两个不同的secrets file(内容):
/etc/secret-volume/username
/etc/secret-volume/password
用例:创建隐藏的secret volume(.file)
kind: Secret
apiVersion: v1
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
kind: Pod
apiVersion: v1
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: gcr.io/google_containers/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
.secret-file
,用.
开头的方式创建secret的keyname,后续被挂载的时候也将被挂载成’.’开头的文件。。最后再生产环境需要注意apiserver访问权限对secrets的控制,watch
和 list
将能够看到secret
的值,拥有get
请求就可以利用secret进行相关的使用了。
至此secrets 部分算是写完了。。
本系列其他内容:
01-环境准备
02-etcd群集搭建
03-kubectl管理工具
04-master搭建
05-node节点搭建
06-addon-calico
07-addon-kubedns
08-addon-dashboard
09-addon-kube-prometheus
10-addon-EFK
11-addon-Harbor
12-addon-ingress-nginx
13-addon-traefik
参考资料:
https://kubernetes.io/docs/concepts/configuration/secret/