【原創】一層Nginx反向代理K8S化部署實踐

wsjhk發表於2020-09-22

目錄:

1)背景介紹
2)方案分析
3)實現細節
4)監控告警
5)日誌收集
6)測試

  

一、背景介紹

    如下圖所示,傳統方式部署一層Nginx,隨著業務擴大,維護管理變得複雜,繁瑣,耗時耗力和易出錯等問題。我們的Nginx是有按照業務來分組的,不同的業務使用不同分組的Nginx例項區分開。通過nginx.conf中include不同分組的配置檔案來實現。

 

 

  

 

    如果有一種方式可以簡化Nginx的部署,擴縮容的管理。日常只需關注nginx的配置檔案釋出上線即可。當前最受歡迎的管理模式莫過於容器化部署,而nginx本身也是無狀態服務,非常適合這樣的場景。於是,通過一個多月的設計,實踐,測試。最終實現了Nginx的“上雲”。

 

二、方案分析

1)架構圖如下所示:

 

 

     

2)整體流程:
在釋出機(nginx003)上的對應目錄修改配置後,推送最新配置到gitlab倉庫,我們會有一個reloader的
容器,每10s 拉取gitlab倉庫到本地pod,pod中會根據nginx.conf檔案include的
物件 /usr/local/nginx/conf-configmap/中是否有include該分組來判斷是否進行reload 。

三、實現細節

    在K8S上部署Nginx例項,由於Nginx是有分組管理的。所以我們使用一個Deployment對應一個分組,Deployment的yaml宣告檔案除了名稱和引用的include檔案不一樣之外,其他的配置都是一樣的。 一個Deployment根據分組的業務負載了來設定replicas數量,每個pod由四個容器組成。包括:1個initContainer容器init-reloader和3個業務容器nginx,reloader和nginx-exporter。下面,我們著重分析每個容器實現的功能。

 

1)init-reloader容器
這個容器是一個initContainer容器,是做一些初始化的工作。

1.1)映象:

# cat Dockerfile
FROM fulcrum/ssh-git:latest

COPY init-start.sh /init-start.sh
COPY start.sh /start.sh
COPY Dockerfile /Dockerfile
RUN apk add --no-cache tzdata ca-certificates libc6-compat inotify-tools bc bash && echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" >> /etc/timezone

        1.2)執行init-start.sh指令碼

功能:
(1)從倉庫拉取最新配置並cp 至/usr/local/nginx/conf.d/目錄
(2)建立代理快取相關的目錄/data/proxy_cache_path/
(3)在/usr/local/nginx/conf/servers/下建立對應的對應的conf 檔案記錄後端服務 realserver:port

 2)nginx-exporter容器

    該容器是實現對接prometheus監控nginx的exporter

2.1)映象:

# cat Dockerfile
FROM busybox:1.28

COPY nginx_exporter /nginx_exporter/nginx_exporter
COPY start.sh /start.sh
ENV start_cmd="/nginx_exporter/nginx_exporter -nginx.scrape-uri http://127.0.0.1:80/ngx_status"

  

    2.2)執行start.sh指令碼

功能
(1) num=$(netstat -anlp | grep -w 80 | grep nginx | grep LISTEN | wc -l)
(2) /nginx_exporter/nginx_exporter -nginx.scrape-uri http://127.0.0.1:80/ngx_status

      

3)nginx容器
該容器是openresty例項的業務容器

3.1)映象

FROM centos:7.3.1611

COPY Dockerfile /dockerfile/
#COPY sysctl.conf /etc/sysctl.conf
USER root
RUN yum install -y logrotate cronie initscripts bc wget git && yum clean all
ADD nginx /etc/logrotate.d/nginx
ADD root /var/spool/cron/root
ADD kill_shutting_down.sh /kill_shutting_down.sh
ADD etc-init.d-nginx /etc-init.d-nginx
COPY openresty.zip /usr/local/openresty.zip
COPY start.sh /start.sh
COPY reloader-start.sh /reloader-start.sh
RUN chmod +x /start.sh /kill_shutting_down.sh reloader-start.sh && unzip /usr/local/openresty.zip -d /usr/local/ && cd /usr/local/openresty && echo "y" | bash install.sh && rm -rf /usr/local/openresty /var/cache/yum && localedef -c -f UTF-8 -i zh_CN zh_CN.utf8 && mkdir -p /usr/local/nginx/conf/servers && chmod -R 777 /usr/local/nginx/conf/servers && cp -f /etc-init.d-nginx /etc/init.d/nginx && chmod +x /etc/init.d/nginx

