statefulset介绍
StatefulSet 是用来管理有状态的应用,例如数据库。数据库、Redis 这类有状态的,则不能随意扩充副本。
部署 StatefulSet 类型的 Mongodb 服务
为了统一固定的入口访问mongodb,需要写一个service。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 3
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
targetPort: 27017
查看pod
、statefulset
、service
:

statefulset特性:
- Service 的 CLUSTER-IP 是空的,Pod 名字也是固定的。通过服务名进行连接。
- Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
- Pod 重建不会改变名字,除了IP,所以不要用IP直连
三个副本之间没有主从或其他关联,往其中一个数据库写入数据,不会影响其他两个数据库。
访问时,如果直接使用 Service 名字(这里是mongodb)连接,会随机转发请求到某个pod下。
要连接到指定 Pod 的数据库中,可以这样pod-name.service-name
(这里是mongodb-0.mongodb
)
configmap
Kubernetes 为我们提供了 ConfigMap,可以方便的配置一些变量。
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-config
data:
mongoHost: mongodb-0.mongodb
data
字段定义数据,key-value形式。
kubectl get configmap mongo-config -o yaml

secret
一些重要数据,例如密码、TOKEN,我们可以放到 secret 中。
注意,数据要进行 Base64 编码。
secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
# Opaque 用户定义的任意数据,更多类型介绍 https://kubernetes.io/zh/docs/concepts/configuration/secret/#secret-types
type: Opaque
data:
# 数据要 base64。https://tools.fun/base64.html
mongo-username: bW9uZ291c2Vy
mongo-password: bW9uZ29wYXNz
kubectl get secret mongo-secret -o yaml

使用configmap和secret中定义的变量
作为环境变量使用
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 3
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
env: # 定义环境变量
- name: MONGO_INITDB_ROOT_USERNAME # 环境变量名字
valueFrom: # 值来自
secretKeyRef: # 来自secret
name: mongo-secret # 上面定义的secret的名字
key: mongo-username # secret中的key
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
- name: MONGO_ADDRESS
valueFrom:
configMapKeyRef:
name: mongo-config
key: mongoHost
# Secret 的所有数据定义为容器的环境变量,Secret 中的键名称为 Pod 中的环境变量名称
# envFrom:
# - secretRef:
# name: mongo-secret
挂载为文件(更适合证书文件)
挂载后,会在容器中对应路径生成文件,一个 key 一个文件,内容就是 value。
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: # 来自于secret
secretName: mysecret
参考链接
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/mJvk9q5z
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/YJf8LMtE