kubernetes(五)k8s进阶

1.Pod lifecycle

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
Pod的生命周期
挂起(Pending):Pod的yaml已被Kubernetes接受执行,但有一个或者多个容器尚未创建完成
运行中(Running):Pod 已经绑定到了一个节点上,其中所有的容器都已被创建。至少有一个容器正在运行,或者处于启动或重启状态。
成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器终止失败 , 也就是说,存在容器以non-zero status状态退出或者被系统终止。
未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败

2.重启策略

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy

A PodSpec has a restartPolicy field with possible values Always, OnFailure, and Never. The default value is Always. restartPolicy applies to all Containers in the Pod. restartPolicy only refers to restarts of the Containers by the kubelet on the same node. As discussed in the Pods document, once bound to a node, a Pod will never be rebound to another node.

重启的Pod会在原来运行的Node上,不会进行变更

  • Always:容器失效时,立即重启(默认策略)
  • OnFailure:容器终止运行且退出码不为0时重启
  • Never:永远不重启

3.静态Pod 


静态Pod是由kubelet直接进行管理的,并且存在于特定的Node上。
不能通过API Server进行管理,无法与ReplicationController,Ddeployment或者DaemonSet进行关联,也无法进行健康检查。

创建静态Pod有两种方式:配置文件方式和HTTP方式

使用配置文件方式创建static Pod的时候,只需要在kubelet守护进程中添加配置参数--pod-manifest-path=<the directory>
kubelet会定期扫描该目录,并根据该目录中的yaml或json文件进行创建

安装完k8s之后我们可以看到一些默认启动的pod(api-server等组件pod),这些都属于是静态pod,其Yaml文件我们可以在
/etc/kubernetes/manifests/下看到。

这些系统组件的pod都是运行在Master节点上,并且使用的是宿主机当前的ip,而不是通过calico插件生成对应的ip

4.健康检查

The kubelet can optionally perform and react to three kinds of probes on running Containers:

livenessProbe : Indicates whether the Container is running. If the liveness probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a liveness probe, the default state is Success .
readinessProbe : Indicates whether the Container is ready to service requests. If the readiness probe fails, the endpoints controller removes the Pod’s IP address from the endpoints of all Services that match the Pod. The default state of readiness before the initial delay is Failure . If a Container does not provide a readiness probe, the default state is Success .
startupProbe : Indicates whether the application within the Container is started. All other probes are disabled if a startup probe is provided, until it succeeds. If the startup probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a startup probe, the default state is Success .
 

LivenessProbe探针:判断容器是否存活  is running 
ReadinessProbe探针:判断容器是否启动完成  is ready to service requests

5.ConfigMap

在生产环境中经常会遇到需要修改配置文件的情形,传统直接修改yaml的方式不仅会影响到服务的正常运行,而且操作步骤也比较繁琐(yaml对格式有严格要求,包括空格等)。为了解决这个问题,kubernetes从1.2版本引入了ConfigMap功能,用于将应用的配置信息与程序的分离。

ConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable. 

简单来说ConfigMap就是用来保存配置数据的键值对,可用于保存单个属性,也可用于保存配置文件。主要用于存储不包含敏感信息的数据。ConfigMap存储的这些配置内容可用于被Pod或者其他资源对象(如RC)访问

创建方式:

5.1.使用kubectl命令行创建

在kubectl create configmap命令中使用参数--from-file或--from-literal指定文件、目录或者文本,可以创建一个或者多个ConfigMap参数。

1)采用键值对的方式创建ConfigMap
#literal -- 字面量
Kubectl create connfigmap NAME --from-literal=key1=value1  --from-literal=key2=value2

eg.创建一个名称为my-config的ConfigMap,key值是db.port,value是'9200' 
kubectl create configmap my-config --from-literal=db.port='9200'


2)采用文件的方式创建ConfigMap
Kubectl create connfigmap NAME --from-file=[key= ] source --from-file=[key= ] source
eg.kubectl create configmap app --from-file=./app.properties 

3)采用目录的方式创建
Kubectl create connfigmap NAME --from-file=config-files-dir
目录中的每个配置文件名都被会被设置为key,文件中的内容将被设置为value

kubectl get configmap
可以通过kubectl get configmap my-config -o yaml命令查看创建的my-config configMap的详细信息

5.2.通过yaml文件创建 

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO

5.3 ConfigMap使用方式

(1)通过环境变量的方式,直接传递给pod
    使用configmap中指定的key
    使用configmap中所有的key
(2)通过在pod的命令行下运行的方式(启动命令中)
(3)作为volume的方式挂载到pod内

注意:
(1)ConfigMap必须在Pod使用它之前创建
(2)使用envFrom时,将会自动忽略无效的键
(3)Pod只能使用同一个命名空间的ConfigMap

5.3.1 通过环境变量使用ConfigMap

使用valueFrom、configMapKeyRef、name来指定使用的configMap的mame
通过key指定要用到的Map里的key

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        # name参数定义环境变量名
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              # 定义使用的ConfigMap的name
              name: special-config
              # 定义ConfigMap里使用的key
              key: special.how
  restartPolicy: Never

5.3.2 用作命令行参数

在命令行下使用时,需要先设置为环境变量,之后可以通过$(VAR_NAME)设置容器启动命令的启动参数

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod2
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY)" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
  restartPolicy: Never

5.3.3 作为volume挂载使用

可以将创建的ConfigMap直接挂载至Pod的对应目录下,其中每一个key-value键值对都会生成一个文件,key为文件名,value为内容。

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap
spec:
  containers:
    - name: test-container
      image: nginx
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

之前ingress搭建中的mandatory.yaml文件中就使用了ConfigMap,打开可以发现有nginx-configuration、tcp-services等名称的ConfigMap,而且也可以发现最后在容器的参数中使用了这些配置

可以查看下ingress创建的容器

在对应的Node w1上通过docker命令进入容器

可以发现nginx-ingress-controller里有/etc/nginx/nginx.conf  实际就是一个nginx,里面还有Nginx的配置文件,而所谓的ingress.yaml文件中配置的内容就会对应到nginx.conf中

如果我们想修改ingress里非端口映射部分的配置呢,肯定不可能直接通过操作容器里的配置文件来修改,这个时候就体现了ConfigMap的用处,我们可以在ConfigMap里定义自己想要修改的参数,然后通过kubectl 执行一下,k8s就会自动帮我们替换相关的参数(目前mandatory里的ConfigMap都是没有data的,所以nginx使用的也是默认的参数)

原来的nginx.conf里

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app: ingress-nginx
data:
  proxy-read-timeout: "208"  #这里修改nginx.conf里的proxy-read-timeout参数

再次进入容器查看就能发现nginx.conf的配置修改了

在官方定义了一系列修改配置文件的参数规则:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/

6.Secret

 Kubernetes secret objects let you store and manage sensitive information, such as passwords, OAuth tokens, and ssh keys

6.1 Secret类型

- Opaque:使用base64编码存储信息,可以通过`base64 --decode`解码获得原始数据,因此安全性弱。
- kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息。
- kubernetes.io/service-account-token:用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。

6.2 Secret创建

6.2.1 Opaque Secret
Opaque类型的Secret的value为base64位编码后的值
1) 从文件中创建
echo -n "admin" > ./username.txt
echo -n "1f2d1e2e67df" > ./password.txt
kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt


2) 使用yaml文件创建

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

根据yaml文件创建资源并查看

6.2.2  kubernetes.io/dockerconfigjson
kubernetes.io/dockerconfigjson用于存储docker registry的认证信息,可以直接使用 kubectl create secret命令创建

6.2.3 kubernetes.io/service-account-token
 用于被 serviceaccount 引用。
serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。

kubectl get secret   可以看到service-account-token

创建一个新的nginx pod,可以看到容器内挂载的servcieaccount信息


 

6.3 Secret使用

1.以Volume方式

#跟ConfigMap的使用类似,只是把cm换成了secret
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:
      secretName: mysecret

2.以环境变量方式

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
  restartPolicy: Never

小结:无论是ConfigMap还是Secret,都可以通过Volume进行挂载,将信息放到Pod中进行使用。

7.Controller进阶

https://kubernetes.io/docs/concepts/architecture/controller/

7.1 Job & CronJob

A Job creates one or more Pods and ensures that a specified number of them successfully terminate. As pods successfully complete, the Job tracks the successful completions. When a specified number of successful completions is reached, the task (ie, Job) is complete. Deleting a Job will clean up the Pods it created.

对于RS,RC之类的Controller,能够保持Pod按照预期数目持久地运行下去,它们针对的是持久性的任务,比如web服务。
而有些操作其实不需要持久,比如压缩文件,计算等,我们希望任务完成之后,Pod就结束运行,不需要保持在系统中,此时就需要使用到Job。
所以可以把Job理解成是对RS、RC等持久性控制器的补充。
Job 负责批量处理短暂的一次性任务,仅执行一次,并保证处理的一个或者多个Pod成功结束。

下面就是一个简单的计算pod,计算完之后pod就需要停止

apiVersion: batch/v1
kind: Job
metadata:
  name: job-demo
spec:
  template:
    metadata:
      name: job-demo
    spec:
      restartPolicy: Never
      containers:
      - name: counter
        image: busybox
        command:
        - "bin/sh"
        - "-c"
        - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"

如果想要在指定的时间内执行对应的Job就可以使用CronJob(create Job on a time-based schedule)

A Cron Job creates Jobs on a time-based schedule.
One CronJob object is like one line of a crontab (cron table) file. It runs a job periodically on a given schedule, written in Cron format.

cronJob是基于时间进行任务的定时管理。
可以在特定的时间点运行任务,或者反复在指定的时间点运行任务:比如定时进行数据库备份,定时发送电子邮件等等。

7.2 StatefulSet

StatefulSet is the workload API object used to manage stateful applications.
 Manages the deployment and scaling of a set of Pods, and provides guarantees about the ordering and uniqueness of  these Pods.

之前接触的Pod的管理对象比如RC、Deployment和Job都是面向无状态的服务,但是现实中有很多服务是有状态的,比如MySQL集群、MongoDB集群、ZK集群等

而之前的RC/Deployment没办法满足要求,所以从Kubernetes v1.4版本就引入了PetSet资源对象,在v1.5版本时更名为StatefulSet。从本质上说,StatefulSet可以看作是Deployment/RC对象的特殊变种
其特点:

  • StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内其他的成员
  • Pod的启动顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态
  • StatefulSet里的Pod采用稳定的持久化存储卷,通过PV/PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷
  • StatefulSet需要与Headless Service配合使用
# 定义StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx 
  serviceName: "nginx"  
  replicas: 3 
  template:
    metadata:
      labels:
        app: nginx 
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

观察下集群pod的创建顺序,这里的Pod是顺序创建的,和RS里的并行创建不一样

7.3 DaemonSet

A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the cluster, Pods are added to them. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created.

特点:集群的每个节点都会运行一个唯一的pod副本

应用场景
1)运行集群存储 daemon,例如在每个节点上运行 `glusterd`、`ceph`。
2)在每个节点上运行日志收集 daemon,例如`fluentd`、`logstash`。
3)在每个节点上运行监控 daemon,例如 [Prometheus Node Exporter](https://github.com/prometheus/node_exporter)、`collectd`、Datadog 代理、New Relic 代理,或 Ganglia `gmond`

7.4 Horizontal Pod Autoscaler

The Horizontal Pod Autoscaler automatically scales the number of pods in a replication controller, deployment or replica set based on observed CPU utilization (or, with custom metrics support, on some other application-provided metrics).

使用Horizontal Pod Autoscaling,Kubernetes会自动地根据观察到的CPU利用率(或者通过一些其他应用程序提供的自定义指标)自动地缩放在replication controller、deployment或replica set上pod的数量。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx 
  replicas: 3 
  template:
    metadata:
      labels:
        app: nginx 
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

# 使nginx pod的数量介于2和10之间,CPU使用率维持在50%
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=50

将配置文件里的副本数改成1,再执行yaml,可以发现其最终运行的Pod还是维持在2个Pod(先停止2个pod,检查后发现不满足hpa的要求,就又新建了一个)

8.Resource和Dashboard

8.1 Resource

在K8S的集群中,Node节点的资源信息会上报给APIServer

我们可以通过requests&limits这两个属性设置cpu和内存

apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
  - name: db
 image: mysql
 env:
    - name: MYSQL_ROOT_PASSWORD
   value: "password"
 resources:
   requests:
     memory: "64Mi"     # 表示需要64M内存
     cpu: "250m"        # 表示需要0.25核的CPU
   limits: 
     memory: "128Mi"    # 表示内存上限:128M
     cpu: "500m"        # 表示CPU上限:0.5核
  - name: wp
 image: wordpress
 resources:
   requests:
     memory: "64Mi"
     cpu: "250m"
   limits:
     memory: "128Mi"
     cpu: "500m"

8.2 Dashboard

yaml:https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta6/aio/deploy/recommended.yaml

(1)执行后查看dashboard资源

(2)使用火狐浏览器访问
https://192.168.56.51:30018/



(3)生成登录需要的token

# 创建service account
kubectl create sa dashboard-admin -n kube-system
# 创建角色绑定关系
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin

# 查看dashboard-admin的secret名字
ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}')
echo ADMIN_SECRET

# 打印secret的token
kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}'

将上面的token填入到浏览器的令牌里,访问成功

发布了47 篇原创文章 · 获赞 12 · 访问量 5084

猜你喜欢

转载自blog.csdn.net/qq_35448165/article/details/103375747