Kubernetes 是一個跨主機集羣的 開源的容器調度平臺,它能夠自動化應用容器的部署、擴展和操做 , 提供以容器爲中心的基礎架構。(官方文檔第一行)node
每一個微服務都是獨立的進程,經過定義好的接口(restful api ,amqp)互相調用mysql
- 不一樣服務依賴庫致使的混亂,須要將每一個服務獨立開(經過docker改善)
- 服務註冊,服務發現:須要動態的更新當前服務。
- 服務編排(即docker容器的編排,docker自身很難解決集羣部署的問題):哪些服務須要在哪些宿主機上啓動
- Docker Swarm
- Mesos + marathon
- Kubernetes
- master 能夠簡單的理解爲控制中心
- etcd:分佈式k-v數據庫,根據配置選擇是cp仍是ap, k8s只有api server 和etcd通信, 其餘組件均和api server 通信
- api server:能夠理解爲etcd的前置過濾器,換一個視角,它和etcd相似於mysql和文件系統。
- controller manager: 核心,負責將如今的狀態調整爲etcd上應該的狀態,包含了全部的實現邏輯
- scheduler: 簡單點說就是給一個pod找一個node。
- slave 能夠簡單的理解爲worker
- kubelet: 負責和master鏈接,註冊node, listen-watch 本node的任務等
- kube-proxy: 用於k8s service對象,以後介紹。
- 容器運行時: 除了docker k8s還支持 rkt等容器實現
- add-on 一些k8s不提供的功能,須要插件實現
- DNS(服務註冊發現)
- CNI(容器網絡接口實現, ex:fannel)
k8s集羣的運行時的大體結構 redis
multiple containers run together說的就是podsql
- pods是k8s管理的最小對象,是一組共享uts, network, ipc namespace的容器(也支持共享pid,默認不開啓)
- 每一個pod 會有一個 infrastructure 容器,volumne, network其實都是共用的這個容器的network和volumne
- pod使邏輯上緊密相關的進程適當的隔離,保持必定的相關:
- 一些進程必須在相同而主機上運行
- 擴容須要保持一致
- 等等
實例配置文件docker
[lukou@khand ~]$ kubectl get po redis-master-jvxld -o yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/created-by: | {"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicationController","namespace":"default","name":"redis-master","uid":"61a3a1c6-43a9-11e9-9f58-00163f007932","apiVersion":"v1","resourceVersion":"510225"}} creationTimestamp: 2019-03-11T02:57:17Z
generateName: redis-master-
labels:
name: redis-master
name: redis-master-jvxld
namespace: default
ownerReferences:
- apiVersion: v1
controller: true
kind: ReplicationController
name: redis-master
uid: 61a3a1c6-43a9-11e9-9f58-00163f007932
resourceVersion: "510247"
selfLink: /api/v1/namespaces/default/pods/redis-master-jvxld
uid: 61a49472-43a9-11e9-9f58-00163f007932
spec:
containers:
- image: kubeguide/redis-master
imagePullPolicy: Always
name: master
ports:
- containerPort: 6379
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: default-token-m6g3l
readOnly: true
livenessProbe:
httpGet:
path: /
port: 8080
dnsPolicy: ClusterFirst
nodeName: 127.0.0.1
restartPolicy: Always
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
volumes:
- name: default-token-m6g3l
secret:
defaultMode: 420
secretName: default-token-m6g3l
複製代碼
- 確保pod健康
- 肯定並動態調整pod 在集羣中中運行的數量,並在pod失敗後從新調度新的pod啓動
- 相似crontab,進行一些定時任務
除了rc, rs以外,還有deamonSet, job, cronjob等controller數據庫
實例配置文件api
apiVersion: v1
kind: ReplicationController
metadata:
name: kubia
spec:
replicas: 3
selector:
app: kubia
template:
metadata:
labels:
app: kubia
spec:
containers:
- name: kubia
image: luksa/kubia
ports:
- containerPort: 8080
複製代碼
rc管理pods,可是pods並非經過rc啓動的, rc將pods的配置文件同步給api server, Scheduler分配node, Kubelet跑node.bash
- pod是非持久的,會不斷的重啓,致使pod的ip是隨時變化的,同時pod的數量會是動態變化的,客戶端很難和pod直接通信,service是用來解決這一問題的
- service 爲提供同一服務的pods 提供了統一的入口
- service 的生命週期內其綁定ip是不會變化的
實例配置文件restful
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
name: redis-master
spec:
ports:
- port: 6379
targetPort: 6379
selector:
name: redis-master
複製代碼
[lukou@khand ~]$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 26d
redis-master 10.254.61.141 <none> 6379/TCP 21d
複製代碼
經過環境變量或者DNS 能夠查詢service 的ip和端口網絡
- 新建的pod會將全部的已經建立service的 ip和port存入環境變量
[lukou@khand ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-master-jvxld 1/1 Running 0 21d
[lukou@khand ~]$ kubectl exec redis-master-jvxld env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=redis-master-jvxld
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.254.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.254.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.254.0.1
KUBERNETES_SERVICE_HOST=10.254.0.1
KUBERNETES_SERVICE_PORT=443
HOME=/root
[lukou@khand ~]$ kubectl delete po --all
pod "redis-master-jvxld" deleted
[lukou@khand ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-master-b7mkh 0/1 ContainerCreating 0 6s
[lukou@khand ~]$ ^C
[lukou@khand ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-master-b7mkh 1/1 Running 0 1m
[lukou@khand ~]$ kubectl exec redis-master-b7mkh env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=redis-master-b7mkh
KUBERNETES_PORT=tcp://10.254.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.254.0.1:443
KUBERNETES_PORT_443_TCP_ADDR=10.254.0.1
REDIS_MASTER_SERVICE_PORT=6379
KUBERNETES_SERVICE_PORT=443
REDIS_MASTER_PORT_6379_TCP_PORT=6379
KUBERNETES_SERVICE_HOST=10.254.0.1
REDIS_MASTER_SERVICE_HOST=10.254.61.141
REDIS_MASTER_PORT=tcp://10.254.61.141:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.254.61.141:6379
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_PORT=443
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_ADDR=10.254.61.141
HOME=/root
複製代碼
- 經過dns服務,註冊cluster域名,相似
redis-master.default
以前建立的service只有一個集羣內的固定ip
[lukou@khand ~]$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 26d
redis-master 10.254.61.141 <none> 6379/TCP 21d
複製代碼
若是須要在集羣外訪問有三種方法
- 默認的service 的類型是 'ClusterIP',修改成NodePort便可
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
name: redis-master
spec:
type: NodePort
ports:
- port: 6379
targetPort: 6379
nodePort: 30123 // The range of valid ports is 30000-32767
selector:
name: redis-master
複製代碼
[lukou@khand ~]$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 26d
redis-master 10.254.61.141 <nodes> 6379:30123/TCP 21d
複製代碼
- 建立一個loadbalance
- 建立Ingress resource
- 簡單地說deployment是rc的上一層,用來管理rc的
- 主要功能是管理pod運行的版本
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: kubia
spec:
replicas: 3
template:
metadata:
name: kubia
labels:
app: kubia
spec:
containers:
- image: luksa/kubia:v1
name: nodejs
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
複製代碼
升級的cmd kubectl set image deployment kubia nodejs=luksa/kubia:v2
大體實現的邏輯是,deployment不斷的下降舊版本rc的 replicas, 增長新版本的replicas
就像rc並非直接控制pod同樣,deployment也是相似,deployment聲明式的通知api server 須要升級後的結果,具體升級的邏輯由development controller去處理