0.深入理解kubernetes:kubernetes in action 学习笔记

1.docker run <image>:<tag> 当引用镜像没有指定tag时,默认的tag为latest。

2.docker build命令会将dockerfile所在目录的文件都传入到docker守护进程所在的机器,如果包含大量文件,速度会变慢。

3.docker镜像的构建是分层的,每一层可以被不通的镜像所复用。

4.docker端口的映射规则:docker run --name kubia-container -p 8070:8080 -d kubia 会绑定本机的8070对应container的8080端口。前面是本机端口。

5.查看更多容器运行信息:docker inspect命令。

6.进入容器,如果容器中包含了bash shell才能执行如下命令:

docker exec -it kubia-container bash

7.pod主机名就是pod的名称。

8.kubectl expose deployment kubia --type=LoadBalancer --name kubia-http 这句话会创建一个loadbalance类型的服务,并且使用阿里云提供的loadbalance创建一个外网地址和端口:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kubia-http LoadBalancer 10.206.123.x 39.97.x.x 8080:30708/TCP 9m5s

serviceIP:10.206.123.x

外网IP:39.97.x.x

9.将指定的deploy管理的pod个数扩容:kubectl scale deploy kubia --replicas=2

10.容器被设计为一个容器只运行一个进程。

11.同一个pod内的两个容器共享Linux命名空间,主机名,同一loopback网络

12.同一个cluster内,所有的pod都处于同一个共享地址网络空间内,pod之间没有NAT网关。

13.查看容器日志:日志到达10M的时候,日志会自动轮替,kubectl仅显示最后一次轮替后的条目。如果需要一个pod中有多个container,那么使用kubectl logs podname -c containername -f

14.不通过server层,仅仅通过pod层直接与主机绑定:kubectl port-forward kubia-manual 8888:8080,将主机的8888端口绑定到pod的8080端口。

15.查看pod的标签信息:kubectl get pods --show-labels

16.选择多出一列感兴趣的标签:kubectl get pods --show-labels -L env

17.更改现有标签:kubectl label pod kubia-manual env=debug --overwrite

18.根据标签选择器筛选pod:

(1)筛选出kv为creation_method=manual的pod:kubectl get po -l creation_method=manual

(2)筛选出包含env这个key的pod:kubectl get po -l env

(3)筛选出不包括env这个key的pod:kubectl get po -l '!env'

19.将pod调度到指定满足条件的node上:

(1)kubectl label node gke-xxx-nodename gpu=true

(2)spec:下,

spec:
  nodeSelector:
    gpu: "true"

20.通过标签选择器删除pod:kubectl delete po -l env=prod -n custom-namespace

21.探针种类:(1)存活探针,(2)就绪探针

22.探针探测方式:HTTP,TCP,EXEC

23.探针使用:放在

spec:
  container:
    livenessProbe:
      httpGet:
        path: /
        port: 8080  
      initialDelaySeconds: 15    

24.查看前一个崩溃的pod的日志:kubectl logs mypod --previous

25.查看pod为何被重启:kubectl describe po mypod,查看其中的event一级exitcode:exitcode=128+x,x表示终止进程的信号编号。

26.java程序不要使用exec探针,这样会启动新的jvm。

27.水平缩放rc(deploy应该一样):kubectl scale rc kubia --replicas=10

28.replicaset与rc区别:标签选择器更具有表达力,支持in,NotIn,Exists,DoesNotExist

29.DaemonSet:确保符合要求的node上都有一个pod在运行.默认在集群所有的节点上运行.

30.job类型的任务不能使用always的重启策略,应该使用restartPolicy:OnFailure.

31.job类型任务的apiVersion是batch/v1

32.job可以设置并行和串行.比如设置completions:5,parallelism:2将计划有5个pod job任务被调起,同时调起2个并行执行.

33.可以设置job最长工作时间,超过该时间认为失败.activeDeadlineSeconds

34.cronJob:分钟,小时,每月的第几天,月,星期几.

35.可以通过service:port访问服务的地方:登录到pod内部或者在集群内部的node上直接curl

36.如果一个serviceA后面又podA里面运行着微服务,通过登录这个pod后curl这个service的Cluster-ip是访问不到这个pod的service的.只能登录别的pod里.

37.会话亲和性设置:同一个客户端总之请求到同一个pod,亲和性属于TCP,不能基于cookie.

spec:
  sessionAffinity: ClientIP

38.客户端pod如何找到server的ip和端口?

(1)如果service先创建,那么客户端可以通过环境变量获取service的ip和端口.

(2)如果service晚于客户端创建,可通过DNS获取service的ip和port

