k8s yaml格式的Pod配置文件


 

kubernetes 核心技術概念

kubernetes 核心技術概念
復制控制器(Replication Controller,RC)

RC是K8s集群中保證Pod高可用的API對象。通過監控運行中的Pod來保證集群中運行指定數目的Pod副本。指定的數目可以是多個也可以是1個;少於指定數目,RC就會啟動運行新的Pod副本;
多於指定數目,RC就會殺死多余的Pod副本。即使在指定數目為1的情況下,通過RC運行Pod也比直接運行Pod更明智,因為RC也可以發揮它高可用的能力,保證永遠有1個Pod在運行。
RC是K8s較早期的技術概念,只適用於長期伺服型的業務類型,比如控制小機器人提供高可用的Web服務。 副本集(Replica Set,RS) RS是新一代RC,提供同樣的高可用能力,區別主要在於RS后來居上,能支持更多種類的匹配模式。副本集對象一般不單獨使用,而是作為Deployment的理想狀態參數使用。 部署(Deployment) 部署表示用戶對K8s集群的一次更新操作。部署是一個比RS應用模式更廣的API對象,可以是創建一個新的服務,更新一個新的服務,也可以是滾動升級一個服務。
滾動升級一個服務,實際是創建一個新的RS,然后逐漸將新RS中副本數增加到理想狀態,將舊RS中的副本數減小到0的復合操作;
這樣一個復合操作用一個RS是不太好描述的,所以用一個更通用的Deployment來描述。 服務(Service) RC、RS和Deployment只是保證了支撐服務的微服務Pod的數量,但是沒有解決如何訪問這些服務的問題。
一個Pod只是一個運行服務的實例,隨時可能在一個節點上停止,在另一個節點以一個新的IP啟動一個新的Pod,因此不能以確定的IP和端口號提供服務。
要穩定地提供服務需要服務發現和負載均衡能力。服務發現完成的工作,是針對客戶端訪問的服務,找到對應的的后端服務實例。在K8s集群中,客戶端需要訪問的服務就是Service對象。
每個Service會對應一個集群內部有效的虛擬IP,集群內部通過虛擬IP訪問一個服務。
在K8s集群中微服務的負載均衡是由Kube
-proxy實現的。Kube-proxy是K8s集群內部的負載均衡器。
它是一個分布式代理服務器,在K8s的每個節點上都有一個;這一設計體現了它的伸縮性優勢,需要訪問服務的節點越多,提供負載均衡能力的Kube-proxy就越多,高可用節點也隨之增多。
與之相比,我們平時在服務器端做個反向代理做負載均衡,還要進一步解決反向代理的負載均衡和高可用問題。 任務(Job) Job是K8s用來控制批處理型任務的API對象。批處理業務與長期伺服業務的主要區別是批處理業務的運行有頭有尾,而長期伺服業務在用戶不停止的情況下永遠運行。
Job管理的Pod根據用戶的設置把任務成功完成就自動退出了。
成功完成的標志根據不同的spec.completions策略而不同:單Pod型任務有一個Pod成功就標志完成;定數成功型任務保證有N個任務全部成功;工作隊列型任務根據應用確認的全局成功而標志成功。 后台支撐服務集(DaemonSet) 長期伺服型和批處理型服務的核心在業務應用,可能有些節點運行多個同類業務的Pod,
有些節點上又沒有這類Pod運行;而后台支撐型服務的核心關注點在K8s集群中的節點(物理機或虛擬機),要保證每個節點上都有一個此類Pod運行。
節點可能是所有集群節點也可能是通過nodeSelector選定的一些特定節點。典型的后台支撐型服務包括,存儲,日志和監控等在每個節點上支持K8s集群運行的服務。 有狀態服務集(PetSet) RC和RS主要是控制提供無狀態服務的,其所控制的Pod的名字是隨機設置的,一個Pod出故障了就被丟棄掉,在另一個地方重啟一個新的Pod,名字變了、名字和啟動在哪兒都不重要,重要的只是Pod總數;
而PetSet是用來控制有狀態服務,PetSet中的每個Pod的名字都是事先確定的,不能更改。PetSet中Pod的名字的作用,是關聯與該Pod對應的狀態。 對於RC和RS中的Pod,一般不掛載存儲或者掛載共享存儲,保存的是所有Pod共享的狀態,Pod像牲畜一樣沒有分別(這似乎也確實意味着失去了人性特征);
對於PetSet中的Pod,每個Pod掛載自己獨立的存儲,如果一個Pod出現故障,從其他節點啟動一個同樣名字的Pod,要掛載上原來Pod的存儲繼續以它的狀態提供服務。 適合於PetSet的業務包括數據庫服務MySQL和PostgreSQL,集群化管理服務Zookeeper、etcd等有狀態服務。
PetSet的另一種典型應用場景是作為一種比普通容器更穩定可靠的模擬虛擬機的機制。
傳統的虛擬機正是一種有狀態的寵物,運維人員需要不斷地維護它,容器剛開始流行時,我們用容器來模擬虛擬機使用,所有狀態都保存在容器里,而這已被證明是非常不安全、不可靠的。
使用PetSet,Pod仍然可以通過漂移到不同節點提供高可用,而存儲也可以通過外掛的存儲來提供高可靠性,PetSet做的只是將確定的Pod與確定的存儲關聯起來保證狀態的連續性。
PetSet還只在Alpha階段,后面的設計如何演變,我們還要繼續觀察。 集群聯邦(Federation) K8s在1.3版本里發布了beta版的Federation功能。在雲計算環境中,服務的作用距離范圍從近到遠一般可以有:
同主機(Host,Node)、跨主機同可用區(Available Zone)、跨可用區同地區(Region)、跨地區同服務商(Cloud Service Provider)、跨雲平台。
K8s的設計定位是單一集群在同一個地域內,因為同一個地區的網絡性能才能滿足K8s的調度和計算存儲連接要求。而聯合集群服務就是為提供跨Region跨服務商K8s集群服務而設計的。 每個K8s Federation有自己的分布式存儲、API Server和Controller Manager。用戶可以通過Federation的API Server注冊該Federation的成員K8s Cluster。
當用戶通過Federation的API Server創建、更改API對象時,Federation API Server會在自己所有注冊的子K8s Cluster都創建一份對應的API對象。
在提供業務請求服務時,K8s Federation會先在自己的各個子Cluster之間做負載均衡,而對於發送到某個具體K8s Cluster的業務請求,
會依照這個K8s Cluster獨立提供服務時一樣的調度模式去做K8s Cluster內部的負載均衡。而Cluster之間的負載均衡是通過域名服務的負載均衡來實現的。 所有的設計都盡量不影響K8s Cluster現有的工作機制,這樣對於每個子K8s集群來說,並不需要更外層的有一個K8s Federation,
也就是意味着所有現有的K8s代碼和機制不需要因為Federation功能有任何變化。 存儲卷(Volume) K8s集群中的存儲卷跟Docker的存儲卷有些類似,只不過Docker的存儲卷作用范圍為一個容器,而K8s的存儲卷的生命周期和作用范圍是一個Pod。
每個Pod中聲明的存儲卷由Pod中的所有容器共享。K8s支持非常多的存儲卷類型,特別的,支持多種公有雲平台的存儲,包括AWS,Google和Azure雲;
支持多種分布式存儲包括GlusterFS和Ceph;也支持較容易使用的主機本地目錄hostPath和NFS。
K8s還支持使用Persistent Volume Claim即PVC這種邏輯存儲,使用這種存儲,使得存儲的使用者可以忽略后台的實際存儲技術(例如AWS,Google或GlusterFS和Ceph),
而將有關存儲實際技術的配置交給存儲管理員通過Persistent Volume來配置。 持久存儲卷(Persistent Volume,PV)和持久存儲卷聲明(Persistent Volume Claim,PVC) PV和PVC使得K8s集群具備了存儲的邏輯抽象能力,使得在配置Pod的邏輯里可以忽略對實際后台存儲技術的配置,而把這項配置的工作交給PV的配置者,即集群的管理者。
存儲的PV和PVC的這種關系,跟計算的Node和Pod的關系是非常類似的;PV和Node是資源的提供者,根據集群的基礎設施變化而變化,由K8s集群管理員配置;而PVC和Pod是資源的使用者,根據業務服務的需求變化而變化,有K8s集群的使用者即服務的管理員來配置。 節點(Node) K8s集群中的計算能力由Node提供,最初Node稱為服務節點Minion,后來改名為Node。
K8s集群中的Node也就等同於Mesos集群中的Slave節點,是所有Pod運行所在的工作主機,可以是物理機也可以是虛擬機。
不論是物理機還是虛擬機,工作主機的統一特征是上面要運行kubelet管理節點上運行的容器。 密鑰對象(Secret) Secret是用來保存和傳遞密碼、密鑰、認證憑證這些敏感信息的對象。使用Secret的好處是可以避免把敏感信息明文寫在配置文件里。
在K8s集群中配置和使用服務不可避免的要用到各種敏感信息實現登錄、認證等功能,例如訪問AWS存儲的用戶名密碼。
為了避免將類似的敏感信息明文寫在所有需要使用的配置文件中,可以將這些信息存入一個Secret對象,而在配置文件中通過Secret對象引用這些敏感信息。
這種方式的好處包括:意圖明確,避免重復,減少暴漏機會。 用戶帳戶(User Account)和服務帳戶(Service Account) 顧名思義,用戶帳戶為人提供賬戶標識,而服務賬戶為計算機進程和K8s集群中運行的Pod提供賬戶標識。
用戶帳戶和服務帳戶的一個區別是作用范圍;用戶帳戶對應的是人的身份,人的身份與服務的namespace無關,所以用戶賬戶是跨namespace的;
而服務帳戶對應的是一個運行中程序的身份,與特定namespace是相關的。 名字空間(Namespace) 名字空間為K8s集群提供虛擬的隔離作用,K8s集群初始有兩個名字空間,分別是默認名字空間default和系統名字空間kube
-system,除此以外,管理員可以可以創建新的名字空間滿足需要。 RBAC訪問授權 K8s在1.3版本中發布了alpha版的基於角色的訪問控制(Role-based Access Control,RBAC)的授權模式。
相對於基於屬性的訪問控制(Attribute-based Access Control,ABAC),RBAC主要是引入了角色(Role)和角色綁定(RoleBinding)的抽象概念。
在ABAC中,K8s集群中的訪問策略只能跟用戶直接關聯;而在RBAC中,訪問策略可以跟某個角色關聯,具體的用戶在跟一個或多個角色相關聯。
顯然,RBAC像其他新功能一樣,每次引入新功能,都會引入新的API對象,從而引入新的概念抽象,而這一新的概念抽象一定會使集群服務管理和使用更容易擴展和重用。

 

 