ENTRYPOINT ["/start.sh"]

  

3.2)執行start.sh指令碼

功能:
(1)啟動crond定時任務實現日誌輪轉
(2)判斷目錄(/usr/local/nginx/conf.d) 不為空,啟動nginx

      

4)reloader容器
改容器是實現釋出流程邏輯的輔助容器
4.1)映象和nginx容器一樣

4.2)執行reloader-start.sh指令碼

功能:
(1)get_reload_flag函式
       通過對比/gitrepo/diff.files 檔案 改變的檔名和/usr/local/nginx/conf-configmap/中 是否include 此檔名發生改變的分組 來判斷是否需要reload (flag=1 則reload)

(2)check_mem函式
       判斷記憶體少於30% 返回1

(3)kill_shutting_down函式
       先執行記憶體剩餘量判斷,如果小於30%,殺掉shutdown 程式

(4)nginx_force_reload函式(只會進行reload)
       kill -HUP ${nginxpid}

(5)reload函式
     (5.1) 首先將倉庫中的配置檔案cp至/usr/local/nginx/conf.d ;
     (5.2) /usr/local/nginx/conf.d不為空時
            建立proxy_cache_path 目錄---/usr/local/nginx/conf/servers/檔案--- nginx -t ---kill_shutting_down -----nginx_force_reload

  總結整體實現流程如下 :
    1)拉取倉庫pull 重新命名舊的commit id 檔案(/gitrepo/local_current_commit_id.old),並生成獲取新的commit id(/gitrepo/local_current_commit_id.new);
    2)通過對比old和new commit id 獲得發生了變更檔案到/gitrepo/diff.files ;
    3)然後呼叫 et_reload_flag 判斷改組nginx是否需要reload
    4)如果/gitrepo/diff.files中有“nginx_force_reload” 欄位 然後kill_shutting_down -- nginx_force_reload       

  

5)Deployment的實現

    通過實現以上容器的功能後,打包成映象用於部署。以下是Deployment的yaml詳細內容:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: slb-nginx-group01
  name: slb-nginx-group01
  namespace: slb-nginx
