k8s部分名稱解釋


k8s部分名詞解釋

NameSpace:命名空間
Namespace是對一組資源和對象的抽象集合,比如可以用來將系統內部的對象划分為不同的項目組或用戶組。常見的pods, services,
replication controllers和deployments等都是屬於某一個namespace的(默認是default),而node,
persistentVolumes等則不屬於任何namespace。

Namespace常用來隔離不同的用戶,比如Kubernetes自帶的服務一般運行在kube-system namespace中。

Namespace操作:

查看命名空間 :

[root@master ~]# kubectl get ns
NAME          STATUS   AGE
default       Active   3d11h
kube-public   Active   3d11h
kube-system   Active   3d11h
## namespace包含兩種狀態”Active”和”Terminating”。在namespace刪除過程中,namespace狀態被設置成”Terminating”。

創建命名空間:

 kubectl create namespace jason-namespace
 查看指定的命名空間
 kubectl get ns  jason-namespace

命名空間名稱滿足正則表達式a-z0-9?,最大長度為63位

刪除命名空間:

kubectl delete namespaces new-namespace
 kubectl delete namespace jason-namespace

刪除一個namespace會自動刪除所有屬於該namespace的資源。

default和kube-system命名空間不可刪除。


Replication Controller(用於保證pod的數量)

Replication Controller 保證了在所有時間內,都有特定數量的Pod副本正在運行,如果太多了,Replication Controller就殺死幾個,如果太少了,Replication Controller會新建幾個。可以這樣理解它,他就是一個pod的管理器,隨時監管着這個pod,讓它始終有那么多個pod在提供服務。

Replication Controller只會對那些RestartPolicy = Always的Pod的生效,(RestartPolicy的默認值就是Always),Replication Controller 不會去管理那些有不同啟動策略pod。

由Replication Controller監控的Pod的數量是是由一個叫 label selector(標簽選擇器)決定的,label
selector在Replication
Controller和被控制的pod創建了一個松散耦合的關系,與pod相比,pod與他們的定義文件關系緊密。

replication controller的任務就是保證預計數量的pod並並保證其可用性

replication controller的任務永遠都只會是單一的。它自身不會進行是否可讀和是否可用的檢測,相比與自動進行縮放和放大,replication controller更傾向與使用外部的自動平衡工具,這些外部工具要作的僅僅是修改replicas的值來實現Pod數量的變化,我們不會增加replicationcontroller的調度策率,也不會讓replication controller來驗證受控的Pod是否符合特定的模版,因為這些都會阻礙自動調整和其它的自動的進程。

常見的使用模式

Rescheduling(重新規划)

​ 也就是說當你的pod掛了或者怎么了,它會重新給你規划以保證有足夠數量的pod在任意時刻都在提供服務。

Scaling(縮放)

​ Replication Controller讓我們更容易的控制pod的副本的數量,不管我們是手動控制還是通過其它的自動管理的工具,最簡單的:修改replicas的值。

這個就是彈性伸縮,當你流量很大的時候,可以增加pod來提供服務,當你流量降下來了可以減少相應的pod數量。

Rolling updates(動態更新)

​ Replication Controller 可以支持動態更新,當我們更新一個服務的時候,它可以允許我們一個一個的替換pod

也就是說不用一下子全部更新,類似於迭代更新。

推薦的方法是創建一個新的只有1個pod副本的Replication Controller,然后新的每次+1,舊的每次-1,直到舊的Replication Controller 的值變成0,然后我們就可以刪除舊的了,這樣就可以規避升級過程中出現的未知錯誤了。

理論上,動態更新控制器應考慮應用的可用性,並確保足夠的pod制成服務在任何時間都能正常提供服務。

兩個 Replication Controller創建的pod至少要由一個不同的標簽,可以是鏡像的標簽,因為一般鏡像的更新都會帶來一個新的更新。

kubectl是實現動態更新的客戶端


ReplicaSet

ReplicaSet是下一代副本控制器。ReplicaSet和 Replication Controller之間的唯一區別是現在的選擇器支持。Replication Controller只支持基於等式的selector(env=dev或environment!=qa),但ReplicaSet還支持新的,基於集合的selector(versionin (v1.0, v2.0)或env notin (dev, qa))。在試用時官方推薦ReplicaSet。

大多數kubectl支持Replication Controller的命令也支持ReplicaSets。rolling-update命令有一個例外 。如果您想要滾動更新功能,請考慮使用Deployments。此外, rolling-update命令是必須的,而Deployments是聲明式的,因此我們建議通過rollout命令使用Deployments。