kubernetes yaml文件解析

復制代碼
# yaml格式的pod定義文件完整內容:
apiVersion: v1          #必選,版本號,例如v1
kind: Pod             #必選,Pod
metadata:             #必選,元數據
  name: string          #必選,Pod名稱
  namespace: string       #必選,Pod所屬的命名空間
  labels:             #自定義標簽
    - name: string       #自定義標簽名字
  annotations:          #自定義注釋列表
    - name: string
spec:                #必選,Pod中容器的詳細定義
  containers:           #必選,Pod中容器列表
  - name: string        #必選,容器名稱
    image: string       #必選,容器的鏡像名稱
    imagePullPolicy: [Always | Never | IfNotPresent]  #獲取鏡像的策略 Alawys表示下載鏡像 IfnotPresent表示優先使用本地鏡像,否則下載鏡像,Nerver表示僅使用本地鏡像
    command: [string]       #容器的啟動命令列表,如不指定,使用打包時使用的啟動命令
    args: [string]         #容器的啟動命令參數列表
    workingDir: string      #容器的工作目錄
    volumeMounts:         #掛載到容器內部的存儲卷配置
    - name: string         #引用pod定義的共享存儲卷的名稱,需用volumes[]部分定義的的卷名
      mountPath: string     #存儲卷在容器內mount的絕對路徑,應少於512字符
      readOnly: boolean     #是否為只讀模式
    ports:              #需要暴露的端口庫號列表
    - name: string         #端口號名稱
      containerPort: int    #容器需要監聽的端口號
      hostPort: int        #容器所在主機需要監聽的端口號,默認與Container相同
      protocol: string      #端口協議,支持TCP和UDP,默認TCP
    env:              #容器運行前需設置的環境變量列表
    - name: string        #環境變量名稱
      value: string       #環境變量的值
    resources:          #資源限制和請求的設置
      limits:           #資源限制的設置
        cpu: string       #Cpu的限制,單位為core數,將用於docker run --cpu-shares參數
        memory: string      #內存限制,單位可以為Mib/Gib,將用於docker run --memory參數
      requests:         #資源請求的設置
        cpu: string       #Cpu請求,容器啟動的初始可用數量
        memory: string      #內存清楚,容器啟動的初始可用數量
    livenessProbe:        #對Pod內個容器健康檢查的設置,當探測無響應幾次后將自動重啟該容器,檢查方法有exec、httpGet和tcpSocket,對一個容器只需設置其中一種方法即可
      exec:             #對Pod容器內檢查方式設置為exec方式
        command: [string]   #exec方式需要制定的命令或腳本
      httpGet:            #對Pod內個容器健康檢查方法設置為HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:            #對Pod內個容器健康檢查方式設置為tcpSocket方式
         port: number
       initialDelaySeconds: 0   #容器啟動完成后首次探測的時間,單位為秒
       timeoutSeconds: 0      #對容器健康檢查探測等待響應的超時時間,單位秒,默認1秒
       periodSeconds: 0       #對容器監控檢查的定期探測時間設置,單位秒,默認10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged: false
    restartPolicy: [Always | Never | OnFailure] #Pod的重啟策略,Always表示一旦不管以何種方式終止運行,kubelet都將重啟,OnFailure表示只有Pod以非0退出碼退出才重啟,Nerver表示不再重啟該Pod
    nodeSelector: obeject     #設置NodeSelector表示將該Pod調度到包含這個label的node上,以key:value的格式指定
    imagePullSecrets:         #Pull鏡像時使用的secret名稱,以key:secretkey格式指定
    - name: string
    hostNetwork: false        #是否使用主機網絡模式,默認為false,如果設置為true,表示使用宿主機網絡
    volumes:              #在該pod上定義共享存儲卷列表
    - name: string          #共享存儲卷名稱 (volumes類型有很多種)
      emptyDir: {}          #類型為emtyDir的存儲卷,與Pod同生命周期的一個臨時目錄。為空值
      hostPath: string        #類型為hostPath的存儲卷,表示掛載Pod所在宿主機的目錄
        path: string        #Pod所在宿主機的目錄,將被用於同期中mount的目錄
      secret:             #類型為secret的存儲卷,掛載集群與定義的secre對象到容器內部
        scretname: string  
        items:     
        - key: string
          path: string
      configMap:          #類型為configMap的存儲卷,掛載預定義的configMap對象到容器內部
        name: string
        items:
        - key: string
          path: string    