spec:
  replicas: 3  // 3個副本數,即:3個pod
  selector:
    matchLabels:
      app: slb-nginx-group01
  strategy:  // 滾動更新的策略,
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: slb-nginx-group01
        exporter: nginx
      annotations:  // 註解,實現和prometheus的對接
        prometheus.io/path: /metrics
        prometheus.io/port: "9113"
        prometheus.io/scrape: "true"
    spec:
      nodeSelector:  // 節點label選擇
        app: slb-nginx-label-group01
      tolerations:  // 容忍度設定
      - key: "node-type"
        operator: "Equal"
        value: "slb-nginx-label-group01"
        effect: "NoExecute"
      affinity:  // pod的反親和性,儘量部署到阿里雲不同的可用區
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - slb-nginx-group01
              topologyKey: "failure-domain.beta.kubernetes.io/zone"
      shareProcessNamespace: true   // 容器間程式空間共享
      hostAliases:  // 設定hosts
      - ip: "xxx.xxx.xxx.xxx"
        hostnames:
        - "www.test.com"
      initContainers:
      - image: www.test.com/library/reloader:v0.0.1
        name: init-reloader
        command: ["/bin/sh"]
        args: ["/init-start.sh"]
        env:
        - name: nginx_git_repo_address
          value: "git@www.test.com:psd/nginx-conf.git"
        volumeMounts:
          - name: code-id-rsa
            mountPath: /root/.ssh/code_id_rsa
            subPath: code_id_rsa
          - name: nginx-shared-confd
            mountPath: /usr/local/nginx/conf.d/
          - name: nginx-gitrepo
            mountPath: /gitrepo/
      containers:
      - image: www.test.com/library/nginx-exporter:v0.4.2
        name: nginx-exporter
        command: ["/bin/sh", "-c", "/start.sh"]
        resources:
          limits:
            cpu: 50m
            memory: 50Mi
          requests:
            cpu: 50m
            memory: 50Mi
        volumeMounts:
          - name: time-zone
            mountPath: /etc/localtime
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      - image: www.test.com/library/openresty:1.13.6
        name: nginx
        command: ["/bin/sh", "-c", "/start.sh"]
        lifecycle:
          preStop:
            exec:
              command:
              - sh
              - -c
              - sleep 10
        livenessProbe:
          failureThreshold: 3
          initialDelaySeconds: 90
          periodSeconds: 3
          successThreshold: 1
          httpGet:
            path: /healthz
            port: 8999
          timeoutSeconds: 4
        readinessProbe:
          failureThreshold: 3
          initialDelaySeconds: 4
          periodSeconds: 3
          successThreshold: 1
          tcpSocket:
            port: 80
          timeoutSeconds: 4
        resources:
          limits:
            cpu: 8
            memory: 8192Mi
          requests:
            cpu: 2
            memory: 8192Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
          - name: nginx-start-shell
            mountPath: /start.sh
            subPath: start.sh
            readOnly: true
          - name: conf-include
            mountPath: /usr/local/nginx/conf-configmap/
          - name: nginx-shared-confd
            mountPath: /usr/local/nginx/conf.d/
          - name: nginx-logs
            mountPath: /data/log/nginx/
          - name: data-nfs-webroot
            mountPath: /data_nfs/WebRoot
          - name: data-nfs-httpd
            mountPath: /data_nfs/httpd
          - name: data-nfs-crashdump
            mountPath: /data_nfs/crashdump
          - name: data-cdn
            mountPath: /data_cdn
      - image: www.test.com/library/openresty:1.13.6
        name: reloader
        command: ["/bin/sh", "-c", "/reloader-start.sh"]
        env:
        - name: nginx_git_repo_address
          value: "git@www.test.com:psd/nginx-conf.git"
        - name: MY_MEM_LIMIT
          valueFrom:
            resourceFieldRef:
              containerName: nginx
              resource: limits.memory
        securityContext:
          capabilities:
            add:
            - SYS_PTRACE
        resources:
          limits:
            cpu: 100m
            memory: 550Mi
          requests:
            cpu: 100m
            memory: 150Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
          - name: code-id-rsa
            mountPath: /root/.ssh/code_id_rsa
            subPath: code_id_rsa
            readOnly: true
          - name: reloader-start-shell
            mountPath: /reloader-start.sh
            subPath: reloader-start.sh
            readOnly: true
          - name: conf-include
            mountPath: /usr/local/nginx/conf-configmap/
          - name: nginx-shared-confd
            mountPath: /usr/local/nginx/conf.d/
          - name: nginx-gitrepo
            mountPath: /gitrepo/
      volumes:
        - name: code-id-rsa
          configMap:
            name: code-id-rsa
            defaultMode: 0600
        - name: nginx-start-shell
          configMap:
            name: nginx-start-shell
            defaultMode: 0755
        - name: reloader-start-shell
          configMap:
            name: reloader-start-shell
            defaultMode: 0755
        - name: conf-include
          configMap:
            name: stark-conf-include
        - name: nginx-shared-confd
          emptyDir: {}
        - name: nginx-gitrepo
          emptyDir: {}
        - name: nginx-logs
          emptyDir: {}
        - name: time-zone
          hostPath:
            path: /etc/localtime
        - name: data-nfs-webroot
          nfs:
            server: xxx.nas.aliyuncs.com
            path: "/WebRoot"
        - name: data-nfs-httpd
          nfs:
            server: xxx.nas.aliyuncs.com
            path: "/httpd"
        - name: data-nfs-crashdump
          nfs:
            server: xxx.nas.aliyuncs.com
            path: "/crashdump"
        - name: data-cdn
          persistentVolumeClaim:
            claimName: oss-pvc

      如上所示,deployment的關鍵配置有:nodeSelector,tolerations,pod反親和性affinity,shareProcessNamespace,資源限制(是否超賣),容器實名週期lifecycle,存活探針livenessProbe,就緒探針readinessProbe,安全上下文授權securityContext和儲存掛載(NFS,OSS,emptyDir和configmap的掛載)。

 

