StatefulSet:
应用场景:数据库
Headless Service
也是一种service,但不同在于spec.clusterIP
定义为None
,也就是不需要ClusterIP
对比
示例程序
headless.yaml
:apiVersion: v1
kind: Service
metadata:
labels:
app: web
name: hd-service
spec:
clusterIP: None
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: web
project: blog
web-dp.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: web
name: web
spec:
serviceName: hd-service
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
project: blog
spec:
containers:
- image: nginx
name: nginx
resources: {}
应用之后发现,程序并非像之前那样并行的去创建pod,而是顺序创建pod
测试dns:
kubectl run -it --rm --image=busybox:1.28.4 sh
在控制台输入nslookup hd-service
之后会响应三个pod的ip,headless 不需要分配clusterIP,它是为每个pod分配了一个固定的dns名称,ping一下这个dns就会访问具体的pod的IP
<service-name>.<namespace-name>.svc.cluster.local
<statefulsetName-index>.<service-name> .<namespace-name>.svc.cluster.local
示例:web-0.nginx.default.svc.cluster.local
StatefulSet
的存储卷使用VolumeClaimTemplate
创建,
称为卷申请模板,当StatefulSet
使用VolumeClaimTemplate
创建一个PersistentVolume
时,同样也会为每个Pod分配并创建一个编号的PVC。
示例程序:
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: web
name: web
spec:
serviceName: hd-service
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
project: blog
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 1Gi
参数解释:
ReadWriteOnce
:单节点读写,因为非数据共享,一个pod对应一个pv
这样就可以保证每个pod存储数据的唯一性了
StatefulSet与Deployment区别:有身份的!
身份三要素:
数据存储在Etcd中,让Pod中容器以Volume或者变量方式访问。
应用场景:应用程序配置
Pod使用configmap两种方式:
创建一个configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfig
namespace: default
data:
special.level: info
special.type: hello
创建一个pod:
apiVersion: v1
kind: Pod
metadata:
name: mypod-cm
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh", "-c", "echo $(LEVEL) $(TYPE) $(ABC) $TYPE" ]
env:
- name: ABC
value: "1234567"
- name: LEVEL
valueFrom:
configMapKeyRef:
name: myconfig
key: special.level
- name: TYPE
valueFrom:
configMapKeyRef:
name: myconfig
key: special.type
restartPolicy: Never
参数解释:
env
:变量,参考
创建一个redis的configmap:
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
data:
redis.properties: |
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
参数解释:
创建pod去引用redis的configmap:
apiVersion: v1
kind: Pod
metadata:
name: mypod-redis
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: redis-config
restartPolicy: Never
与ConfigMap类似,区别在于Secret主要存储敏感数据,所有的数据要经过编码。
应用场景:凭据
secret应用场景:
generic
举例,将用户名和密码保存在k8s中:先给用户名和密码进行编码:
echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
创建secret:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
注意:用户名和密码需要经过base64位编码提高安全性。如
echo "123456" | base64
创建pod:
apiVersion: v1
kind: Pod
metadata:
name: mypod-secret
spec:
containers:
- name: nginx
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
# echo $SECRET_USERNAME
# echo $SECRET_PASSWORD
参数说明:
env.name
:变量名编码过后的用户名和密码在注入到pod中后会解码
secret解决了pod镜像中的敏感信息问题,将信息放在secret中,通过动态的往pod中注入的方式提高pod的安全性。
数据卷挂载方式
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
# cat /etc/foo/username
# cat /etc/foo/password
“The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.” – Tom Cargill
标 题:kubernetes存储(下)