一.初始化容器initContainer

参考链接:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/

应用场景:1.创建文件;2.修改内核参数;3.等待依赖程序启动等

1. 示例1:等待依赖服务启动

后端应用需要依赖数据库服务

  initContainers:
    - command: 
      - sh
      - -c
      - for i in {1..100}; do sleep 1; echo $i; if dig SERVICE_NAME_OR_DOMAIN; then exit 0; fi; exit 1; done
      env:
      - name: TZ
        value: Aisa/Shanghai
      - name: LANG
        value: C.UTF-8
    image: centos:6
    imagePullPolicy: Always
    name: check-service
  restartPolicy: Always
2. 示例2:服务注册

注册这个Pod的IP到远程服务器,通过在命令中调用API

  initContainers:
    - command: 
      - sh
      - -c
      - |
        curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register \
          -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
      env:
      - name: TZ
        value: Aisa/Shanghai
      - name: LANG
        value: C.UTF-8
    image: curl
    imagePullPolicy: Always
    name: init-curl
  restartPolicy: Always
3. 示例3:克隆Git代码到容器中
  initContainers:
    - command: 
      - sh
      - -c
      - |
        git clone https://github.com/dotbalo/kubernetes-guide.git
      env:
      - name: TZ
        value: Aisa/Shanghai
      - name: LANG
        value: C.UTF-8
    image: alpine/git:latest
    imagePullPolicy: Always
    name: init-git
  restartPolicy: Always
4. 示例4:多个初始化容器使用

一个应用需要等待该应用所在Namespace的一个Service对应的Pod启动,也需要一个DB的Service启动。

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  # 业务应用容器
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  # 初始化容器列表
  initContainers:
  # 第1个初始化容器,等待当前ns下的myservice启动
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  # 第2个初始化容器,等待DB的service启动
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

# 查看容器日志
k logs myapp-pod -c init-myservice
k logs myapp-pod -c init-mydb
二.临时容器——Ephemeral Containers

参考链接:[https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/ephemeral-containers/](https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/ephemeral-containers/)

用来调试程序,不会影响正常容器。

在1.18+版本使用的步骤:
k alpha debug(1.18版)

k debug(1.19版+)
k debug metrics-server-795dc6d4d8-mzcjl -i --image=busybox -n kube-system
三.HPA——自动扩缩容

参考链接:https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

前提:需要依赖metrics server,不适用于无法缩放的对象如daemonset

实践:

# 新建deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-server
  name: nginx-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-server
  template:
    metadata:
      labels:
        app: nginx-server
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 100m

# clusterIP
k expose deploy nginx-server --port=80
# 新建HPA,平均cpu利用率是10%,允许最大的Pod数量为10,最少为1
k autoscale deploy nginx-server --cpu-percent=10 --min=1 --max=10 
# 当前HPA状态,未发送请求,CPU使用率为10%
k get hpa                 
NAME           REFERENCE                 TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-server   Deployment/nginx-server   0%/10%    1         10        6          3m48s

k get service 
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-server   ClusterIP   10.96.161.205   <none>        80/TCP         2m10s

# 模拟访问
while true;do curl 10.96.161.205 &> /dev/null; done

# CPU升高
k get hpa  
NAME           REFERENCE                 TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-server   Deployment/nginx-server   40%/10%   1         10        6          2m36s

# Pod自动扩容
k get pods 
NAME                            READY   STATUS    RESTARTS   AGE
nginx-server-74544d6d5f-dfbmp   0/1     Pending   0          46s
nginx-server-74544d6d5f-dkf85   0/1     Pending   0          61s
nginx-server-74544d6d5f-dqg45   1/1     Running   0          3m36s
nginx-server-74544d6d5f-gkdt5   0/1     Pending   0          46s
nginx-server-74544d6d5f-wvgbc   0/1     Pending   0          61s
nginx-server-74544d6d5f-xskn6   0/1     Pending   0          61s
四.Taints和Toleration

参考链接:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/

添加污点:

kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule
如果给一个节点添加了一个 effect 值为 NoExecute的污点, 则任何不能忍受这个污点的 Pod 都会马上被驱逐,任何可以忍受这个污点的 Pod 都不会被驱逐。

删除污点:

kubectl taint nodes node1 key1:NoSchedule-

查看污点:

kubectl describe node node1|grep Taints
五.Affinity亲和力——只有在调度时起作用

参考链接:https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity

亲和力分为软亲和力(非强制性) preferredDuringSchedulingIgnoredDuringExecution和硬亲和力(强制性)requiredDuringSchedulingIgnoredDuringExecution

  • 1.Node Affinity:根据节点的标签进行匹配。
  • 2.PodAffinity(Pod亲和力):根据Pod的标签进行匹配。
  • 3.PodAntiAffinity(Pod反亲和力)
1.Node Affinity
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity 
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname 
            operator: In
            values:
            - k8s-master-node1
            - k8s-worker-node1 
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1  # 权重越高优先级越大
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: nginx
    imagePullPolicy: IfNotPresent

只能部署在具有label的key为kubernetes.io/hostname,value为k8s-master-node1或k8s-worker-node1的节点上(硬亲和力),在满足条件后,尽量部署在具有another-node-label-key=another-node-label-value的节点(软亲和力),没有该标签的node不会影响部署。

2.PodAffinity和PodAntiAffinity
apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: failure-domain.beta.kubernetes.io/zone 
  containers:
  - name: with-pod-affinity
    image: nginx 

必须和具有security=S1标签的Pod部署在同一域内,域的名称是failure-domain.beta.kubernetes.io/zone;尽量不和具有security=S2标签的Pod部署在同一域内。
Pod的标签是Pod本身的配置,所以和Pod一样具有隔离性,在配置Pod亲和力和反亲和力时可以匹配其他Namespace下Pod的标签。指定和kube-public ns具有security为S1标签的Pod部署在同一个域的配置如下:

spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        namespaces:
        - kube-public
        topologyKey: failure-domain.beta.kubernetes.io/zone
示例1:同一应用部署在不同宿主机

将一个应用部署在不同的节点上,达到更高的可用率,以免同一个应用部署到相同的宿主机带来风险。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: must-be-diff-nodes
  name: must-be-diff-nodes
  namespace: kube-public
spec:
  replicas: 3
  selector:
    matchLabels:
      app: must-be-diff-nodes
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: must-be-diff-nodes
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - must-be-diff-nodes
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: must-be-diff-nodes
        image: nginx
        imagePullPolicy: Always
        env:
        - name: TZ
          value: Asia/Shanghai
        - name: LANG
          value: C.UTF-8
示例2:同一应用不同副本的固定节点

适用于有状态服务,NodeSelector/NodeAffinity+PodAntiAffinity
部署2个redis示例,部署至2台宿主机,且单个实例部署的节点保持不变

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-cache
spec:
  selector:
    matchLabels:
      app: store
  replicas: 2
  template:
    metadata:
      labels:
        app: store
    spec:
      nodeSelector:
        app: store
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: redis-server
        image: redis:3.2-alpine
示例3:应用和缓存尽量部署在同一域内

后端应用请求数据库服务会增大数据库服务的压力,直接请求缓存中间件可以提高数据加载速度,减少网络消耗。
部署2个不在同一域内的nginx实例,但必须和redis在同一域内。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: web-store
  replicas: 2
  template:
    metadata:
      labels:
        app: web-store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - web-store
            topologyKey: "kubernetes.io/hostname"
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: web-app
        image: nginx:1.16-alpine
posted on 2023-06-07 14:55  jiayou111  阅读(47)  评论(0编辑  收藏  举报