復制代碼

 

 

 

 

 

k8s dns

 


Cluster DNS主要包含如下幾項:

1)SkyDNS 
提供DNS解析服務。 
2)Etcd 
用於DNS的存儲。 
3)Kube2sky 
監聽Kubernetes,當有新的Service創建時,將其注冊到etcd上。 
4)healthz 
提供對skydns服務的健康檢查功能。


在 master服務器上

復制代碼
Cluster DNS在Kubernetes發布包的cluster/addons/dns目錄下

yum -y install wget
wget https://codeload.github.com/kubernetes/kubernetes/tar.gz/v1.2.7
tar zxvf v1.2.7
cd kubernetes-1.2.7/cluster/addons/dns
復制代碼

 

skydns服務使用的clusterIP需要我們指定一個固定的IP地址,每個Node的kubelet進程都將使用這個IP地址,不能通過Kuberneters自動給skydns分配。

通過環境變量,配置參數
export DNS_SERVER_IP="10.254.10.2"
export DNS_DOMAIN="cluster.local"
export DNS_REPLICAS=1

設置 Cluster DNS Service的IP為 10.254.10.2(不能和已分配的IP重復),Cluster DNS的本地域為 cluster.local。

 

修改每台Node上的kubelet啟動參數

vim /etc/kubernetes/kubelet
#在KUBELET_ARGS里增加:
--cluster_dns=10.254.10.2 
--cluster_domain=cluster.local
#中間用空格隔開

 