6)對接阿里雲SLB的service宣告檔案:

# cat external-group01-svc.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "xxx"
    #service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "true"
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler: "wrr"
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-remove-unscheduled-backend: "on"
  name: external-grou01-svc
  namespace: slb-nginx
spec:
  externalTrafficPolicy: Local
  ports:
  - port: 80
    name: http
    protocol: TCP
    targetPort: 80
  - port: 443
    name: https
    protocol: TCP
    targetPort: 443
  selector:
    app: slb-nginx-group01
  type: LoadBalancer

# cat inner-group01-svc.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "xxx"
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler: "wrr"
    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-remove-unscheduled-backend: "on"
  name: inner-stark-svc
  namespace: slb-nginx
spec:
  externalTrafficPolicy: Local
  ports:
  - port: 80
    name: http
    protocol: TCP
    targetPort: 80
  - port: 443
    name: https
    protocol: TCP
    targetPort: 443
  selector:
    app: slb-nginx-group01
  type: LoadBalancer

  

    如上所示,對接阿里雲SLB分別建立內網外的service。通過註解指定使用的負載均衡演算法,指定的SLB,以及是否覆蓋已有監聽。externalTrafficPolicy引數指定SLB的後端列表只有部署了pod的宿主機。部署後可在阿里雲SLB控制檯檢視負載情況。

 

四、監控告警

在叢集中以prometheus-operator方式部署監控系統,配置監控有兩種方式。分別如下:

1)第一種:建立service和ServiceMonitor來實現:
// 建立service
# cat slb-nginx-exporter-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: slb-nginx-exporter-svc
  labels:
    app: slb-nginx-exporter-svc
  namespace: slb-nginx
spec:
  type: ClusterIP
  ports:
    - name: exporter
      port: 9113
      targetPort: 9113
  selector:
    exporter: nginx  // 這裡的selector對應depolyment中的label

// 建立ServiceMonitor
# cat nginx-exporter-serviceMonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    k8s-app: nginx-exporter
  name: nginx-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: slb-nginx-exporter-svc  //這裡的選擇的label和service對應
  namespaceSelector:
    matchNames:
    - slb-nginx
  endpoints:
  - interval: 3s
    port: "exporter"  //這裡port的名稱也需要和service對應
    scheme: http
    path: '/metrics'
  jobLabel: k8s-nginx-exporter

#建立完這兩個資源後,prometheus會自動新增生效以下配置:
# kubectl -n monitoring exec -ti  prometheus-k8s-0 -c prometheus -- cat /etc/prometheus/config_out/prometheus.env.yaml
...
scrape_configs:
- job_name: monitoring/nginx-exporter/0
  honor_labels: false
  kubernetes_sd_configs:
  - role: endpoints
    namespaces:
      names:
      - slb-nginx
  scrape_interval: 3s
  metrics_path: /metrics
  scheme: http
  relabel_configs:
  - action: keep
    source_labels:
    - __meta_kubernetes_service_label_app
    regex: slb-nginx-exporter-svc
  - action: keep
    source_labels:
    - __meta_kubernetes_endpoint_port_name
    regex: exporter
  - source_labels:
    - __meta_kubernetes_endpoint_address_target_kind
    - __meta_kubernetes_endpoint_address_target_name
    separator: ;
    regex: Node;(.*)
    replacement: ${1}
    target_label: node
  - source_labels:
    - __meta_kubernetes_endpoint_address_target_kind
    - __meta_kubernetes_endpoint_address_target_name
    separator: ;
    regex: Pod;(.*)
    replacement: ${1}
    target_label: pod
  - source_labels:
    - __meta_kubernetes_namespace
    target_label: namespace
  - source_labels:
    - __meta_kubernetes_service_name
    target_label: service
  - source_labels:
    - __meta_kubernetes_pod_name
    target_label: pod
  - source_labels:
    - __meta_kubernetes_service_name
    target_label: job
    replacement: ${1}
  - source_labels:
    - __meta_kubernetes_service_label_k8s_nginx_exporter
    target_label: job
    regex: (.+)
    replacement: ${1}
  - target_label: endpoint
    replacement: exporter