雖然ReplicaSets可以獨立使用,但是今天它主要被 Deployments 作為協調pod創建,刪除和更新的機制。當您使用Deployments時,您不必擔心管理他們創建的ReplicaSets。Deployments擁有並管理其ReplicaSets。

ReplicaSet可確保指定數量的pod“replicas”在任何設定的時間運行。然而,Deployments是一個更高層次的概念,它管理ReplicaSets,並提供對pod的聲明性更新以及許多其他的功能。因此,我們建議您使用Deployments而不是直接使用ReplicaSets,除非您需要自定義更新編排或根本不需要更新。

這實際上意味着您可能永遠不需要操作ReplicaSet對象:直接使用Deployments並在規范部分定義應用程序。


Node:node節點名詞解釋

Node是Pod真正運行的主機,可以物理機,也可以是虛擬機。為了管理Pod,每個Node節點上至少要運行container runtime(比如docker或者rkt)、kubelet和kube-proxy服務。

Node管理

Node本質上不是Kubernetes來創建的,Kubernetes只是管理Node上的資源。雖然可以通過Manifest創建一個Node對象,但Kubernetes也只是去檢查是否真的是有這么一個Node,如果檢查失敗,也不會往上調度Pod。

這個檢查是由Node Controller來完成的。Node Controller負責

  • 維護Node狀態
  • 與Cloud Provider同步Node
  • 給Node分配容器CIDR
  • 刪除帶有NoExecute taint的Node上的Pods

默認情況下,kubelet在啟動時會向master注冊自己,並創建Node資源。這個注冊的過程就是授權的過程,是需要master授權。

Node的狀態

每個Node都包括以下狀態信息

  • 地址:包括hostname、外網IP和內網IP
  • 條件(Condition):包括OutOfDisk、Ready、MemoryPressure和DiskPressure
  • 容量(Capacity):Node上的可用資源,包括CPU、內存和Pod總數
  • 基本信息(Info):包括內核版本、容器引擎版本、OS類型等

Taints和tolerations

​ Taints和tolerations用於保證Pod不被調度到不合適的Node上,Taint應用於Node上,而toleration則應用於Pod上(Toleration是可選的)。

Node維護模式

​ 標志Node不可調度但不影響其上正在運行的Pod,這種維護Node時是非常有用的

kubectl cordon $NODENAME

Service對象:名詞解釋

Kubernete Service 是一個定義了一組Pod的策略的抽象,我們也有時候叫做宏觀服務。這些被服務標記的Pod都是(一般)通過label Selector決定的。

對於Kubernete原生的應用,Kubernete提供了一個簡單的Endpoints API,這個Endpoints
api的作用就是當一個服務中的pod發生變化時,Endpoints
API隨之變化,對於哪些不是原生的程序,Kubernetes提供了一個基於虛擬IP的網橋的服務,這個服務會將請求轉發到對應的后台pod。

一個Kubernete服務是一個最小的對象,類似pod,和其它的終端對象一樣,我們可以朝paiserver發送請求來創建一個新的實例。

Virtual IPs and service proxies(虛擬IP和服務代理)

每一個節點上都運行了一個kube-proxy,這個應用監控着Kubermaster增加和刪除服務,對於每一個服務,kube-proxy會隨機開啟一個本機端口,任何發向這個端口的請求都會被轉發到一個后台的Pod當中,而如何選擇是哪一個后台的pod的是基於SessionAffinity進行的分配。kube-proxy會增加iptables rules來實現捕捉這個服務的Ip和端口來並重定向到前面提到的端口。

最終的結果就是所有的對於這個服務的請求都會被轉發到后台的Pod中,這一過程用戶根本察覺不到。

默認的,后台的選擇是隨機的,基於用戶session機制的策略可以通過修改service.spec.sessionAffinity 的值從NONE到ClientIP。

也可以實現多端口服務,因為有時候需要開放不同的端口。

也可以在創建服務的時候指定ip地址

我們可以在創建服務的時候指定IP地址,將spec.clusterIP的值設定為我們想要的IP地址即可。例如,我們已經有一個DNS域我們希望用來替換,或者遺留系統只能對指定IP提供服務,並且這些都非常難修改,用戶選擇的IP地址必須是一個有效的IP地址,並且要在API
server分配的IP范圍內,如果這個IP地址是不可用的,apiserver會返回422http錯誤代碼來告知是IP地址不可用

服務的發現

Kubernetes 支持兩種方式的來發現服務 ,環境變量和 DNS。