重啟kubelet服務

systemctl restart kubelet

 

master下

生成dns-rc.yaml和dns-svc.yaml
kubernetes-1.2.7/cluster/addons/dns目錄下。

 

skydns-rc.yaml.in和skydns-svc.yaml.in是兩個模板文件,通過設置的環境變量修改其中的相應屬性值,可以生成Replication Controller和Service的定義文件。

生成Replication Controller的定義文件dns-rc.yaml創建RC

sed -e "s/{{ pillar\['dns_replicas'\] }}/${DNS_REPLICAS}/g;s/{{ pillar\['dns_domain'\] }}/${DNS_DOMAIN}/g" \skydns-rc.yaml.in > dns-rc.yaml

 

查看dns-rc.yaml

復制代碼
apiVersion: v1
kind: ReplicationController
metadata:
  name: kube-dns-v11
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    version: v11
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 1
  selector:
    k8s-app: kube-dns
    version: v11
  template:
    metadata:
      labels:
        k8s-app: kube-dns
        version: v11
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - name: etcd
        image: index.tenxcloud.com/google_containers/etcd-amd64:2.2.1
        resources:
          # TODO: Set memory limits when we've profiled the container for large
          # clusters, then set request = limit to keep this container in
          # guaranteed class. Currently, this container falls into the
          # "burstable" category so the kubelet doesn't backoff from restarting it.
          limits:
            cpu: 100m
            memory: 500Mi
          requests:
            cpu: 100m
            memory: 50Mi
        command:
        - /usr/local/bin/etcd
        - -data-dir
        - /var/etcd/data
        - -listen-client-urls
        - http://127.0.0.1:2379,http://127.0.0.1:4001
        - -advertise-client-urls
        - http://127.0.0.1:2379,http://127.0.0.1:4001
        - -initial-cluster-token
        - skydns-etcd
        volumeMounts:
        - name: etcd-storage
          mountPath: /var/etcd/data
      - name: kube2sky
        image: index.tenxcloud.com/google_containers/kube2sky:1.14
        resources:
          # TODO: Set memory limits when we've profiled the container for large
          # clusters, then set request = limit to keep this container in
          # guaranteed class. Currently, this container falls into the
          # "burstable" category so the kubelet doesn't backoff from restarting it.
          limits:
            cpu: 100m
            # Kube2sky watches all pods.
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 50Mi
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          httpGet:
            path: /readiness
            port: 8081
            scheme: HTTP
          # we poll on pod startup for the Kubernetes master service and
          # only setup the /readiness HTTP server once that's available.
          initialDelaySeconds: 30
          timeoutSeconds: 5
        args:
        # command = "/kube2sky"
        #特別注意
        #- -domain=cluster.local是錯誤的寫法
        #- -kube-master-url=http://192.168.121.143:8080是錯誤的設置
        #會導致CrashLoopBackOff的錯誤
        #如果已經進行CA認證,則可以不指定kube-master-url
        - --domain=cluster.local
        - --kube-master-url=http://192.168.132.148:8080    ##master地址
      - name: skydns
        image: index.tenxcloud.com/google_containers/skydns:2015-10-13-8c72f8c
        resources:
          # TODO: Set memory limits when we've profiled the container for large
          # clusters, then set request = limit to keep this container in
          # guaranteed class. Currently, this container falls into the
          # "burstable" category so the kubelet doesn't backoff from restarting it.
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 50Mi
        args:
        # command = "/skydns"
        - -machines=http://127.0.0.1:4001
        - -addr=0.0.0.0:53
        - -ns-rotate=false
        - -domain=cluster.local.
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
      - name: healthz
        image: index.tenxcloud.com/google_containers/exechealthz:1.0
        resources:
          # keep request = limit to keep this container in guaranteed class
          limits:
            cpu: 10m
            memory: 20Mi
          requests:
            cpu: 10m
            memory: 20Mi
        args:
        - -cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
        - -port=8080
        ports:
        - containerPort: 8080
          protocol: TCP
      volumes:
      - name: etcd-storage
        emptyDir: {}
      dnsPolicy: Default  # Don't use cluster DNS.