...

          這樣,監控資料就被採集到prometheus中了。可以配置對應的告警規則了。如下:

 

 2)第二種:直接在prometheus新增對應的配置來實現:

// 在deployment中新增如下pod的annotation
annotations:
  prometheus.io/path: /metrics
  prometheus.io/port: "9113"
  prometheus.io/scrape: "true"

// 新增role:pods的配置,prometheus會自動去採集資料
- job_name: 'slb-nginx-pods'
  honor_labels: false
  kubernetes_sd_configs:
  - role: pod
  tls_config:
    insecure_skip_verify: true
  relabel_configs:
  - target_label: dc
    replacement: guangzhou
  - target_label: cluster
    replacement: guangzhou-test2
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] // 以下三個引數和annotation想對應
    action: keep
    regex: true
  - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
    action: replace
    target_label: __metrics_path__
    regex: (.+)
  - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
    action: replace
    regex: ([^:]+)(?::\d+)?;(\d+)
    replacement: $1:$2
    target_label: __address__
  - action: labelmap
    regex: __meta_kubernetes_pod_label_(.+)
  - source_labels: [__meta_kubernetes_namespace]
    action: replace
    target_label: kubernetes_namespace
  - source_labels: [__meta_kubernetes_pod_name]
    action: replace
    target_label: kubernetes_pod_name

// 新增告警規則
# cat slb-nginx-pods.rules
groups:
- name: "內網一層Nginx pods監控"
  rules:
  - alert: 內網Nginx pods 例項down
    expr: nginx_up{dc="guangzhou",namespace="slb-nginx"} == 0
    for: 5s
    labels:
      severity: 0
      key: "nginx-k8s"
    annotations:
      description: "5秒鐘內一層Nginx {{ $labels.instance }} 發生當機."
      summary: "內網k8s1.18叢集{{ $labels.namespace }} 名稱空間下的pod: {{ $labels.pod }} down"
      hint: "登入內網k8s1.18叢集檢視{{ $labels.namespace }} 名稱空間下的pod: {{ $labels.pod }} 是否正常。或者聯絡k8s管理員進行處理。"

  

        測試告警如下:

【原創】一層Nginx反向代理K8S化部署實踐

 

 

  

五、日誌收集

    日誌收集通過在K8S叢集中部署DaemonSet實現收集每個節點上的Nginx和容器日誌。這裡使用Filebeat做收集,然後傳送到Kafka叢集,再由Logstash從Kafka中讀取日誌過濾後傳送到ES叢集。最後通過Kibana檢視日誌。

    流程如下:

            Filebeat --> Kafka --> Logstash --> ES --> Kibana

 

        1)部署

    Filebeat的DaemonSet部署yaml內容:
