kubernetes 權威指南學習筆記(2) -- 基本概念和術語

基本概念和術語

Master&Node

Kubernetes 集羣的兩種管理角色: Master 和 Nodenode

Master

Master 只的是集羣控制節點,每一個集羣須要一個檢點來負責整個集羣的管理和控制。 基本上全部控制命令都發給它,它來負責具體的執行過程。mysql

Master 節點一般會佔據一個獨立的服務器。git

Master 節點上運行着如下一組關鍵進程web

  • Kubernetes API Server (kube-apiserver): 提供了HTTP Rest接口的關鍵服務進程,是Kubernetes裏全部資源的增、刪、改、查等操做的惟一入口,也是集羣控制的入口進程
  • Kubernetes Controller Manager(kube-controller-manager): Kubernetes 裏全部資源對象的自動化控制中心
  • Kubernetes Scheduler (kube-scheduler): 負責資源調度(Pod 調度) 的進程

Master 節點上還須要啓動一個etcd服務,k8s裏的全部資源對象的數據所有保存在etcd中redis

Node

集羣中除了Master其餘機器被稱爲Node節點,Node能夠是一臺物理機,也能夠是一臺虛擬機。Node是k8s集羣中工做負載節點,沒個Node會被Master分配一些工做負載(docker 容器), 當某個Node宕機時,其上的工做負載會被Master自動轉移到其餘節點上去。sql

Node 節點運行如下一組關鍵進程docker

  • kubelet: 負責Pod對應的容器的建立、啓停等任務,同時與Master節點密切協做,實現集羣管理的基本功能
  • kube-proxy: 實現Kubernetes Service 的通訊與負載均衡機制的重要組件。
  • Docker Engine (docker): Docker 引擎,負責本機的容器建立和管理工做。

Node 能夠在運行期間動態增長到Kubernetes集羣中,前提是節點已正確安裝、配置和啓動上述關鍵進程。後端

默認狀況kubelet會向Master註冊本身, 這也是Kubernetes推薦的Node管理方式。api

一旦Node歸入集羣管理範圍,kubelet進程就會定時向Master節點回報自身的情報,如操做系統、Docker版本、機器的CPU和內存狀況,以及當前有哪些Pod在運行。這樣Master能夠獲知每一個Node的資源使用狀況,並實現高效均衡的資源調度策略。tomcat

某個Node超過指定時間不上報信息,會被Master斷定爲「失聯」,Node的狀態被標記爲不可用(Not Ready), 隨後Master會觸發「工做負載轉移」的自動流程。

Pod

構成

  • Pause 容器: 根容器
  • User 容器: 一個或多個緊密相關的用戶業務容器。

設計 Pause 緣由:

  1. 以它的狀態表明整個容器組的狀態。
  2. Pod裏多個容器共享Pause容器的IP, 共享Pause容器掛接的Volume, 簡化容器通信,文件共享的問題。

Pod IP: k8s 爲每一個Pod 分配了惟一IP地址,Pod裏多個容器共享。

k8s要求底層網絡支持集羣內任意兩個Pod之間的TCP/IP直接通訊,一般採用虛擬二層網絡技術來實現,如 Flannel、Open vSwitch.

一個Pod裏的容器與另外主機上的Pod容器可以直接通訊。

分類:

  1. 普通Pod: 一旦被建立,就會放入到etcd中存儲, 隨後被master調度到某個具體的Node上並進行綁定(Binding),隨後被Node的kubelet進程實例化成Docker容器啓動。
  2. 靜態Pod(Static Pod): 存放在某個具體的Node上的一個具體文件內,而且只在此Node上啓動運行。

默認狀況Pod裏某個容器中止,k8s會自動檢測到並重啓這個Pod(重啓Pod內全部容器),若是Pod所在Node宕機,將會將Node上全部Pod從新調度到其餘節點上。

Endpoint: Pod的IP加上容器的端口(containerPort)

Pod Volume: 定義在Pod上, 被各個容器掛載到本身的文件系統中。

查看pod描述信息,定位問題。

kubectl describe pod <pod name>

Event:是一個事件的記錄, 記錄了時間的最先產生時間、最後重現時間、重複次數、發起者、類型,以及致使此時間的緣由等衆多信息。Event 一般會關聯到某個具體的資源對象上,是排查故障的重要參考信息。

