Master/nodehtml
Master核心組件: API server,Scheduler,Controller-Manager etcd(存儲組件)node
Node核心組件: kubelet(核心組件), docke(容器引擎(支持的引擎不止docker一個)), kube-proxylinux
Pod Label, label selectornginx
Label: key=valuegit
Label Selector:github
Pod:golang
自主式Podweb
控制器管理的Podredis
ReplictionController(老版本控制器)docker
ReplicaSet(新版本控制器)
Deployment #經過控制replicaset來控制pod,最應該掌握的控制器之一
StatefuSet
Job,Ctonjob
AddOns: 附加組件
環境準備:、
Master, etcd: 172.18.0.70
Node1: 172.18.0.67
Node2: 172.18.0.68
前提:
OS: Centos 7.3.1611 Rxtras倉庫中
安裝配置步驟:
Kubernetes-master
啓動的服務:
Kube-apiserver, kube-scheduler, kube-controller-manager
Kubernetes-node
先設定啓動docker服務
啓動的k8s的服務
Kube-proxy, kubelet
補充知識:harbor 鏡像倉庫
參考 http://www.javashuo.com/article/p-vmfddcqg-mg.html
k8s
先準備兩臺機器:
172.18.0.70 master #
172.18.0.67 node1
172.18.0.68 node2
注意: 必定要作好時間同步 要否則會有一大推莫名其妙的報錯
而後兩臺機器都要配置docker和k8s的yum源
#docker18.09版本和k8s1.15.3版本
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
直接都使用阿里的鏡像源
[root@master ~]# yum list docker-ce --showduplicates | sort -r
#若是對版本有要求可使用這個查看 18.09,安裝對應的包
全部機器都安裝
[root@master ~]# yum install docker-ce-18.09.3-3.el7
yum -y install kubelet kubeadm kubectl(api命令行工具)
而後準備啓動docker,在啓動docker以前建議先定義一個環境變量 隨便另起一行寫
[root@master ~]# vim /usr/lib/systemd/system/docker.service
Environment="HTTPS_PROXY=http://www.ik8s.io:10080""
#意思是咱們訪問docker服務的時候經過代理下載相關的鏡像文件
Environment="NO_PROXY=127.0.0.8,172.18.0.0/16" #不用代理 本機
:wq
docker國內加速
mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://lvb4p7mn.mirror.aliyuncs.com"]
}
上面這個貌似不太好用,
#!/bin/bash
# download k8s 1.15.3 images
# get image-list by 'kubeadm config images list --kubernetes-version=v1.15.3'
# gcr.azk8s.cn/google-containers == k8s.gcr.io
images=(
kube-apiserver:v1.15.3
kube-controller-manager:v1.15.3
kube-scheduler:v1.15.3
kube-proxy:v1.15.3
pause:3.1
etcd:3.3.10
coredns:1.3.1
)
for imageName in ${images[@]};do
docker pull gcr.azk8s.cn/google-containers/$imageName
docker tag gcr.azk8s.cn/google-containers/$imageName k8s.gcr.io/$imageName
docker rmi gcr.azk8s.cn/google-containers/$imageName
Done
#使用此腳本能夠避免由於鏡像源的問題!!!很是重要!!!
加載環境變量
[root@master ~]# systemctl daemon-reload
啓動docker並使用docker info 查看
[root@master ~]# systemctl start docker && docker info
[root@master ~]#
#默認是1就不用改
[root@master ~]# rpm -ql kubelet
/etc/kubernetes/manifests #清單目錄
/etc/sysconfig/kubelet #配置文件
/usr/bin/kubelet
/usr/lib/systemd/system/kubelet.service
[root@master ~]# systemctl enable kubelet.service #設置成開機自啓動就能夠了
[root@master ~]# systemctl enable docker
[root@master ~]# kubelet init --help
#準備初始化
要把swap交換分區關了!!!!!!!!
初始化:
[root@master ~]# kubeadm init --kubernetes-version=v1.15.3 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12
##ps: 若是由於鏡像問題可使用上面的腳本執行,直接拉取鏡像
成功以後會有如下幾條命令,執行一下 注意必定不要忘記執行!!
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
初始化完成以後會有一段token哈希值,加入集羣用的很是重要,能夠把他先保存下來,以下:
kubeadm join 172.18.0.70:6443 --token nsezuu.f8xhql0lmz262tqv \
--discovery-token-ca-cert-hash sha256:c98f345addbb9a585d1e9edf3f584c9dcee4dbb847a63392dc2ba444e77ec0a7
[root@master ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/kube-proxy v1.15.3 232b5c793146 8 days ago 82.4MB
k8s.gcr.io/kube-apiserver v1.15.3 5eb2d3fc7a44 8 days ago 207MB
k8s.gcr.io/kube-controller-manager v1.15.3 e77c31de5547 8 days ago 159MB
k8s.gcr.io/kube-scheduler v1.15.3 703f9c69a5d5 8 days ago 81.1MB
k8s.gcr.io/coredns 1.3.1 eb516548c180 7 months ago 40.3MB
k8s.gcr.io/etcd 3.3.10 2c4adeb21b4f 9 months ago 258MB
k8s.gcr.io/pause 3.1 da86e6ba6ca1 20 months ago
成功以後在node1和node2上面都安裝—
[root@node1 ~]# yum install docker-ce-18.09.7-3.el7 kubectl.x86_64 kubelet.x86_64 kubeadm.x86_64
[root@node2 ~]# yum install docker-ce-18.09.7-3.el7 kubectl.x86_64 kubelet.x86_64 kubeadm.x86_64
swap沒關的話就忽略swap參數
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
KUBE_PROXY_MODE=ipvs
[root@master ~]# kubectl get cs #查看組件信息
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady master 32m v1.15.3
#這裏的狀態信息顯示還未準備好是由於缺乏一個重要組件flannel
在git上查找flannel獲取如下命令:
[root@master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#這是一個在線的部署清單,基於此清單下載鏡像flannel
[root@master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 41m v1.15.3
#如今就已經準備好了
[root@master ~]# kubectl get ns #查看名稱空間
NAME STATUS AGE
default Active 43m
kube-node-lease Active 43m
kube-public Active 43m
kube-system Active 43m
把master的配置文件分別拷給node1和node2
[root@master ~] scp /usr/lib/systemd/system/docker.service node1:/usr/lib/systemd/system/docker.service
[root@master ~]# scp /usr/lib/systemd/system/docker.service node2:/usr/lib/systemd/system/docker.service
[root@master ~]# scp /etc/sysconfig/kubelet node1:/etc/sysconfig/kubelet
[root@master ~]# scp /etc/sysconfig/kubelet node2:/etc/sysconfig/kubelet
分別在node1和node2上面啓動docker並設置成開啓自啓
[root@node1 ~]# systemctl start docker #啓動docker
[root@node1 ~]# systemctl enable docker.service kubelet.service #設置成開啓自啓
[root@node2 ~]# systemctl start docker #啓動docker
[root@node2 ~]# systemctl enable docker.service kubelet.service #設置成開啓自啓
[root@node1 ~]# kubeadm join 172.18.0.70:6443 --token k0q4vt.2ok77anvdhzip6s8 --discovery-token-ca-cert-hash sha256:77b7364b7fc2c886aa889488d3c06d6c1f3a8a1cfc48a8857354afa749c37630 --ignore-preflight-errors=Swap
[root@node2 ~]# kubeadm join 172.18.0.70:6443 --token k0q4vt.2ok77anvdhzip6s8 --discovery-token-ca-cert-hash sha256:77b7364b7fc2c886aa889488d3c06d6c1f3a8a1cfc48a8857354afa749c37630 --ignore-preflight-errors=Swap
#加入集羣
----------------------------------------------------------------------------------------------------------
[root@master ~]# kubectl describe node master #查看節點的詳細信息,比較經常使用
[root@master ~]# kubectl cluster-info #查看集羣信息
使用k8s進行增刪改查
測試:
[root@master ~]# kubectl run nginx-ceshi --image=nginx --port=80 --replicas=1
#啓動一個nginx pod
[root@master ~]# kubectl get pod #查看pod
NAME READY STATUS RESTARTS AGE
nginx-ceshi-748587595b-975t7 0/1 ContainerCreating 0 8s
[root@master ~]# kubectl get svc #查看服務
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 93m
myapp ClusterIP 10.97.57.166 <none> 80/TCP 22s
nginx ClusterIP 10.108.78.248 <none> 80/TCP 72m
[root@master ~]# kubectl scale --replicas=5 deployment myapp
#擴容副本,後面數值多少就是幾個副本
[root@master ~]# kubectl run client1 --image=busybox --replicas=1 -it --restart=Never
#加一個-it表示建立完直接以交互式方式進去,建立一個客戶端進行測試
/ # wget -O - -q 10.244.1.5/hostname.html #查看是從哪一個節點上運行的
myapp-84cd4b7f95-mj6k6
[root@master ~]# kubectl describe deployment nginx-ceshi
#查看選擇器詳細信息
[root@master ~]# kubectl get deployment -w
#-w實時查看
[root@master ~]# kubectl set image deployment myapp myapp=ikubernetes/myapp:v2
deployment.extensions/myapp image updated
#使用set image進行版本升級
[root@master ~]# kubectl rollout undo deployment myapp
#使用rollout out進行回滾版本
[root@master ~]# kubectl edit svc myapp
##修改svc內容
27: type: NodePort
#大約27行,吧他修改成NodePort,就可使用外網訪問了,大小寫不能錯!
[root@master ~]# kubectl get svc #修改完以後使用get svc查看就會發現多一個端口
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 155m
myapp NodePort 10.97.57.166 <none> 80:30257/TCP 62m
刪除node節點:
一共分兩步:
1.排幹此節點
kubectl drain 節點名稱 --delete-local-data --force --ignore-daemonsets
2.刪除此節點
kubectl delete node 節點名稱
Yaml:
具體能夠參考:http://www.javashuo.com/article/p-qnwgsgur-cg.html
建立資源的方法:
apiserver僅接受JSON格式的資源定義;
yaml格式提供配置清單,apiserver可自動 將其轉化爲JSON格式,然後再提交。
大部分資源的配置清單:
[root@master ~]# kubectl explain pod #查看字段,至關於一個幫助
[root@master ~]# kubectl explain pods.status
##查看字段的詳細幫助
apiversion: group/version
kind: 資源類別
metadata: 元數據
name
namespace
Latels
Annotations
每一個資源的引用PATH
/api/GROUP/VERSION/namespeaces/NAMESPEACE/TYPE/NAME
Sepc: 指望的狀態
Status: 當前狀態,current state, 這五個一級字段由kubernetes集羣維護;
下面是建立了一個pod裏面有兩個容器:格式注意下 yaml文件
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
- name: busybox
image: busybox:latest
command:
- "/bin/sh"
- "-c"
- "echo $(date) >> /usr/share/nginx/html/index.html; sleep 5"
[root@master yamls]# kubectl create -f pod-damo.yaml
#根據清單建立pod
[root@master yamls]# kubectl delete -f pod-damo.yaml
[root@master yamls]# kubectl delete pods pod-demo
#刪除pod
標籤:
Key=value 鍵名和鍵值都必須小於63個字符
Key只能使用: 字母 數字 下劃線 點號 , 只能使用字母或數字開頭
Value 能夠爲空,鍵值不能爲空,只能以字母或數字開頭及結尾,之間可以使用
[root@master yamls]# kubectl get pod -l app #-l標籤過濾
[root@master yamls]# kubectl label pods pod-demo release=ccc ##打標籤
[root@master yamls]# kubectl get pods -l app --show-labels #查看
節點選擇器:
nodeSelector: yaml參數指定在哪一個標籤的node上運行,和containers平行
KEY=VALUE
NodeName :
標識:
annotations: #與label不一樣的地方在於,它不能用於挑選資源對象,僅用於爲對象提供「元數據」,,寫在metadata裏面,以下
使用kubectl describe pods pod名字 查看
----------------------------------------------------------------------------------------------------------
Pod的生命週期:
狀態: Pending(掛起), Running,Failed,Succeeded,Unknown
探針:
探針是由kubelet對容器執行的按期診斷,要執行診斷,kubelet調用由容器實現的Handler,有三種類型的探針:
探測方式:
LivenessProbe(存活探測): 指示器是否正在運行。若是存活探測失效,則kubelet會殺死容器,而且容器將受到其重啓策略的影響,若是容器不提供存活探針,則默認狀態爲Success
readinessProbe(就緒與否): 指示容器是否準備好服務請求,若是就緒探測失效,斷點控制器將從與Pod匹配的全部service的端點中刪除該Pod的ip地址。初始延遲以前的就緒狀態Failure。若是容器不提供就緒探針,則默認狀態爲success
探針類型有三種:
ExecAction TCPSocketAction HTTPGetAction
ExecAction 在容器內執行指定的命令,若是命令退出時返回碼爲0則認爲診斷成功。
TCPSocketAction 對指定端口上的容器的IP地址進行TCP檢查。若是端口打開,則診斷被認爲是成功的
HTTPGetAction 對指定的端口和路徑上的容器的IP地址執行HTTP GET 請求。若是響應的狀態碼大於等於200 且小於 400, 則診斷被認爲是成功的
Pod生命週期中的重要行爲:
初始化容器
容器探測
Liveness(存活性探測)
Readinessi(就緒與否)
--必須作的
示例:
Init表明延時
Per表明多少秒檢測一次
Livenessprobe-HTTPGetAction:
livenessProbe-tcp
----------------------------------------------------------------------------------------------------------
啓動或退出動做:
[root@master ym]# kubectl explain pods.spec.container.lifecycle #查看pod生命週期幫助
回顧: Pod
apiVersion, kind, metadata, status(只讀)
spec:
containers:
nodeSelector
nodeName
restartPolicy: #重啓策略
Always, Never, OnFailure
containers:
name
image
imagePullPolicy: Always Never IfNotPresent
ports:
name
contarnerPort #暴露端口
livenessProbe #存活性探測
readlinessProbe #就緒狀態探測
Liftcycle #啓動或退出動做
ExecAction: exec
TCPocketAction: tcpSocket
HTTPGetAction: httpGet
Pod 控制器
ReplictionController(老版本控制器)
ReplicaSet(新版本控制器) #支持擴容,直接編輯yaml實時文件replicas
[root@master ~]# kubectl edit rs myapp 保存即生效
Deployment #經過控制replicaset來控制pod,最應該掌握的控制器之一
DaemoSet #控制每一個node上都有一個pod副本
Job #一次性
Cronjob
StatefulSet #有狀態
聲明式編程(deployment) apply(優) create
命令式編程(rs) create(優) apply
[root@master ~]# kubectl explain rs #查看新版本控制器的手冊
使用ReplicaSet控制器建立的yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
name: myapp-pod
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp-container
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
使用Deployment控制器建立pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
[root@master ~]# kubectl apply -f deplo.yaml
[root@master ~]# kubectl get deploy
[root@master ~]# kubectl get rs
若是想要擴容副本數,直接用vim編輯yaml文件 而後再執行apply -f 建立,apply能夠重複建立
[root@master ~]# kubectl describe deploy myapp-deploy #查看詳細信息
改文件也可使用打補丁的方式:
[root@master ~]# kubectl patch deploy myapp-deploy -p '{"spec":{"replicas":6}}'
[root@master ~]# kubectl explain deploy.spec.strategy.rollingUpdate #查看幫滾動更新策略幫助
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
滾動更新:
1 直接修改yaml文件而後apply執行就能夠
2 若是隻更新鏡像版本 可使用 kubectl set image
[root@master ~]# kubectl set image deploy myapp-deploy myapp=ikubernetes/myapp:v3
[root@master ~]# kubectl set image deploy myapp-deploy myapp=ikubernetes/myapp:v3 && kubectl rollout pause deploy myapp-deploy #金絲雀發佈
[root@master ~]# kubectl get rs -o wide #查看歷史版本
回滾:
[root@master ~]# kubectl rollout undo -h
[root@master ~]# kubectl rollout history deploy myapp-deploy #查看版本
[root@master ~]# kubectl rollout undo deploy/myapp-deploy --to-revision=1
使用DamoSet控制器 實例:
[root@master ~]# kubectl explain ds ds縮寫 每一個node運行一個pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: logstor
template:
metadata:
labels:
app: redis
role: logstor
spec:
containers:
- name: redis
image: redis:4.0-alpine
ports:
- name: redis
containerPort: 6379
--- #用三橫槓隔開就能夠寫在同一個yaml文件裏
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: myapp-ds
namespace: default
spec:
selector:
matchLabels:
release: stable
app: filebeat
template:
metadata:
labels:
app: filebeat
release: stable
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: redis_log
value: info+
兩個pod以前聯動靠svc
Job控制器
Conjob控制器案例:
Service:
工做模式: userspace, iptables, ipvs
Userspace: 1.1
iptables: 1.10
Ipvs: 1.11+
類型:
ExternalName,ClusterIP(集羣內部), NodePort, and LoadBalancer
NodePort:
過程:Client-->NodeIP:NodePort-->ClusterIP:ServicePort-->PodIP:contarinersPort
資源記錄:
SVC_NAME. NS_NAME DAMAIN.LTD
Svc.Cluster.Local
Redis.default.svc.cluster.local
Svc經過標籤關聯pod
案列:
·
Headless service(無頭服務)
有時不須要或不想要負載均衡,以及單獨的service ip 。遇到這種狀況,能夠經過指定cluster ip(spec.cluster IP)的值爲「None」來建立headless service。這類service並不會分配cluster IP,kube-proxy不會處理它們,並且平臺也不會爲它們進行負載均衡和路由
實例:
NodePort:
Ingress-nginx
Ingress-nginx: https://kubernetes.github.io/ingress-nginx/deploy/
-------------------------------------------------------------------------------------------
存儲卷:
介紹:
容器磁盤上的文件的生命週期是短暫的,這就使得在容器中運行重要應用時會出現一些問題,首先,當容器奔潰時,kubelet會重啓它,可是容器中的文件將丟失--容器以乾淨的狀態(鏡像最初的狀態)從新啓動,其次在pod中同時運行多個容器時,這些容器以前一般須要共享文件。Kubernetes中的volume抽象就很好的解決了這些問題
Kubernetes支持如下類型的卷:
SAN(本地存儲): ISCSI
NAS(網絡存儲): nfs, cifs
分佈式存儲: glusterfs, rbd, cephfs
雲存儲:EBS(亞馬遜的),Azure Disk(微軟的)
# Kubectl explain pods.spec.volumes 這裏顯示它支持哪些存儲
[root@master ~]# kubectl explain pods.spec.volumes.emptyDir
[root@master ~]# kubectl explain pods.spec.containers.volumeMounts
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
annotations:
magedu.com/created-by: "cluster admin"
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
volumeMounts:
- name: html
mountPath: /data/web/html
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
command:
- "/bin/sh"
- "-c"
- "sleep 7200"
volumeMounts:
- name: html
mountPath: /data/
volumes:
- name: html
emptyDir: {}
hostPath: 節點級存儲 缺點節點壞了,數據也就沒了
Hostpath卷將主機節點的文件系統中的文件或目錄掛載到集羣中
Hostpath的用途以下:
示例:
apiVersion: v1
kind: Pod
metadata:
name: pod-vol
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html/
volumes:
- name: html
hostPath:
path: /data/pod/volume1
type: DirectoryOrCreate
NFS: 網絡持久化存儲
PVC:
概念:
PersistentVolume(pv)
是由管理員設置的存儲,它是集羣的一部分。就像節點是集羣中的資源同樣,pv也是集羣中的資源。Pv是volume之類的卷插件,但具備獨立於使用pv的pod的生命週期。此api對象包含存儲實現的細節,即NFS iscsi或特定於雲供應商的存儲系統
PersistentVolumeClaim(pvc)
是用戶存儲的請求,它與pod類似。Pod消耗節點資源,pvc消耗pv資源。Pod能夠請求特定級別的資源(cpu或內存)。它聲明能夠請求特定的大小和訪問模式(例如,能夠以讀/寫或一次貨只讀屢次模式掛載)
綁定:
Master中的控制環路監視新的pvc,尋找匹配的pv(若是可能),能將它們綁定在一塊兒,若是爲新的pvc動態調配pv,則該環路將始終將該pv綁定到pvc。不然,用戶總戶獲得他們請求的存儲。可是容量可能超出要求的數量,一旦pv和pvc綁定後,pvc綁定是排他性的,無論他們是如何綁定的。Pvc跟pv綁定是一對一的映射關係。
狀態:
l Available(可用) ---- 一款空閒資源尚未被任何聲明綁定
l Bound(已綁定) --- 卷已經被聲明綁定
l Released(已釋放) --- 聲明被刪除,可是資源還未被集羣從新聲明
l Failed(失敗) --- 該卷的自動回收失敗
Pvc也是kubernetes裏標準的資源
[root@master ~]# kubectl explain pvc.spec
accessModes #訪問模式:
ReadWriteOnce: 單路讀寫
ReadOnlyMany: 多路只讀
ReadWriteMany: 多路讀寫
resources #資源限制
Selector #標籤選擇器
storageClassName #存儲類
volumeMode #存儲卷的模式
volumeName #存儲卷的名字
環境準備:
在全部機器上都安裝nfs-utils
以node2做爲nfs服務器
在node2上建立五個掛載目錄 : [root@node2 ~]# mkdir v{1..5}
[root@node2 ~]# vim /etc/exports
/root/v1 172.18.0.0/16(rw)
/root/v2 172.18.0.0/16(rw)
/root/v3 172.18.0.0/16(rw)
/root/v4 172.18.0.0/16(rw)
/root/v5 172.18.0.0/16(rw)
建立pv: 以下
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
labels:
name: pv001
spec:
nfs:
path: /root/v1
server: node2
accessModes: ["ReadWriteMany","ReadWriteOnce"] #設置訪問類型。必需要寫
capacity:
storage: 1Gi #大小
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
path: /root/v2
server: node2
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 2Gi
[root@master vl]# kubectl apply -f pv.yaml
persistentvolume/pv001 created
persistentvolume/pv002 created
。。。
[root@master vl]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY(回收策略) STATUS CLAIM STORAGECLASS REASON AGE
pv001 1Gi RWO,RWX Retain Available 5s
pv002 2Gi RWO,RWX Retain Available 5s
。。。。
建立pvc
[root@master vl]# vim pvc.yaml 以下
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
namespace: default #pvc有命名空間,pv沒有
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc
namespace: default
labels:
app: myapp
spec:
containers:
- name: mypvc
image: ikubernetes/myapp:v1
volumeMounts:
- name: mydisk
mountPath: /data/wengwengweng
volumes:
- name: mydisk
persistentVolumeClaim:
claimName: mypvc
[root@master vl]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc Bound綁定 pv001 1Gi RWO,RWX 2m58s
Pvc是存儲在etcd中,就算pod死機,數據也不會丟失
當綁定pv的pvc刪掉以後 想要回收此pv 可使用edit pv 刪掉ChaimRef這一行 就能夠了
------------------------------------------------------------------------------------------------------
configmap
配置容器化應用的方式:
1 自定義命令行參數
Args:
2 把配置文件直接焙進鏡像
3 環境變量
4 存儲卷
[root@master volume]# kubectl create configmap --help #查看configmap幫助信息
[root@master ~]# kubectl create configmap nginx.cconf --from-file=./nginx.cconf
#建立文件式的cm
[root@master ~]# kubectl create configmap nginxport --from-literal=nginx_pory=80
#簡單的cm
configmap是名稱空間級別的資源 直接搜索:
[root@master ~]# kubectl explain cm
以環境變量的方式注入到容器裏:
以掛載的方式:
支持edit動態修改
[root@master ~]# kubectl edit cm cm名
secret
Secret存在的意義:
Secret解決了密碼,token,密鑰等敏感數據的配置問題,而不須要把這額敏感數據暴露到鏡像或pod spec中。Secret能夠以volume或者環境變量的方式使用
Secret有三種類型:
Service account: 用來訪問k8s API,由k8s自動建立,而且會自動掛載到Pod的/usr/secrets/kubernetes.io/serviceaccount目錄中
Opaque: base64編碼格式的secret,用來存儲密碼,密鑰等 安全性不怎麼高,一條命令就能夠解開(base64 -d)
Kubernetes.io/dockerconfigjson: 用來存儲私有docker regisry的認證信息
[root@master ~]# kubectl create secret --help
docker-registry #保存認證信息
generic #通用的
tls #私鑰類型
和configmap很類似
以環境變量方式注入:
注意以這種方式注入的密碼都是解碼以後的,安全性不高
若是支持dry-run的方式 可使用-o yaml 來生成一個yaml框架!
使用secret作私有鏡像認證:
命令裏的大寫表明變量
----------------------------------------------------------------------------------------------------------
Statefulset控制器
一個典型的statefulset應該由三個組件組成: headless(必須是一個無頭服務)
Statefulset
volumeclaimTemplate
Sts爲每一個pod副本建立了一個DNS域名,這個域名的格式爲: $(podname).(headless service name),也就意味着服務間是經過pod域名來通訊而非pod IP ,由於opd所在的node發生故障時,pod會飄逸到其它node上,pod IP會發生變化,可是pod域名不會有變化
由於懶:
Statefulset的啓停順序:
l 有序部署:部署statefulset時,若是有多個Pod副本,它們會被順序地建立(從0到N-1)而且在下一個pod運行以前全部以前的pod必須都是running和ready狀態
l 有序刪除: 當pod被刪除時,它們被終止的順序是從N-1到0
l 有序擴展: 當對pod執行擴展操做時,與部署同樣,它前面的pod必須都處於running和ready狀態
[root@master ~]# kubectl explain sts #查看控制器的幫助,簡稱
apiVersion: v1
kind: Service
metadata:
name: myapp
labels:
app: myapp
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: myapp
replicas: 3
selector:
matchLabels:
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: myappdata
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
sts也支持動態更新,動態擴容
----------------------------------------------------------------------------------------------------------
認證
認證 ----> 受權-----> 准入控制
受權用戶:
ServiceaccessountName 受權名 寫在spec下面
建立sa: kubectl create serviceaccount admin
Dashboard:
[root@master ~]# kubectl proxy --port=8080
[root@master ~]# curl http://localhost:8080/ #查看各類資源
(1) [root@master ~]# Kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
(2) 將service改成Nodeport
[root@master ~]# kubectl patch svc kubernetes-dashboard -p '{"spec": {"type": Nodeport}}' -n kube-system
要使用https的方式訪問
(3) 認證:
認證時的帳號必須爲serviceaccount,被dashboard pod拿來由kubernetes進行認證
token:
(1)建立ServiceAccount,根據其管理目標,使用rolebinding或clusterrolebinding綁定至合理role或
clusterrole;
(2)獲取到此ServiceAccount的secret,查看secret的詳細信息,其中就有token;
kubeconfig: 把ServiceAccount的token封裝爲kubeconfig文件
(1)建立ServiceAccount,根據其管理目標,使用rolebinding或clusterrolebinding綁定至合理role或
clusterrole;
(2)kubectl get secret | awk '/^ServiceAccount/{print $1}'
KUBE_TOKEN=$(kubectl get secret SERVCIEACCOUNT_SERRET_NAME -o jsonpath={.data.token} |
base64 -d)
(3)生成kubeconfig文件
kubectl config set-cluster --kubeconfig=/PATH/TO/SOMEFILE
kubectl config set-credentials NAME --token=$KUBE_TOKEN --kubeconfig=/PATH/TO/SOMEFILE
kubectl config set-context
kubectl config use-context
令牌認證:
[root@master ~]# kubectl create serviceaccount dashboard-admin -n kube-system
#先建立一個用戶
[root@master ~]# kubectl create clusterrolebinding dashboard-cluster-admin --clusterrole=clu
ster-admin --serviceaccount=kube-system:dashboard-admin #與集羣角色進行綁定,左側名稱空間,右側帳號
[root@master ~]# kubectl get secret #找到剛建立角色的token
[root@master ~]# kubectl describe secret dashboard-admin-token-ctjgn -n kube-system
把查到的token信息複製到網頁上完成登入
Config認證:
[root@master ~]# kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server="https://172.18.0.70:6443" --embed-certs=true --kubeconfig=/root/def-ns-admin.conf
[root@master ~]# kubectl config view --kubeconfig=/root/def-ns-admin.conf
[root@master ~]# DEF_NS_ADMIN_TOKEN=$(kubectl get secret def-ns-admin-token-v4wxn -o jsonpath={.data.token} | base64 -d) #知道它的token並解碼賦值給變量
[root@master ~]# kubectl config set-credentials def-ns-admin --token=$DEF_NS_ADMIN_TOKEN --kubeconfig=/root/def-ns-admin.conf #把token傳進去
[root@master ~]# kubectl config set-context def-ns-admin@kubernetes --cluster=kubernetes --user=def-ns-admin --kubeconfig=/root/def-ns-admin.conf
[root@master ~]# kubectl config use-context def-ns-admin@kubernetes --kubeconfig=/root/def-ns-admin.conf
完成! 如今的配置文件能夠下載下去,傳到網頁上就能夠用了
----------------------------------------------------------------------------------------------------------
受權插件:
Node, ABAC , RBAC, Webhook
Kubernetes集羣的管理方式:
三、聲明式配置文件: apply -f, patch,
----------------------------------------------------------------------------------------------------------
網絡插件calico(網絡策略)
Calico做爲網絡插件使用工做於192.168.0.0/16網段
官網文檔:
https://docs.projectcalico.org/v3.9/getting-started/kubernetes/installation/flannel
選擇使用calico用於網絡策略,flannel用於網絡
部署:
[root@master ~]# kubectl apply -f https://docs.projectcalico.org/v3.9/manifests/canal.yaml
[root@master ~]# kubectl get pods -n kube-system #查看是否安裝
使用:
[root@master ~]# kubectl explain networkpolicy.spec
egress 出站
ingress 入站
potSelector 選擇哪一個pod
policyTypes 策略
基於名稱空間的網絡策略
拒絕全部入站:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dey-all-ingress
spec:
podSelector: {}
policyTypes:
- Ingress #拒絕全部入站
[root@master ~]# kubectl apply -f ingress.yaml -n dev -n 表明指定名稱空間
[root@master ~]# kubectl get netpol -n dev #查看策略
放行全部進站:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dey-all-ingress
spec:
podSelector: {}
ingress:
- {} #寫上以後默認放行全部
policyTypes:
- Ingress
放行特定的網絡:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector:
matchLabels:
app: myapp #放行有這個標籤的pod
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16
except: #指定拒絕特定的網絡
- 10.244.1.2/32
ports: #指定放行的端口
- protocol: TCP
port: 80
----------------------------------------------------------------------------------------------------------
Node親和性:
[root@master ~]# kubectl explain pod.spec.affinity.nodeAffinity
preferredDuringSchedulingIgnoredDuringExecution #軟策略
requiredDuringSchedulingIgnoredDuringExecution #硬策略
節點選擇器:nodeSelector, nodeName
節點親和調度:nodeAffinity
Pod親和性
[root@master ~]# kubectl explain pod.spec.affinity.podAffinity
----------------------------------------------------------------------------------------------------------
Taint和toleration:
節點親和性,是pod的一種屬性(偏好或硬性要求),它使pod被吸引到這一類特定的節點,taint則相反,它是節點可以排斥一類特定的pod
taint的effect定義對Pod排斥效果:
NoSchedule:僅影響調度過程,對現存的Pod對象不產生影響;
NoExecute:既影響調度過程,也影響如今的Pod對象;不容忍的Pod對象將被驅逐;
PreferNoSchedule:
資源需求與限制:
容器的資源需求,資源限制
requests: 需求,最低保障;
limits: 限制,硬限制
CPU:
1顆邏輯cpu
1=1000,millicores
500=0.5CPU
內存:
E, P, T, G, M, K
Ei,Pi
limits 表明上限
Qos: #服務質量
Guranteed: 當資源不夠的時候,優先運行#同時設置CPU和內存的requests和limit
cpu.limits = cpu.requests
memory.limits = memory.request #當條件知足時,自動歸類爲 guranteed
Burstable: #至少有一個容器設置CPU或內存資源的requests屬性
BestEffort: #沒有任何一個容器設置了requests或limit屬性;最低優先級
#當pod資源不夠時,自動殺死BestEffort屬性的容器
----------------------------------------------------------------------------------------------------------
Kubectl top:
Heapster 收集各類指標數據,存到InfluxDB裏在由Grafana圖形化展現出來
部署:
在git上搜索heapster
https://github.com/kubernetes-retired/heapster/tree/master/deploy/kube-config #部署方法
這裏先部署了infuexDB
[root@master ~]# wget https://raw.githubusercontent.com/kubernetes-retired/heapster/master/deploy/kube-config/influxdb/influxdb.yaml #把yaml文件wget下來
spec: 修改版本爲apps/v1
replicas: 1
selector: #添加標籤這4行
matchLabels:
task: monitoring
k8s-app: influxdb
因谷歌網絡限制問題,國內的K8ser大多數在學習Kubernetes過程當中由於鏡像下載失敗問題間接地產生些許失落感,筆者也所以腦袋疼,故翻閱資料獲得如下解決方式:
在應用yaml文件建立資源時,將文件中鏡像地址進行內容替換便可:
將k8s.gcr.io替換爲
registry.cn-hangzhou.aliyuncs.com/google_containers
或者
registry.aliyuncs.com/google_containers
或者
mirrorgooglecontainers
而後部署heapster:
https://github.com/kubernetes-retired/heapster/tree/master/deploy/kube-config/influxdb
[root@master ~]# vim heapster.yaml #羣組改爲apps/v1 貌似不改也不要緊,加一個標籤
spec:
replicas: 1
selector:
matchlabels:
task: monitoring
k8s-app: heapster
部署grafana:
[root@master ~]# wget https://raw.githubusercontent.com/kubernetes-retired/heapster/master/deploy/kube-config/influxdb/grafana.yaml
[root@master ~]# vim grafana.yaml #跟上面同樣修改版本,添加標籤,若是有須要還能夠添加一個nodePort 暴露在公網上
而後查看grafana的svc 瀏覽
如何導入導出面板能夠參考:https://blog.csdn.net/gx_1_11_real/article/details/85161491
----------------------------------------------------------------------------------------------------------
Helm:
核心術語:
Chart:一個helm程序包;
Repository:Charts倉庫,https/http服務器;
Release:特定的Chart部署於目標集羣上的一個實例;
Chart -> Config -> Release
程序架構:
helm:客戶端,管理本地的Chart倉庫,管理Chart, 與Tiller服務器交互,發送Chart,實例安裝、查詢、卸載等 操做
Tiller:服務端,接收helm發來的Charts與Config,合併生成relase;
安裝步驟:
如今git上找到相應的helm包,下載下來
地址:https://github.com/helm/helm/releases
解壓下載的文件:
[root@master linux-386]# tar -xf tar -xf helm-v2.9.1-linux-amd64.tar.gz
#建議使用舊版本的,要否則會有不少莫名其妙的錯誤
把helm文件直接mv到/usr/bin 就能夠直接使用
由於helm運行要使用管理員權限因此還要綁定cluster-admin集羣角色上:
RBAC示例:
https://github.com/helm/helm/blob/master/docs/rbac.md
把示例裏的yaml文件複製下來,使用apply部署
helm init --service-account tiller --upgrade -i registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.9.1 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
#由於網絡問題,這裏使用阿里雲的helm鏡像
[root@master helm]# kubectl get pods -n kube-system #查看pod是否啓動
[root@master helm]# helm version #查看helm和tiller版本
[root@master helm]# helm repo update
[root@master helm]# helm repo list #查看可用的正在使用的倉庫
官方可用的chart列表:
Stable表明穩定版 incubator表明測試版,最好仍是使用穩定版
示例:
部署一個memcache:
[root@master ~]# helm search stable/memcachecd
[root@master ~]# helm inspect table/memcached
[root@master ~]# helm install --name mem1 stable/memcached
#部署完會有一個反饋信息在下面
[root@master ~]# helm delete mem1 #卸載
helm經常使用命令:
release管理:
install #安裝
delete #刪除
upgrade/rollback #更新/回滾
list #列出
history:release的歷史信息;
status:獲取release狀態信息;
chart管理:
create
fetch
get
inspect
package
Verify
[root@master ~]# helm fetch stable/redis 下載包
[root@master redis]# tree ./
./
├── Chart.yaml #記錄chart的元數據。。
├── README.md #說明
├── templates #各類模板文件
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── networkpolicy.yaml
│ ├── NOTES.txt
│ ├── pvc.yaml
│ ├── secrets.yaml
│ └── svc.yaml
└── values.yaml #自定義屬性設置默認值
建立chart:
[root@master ~]# helm create myapp 它會自動生成配置文件
[root@master ~]# tree myapp/
myapp/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── ingress.yaml
│ ├── NOTES.txt
│ └── service.yaml
└── values.yaml
修改完yaml文件後使用
[root@master redis]# helm lint ../redis #語法檢測
ElK: #相似於ELK
E: elasticsearch 和kibana版本必定要一致,錯一個小版本號都不行
L: logstash
K:
Fluentd 日誌收集代理工具
部署ELK:
[root@master ~]# helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/ #添加測試版倉庫
[root@master ~]# helm fetch incubator/elasticsearch #下載el chart包
[root@master ~]# tar -xf elasticsearch-1.10.2.tgz
[root@master ~]# cd elasticsearch/
[root@master elasticsearch]# helm install --name els2 --namespace=efk -f values.yaml incubator/elasticsearch
[root@master elasticsearch]# kubectl run -it --rm cirror-$RANDOM --image=cirros -- /bin/sh
#運行一個測試的容器
[root@master ~]# helm status el2 #查看入口
在測試的機器裏:
/ # nslookup el2-elasticsearch-client.efk.svc
/ # curl el2-elasticsearch-client.efk.svc:9200 #訪問它的端口
/ # curl el2-elasticsearch-client.efk.svc.cluster.local:9200/_cat #查看es庫
部署fluentd:
[root@master mnt]# helm fetch incubator/fluentd-elasticsearch 下載對應chart
elasticsearch:
host: 'el2-elasticsearch-client.efk.svc.cluster.local' #把這裏改爲解析的主機名的地址
tolerations:
- key: node-role.kubernetes.io/master #把這三個註釋打開,能夠容忍主節點的污點
operator: Exists
effect: NoSchedule
service: #若是指望經過服務的方式來訪問它就把這注釋打開
type: ClusterIP
ports:
- name: "monitor-agent"
port: 24231
[root@master fluentd-elasticsearch]# helm install --name flu1 --namespace=efk -f values.yaml incubator/fluentd-elasticsearch #進行安裝
部署k:
]# helm fetch stable/kibana
]# tar -xf kibana-0.2.2.tgz
若是是新版本配置以下:
]# helm install --name kib1 --namespace=efk -f values.yaml stable/kibana
]# kubectl edit svc -n efk kib1-kibana 修改svc爲NodePort
完成後的頁面:
證書
證書默認路徑: [root@master pki]# ls /etc/kubernetes/pki/
查看證書使用年限: [root@master pki]# openssl x509 -in apiserver.crt -text -noout
使用go語言修改kubeadm源碼,修改年限
準備go語言環境: 首先在百度上搜索go中文社區(由於官方在谷歌,國內不方便)
百度--> go中文社區--> 下載 --> 選擇linux版本
[root@master data]# wget https://studygolang.com/dl/golang/go1.13.linux-amd64.tar.gz
[root@master data]# tar -xf go1.13.linux-amd64.tar.g -C /usr/local/
export PATH=$PATH:/usr/local/go/bin #變量
[root@master ~]# vim /etc/profile #在這裏設置環境變量
export PATH=$PATH:/usr/local/go/bin #把這個貼在文件裏,官網上有
[root@master ~]# source /etc/profile
[root@master ~]# go version #查看版本
go version go1.13 linux/amd64
[root@master data]# git clone https://github.com/kubernetes/kubernetes 克隆
[root@master data]# cd kubernetes
[root@master kubernetes]# git checkout -b remotes/origin/release-1.15.3 v1.15.3 #切換分支
cmd/kubeadm/app/util/pkiutil/pki_helpers.go #修改年限的文件(1.14版本到1.15)
[root@master kubernetes]# vim cmd/kubeadm/app/util/pkiutil/pki_helpers.go
const duration3650d = time.Hour * 24(小時) * 365(天) *10(年) #添加,設置常量
certTmpl := x509.Certificate{ #大約566行
Subject: pkix.Name{
CommonName: cfg.CommonName,
Organization: cfg.Organization,
},
DNSNames: cfg.AltNames.DNSNames,
IPAddresses: cfg.AltNames.IPs,
SerialNumber: serial,
NotBefore: caCert.NotBefore,
NotAfter: time.Now().Add(duration3650d).UTC() #改爲剛剛的常量
:wq
[root@master kubernetes]# make WHAT=cmd/kubeadm GOFLAGS=-v 編譯
不知道爲何沒有成功。。。
高可用k8s集羣構建
睿雲
補充:
Init(容器啓動以前的操做):
參考http://www.javashuo.com/article/p-pajchvbi-ks.html
registry.cn-shanghai.aliyuncs.com/mydlq/