Kubernetes挂载常用资源

Posted by Zeusro on November 5, 2018

最近有点划水,文章还是有写的,只是没成型,所以没发出来.

今天介绍下用k8s挂载一些常用的资源

当前版本Kubernetes版本:1.12.2

env

env

1
2
3
          env:
            - name: GIT_REPO
              value: 'ssh://[email protected]:22/a/b.git'

嵌套env

1
2
3
4
5
6
7
8
9
          env:
            - name: spring.profiles.active
              value: 'product'
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP              
            - name: GOMS_API_HTTP_ADDR
              value: 'http://$(MY_POD_IP):9090'

configMap

注意一下,修改configmap不会导致容器里的挂载的configmap文件/环境变量发生改变;删除configmap也不会影响到容器内部的环境变量/文件,但是删除configmap之后,被挂载的pod上面会出现一个warnning的事件

1
2
3
4
Events:
  Type     Reason       Age                 From                                         Message
  ----     ------       ----                ----                                         -------
  Warning  FailedMount  64s (x13 over 11m)  kubelet, cn-shenzhen.i-wz9498k1n1l7sx8bkc50  MountVolume.SetUp failed for volume "nginx" : configmaps "nginx" not found

config map写的很清楚了,这里恬不知耻得copy一下

注意,configmap有1M的限制,一般用来挂载小型配置,大量配置建议上配置中心

挂载单一项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        # Define the environment variable
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
              name: special-config
              # Specify the key associated with the value
              key: special.how
  restartPolicy: Never

表示挂载special-config这个configmap的special.how

挂载整个configmap

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: special-config
  restartPolicy: Never

参考:

  1. Add nginx.conf to Kubernetes cluster
  2. Configure a Pod to Use a ConfigMap

fieldRef

可以挂载pod的一些属性

1
2
3
4
5
6
          env:
          - name: MY_POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP

Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.

resourceFieldRef

Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.

英文介绍得很明白,用来挂载当前yaml里面container的资源(CPU/内存)限制,用得比较少啦其实.此外还可以结合downloadAPI

注意containerName不能配错,不然pod状态会变成CreateContainerConfigError

1
2
3
4
5
6
          env:  
            - name: a
              valueFrom: 
                 resourceFieldRef:
                      containerName: nginx-test2
                      resource: limits.cpu

secretKeyRef

Selects a key of a secret in the pod’s namespace

1
2
3
4
5
6
7
8
9
10
11
        env:
        - name: WORDPRESS_DB_USER
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password

参考:

  1. Kubernetes中Secret使用详解
  2. https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.12/#envvarsource-v1-core

目录/文件类挂载

k8s可以挂载的资源实在是太多,这里挑一些比较有代表性的来讲一下

这一类资源一般要先在spec层级定义volumes,然后在containers定义volumeMounts,有种先声明,再使用的意思

hostPath(宿主机目录/文件)

  1. 既有目录/文件用Directory/File+nodeSelector 但是用了nodeSelector之后,以后的伸缩都会在匹配的节点上,如果节点只有1个,副本集设置得超出实际节点可承受空间,最终将导致单点问题,这个要注意下
  2. 应用启用时读写空文件用DirectoryOrCreate或者FileOrCreate

以下演示第一种方案

1
2
#给节点打上标签(这里省略)
kubectl get node --show-labels
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
apiVersion: apps/v1beta2
kind: Deployment
metadata:  
  labels:
    app: nginx-test2
  name: nginx-test2
  namespace: test
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 2
  selector:
    matchLabels:
      app: nginx-test2
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx-test2
    spec:
      containers:
        - image: 'nginx:1.15.4-alpine'
          imagePullPolicy: Always
          name: nginx-test2
          resources: {}
          terminationMessagePolicy: File
          volumeMounts:
            - name: host1
              mountPath: /etc/nginx/sites-enabled
            - name: host2
              mountPath: /etc/nginx/sites-enabled2/a.com.conf            
      nodeSelector: 
        kubernetes.io/hostname: cn-shenzhen.i-wz9aabuytimkomdmjabq        
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
        - name: host1
          hostPath:
            path: /root/site
            type: Directory
        - name: host2
          hostPath:
            path: /root/site/a.com.conf
            type: File            

configMap

单项挂载(第1种)

这种挂载会热更新,更改后大约10秒后能看到变化

1
2
3
4
5
6
7
8
9
10
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level

单项挂载(第2种)

这种挂载方式不会热更新

1
2
3
4
5
6
7
8
          volumeMounts:                  
            - name: nginx
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf                            
      volumes:             
          - name: nginx
            configMap:
              name: amiba-nginx 

完全挂载

这种挂载会热更新,更改后大约10秒后能看到变化

1
2
3
4
5
6
7
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config

secret

单项挂载

1
2
3
4
5
6
7
8
9
10
11
  volumes:
  - name: secrets
    secret:
      secretName: mysecret
      items:
      - key: password
        mode: 511
        path: tst/psd
      - key: username
        mode: 511
        path: tst/usr

完全挂载

这里用了特定权限去挂载文件,默认好像是777

1
2
3
4
5
6
7
8
          volumeMounts:
            - name: sshkey
              mountPath: /root/.ssh              
      volumes:
        - name: sshkey
          secret:           
           secretName: pull-gitea
           defaultMode: 0400    
1
2
3
4
 kubectl create secret generic pull-gitea  \
--from-file=id_rsa=/Volumes/D/temp/id_rsa  \
--from-file=id_rsa.pub=/Volumes/D/temp/id_rsa.pub  \
--from-file=known_hosts=/Volumes/D/temp/known_hosts \

比如这个模式创建出来的secret,容器里面/root/.ssh目录就会有id_rsa,id_rsa.pub,known_hosts3个文件

downwardAPI

参考链接:

  1. volumes
  2. kubernetes-api/v1.12