復制代碼

需要注意kube2sky需要ServiceAccount來調用Kubernetes API。 
而ServiceAccount的使用需要對Kubernetes集群進行安全認證,否則可能會導致RC無法自動創建Pod等錯誤。

 

通過定義文件dns-rc.yaml創建Cluster DNS Replication Controller

kubectl create -f dns-rc.yaml

 

驗證Cluster DNS Pod是否創建運行成功:

kubectl get pod --namespace=kube-system -o wide

 

生成Service的定義文件dns-svc.yaml創建Service

sed -e "s/{{ pillar\['dns_server'\] }}/${DNS_SERVER_IP}/g" \skydns-svc.yaml.in > dns-svc.yaml

 

dns-svc.yaml

復制代碼
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.254.10.2
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
復制代碼

 

根據dns-svc.yaml創建Cluster DNS Service

kubectl create -f dns-svc.yaml

 

驗證:

kubectl get svc --namespace=kube-system -o wide

創建Pod驗證Cluster DNS

使用一個帶有nslookup的工具來驗證DNS是否能夠正常工作: 
busybox.yaml

復制代碼
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - name: busybox
    image: index.tenxcloud.com/google_containers/busybox
    command:
      - sleep
      - "3600"
復制代碼

 

#kubectl create -f busybox.yaml
#kubectl exec busybox -- nslookup kubernetes.default.svc.cluster.local

 

ok,搭建完成

 

done

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM