Contents

Kubernetes Note 03

Contents
  • 使用一种 API 对象(Deployment)管理另一种 API 对象(Pod)的方法,在 Kubernetes 中,叫作“控制器”模式(controller pattern)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80
  • kubectl get pods -l app=nginx
    • 在命令行中,所有 key-value 格式的参数,都使用“=”而非“:”表示
  • Kubernetes 的 emptyDir 类型,只是把 Kubernetes 创建的临时目录作为 Volume 的宿主机目录,交给了 Docker
  • 容器的“单进程模型”,并不是指容器里只能运行“一个”进程,而是指容器没有管理多个进程的能力。这是因为容器里 PID=1 的进程就是应用本身,其他的进程都是这个 PID=1 进程的子进程
  • Pod 的实现原理
    • Pod 只是一个逻辑概念
    • Pod,其实是一组共享了某些资源的容器
    • Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume
  • 在 Pod 中,所有 Init Container 定义的容器,都会比 spec.containers 定义的用户容器先启动。并且,Init Container 容器会按顺序逐一启动,而直到它们都启动并且退出了,用户容器才会启动
  • sidecar 指的就是我们可以在一个 Pod 中,启动一个辅助容器,来完成一些独立于主进程(主容器)之外的工作
  • 凡是调度、网络、存储,以及安全相关的属性,基本上是 Pod 级别的
  • 凡是 Pod 中的容器要共享宿主机的 Namespace,也一定是 Pod 级别的定义
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  hostNetwork: true
  hostIPC: true
  hostPID: true
  containers:
    - name: nginx
      image: nginx
    - name: shell
      image: busybox
      stdin: true
      tty: true
  • ImagePullPolicy 的值默认是 Always,即每次创建 Pod 都重新拉取一次镜像。另外,当容器的镜像是类似于 nginx 或者 nginx:latest 这样的名字时,ImagePullPolicy 也会被认为 Always

  • Projected Volume 不是为了存放容器里的数据,也不是用来进行容器和宿主机之间的数据交换, 是为容器提供预先定义好的数据.

    • Secret
    • ConfigMap
    • Downward API
    • ServiceAccountToken
    1
    2
    3
    
    $ kubectl create secret generic user --from-file=./username.txt
    $ kubectl create secret generic pass --from-file=./password.txt
    $ kubectl get secrets
    
  • Secret 对象要求这些数据必须是经过 Base64 转码的

    1
    2
    
    $ echo -n 'admin' | base64YWRtaW4=
    $ echo -n '1f2d1e2e67df' | base64MWYyZDFlMmU2N2Rm
    
    1
    2
    3
    4
    5
    6
    7
    8
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque
    data:
      user: YWRtaW4=
      pass: MWYyZDFlMmU2N2Rm
    
  • ConfigMap

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    # .properties文件的内容
    $ cat ui.properties
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    
    # 从.properties文件创建ConfigMap
    $ kubectl create configmap ui-config --from-file=example/ui.properties
    
    # 查看这个ConfigMap里保存的信息(data)
    $ kubectl get configmaps ui-config -o yaml
    apiVersion: v1
    data:
      ui.properties: |
        color.good=purple
        color.bad=yellow
        allow.textmode=true
        how.nice.to.look=fairlyNice
    kind: ConfigMap
    metadata:
      name: ui-config
      ...
    
  • Downward API

    • Downward API 能够获取到的信息,一定是 Pod 里的容器进程启动之前就能够确定下来的信息
    • 通过环境变量获取这些信息的方式,不具备自动更新的能力。所以,一般情况下,建议使用 Volume 文件的方式获取这些信息。
     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
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-downwardapi-volume
      labels:
        zone: us-est-coast
        cluster: test-cluster1
        rack: rack-22
    spec:
      containers:
        - name: client-container
          image: k8s.gcr.io/busybox
          command: ["sh", "-c"]
          args:
            - while true; do
              if [[ -e /etc/podinfo/labels ]]; then
              echo -en '\n\n'; cat /etc/podinfo/labels; fi;
              sleep 5;
              done;
          volumeMounts:
            - name: podinfo
              mountPath: /etc/podinfo
              readOnly: false
      volumes:
        - name: podinfo
          projected:
            sources:
              - downwardAPI:
                  items:
                    - path: "labels"
                      fieldRef:
                        fieldPath: metadata.labels
    
  • Service Account 的授权信息和文件,实际上保存在它所绑定的一个特殊的 Secret 对象里的。这个特殊的 Secret 对象,就叫作 ServiceAccountToken

    • 查看一下任意一个运行在 Kubernetes 集群里的 Pod,就会发现,每一个 Pod,都已经自动声明一个类型是 Secret、名为 default-token-xxxx 的 Volume,然后 自动挂载在每个容器的一个固定目录上

    • 这个容器内的路径在 Kubernetes 里是固定的,即:/var/run/secrets/kubernetes.io/serviceaccount

      1
      2
      
      $ ls /var/run/secrets/kubernetes.io/serviceaccount
      ca.crt namespace  token
      
    • 这种把 Kubernetes 客户端以容器的方式运行在集群里,然后使用 default Service Account 自动授权的方式,被称作InClusterConfig