環境變量

當一個Pod在一個node上運行時,kubelet 會針對運行的服務增加一系列的環境變量,它支持Docker links compatible 和普通環境變量。

使用環境變量是需要注意的是:對系統有一個要求:所有的想要被POD訪問的服務,必須在POD創建之前創建,否則這個環境變量不會被填充,使用DNS則沒有這個問題。

DNS

一個可選擇的雲平台插件就是DNS,DNS 服務器監控着API SERVER ,當有服務被創建的時候,DNS 服務器會為之創建相應的記錄,如果DNS這個服務被添加了,那么Pod應該是可以自動解析服務的。

舉個例子來說:如果我們在my-ns命名空間下有一個服務叫做“my-service”,這個時候DNS就會創建一個my-service.my-ns的記錄,所有my-ns命名空間下的Pod,都可以通過域名my-service查詢找到對應的ip地址,不同命名空間下的Pod在查找是必須使用my-sesrvice.my-ns才可以。

Kubernete 同樣支持端口的解析,如果my-service有一個提供http的TCP主持的端口,那么我們可以通過查詢“_http._tcp.my-service.my-ns”來查詢這個端口。

External services(外部服務)

​ 對於我們的應用程序來說,我們可能有一部分是放在Kubernete外部的(比如我們有單獨的物理機來承擔數據庫的角色),Kubernetes支持兩種方式:NodePorts,LoadBalancers。

每一個服務都會有一個字段定義了該服務如何被調用(發現),這個字段的值可以為:

  • ClusterIP:使用一個集群固定IP,這個是默認選項
  • NodePort:使用一個集群固定IP,但是額外在每個POD上均暴露這個服務,端口
  • LoadBalancer:使用集群固定IP,和NODEPord,額外還會申請申請一個負載均衡器來轉發到服務(load balancer )

注意:NodePort 支持TCP和UDN,但是LoadBalancers在1.0版本只支持TCP。

Type NodePort

如果你選擇了“NodePort”,那么 Kubernetes master 會分配一個區域范圍內,(默認是30000-32767),並且,每一個node,都會代理(proxy)這個端口到你的服務中,我們可以在spec.ports[*].nodePort 找到具體的值

如果我們向指定一個端口,我們可以直接寫在nodePort上,系統就會給你指派指定端口,但是這個值必須是指定范圍內的。這樣的話就能夠讓開發者搭配自己的負載均衡器,去撘建一個kubernete不是完全支持的系統,又或者是直接暴露一個node的ip地址。

Type LoadBalancer

在支持額外的負載均衡器的的平台上,將值設置為LoadBalancer會提供一個負載均衡器給你的服務,負載均衡器的創建其實是異步的。所有服務的請求均會直接到Pod,具體是如何工作的是由平台決定的。

LoadBalancers 只支持TCP,不支持UDP。


Volume數據卷

Docker有一個Volumes的概念,雖然這個Volume有點寬松和管理性比較小。在Docker中,一個 Volume 是一個簡單的所在主機的一個目錄或者其它容器中的。生命周期是沒有辦法管理,直到最近才有 local-disk-backed 磁盤。Docker現在提供了磁盤驅動,但是功能非常有限(例如Docker1.7只能掛在一個磁盤每個容器,並且無法傳遞參數)

從另外一個方面講,一個Kubernetes volume,擁有明確的生命周期,與所在的Pod的生命周期相同。因此,Kubernetes volume獨立與任何容器,與Pod相關,所以數據在重啟的過程中還會保留,當然,如果這個Pod被刪除了,那么這些數據也會被刪除。更重要的是,Kubernetes volume 支持多種類型,任何容器都可以使用多個Kubernetes volume。

它的核心,一個 volume 就是一個目錄,可能包含一些數據,這些數據對pod中的所有容器都是可用的,這個目錄怎么使用,什么類型,由什么組成都是由特殊的volume 類型決定的。想要使用一個volume,Pod必須指明Pod提供了那些磁盤,並且說明如何掛在到容器中。

Kubernete 支持如下類型的volume:

emptyDir,hostPath,gcePersistentDisk,awsElasticBlockStore,nfs, iscsi, glusterfs, rbd, gitRepo,secret,persistentVolumeClaim

emptyDir

一個emptyDir
第一次創建是在一個pod被指定到具體node的時候,並且會一直存在在pod的生命周期當中,正如它的名字一樣,它初始化是一個空的目錄,pod中的容器都可以讀寫這個目錄,這個目錄可以被掛在到各個容器相同或者不相同的的路徑下。當一個pod因為任何原因被移除的時候,這些數據會被永久刪除。注意:一個容器崩潰了不會導致數據的丟失,因為容器的崩潰並不移除pod.