客户端通过"FQDN"来访问service,服务域名通常格式是:servicename.default.svc.cluster.local

39.服务的CLUSTER-IP是无法ping通的.

40.service与pod之间通过endpoint相连,通过命令kubectl get endpoints kubia查看服务kubia后面的pod的ip加端口.service的名称与对应的endpoints资源的名称是一致的.

41.创建nodePort类型的service,及几个port的关系。

apiVersion: v1
kind: Service
metadata:
    name: kubia-nodeport
spec:
    type: NodePort
    ports:
    - port: 80 #service层的port
      targetPort: 8080 #pod的port
      nodePort: 30123 #节点的port
   selector:
      app: kubia      

42.Loadbalance服务是nodeport服务的扩展,几个port的设置与上面nodeport一致。loadbalance的定义:

apiVersion: v1
kind: Service
metadata:
  name: kubia-loadbalancer
spec:
  type: LoadBalancer
  ports:
  - port: 80 #service层的port
    targetPort: 8080 #pod的port
    nodePort: 30005 #节点的port
  selector:
    app: kubia    

查看svc,会看到EXTERNAL-IP这一列会出现一个外网IP。

测试:如果使用nodeport的端口为30123(防火墙没有放开该端口),也不会影响该服务的使用,因为是通过loadbalancer来调用的nodeport,一样可以访问。

但是:EXTERNAL-IP在每次启动的时候是会变化的。

43.nodeport的缺点

外部访问服务时,随机选择的pod不一定在链接的node节点上,可能需要网络跳转,可以通过设置来达到只将请求转发到接受请求的node上的pod上,但是这种方式必须确保所有的node节点都有pod运行。

spec:
    externalTrafficPolicy: Local

44.查看本集群的所有ingress资源

kubectl get pod --all-namespaces -o wide|grep ingress

45.通过ingress的方式访问,需要确保域名解析为ingress控制器的IP。通过测试,两次创建同一个ingress,ip地址是一样的!!创建ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubia
spec:
  rules:
  - host: kubia.example.com
    http:
      paths:
      - path: /
        backend: 
          serviceName: kubia-nodeport #后端service的名称
          servicePort: 80  #后端service的端口

46.ingress的rules和paths都是数组,可以包含多个条目,一个ingress可以将多个注解和路径映射到多个服务。比如,一个host的多个多个path

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubia
spec:
  rules:
  - host: kubia.example.com
    http:
      paths:
      - path: /kubia
        backend: 
          serviceName: kubia-nodeport
          servicePort: 80
	  - path: /bar
	    backend:
		  serviceName: bar
		  servicePort: 80

47.就绪探针

 

48.headless服务

该服务不存在cluster-ip,请求dns会返回所有的后端的pod的ip。

apiVersion: v1
kind: Service
metadata:
  name: kubia-headless
spec:
  clusterIP: None
  ports:
  - port: 80
    targetPort: 8080
  selector: 
    app: kubia

创建后,该service不存在CLUSTER-IP

 

49.故障排除

(1)service是个虚拟ip,无法ping通的。

(2)就绪探针如果不成功,就不能能成为service的一部分。

(3)使用kubectl get endpoints来检查断点对象。

 

50.kubectl explain deploy.spec.strategy

更新策略:

 

51.卷类型

(1)emptyDir:存储临时目录的简单空目录

(2)hostPath:工作节点的文件系统挂载到pod中。

(3)nfs:NFS共享卷

(4)configMap,secret,downwardAPI:将k8s部分资源和集群信息公开给pod的特殊类型的卷。将k8s元数据信息公开给pod使用。

(5)persistentVolumeClain:动态配置持久存储卷。

 

52.创建两个container共用的卷,/usr/share/nginx/html是nginx的默认路径。

apiVersion: v1
kind: Pod
metadata:
  name: fortune
spec:
  containers:
  - image: luksa/fortune
    name: html-generator
    volumeMounts:
   - name: html
     mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}          

默认使用节点的磁盘来当作卷,如果需要使用内存作为卷,修改:

volumes:
- name: html
  emptyDir:
    midium: Memory   

53.hostPath卷:指向节点的文件系统特定的目录或文件,hostPath卷的特性是pod挂了之后,数据不会被删除,如果后续pod再次被调度到该节点,可以继续使用该节点卷的数据。这种方式适用于需要读取主机配置的场景。

 

54.使用NFS卷

volumes:
- name: mongodb-data
  nfs:
    server: 1.2.3.4
    path: /some/path 