Pod 對服務器上計算資源設置限額

  1. CPU : CPU的資源單位爲CPU(Core) 的數量,是一個絕對值。
  2. Memory: 單位是內存字節數,也是一個絕對值

k8s裏一般以千分之一的CPU配額爲最小單位。用m來表示。一般一個容器的配額被定義爲100~300m,既0.1~0.3個cpu.由於是一個絕對值,因此不管是一個Core仍是48個Core的機器 100m所表明的使用量是同樣的。

k8s裏一個計算資源進行配額限定須要設定兩個參數

  1. Requests: 該資源的最小申請量,系統必須知足要求。
  2. Limits 該資源最大循序使用的量,不能被突破,當容器試圖使用超過這個量的資源時,可能會被k8s kill並重啓。

一般將 Request 設置爲一個比較小的值,符合容器平時的工做負載狀況下的資源需求,把Limits設置爲峯值負載下資源佔用的最大值。。

如代表mysql容器最少申請0.25個CPU和64Mib內存,在運行時,mysql鎖能使用的資源配額爲 0.5個CPU及128Mib內存

spec:
  containers:
  - name: db
    image: mysql
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

Label 標籤

Label 是一個鍵值對,能夠附加到各類資源對象上,如 Node、Pod、Service、RC等。

一個資源能夠定義任意數量的Lable, 同一個Lable也能夠被添加到任意數量的資源對象上去。

能夠在對象定義時肯定,也能夠在對象建立後動態添加或者刪除。

經過制定的資源對象捆綁一個或多個不一樣的Label 來實現多維度的資源分組管理,方便的進行資源分配、調度、配置、部署等管理工做。

經常使用標籤示例

  • 版本標籤: "release": "stable", "release": "canary" ...
  • 環境標籤: "environment": "dev", "environment": "qa", "environment": "production",
  • 架構標籤: "tier": "frontend", "tier": "backend", "tier": "middleware",
  • 分區標籤: "partition": "customerA",
  • 質量管控標籤: "track": "daily", "track": "weekly",

Label Selector 標籤選擇器

經過標籤選擇器(Label Selector) 查詢和篩選擁有Label的資源對象。

Label Selector 表達式:

  • 基於等式(Equality-based):
    • name = redis 匹配全部具備標籤的資源對象
    • name != mysql 匹配不具備標籤的對象
  • 基於集合(Set-based):
    • name in (redis, mysql) 匹配全部具備標籤 name=redis 或 name=mysql的資源對象
    • name not in (redis) 匹配全部不具備標籤 name=redis的資源對象

可使用多個Label Selector 表達式組合實現複雜的條件選擇,多個表達式使用,進行分隔,幾個條件是AND關係

name=redis,env!=production

新出現的管理對象Deployment、ReplicaSet、DaemonSet和Job 可使用Selector中使用基於集合篩選條件定義

selector:
  matchLabels:
    app: myweb
  matchExpressions:
    - {key: tier, operator: In, values: [frontend]}
    - {key: environment, operator: NotIn, values: [dev]}
  • matchLabels: 定義一組Label, 與直接寫在Selector做用相同
  • matchExpressions: 定義一組篩選條件,可用條件運算符包括: In、NotIn、Exists和DoesNotExist。

同時設置了這兩組,他們的關係是 AND 關係,全部條件都知足才能完成篩選。

Replication Controller

RC: 聲明某種Pod的副本數量在任意時刻都符合某種預期值

  • Pod 期待的副本數(replicas)
  • 用於篩選目標Pod的Label Selector
  • 當Pod的副本數量小於預期數量時,用於建立新Pod的模版(template)

定義RC提交到k8s集羣后,master節點的Controller Manager組件得到通知,按期巡檢系統中存活的目標Pod, 並確保Pod實例的數量恰好等於此RC的指望值。 若是過多的Pod運行,就停一些Pod,不然會建立一些Pod.

經過RC實現了用戶應用集羣的高可用,減小手工運維工做。

在運行時,能夠經過修改RC的副本數量,來實現Pod的動態縮放(Scaling)。

kubectl scale rc redis-slave --replicas=3