emptyDir 磁盤的作用:

  • 普通空間,基於磁盤的數據存儲
  • 作為從崩潰中恢復的備份點
  • 存儲那些那些需要長久保存的數據,例web服務中的數據

默認的,emptyDir 磁盤會存儲在主機所使用的媒介上,可能是SSD,或者網絡硬盤,這主要取決於你的環境。當然,我們也可以將emptyDir.medium的值設置為Memory來告訴Kubernetes 來掛在一個基於內存的目錄tmpfs,因為tmpfs速度會比硬盤快了,但是,當主機重啟的時候所有的數據都會丟失。


Deployment名詞解析

Deployment為Pod和ReplicaSet提供了一個聲明式定義(declarative)方法,用來替代以前的ReplicationController來方便的管理應用。典型的應用場景包括:

  • 定義Deployment來創建Pod和ReplicaSet
  • 滾動升級和回滾應用
  • 擴容和縮容
  • 暫停和繼續Deployment

例如一個簡單的nginx:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

自動擴容和縮容擴容:

kubectl scale deployment nginx-deployment --replicas 10

如果集群支持 horizontal pod autoscaling 的話,還可以為Deployment設置自動擴展:

kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80

更新鏡像

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
//也可以直接使用edit進行編輯
kubectl edit deployment/nginx-deployment 

回滾

kubectl rollout undo deployment/nginx-deployment

Deployment為Pod和Replica Set(下一代Replication Controller)提供聲明式更新。

它會自動的去給你創建pod和副本數,讓任何時候都有足夠的副本在提供服務。

//查看rs狀態,rs的名稱總是deployment的名稱+hash值
kubectl get rs 
//查看pod
kubectl get pods

Secret名詞解析

Secret解決了密碼、token、密鑰等敏感數據的配置問題,而不需要把這些敏感數據暴露到鏡像或者Pod Spec中。Secret可以以Volume或者環境變量的方式使用。

Secret有三種類型:

  • Service Account:用來訪問Kubernetes API,由Kubernetes自動創建,並且會自動掛載到Pod的/run/secrets/kubernetes.io/serviceaccount目錄中;
  • Opaque:base64編碼格式的Secret,用來存儲密碼、密鑰等;
  • kubernetes.io/dockerconfigjson:用來存儲私有docker registry的認證信息。

Opaque Secret

Opaque類型的數據是一個map類型,要求value是base64編碼格式:

$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "1f2d1e2e67df" | base64
MWYyZDFlMmU2N2Rm

secret.yaml

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

然后進行創建kubectl create -f secrets.yml

使用secret有兩種方式:

  • 以Volume方式
  • 以環境變量方式

第一種使用Volume掛載的方式:

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: db
  name: db
spec:
  volumes:
  - name: secrets
    secret:
      secretName: mysecret
  containers:
  - image: gcr.io/my_project_id/pg:v1
    name: db
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
    ports:
    - name: cp
      containerPort: 5432
      hostPort: 5432

將Secret導出到環境變量中

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: wordpress-deployment
spec:
  replicas: 2
  strategy:
      type: RollingUpdate
  template:
    metadata:
      labels:
        app: wordpress
        visualize: "true"
    spec:
      containers:
      - name: "wordpress"
        image: "wordpress"
        ports:
        - containerPort: 80
        env:
        - name: WORDPRESS_DB_USER
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password

其他的兩個都沒有怎么用,而且都是k8s自動創建的,所以這兒就不用再去創建了,對於那些比較私密的數據也就是密碼用戶名和賬號等信息,這個時候可以使用secret來進行管理,可以是volume掛載到數據卷,也可以是以變量的形式進行引用。

其他參見:https://www.kubernetes.org.cn/secret


StatefulSet名詞解析

StatefulSet是為了解決有狀態服務的問題(對應Deployments和ReplicaSets是為無狀態服務而設計),其應用場景包括

  • 穩定的持久化存儲,即Pod重新調度后還是能訪問到相同的持久化數據,基於PVC來實現

  • 穩定的網絡標志,即Pod重新調度后其PodName和HostName不變,基於Headless Service(即沒有Cluster IP的Service)來實現

  • 有序部署,有序擴展,即Pod是有順序的,在部署或者擴展的時候要依據定義的順序依次依次進行(即從0到N-1,在下一個Pod運行之前所有之前的Pod必須都是Running和Ready狀態),基於init containers來實現

  • 有序收縮,有序刪除(即從N-1到0)

從上面的應用場景可以發現,StatefulSet由以下幾個部分組成:

  • 用於定義網絡標志(DNS domain)的Headless Service
  • 用於創建PersistentVolumes的volumeClaimTemplates
  • 定義具體應用的StatefulSet

StatefulSet中每個Pod的DNS格式為statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中

  • serviceName為Headless Service的名字
  • 0..N-1為Pod所在的序號,從0開始到N-1
  • statefulSetName為StatefulSet的名字
  • namespace為服務所在的namespace,Headless Servic和StatefulSet必須在相同的namespace
  • .cluster.local為Cluster Domain,

簡單的一個web.yaml示例

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: gcr.io/google_containers/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
      annotations:
        volume.alpha.kubernetes.io/storage-class: anything
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
#根據文件進行創建服務
$ kubectl create -f web.yaml
service "nginx" created
statefulset "web" created

# 查看創建的headless service和statefulset
$ kubectl get service nginx
NAME      CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx     None         <none>        80/TCP    1m
$ kubectl get statefulset web
NAME      DESIRED   CURRENT   AGE
web       2         2         2m

# 根據volumeClaimTemplates自動創建PVC(在GCE中會自動創建kubernetes.io/gce-pd類型的volume)
$ kubectl get pvc
NAME        STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE
www-web-0   Bound     pvc-d064a004-d8d4-11e6-b521-42010a800002   1Gi        RWO           16s
www-web-1   Bound     pvc-d06a3946-d8d4-11e6-b521-42010a800002   1Gi        RWO           16s

# 查看創建的Pod,他們都是有序的
$ kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          5m
web-1     1/1       Running   0          4m

# 使用nslookup查看這些Pod的DNS
$ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
/ # nslookup web-0.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 10.244.2.10
/ # nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-1.nginx
Address 1: 10.244.3.12
/ # nslookup web-0.nginx.default.svc.cluster.local
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx.default.svc.cluster.local
Address 1: 10.244.2.10

其他操作,擴容縮容,更新鏡像刪除等操作

# 擴容
$ kubectl scale statefulset web --replicas=5

# 縮容
$ kubectl patch statefulset web -p '{"spec":{"replicas":3}}'

# 鏡像更新(目前還不支持直接更新image,需要patch來間接實現)
$ kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.7"}]'

# 刪除StatefulSet和Headless Service
$ kubectl delete statefulset web
$ kubectl delete service nginx

# StatefulSet刪除后PVC還會保留着,數據不再使用的話也需要刪除
$ kubectl delete pvc www-web-0 www-web-1


DaemonSet

DaemonSet保證在每個Node上都運行一個容器副本,常用來部署一些集群的日志、監控或者其他系統管理應用。典型的應用包括:

  • 日志收集,比如fluentd,logstash等
  • 系統監控,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等
  • 系統程序,比如kube-proxy, kube-dns, glusterd, ceph等

指定Node節點

DaemonSet會忽略Node的unschedulable狀態,有兩種方式來指定Pod只運行在指定的Node節點上:

  • nodeSelector:只調度到匹配指定label的Node上
  • nodeAffinity:功能更豐富的Node選擇器,比如支持集合操作
  • podAffinity:調度到滿足條件的Pod所在的Node上

nodeSelector示例

給node打標簽

kubectl label nodes node-01 disktype=ssd

然后指定在daemonset中指定標簽
spec:
  nodeSelector:
    disktype: ssd

nodeAffinity示例

nodeAffinity目前支持兩種:requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution,分別代表必須滿足條件和優選條件。比如下面的例子代表調度到包含標簽kubernetes.io/e2e-az-name並且值為e2e-az1或e2e-az2的Node上,並且優選還帶有標簽another-node-label-key=another-node-label-value的Node。

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: gcr.io/google_containers/pause:2.0

podAffinity示例

podAffinity基於Pod的標簽來選擇Node,僅調度到滿足條件Pod所在的Node上,支持podAffinity和podAntiAffinity。這個功能比較繞,以下面的例子為例:

  • 如果一個“Node所在Zone中包含至少一個帶有security=S1標簽且運行中的Pod”,那么可以調度到該Node
  • 不調度到“包含至少一個帶有security=S2標簽且運行中Pod”的Node上
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: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0

靜態Pod