55.持久卷和持久卷声明,用户定义持久化卷声明(PVC),指定需要的最低容量要求和访问模式。然后将声明清单提交给k8s api服务器。持久卷声明在pod中,只能由一个用户使用。需要管理员先创建持久化卷,然后用户通过持久化卷声明来挑选管理员创建的符合标准的持久化卷。

(1)创建持久化卷

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mongodb-pv
spec:
  capacity:
    storage: 1Gi
    accessMode:
    - ReadWriteOnce #单个用户读写模式
   - ReadOnlyMany  #多个用户只读模式
   persistentVolumeReclaimPolicy: Retain #声明被释放后,保留数据
   gcePersistentDisk:
     pdName: mongodb
     fsType: ext4   

查看声明的pv:kubectl get pv ,持久卷不属于任何命名空间,跟节点一样属于集群层面的资源。

(2)持久卷声明,这是与pod的创建独立的过程,作为一种独立的PersistentVolumeClaim类型的资源存在,查看pvc命令:kubectl get pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-pvc
spec:
  resources:
    requests:
      storage: 1Gi
  accessModes:
 - ReadWriteOnce: #持久化卷的模式必须包含持久化声明卷中的访问模式
 storageClassName: ""

accessModes:

RWO:ReadWriteOnce:仅允许单个节点挂载读写

ROX:ReadOnlyMany:允许多个节点挂载只读

RWX:ReadWriteMany:允许多个节点挂载读写

再次查看pv状态:kubectl get pv

可以看到status变为Bound状态,显示已经被绑定。

(3)在pod中使用持久卷声明

apiVersion: v1
kind: Pod
metadata:
  name: mongodb
spec:
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - name: mongodb-data   #挂载名称为mongodb-data的volume,下面有声明
      mountPath: /data/db  #挂载到容器的/data/db下面
    ports:
    - containerPort: 27017
      protocol: TCP
  volumes:
  - name: mongodb-data  
    persistentVolumeClaim:
      claimName: mongodb-pvc   #调用名称为mongodb-pvc的pvc 

(4)回收持久化卷

kubectl delete pod mongodb

kubectl delete pvc mongodb-pvc

查看pvc状态:kubectl get pvc

status:pending

查看pv状态:kubectl get pv

status:Released

状态时released而不是avaliable是因为包含了前一个pod的数据。

 

56.向容器中传递命令行参数

Dockerfile中:

ENTRYPOINT:定义容器被调用时执行的程序。

CMD:传递给entrypoint的参数。

 

57.shell形式和exec的区别

shell形式:ENTRYPOINT node app.js

exec像是:ENTRYPOINT ["node","app.js"]

exec形式直接运行,而不是利用shell来调用的。可以查看进程列表看出来:

如果直接运行在是node app.js进程;如果是通过shell调用则是:/bin/sh -c node app.js

 

58.docker中如何传入镜像中脚本参数:

(1)shell脚本:fortuneloop.sh

#! /bin/bash interval=$1

 

(2)构建镜像

FROM ubuntu:latest
RUN apt-get update; apt-get install -y fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
ENTRYPOINT ["/bin/fortuneloop.sh"]
CMD ["10"]

docker执行的时候,docker run -it docker.io/luksa/fortune:args 15 ,这样就能将15这个参数传给docker去执行了。

 

59.kubernetes中的执行命令和参数:command和args

command会覆盖docker中定义的ENTRYPOINT,args会覆盖docker中的CMD

 

60.pod中传参给docker容器

apiVersion: v1
kind: Pod
metadata:
  name: fortune2s
spec:
  containers:
  - image: luksa/fortune:args   #使用上面制作好的镜像
    args: ["2"]     # 将参数传给了镜像
    name: html-generator
   volumeMounts:
   - name html
     mountPath: /var/htdocs
     ...       

多参数除了[]形式外,如果是多个参数,表示如下,其中,字符串值不需要引号,数值需要。

args:
- foo
- bar
- "15"   

61.环境变量

(1)使用环境变量,如果是个脚本,那么脚本中$INTERNEVAL就可以直接接受环境变量中的INTERNEVAL值,如果是Java程序,就是System.getenv("INTERNEVAL")来获取。

(2)传递给pod:环境变量设置在pod容器中,并非pod级别,这样就可以将INTERVAL这个变量传递给image里使用了。

kind:Pod
spec:
  containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL
      value: "30"
    name: html-generator
    ...      

62.在环境变量中引用其他环境变量

env:
- name: FIRST_VAR
  value: "foo"
- name: SECOND_VAR
  value: "$(FIRST_VAR)bar" 

63.configmap通过环境变量的形式或挂载volume的方式,创建一个configmap