注意 刪除RC並不會影響經過該RC已建立好的Pod, 爲了刪除全部Pod,能夠將replicas的值爲0,而後更新該RC.

還提供了 stop 和 delete 命令來一次性刪除RC和RC 控制的全部Pod.

經過RC能夠實現 滾動升級(Rolling Update)

Kubernetes v1.2時,升級爲新的概念 Replica Set, 下一代RC.

區別:

  • Replica Sets 支持基於集合的Label selector
  • RC 只支持基於等式的Label selector
apiVersion: v1
kind: ReplicaSet # 對比: 這裏寫的是 ReplicationController
metadata:
  name: mysql 
spec:
  selector: 
      matchLabels:
        app: myweb
      matchExpressions:
        - {key: tier, operator: In, values: [frontend]}

當前咱們不多單獨使用,主要被Deployment這個高層對象所使用。咱們在使用Deployment時,無須關心如何建立ReplicaSet.

  • 改變RC 副本數量,能夠實現Pod的擴容和縮容的功能
  • 改變RC 裏Pod 模版的鏡像版本, 能夠實現Pod的滾動升級功能。

Deployment

爲了更好解決Pod編排問題,內部使員工ReplicaSet

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: dev
  template:
    metadata:
      labels:
        app: myapp
        release: dev
    spec:
      containers:
      - name: myapp-containers
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80

建立:

kubectl create -f deployment.yaml

查看Deployment的信息

➜  k8s kubectl get deployments
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
myapp-deploy   1         1         1            1           1m
  • DESIRED: Pod副本數量的指望值, 既Deployment裏定義的Replica
  • CURRENT: 當前Replica的值,這個值不斷增長,直到達到DESIRED爲止, 完成整個部署過程
  • UP-TO-DATE: 最新版本的Pod的副本數量,用於指示在滾動升級的過程當中,有多少Pod副本已成功升級
  • AVAILABLE: 當前集羣可用Pod副本數量, 既集羣中當前存活的Pod數量。

查看對應的ReplicaSet, 命名和Deployment有關

➜  k8s kubectl get rs
NAME                     DESIRED   CURRENT   READY     AGE
myapp-deploy-f4bcc4799   1         1         1         10m

查看Pod, 以ReplicaSet的名稱爲前綴, 清晰代表那些rs建立了哪些Pod,對於滾動升級,能夠容易排除錯誤。

➜  k8s kubectl get pods
NAME                           READY     STATUS    RESTARTS   AGE
myapp-deploy-f4bcc4799-d9pqn   1/1       Running   0          14m

Horizontal Pod Autoscaler

Pod 橫向自動擴容, 簡稱HPA

HPA有兩種方式做爲Pod負載的度量指標

  • CPUUtilizationPercentage
  • 應用程序自定義的度量指標,好比服務在每秒內的相應的請求數(TPS和QPS)

CPUUtilizationPercentage 是一個算數平均值,既目標Pod全部副本自身的CPU利用率的平均值。

一個Pod自身CPU利用率是該Pod當前CPU的使用量除以它的Pod Request的值。

如:一個Pod的PodRequest爲0.4,當前CPU使用率是0.2, 那麼它CPU使用率爲50% (0.2/0.4=0.5)

這樣咱們就能夠算出一個RC控制的Pod副本的CPU利用率的算數平均值。

若是某個時刻CPUUtilizationPercentage的值超過80%,則意味着當前的Pod副本數量可能不足以支撐接下來更多的請求,須要動態擴容。 當峯值時段過去,CPU利用率又降下來,此時對應的Pod副本應該自動減小到一個合理水平。

CPUUtilizationPercentage計算使用到的Pod的CPU使用量一般在1min內的平均值,目前經過Heapster擴展組件來獲得這個值。因此須要安裝Heapster.

若是目標沒定義Pod Request,則沒法使用CPUUtilizationPercentage

StatefulSet

提供有狀態的服務。

  • StatefulSet 裏的每一個Pod都有穩定、惟一的網絡標識,能夠用來發現集羣內的其餘成員。如 StatefulSet 的名字是kafka, 第一個pod叫kafka-0, 依次類推
  • StatefulSet 控制的Pod副本的啓停順序是受控的,操做第n個Pod時, 前n-1個Pod已經運行且準備好的狀態。
  • StatefulSet 裏的Pod採用穩定的持久化存儲卷,經過PV/PVC來實現, 刪除Pod時默認不會刪除與StatefulSet相關的存儲卷。