# cat filebeat.yml
filebeat.inputs:
  - type: container
    #enabled: true
    #ignore_older: 1h
    paths:
      - /var/log/containers/slb-nginx-*.log
    fields:
      nodeIp: ${_node_ip_}
      kafkaTopic: 'log-collect-filebeat'
    fields_under_root: true
    processors:
      - add_kubernetes_metadata:
          host: ${_node_name_}
          default_indexers.enabled: false
          default_matchers.enabled: false
          indexers:
            - container:
          matchers:
            - logs_path:
                logs_path: '/var/log/containers'
                resource_type: 'container'
          include_annotations: ['DISABLE_STDOUT_LOG_COLLECT']
      - rename:
          fields:
            - from: "kubernetes.pod.ip"
              to: "containerIp"
            - from: "host.name"
              to: "nodeName"
            - from: "kubernetes.pod.name"
              to: "podName"
          ignore_missing: true
          fail_on_error: true

  - type: log
    paths:
      - "/var/lib/kubelet/pods/*/volumes/kubernetes.io~empty-dir/nginx-logs/*access.log"
    fields:
      nodeIp: ${_node_ip_}
      kafkaTopic: 'nginx-access-log-filebeat'
      topic: 'slb-nginx-filebeat'
    fields_under_root: true

processors:
  - drop_fields:
      fields: ["ecs", "agent", "input", "host", "kubernetes", "log"]

output.kafka:
  hosts: ["kafka-svc.kafka.svc.cluster.local:9092"]
  topic: '%{[kafkaTopic]}'
  required_acks: 1
  compression: gzip
  max_message_bytes: 1000000

filebeat.config:
  inputs:
    enabled: true

# cat filebeat-ds.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: filebeat
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: filebeat
subjects:
  - kind: ServiceAccount
    name: filebeat
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  generation: 1
  labels:
    k8s-app: slb-nginx-filebeat
  name: slb-nginx-filebeat
  namespace: kube-system
spec:
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: slb-nginx-filebeat
  template:
    metadata:
      labels:
        k8s-app: slb-nginx-filebeat
    spec:
      nodeSelector:
        app: slb-nginx-guangzhou
      serviceAccount: filebeat
      serviceAccountName: filebeat
      containers:
      - args:
        - -c
        - /etc/filebeat/filebeat.yml
        - -e
        env:
        - name: _node_name_
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName
        - name: _node_ip_
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.hostIP
        image: www.test.com/library/filebeat:7.6.1
        imagePullPolicy: IfNotPresent
        name: slb-nginx-filebeat
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        securityContext:
          procMount: Default
          runAsUser: 0
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/filebeat
          name: filebeat-config
          readOnly: true
        - mountPath: /var/lib/kubelet/pods
          name: kubeletpods
          readOnly: true
        - mountPath: /var/log/containers
          name: containerslogs
          readOnly: true
        - mountPath: /var/log/pods
          name: pods-logs
          readOnly: true
        - mountPath: /var/lib/docker/containers
          name: docker-logs
          readOnly: true
      dnsPolicy: ClusterFirstWithHostNet
      hostNetwork: true
      restartPolicy: Always
      volumes:
      - configMap:
          defaultMode: 384
          name: slb-nginx-filebeat-ds-config
        name: filebeat-config
      - hostPath:
          path: /var/lib/kubelet/pods
          type: ""
        name: kubeletpods
      - hostPath:
          path: /var/log/containers
          type: ""
        name: containerslogs
      - hostPath:
          path: /var/log/pods
          type: ""
        name: pods-logs
      - hostPath:
          path: /var/lib/docker/containers
          type: ""
        name: docker-logs
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate

  

        2)檢視日誌:

 

六、測試

    測試邏輯功能和pod的健壯性。釋出nginx的邏輯驗證;修改nginx配置檔案和執行nginx -t,nginx -s reload等功能;pod殺死後自動恢復;擴縮容功能等等。如下是釋出流程的日誌:

  

    可以看到,Nginx釋出時,會顯示更新的配置檔案,並做語法檢測,然後判斷記憶體大小是否要做記憶體回收,最後執行reload。如果更新的不是自己分組的配置檔案則不會執行reload。

 

總結:

    最後,經過一個月的時間我們實現一層Nginx的容器化的遷移。實現了更加自動化和簡便的Nginx的管理方式。同時,也更加熟悉對K8S的使用。在此分享記錄,讓大家對遷移傳統應用到K8S等容器化平臺做個參考。如果會開發,當然要擁抱Operator這樣的好東西。

 

 

附:歡迎關注本人公眾號(內有其他分享):

 

相關文章