kubectl create configmap fortune-config --from-literal=sleep-interval=25

查看configmap:

kubectl get configmap fortune-config -o yaml

apiVersion: v1
data:
  sleep-interval: "25"
kind: ConfigMap
metadata:
  creationTimestamp: "2019-11-26T01:35:58Z"
  name: fortune-config
  namespace: default
  resourceVersion: "9376362"
  selfLink: /api/v1/namespaces/default/configmaps/fortune-config
  uid: 18de25d6-0fed-11ea-80c2-00163e164b6a

64.可以使用一个文件或者文件夹来创建configMap:

kubectl create configmap fortune-config --from-file=/a.yaml

文件夹:

kubectl create configmap fortune-config --from-file=/files/

 

65.给容器传递环境变量

(1)第一种:设置环境变量,使用env+valueFrom字段

apiVersion: v1
kind: Pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL
     valueFrom:
       configMapKeyRef:
         name: fortune-config
         key: sleep-interval     

如果引用的configMap不存在,启动会失败,可以标记为configMap为可选的。

configMapKeyRef.optional:true

 

(2)第二种:读取所有的configmap字段。使用envFrom字段而不是env

spec:
  containers:
  - image: some-image
    envFrom:
    - prefix: CONFIG_
      configMapRef:
        name: my-config-map  

CONFIG_为前缀的环境变量都会被读取。这样会匹配到所有,因为所有的环境变量都会包含该前缀。环境变量带有破折号“-”是不合法的,因为无法转换成下划线。

 

(3)传递configmap条目作为命令行参数

apiVersion: v1
kind: Pod
metadata:
  name: fortune-args-from-configmap
spec:
  containers:
  - image : luksa/fortune:args
    env:
    - name: INTERVAL  #定义环境变量,该环境变量的值从configmap中获取
     valueFrom: 
       configMapKeyRef:
         name: fortune-config
         key: sleep-interval
    args: ["$(INTERVAL)"]  #获取上面定义的环境变量INTERVAL传递给容器   

(4)configMap卷

configMap卷讲configMap中的每个条目均暴露成一个文件。容器中进程可以通过读取文件内容获取对应的条目值。

创建文件my-nginx-config.conf

server{
	listen:		80;
        server_name:    www.kubia-example.com;

	gzip on;
	gzip_types text/plain application/xml;

	location /{
        	root	/usr/share/nginx/html;
		index	index.html index.htm;
	}
}

创建文件sleep-interval文件,里面写入值25

创建名为fortune-config的configmap:

kubectl create configmap fortune-config --from-file=configmap-files

查看创建的configmap:kubectl get configmap fortune-config -o yaml

apiVersion: v1
data:
  my-nginx-config.conf: |
    server{
      listen: 80;
      server_name: www.kubia-example.com;

      gzip on;
      gzip_types text/plain application/xml;

      location {
        root  /usr/share/nginx/html;
        index  index.html  index.htm;
      }
    }
  sleep-interval: |
    25
kind: ConfigMap
metadata:
  creationTimestamp: "2019-11-26T02:30:07Z"
  name: fortune-config
  namespace: default
  resourceVersion: "9384620"
  selfLink: /api/v1/namespaces/default/configmaps/fortune-config
  uid: a92e8cad-0ff4-11ea-80c2-00163e164b6a

可以看出:configmap包含两个条目,每个条目的键是文件名。

nginx需要读取配置文件/etc/nginx/nginx.conf,并且会将其内容嵌入到/etc/nginx/conf.d/下面所有的.conf文件中,所以可以将configmap中的my-nginx-config.conf挂载到/etc/nginx/conf.d/下面,下面将configMap作为卷挂载到容器对应目录中:vim fortune-pod-configmap-volume.yaml

apiVersion: v1
kind: Pod
metadata:
  name: fortune-config-volume
spec:
  containers:
  - image: nginx
    name: web-server
    volumeMounts:
    - name: conf  #引用下面名称为conf的volume
      mountPath: /etc/nginx/conf.d  #挂载到容器的该目录下
      readOnly: true
  volumes:
  - name: conf
    configMap:
      name: fortune-config #名称为fortune-config的configmap

这种形式会将fortune-config下的两个文件都包含进来,如果只需要configmap中的部分文件,使用item指定。这样/etc/nginx/conf.d下面只会包含gzip.conf文件

volumes:
- name: config
  configMap: 
    name: fortune-config
    items:
    - key: my-nginx-config.conf   #仅使用fortune-config这个configmap中的这个key
      path: gzip.conf    #将上面的key指定的item存储在这里