StatefulSet除了要與PV卷捆綁使用以存儲Pod的狀態數據,還要與Headless Service配合,每一個定義中要聲明它屬於哪一個Headless Service。

Headless Service 與普通Service的區別在於,它沒有Cluster IP, 如解析Headless Service的DNS域名, 則返回的是該Service對應的所有Pod的Endpoint列表。

StatefulSet在Headless Service的基礎上又爲控制的每一個Pod實例建立了一個DNS域名:

$(podname).$(headless service name)

如: 3 個節點的kafka, Headless Service名字kafka,則3個Pod的DNS名稱分別爲kafka-0.kafka、kafka-1.kafka、kafka-2.kafka

這些DNS名稱能夠直接在集羣的配置文件中固定下來。

Service(服務)

每一個Service至關於微服務架構中的 "微服務"

Service與其後端Pod副本集羣經過Label Selector 來實現"無縫對接"

RC 保證 Service 的服務能力和服務質量始終處於預期的標準值。

運行在Node上的kube-proxy進程負責負載,把請求轉發到後盾Pod實例上, 內部實現負載與會話保持。

Cluster IP : Service不是共用一個負載均衡器的IP地址,而是沒個Service分配了一個全局惟一的虛擬IP地址, 這個IP叫Cluster IP

這樣每一個服務都變成了具備惟一IP地址的"通訊節點",服務變成了基礎的TCP網絡通訊問題。

Pod的Endpoint地址會隨着Pod的銷燬和從新建立而發生改變,由於新Pod的IP地址和舊的Pod的不一樣

Service一旦被建立,Kubernetes就會自動爲它分配一個可用的Cluster IP, 並且在Service的整個生命週期內, 它的Cluster IP不會發生改變。

因此服務發現使用Service的NameCluster IP地址作一個DNS域名映射就解決問題。

建立一個Service: tomcat-service.yaml

apiVersion: v1
kind: Service 
metadata:
  name: tomcat-service
spec:
  ports:
  - port: 8080
  selector:
    tier: frontend

建立

kubectl create -f tomcat-service.yaml

這時候就會去對應一個Pod, 使用下面的命令查看對應狀況

kubectl get endpoints

查看Cluster IP

kubectl get svc tomcat-service -o yaml

服務多端口問題,存在多個Endpoint,定義例子如:

apiVersion: v1
kind: Service 
metadata:
  name: tomcat-service
spec:
  ports:
  - port: 8080
   name: service-port
  - port: 8005
     name: shutdown-port 
  selector:
    tier: frontend

服務發現機制

Service 都有一個惟一的Cluster IP 及惟一的名字。名字由開發者本身定義,部署也不須要改,因此徹底能夠固定在配置中。

最先使用環境變量(env),在每一個Pod的容器在啓動時,自動注入。可是不夠直觀。

經過Add-On增值包的方式引入了DNS系統, 把服務名做爲DNS域名, 這樣程序就能夠直接使用服務名來簡歷通訊鏈接了。

外部訪問Service的問題

三種IP

  • Node IP: Node節點的IP地址
  • Pod IP: Pod的IP的地址
  • Cluster IP: Service的IP地址
Node IP

Node IP是 k8s集羣中沒個節點的物理網卡的IP地址, 這是一個真實存在的物理網絡。

這代表k8s集羣以外的節點訪問k8s集羣某個節點或TCP/IP服務,必須經過Node IP 通訊。

Pod IP

Pod IP 是每一個Pod的IP地址,它是根據Docker Engine 根據 docker0 網橋IP地址段進行分配的,一般是一個虛擬的二層網絡。

因此k8s裏一個Pod裏的容器訪問另外一個Pod裏的容器,就經過Pod IP 所在的虛擬二層網絡進行通訊,真實流量則是經過Node IP所在的物理網卡流出。

Cluster IP

Cluster IP 也是虛擬IP,

  • Cluster IP 只做用於 Kubernetes Service 這個對象,並由k8s管理和分配IP地址 (來源於 Cluster IP 地址池)
  • 沒法被Ping, 沒有一個"實體網絡對象"來響應
  • 只能結合Service Port 組成一個具體的通訊端口,單獨的Cluster IP 不具有TCP/IP通訊的基礎,而且他們屬於集羣內部封閉空間,如集羣外想訪問,須要額外的工做。
  • k8s 集羣內 Node IP網、Pod IP網與 Cluster IP網之間通訊,採用k8s本身設計的一套特殊路由規則,與咱們熟悉的IP路由有很大不一樣。

Cluster IP 屬於 k8s 內部的地址,沒法在集羣外部直接使用這個地址。

採用NodePort 解決上述問題

apiVersion: v1
kind: Service 
metadata:
  name: tomcat-service
spec:
  type: NodePort
  ports:
  - port: 8080
    nodePort: 31002  # 手動指定NodePort 端口號,否則會自動分配。
  selector:
    tier: frontend

NodePort還沒徹底解決外部訪問Service的全部問題,如負載均衡。最好使用一個負載均衡器,由負載均衡器負責轉發流量到後面某個Node的NodePort.

如: 使用硬件 Load balancer 負載, 活 HAProxy 或者 Nginx.

谷歌GCE公有云上,將 type=NodePort 改成 type=LoadBalancer, k8s會自動建立一個對應的Load balancer 使用。其餘公有云實現此驅動,也可以使用。

Volume (存儲卷)

Volume 是 Pod 中可以被多個容器訪問的共享目錄。

k8s中的 Volume 定義在Pod上, 而後被一個Pod裏的多個容器掛載到具體的文件目錄下。

k8s中的 Volume 與Pod的生命週期相同, 與容器的生命週期不相關。

當容器終止或者重啓時,Volume 中的數據不會丟失。

k8s 支持多種文件類型的 Volume.

使用: 在Pod上聲明一個 Volume, 而後在容器裏引用Volume並Mount到容器的某個目錄上。

如: 給 Pod 增長一個 名字爲 datavol 的 Volume, 掛載到 /mydata-data上

template:     
metadata:
  labels:
    app: mysql  
spec:
  volumes: 
    - name: datavol
      emptyDir: {}
  containers:    
  - name: mysql   
    image: mysql  
    volumeMounts:
      - mountPath: /mydata-data
        name: datavol

emptyDir

一個emptyDir Volume 是在Pod 分配到Node時建立的。它的內容爲空,而且無須指定宿主機上對應的文件目錄。這是k8s自動分配的一個目錄。 Pod 從Node上移除, emptyDir 中的數據也會被永久刪除。

用途:

  • 臨時空間, 例如用於某些應用程序運行時所需的零時目錄,且無須永久保存。
  • 長時間任務的中間過程Check Point的零時保存目錄
  • 一個容器須要從另外一個容器中獲取數據的目錄(多容器共享目錄)

hostPath

hostPath 爲在Pod上掛載宿主機上的文件或目錄,

  • 容器應用程序生成的日誌文件須要永久保存時,可使用宿主機的高速文件系統進行存儲。
  • 須要訪問宿主機Docker 引擎內部數據結構的容器應用時, 能夠經過定義hostPath爲宿主機/var/lib/docker目錄,使容器內部能夠直接訪問Docker的文件系統。

使用注意:

  • 在不一樣的Node 上具備相同配置的Pod 可能會由於宿主機上的目錄和文件不一樣而致使對Volume上的目錄和文件訪問結果不一致。
  • 若是使用了資源配額管理,則k8s沒法將hostPath在宿主機上使用資源歸入管理。
volumes: 
- name: datavol
  hostPath:
    path: "/data"

gcePersistentDisk (用不到)

使用這種類型的Volume 表示使用谷歌公開雲提供的永久磁盤(Persisteent Disk, PD)存放Volume的數據,它與emptyDir不一樣,會永久保存。 當Pod被刪除時,PD只會卸載,但不會被刪除。你須要先建立一個永久磁盤(PD), 才能使用

gcloud compute disks create --size=500GB --zone=us-centrall-a my-data-disk
volumes: 
- name: datavol
  gcePersistentDisk:
    pdName: my-data-disk
    fsType: ext4

awsElasticBlockStore (用不到)

亞馬遜公有云提供的EBS Volume存儲數據,須要先建立一個ESB Volume才能使用。