除了DaemonSet,還可以使用靜態Pod來在每台機器上運行指定的Pod,這需要kubelet在啟動的時候指定manifest目錄:

kubelet --pod-manifest-path=/etc/kubernetes/manifests

然后將所需要的Pod定義文件放到指定的manifest目錄中。

注意:靜態Pod不能通過API Server來刪除,但可以通過刪除manifest文件來自動刪除對應的Pod。


Ingress名詞解析

​ 通常情況下,service和pod的IP僅可在集群內部訪問。集群外部的請求需要通過負載均衡轉發到service在Node上暴露的NodePort上,然后再由kube-proxy將其轉發給相關的Pod。

而Ingress就是為進入集群的請求提供路由規則的集合。

Ingress可以給service提供集群外部訪問的URL、負載均衡、SSL終止、HTTP路由等。為了配置這些Ingress規則,集群管理員需要部署一個Ingress controller,它監聽Ingress和service的變化,並根據規則配置負載均衡並提供訪問入口。

例如

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        backend:
          serviceName: test
          servicePort: 80

每個Ingress都需要配置rules,目前Kubernetes僅支持http規則。上面的示例表示請求/testpath時轉發到服務test的80端口。

ingress的分類:

單服務ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  backend:
    serviceName: testsvc
    servicePort: 80

單個服務還可以通過設置Service.Type=NodePort或者Service.Type=LoadBalancer來對外暴露。

路由到多服務的Ingress

路由到多服務的Ingress即根據請求路徑的不同轉發到不同的后端服務上。例如下面的ingress配置

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: s1
          servicePort: 80
      - path: /bar
        backend:
          serviceName: s2
          servicePort: 80

ConfigMap

ConfigMap用於保存配置數據的鍵值對,可以用來保存單個屬性,也可以用來保存配置文件。ConfigMap跟secret很類似,但它可以更方便地處理不包含敏感信息的字符串。

configMap的創建

可以使用kubectl create configmap從文件、目錄或者key-value字符串創建等創建ConfigMap。

# 從key-value字符串創建ConfigMap
$ kubectl create configmap special-config --from-literal=special.how=very
configmap "special-config" created
$ kubectl get configmap special-config -o go-template='{{.data}}'
map[special.how:very]

# 從env文件創建
$ echo -e "a=b\nc=d" | tee config.env
a=b
c=d
$ kubectl create configmap special-config --from-env-file=config.env
configmap "special-config" created
$ kubectl get configmap special-config -o go-template='{{.data}}'
map[a:b c:d]

# 從目錄創建
$ mkdir config
$ echo a>config/a
$ echo b>config/b
$ kubectl create configmap special-config --from-file=config/
configmap "special-config" created
$ kubectl get configmap special-config -o go-template='{{.data}}'
map[a:a
 b:b
]

configMap的使用

ConfigMap可以通過多種方式在Pod中使用,比如設置環境變量、設置容器命令行參數、在Volume中創建配置文件等。

需要注意的是:

  • ConfigMap必須在Pod引用它之前創建
  • 使用envFrom時,將會自動忽略無效的鍵
  • Pod只能使用同一個命名空間內的ConfigMap

用作環境變量時

 //先創建configmap
 kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
kubectl create configmap env-config --from-literal=log_level=INFO

然后以環境變量形式引用

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.type
      envFrom:
        - configMapRef:
            name: env-config
  restartPolicy: Never

當pod運行結束后輸出

SPECIAL_LEVEL_KEY=very
SPECIAL_TYPE_KEY=charm
log_level=INFO

用作命令行參數

將ConfigMap用作命令行參數時,需要先把ConfigMap的數據保存在環境變量中,然后通過$(VAR_NAME)的方式引用環境變量。

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

當pod結束后輸出

very charm

使用volume將ConfigMap作為文件或目錄直接掛載

將創建的ConfigMap直接掛載至Pod的/etc/config目錄下,其中每一個key-value鍵值對都會生成一個文件,key為文件名,value為內容。

apiVersion: v1
kind: Pod
metadata:
  name: vol-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

當Pod結束后會輸出

very

將創建的ConfigMap中special.how這個key掛載到/etc/config目錄下的一個相對路徑/keys/special.level。如果存在同名文件,直接覆蓋。其他的key不掛載。

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh","-c","cat /etc/config/keys/special.level" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: special.how
          path: keys/special.level
  restartPolicy: Never

因為這個和以上的那個存在了相同的文件special.how所以會覆蓋,而其他key則不會再進行掛載。

所以輸出還是very。


免責聲明!

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



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