注意:将卷挂载至某个文件夹下,文件夹下原本存在的任何文件都会被隐藏起来。如果不想原来的文件被隐藏,使用volumeMounts下的subPath属性,用来指定条目而非完整的卷。

spec:
  containers:
  - image: some/image
    volumeMounts:
    - name: myvolume
      mountPath: /etc/someconfig.conf
      subPath: myconfig.conf

但是这种挂载方式会有更新上的缺陷。

(5)configmap挂载到volume中的文件权限默认是644,可以修改权限:

volumes:
- name: config
  configMap:
    name: fortune-config
    defaultMode: "6600"    

66.secret

secret用法与configmap类似,secret只会写到需要访问secret节点的内存里,不会写磁盘。

etcd中会以加密方式存储secret,提高了系统的安全性。

默认情况下每个容器的/var/run/secrets/kubernetes.io/serviceaccount/下都会挂载三个secret文件:ca.crt;namespace;token

secret的data字段会被Base64编码,这样对于二进制文件也可以编程base64编码来存储,但不能大于1M。如果secret数据不想被编码可以将data变成stringData,stringData是只写的,如:

kind: Secret
apiVersion: v1
stringData:
  foo: plain text
data:
  https.cert: base64code
  https.key: base64code 

67.挂载secret到pod里:

apiVersion: v1
kind: Pod
metadata: 
  name: fortune-https
spec:
  containers:
  - image: luksa/fortune:env
    name: html-generator
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval
    valumeMounts:
    - name: html
      mountPath: /var/htdocs      
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
    - name: certs
      mountPath: /etc/nginx/certs/  #配置nginx从/etc/nginx/certs中读取证书和密钥文件,将secret挂载在这里
      readOnly: true
    ports:
    - containerPort: 80
    - containerPort: 443
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    configMap:
      name: fortune-config
      items:
      - key: my-nginx-config.conf
        path: https.conf
  - name: certs
    secret:
      secretName: fortune-https   

68.通过环境变量的方式使用secret

env:
- name: FOO_SECRET
  valueFrom:
    secretKeyRef: #这里非configmap的configMapKeyRef
      name: fortune-https
      key: foo    

但是通过环境变量的方式会暴漏出secret,所以最好使用卷的方式。

 

69.downwardApi

downwardApi通过环境变量或者dwonwardapi卷来对外暴露pod元数据信息。

 

70.downwardApi可以获取的信息:

pod名称,pod ip,pod 名称空间,pod节点名称,容器的cpu和内存使用量及限制,pod的标签,pod的注解。服务账户(pod访问api时的身份);这些大部分都能通过环境变量或者downwardapi卷暴漏,标签和注解只能通过卷暴露。

 

71.通过环境变量的方式传递到容器中

apiVersion: v1
kind: Pod
metadata: 
  name:downward
spec:
  containers:
  - name: main
    image: busybox
    command: ["sleep","999999"]
    resources:
      requests:
        cpu: 15m
        memory: 100Ki
      limits:
        cpu: 100m
        memory: 4Mi
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: POD_NAMESPACE
      valueFrom: 
        fieldRef:
          fieldPath: metadata.namespace
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
    - name: CONTAINER_CPU_REQUEST_MILLICORES
      valueFrom:
        resourceFieldRef:
          resource: request.cpu
          divisor: 1m
    - name: CONTAINER_MEMORY_LIMIT_KIBIBYTES
      valueFrom:
        resourceFieldRef:
          resource: limits.memory
          divisor: 1Ki                  

创建完成后,可以使用kubectl exec downward env查看到所有的环境变量。

 

72.通过downwardapi卷读取元数据

apiVersion: v1
kind: Pod
metadata:
  name: downward
  lables:
    foo: bar
  annotations:
    key1: value1
    key2: |
     multi
     line
     value
spec:
  containers:
  - name: main
    imgae: busybox
    command: ["sleep","999999"]
    resources:
      requests:
        cpu: 15m
        memory: 100Ki
      limits:
        cpu: 100m
        memory: 4Mi
    volumeMounts:
    - name: downward
      downwardAPI:
        items:
        - path: "podName"    
          fieldRef:
            fieldPath: metadata.name
        - path: "podNamespace"
          fieldRef:
            fieldPath: metadata.namespace
        - path: "containerCpuRequestMilliCores"
          resourceFieldRef:
            containerName: main
            resource: requests.cpu
            divisor: 1m  

这里通过挂载一个名为downward的卷来挂载到/etc/downward目录下,上面定于的每个path都会对应/etc/downward下的一个文件。

 

 

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值