一些限制:

  • Node(運行kubelet的節點) 須要是 AWS EC2實例
  • 這些AWS EC2 實例須要與 EBS volume存在相同的 region 和 availability-zone中,
  • EBS 只支持當個EC2 實例 mount 一個 volume
aws ec2 create-volume --availability-zone eu-west-1a --size 10 --volume-type gp2
volumes: 
- name: datavol
  awsElasticBlockStore:
    volumeID: aws://<availability-zone>/<volume-id>
    fsType: ext4

NFS (用不到)

使用NFS網絡文件系統提供的共享目錄存儲數據時,須要在系統部署一個NFS Server.

volumes: 
- name: nfs
  nfs:
    server: nfs-server.localhost
    path: "/"

其餘 (用不到)

  • iscsi: 使用iSCSI存儲設備上的目錄掛載到Pod中
  • flocker: 使用Flocker來管理存儲卷
  • glusterfs: 使用 GlusterFS 網絡文件系統的目錄
  • rbd: 使用Ceph塊設備共享存儲(Rados Block Device)
  • gitRepo: 掛載一個空目錄,並從git庫clone一個git repository
  • secret: 一個secret volume 用於爲Pod 提供加密信息,能夠將定義在k8s中的secret 直接掛載爲文件讓Pod訪問。secret volume 是經過tmfs(內存文件系統實現的,因此這種類型的volume老是不會持久化)

Persistent Volume

以前說的Volume是定義在Pod上,屬於"計算資源"的一部分

"網絡存儲" 是相對獨立於"計算資源"而存在的一種實體資源

Persistent Volume: 簡稱 PV 。

Persistent Volume Claim (簡稱PVC) 。

能夠認爲是集羣中某個網絡存儲對應的一塊存儲,與 Volume相似

區別:

  • PV 只能是網絡存儲, 不屬於Node, 但能夠在每一個Node 上訪問。
  • PV 並非定義在Pod上的,而是獨立於Pod以外定義。

例子: NFS類型的PV的yaml, 聲明須要5Gi的空間

apiVersion: v1
kind: PersistentVolume 
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  nfs: 
    path: /somepath
    server: 127.17.0.2

PV 的 accessModes 屬性

  • ReadWriteOnce: 讀寫權限、而且只能被單個Node掛載
  • ReadOnlyMany: 只讀權限、容許多個Node掛載
  • ReadWriteMany: 讀寫權限、容許多個Node掛載

若是Pod 想申請PV, 須要先定義一個PVC.

apiVersion: v1
kind: PersistentVolumeClain 
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources: 
    requests:
      storage: 8Gi

而後在Pod 的 Volume 定義上引用上述PVC :

volumes: 
- name: datavol
  persistentVolumeClain:
    claimName: myclaim

Namespace (命名空間)

namespace 在不少狀況下用於多租戶資源隔離。經過將集羣內部的資源對象分配到不一樣的namespace 造成邏輯上分組的不一樣項目、小組、用戶組。 便於不一樣分組在共享使用整個集羣的資源的同時還能被分別管理。

k8s 啓動後,會建立一個名爲default的Namespace 經過

kubectl get namespaces

若是不特別指明,則用戶建立的Pod、RC、Service都將被系統建立到這個默認namespace。

建立一個名爲 development 的 Namespace:

apiVersion: v1
kind: Namespace 
metadata:
  name: development

建立後能夠指定這個資源對象屬於哪一個Namespace.

定義一個名爲busybox的Pod, 放入上面建立的:

apiVersion: v1
kind: Pod 
metadata:
  name: busybox
  namespace: development
spec:
    ...

這時使用命令將看不到上面建立的pod, 默認使用的是default

kubectl get pods

須要添加參數--namespace 來查看

kubectl get pods --namespace=development

Annotation 註釋

使用key/value 鍵值對

Annotation 用來記錄的信息以下:

  • build信息、release信息、docker鏡像消息等,如時間戳、release id 號、 PR號、
  • 日誌庫、監控庫、分析庫、等資源庫的地址信息。
  • 程序調試工具,如工具名稱、版本號、
  • 團隊的聯繫信息,例如:電話號、負責人名稱、網址等。
相關文章
相關標籤/搜索