kubernetes 存储(下)

本贴最后更新于 1369 天前,其中的信息可能已经时过境迁

1.StatefulSet

1.1 概述:

StatefulSet:

  • 部署有状态应用
  • 解决 Pod 独立生命周期,保持 Pod 启动顺序和唯一性
    -- 稳定,唯一的网络标识符,持久存储
    -- 有序,优雅的部署和扩展、删除和终止
    -- 有序,滚动更新

应用场景:数据库

1.2 稳定的网络 ID

Headless Service
也是一种 service,但不同在于 spec.clusterIP 定义为 None,也就是不需要 ClusterIP

对比
image.png

示例程序

  • 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

image.png

测试 dns:

kubectl run -it --rm --image=busybox:1.28.4 sh

在控制台输入 nslookup hd-service 之后会响应三个 pod 的 ip,headless 不需要分配 clusterIP,它是为每个 pod 分配了一个固定的 dns 名称,ping 一下这个 dns 就会访问具体的 pod 的 IP

image.png

dns 名称规律

  • ClusterIP A 记录格式:

<service-name>.<namespace-name>.svc.cluster.local

  • ClusterIP=None A 记录格式:

<statefulsetName-index>.<service-name> .<namespace-name>.svc.cluster.local

示例:web-0.nginx.default.svc.cluster.local

1.3 稳定的存储

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

image.png
这样就可以保证每个 pod 存储数据的唯一性了

1.4 小结

StatefulSet 与 Deployment 区别:有身份的!

身份三要素:

  • 域名
  • 主机名
  • 存储(PVC)

2.ConfigMap

数据存储在 Etcd 中,让 Pod 中容器以 Volume 或者变量方式访问。

应用场景:应用程序配置

Pod 使用 configmap 两种方式:

  • 变量注入——主要适用少的数据,以键值存储
  • 数据卷挂载——适用于配置文件

2.1 变量注入

创建一个 configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfig
  namespace: default
data:
  special.level: info
  special.type: hello

image.png

创建一个 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

参数解释:

image.png

2.2 数据卷挂载

创建一个 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

参数解释:

  • redis.properties:相当于 redis 的配置文件名称
  • |:特殊字符,代表下面的内容为多行数据,作为整体处理

image.png

创建 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

image.png

3.Secret

与 ConfigMap 类似,区别在于 Secret 主要存储敏感数据,所有的数据要经过编码。

image.png

应用场景:凭据

secret 应用场景:

  • docker-registry docker 镜像仓库认证信息
  • generic 通用的数据存储
  • tls https 证书

3.1 拿 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

image.png

注意:用户名和密码需要经过 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 中后会解码

image.png

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

image.png

  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    108 引用 • 54 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...