k8s docker集羣搭建
1、Kubernetes系列之介紹篇
- 擁有一個惟一指定的名字
- 擁有一個虛擬IP(Cluster IP、Service IP、或VIP)和端口號
- 可以體統某種遠程服務能力
- 被映射到了提供這種服務能力的一組容器應用上
- 目標Pod的定義
- 目標Pod須要運行的副本數量(Replicas)
- 要監控的目標Pod標籤(Label)
- 每一個Node節點都運行着如下一組關鍵進程
- kubelet:負責對Pod對於的容器的建立、啓停等任務
- kube-proxy:實現Kubernetes Service的通訊與負載均衡機制的重要組件
- Docker Engine(Docker):Docker引擎,負責本機容器的建立和管理工做
- Cluster IP僅僅做用於Kubernetes Service這個對象,並由Kubernetes管理和分配P地址
- Cluster IP沒法被ping,他沒有一個「實體網絡對象」來響應
- Cluster IP只能結合Service Port組成一個具體的通訊端口,單獨的Cluster IP不具有通訊的基礎,而且他們屬於Kubernetes集羣這樣一個封閉的空間。
- 版本標籤:"release":"stable","release":"canary"......
- 環境標籤:"environment":"dev","environment":"qa","environment":"production"
- 架構標籤:"tier":"frontend","tier":"backend","tier":"middleware"
- 分區標籤:"partition":"customerA","partition":"customerB"
- 質量管控標籤:"track":"daily","track":"weekly"
-
- kube-Controller進程經過資源對象RC上定義Label Selector來篩選要監控的Pod副本的數量,從而實現副本數量始終符合預期設定的全自動控制流程
- kube-proxy進程經過Service的Label Selector來選擇對應的Pod,自動創建起每一個Service島對應Pod的請求轉發路由表,從而實現Service的智能負載均衡
- 經過對某些Node定義特定的Label,而且在Pod定義文件中使用Nodeselector這種標籤調度策略,kuber-scheduler進程能夠實現Pod」定向調度「的特性

2、基於kubernetes構建Docker集羣環境實戰

1
2
|
#setenforce 0
#sed -i '/^SELINUX=/cSELINUX=disabled' /etc/sysconfig/selinux
|
1
|
# yum -y install etcd kubernetes
|
配置etcd。確保列出的這些項都配置正確而且沒有被註釋掉,下面的配置都是如此 php
1
2
3
4
5
6
|
#vim /etc/etcd/etcd.conf
ETCD_NAME=default
ETCD_DATA_DIR=
"/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS=
"http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS=
"http://localhost:2379"
|
配置kuberneteshtml
1
2
3
4
5
6
7
8
|
vim
/etc/kubernetes/apiserver
KUBE_API_ADDRESS=
"--address=0.0.0.0"
KUBE_API_PORT=
"--port=8080"
KUBELET_PORT=
"--kubelet_port=10250"
KUBE_ETCD_SERVERS=
"--etcd_servers=http://127.0.0.1:2379"
KUBE_SERVICE_ADDRESSES=
"--service-cluster-ip-range=10.254.0.0/16"
KUBE_ADMISSION_CONTROL=
"--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
KUBE_API_ARGS=
""
|
1
|
# for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do systemctl restart $SERVICES systemctl enable $SERVICES systemctl status $SERVICES done
|
3.設置etcd網絡前端
1
|
#etcdctl -C 10.0.0.81:2379 set /atomic.io/network/config '{"Network":"10.1.0.0/16"}'
|
1
|
# kubectl get nodes NAME LABELS STATUS
|
1
|
# yum -y install flannel kubernetes
|
配置kubernetes鏈接的服務端IPjava
1
2
3
|
#vim /etc/kubernetes/config
KUBE_MASTER=
"--master=http://10.0.0.81:8080"
KUBE_ETCD_SERVERS=
"--etcd_servers=http://10.0.0.81:2379"
|
配置kubernetes ,(請使用每臺minion本身的IP地址好比10.0.0.81:代替下面的$LOCALIP)node
1
2
3
4
5
|
#vim /etc/kubernetes/kubelet<br>KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_PORT=
"--port=10250"
# change the hostname to this host’s IP address KUBELET_HOSTNAME="--hostname_override=$LOCALIP"
KUBELET_API_SERVER=
"--api_servers=http://10.0.0.81:8080"
KUBELET_ARGS=
""
|
1
2
3
4
5
|
# ifconfig docker0
Link encap:Ethernet HWaddr 02:42:B2:75:2E:67 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 UP
BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0
errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
|
warning:在運行過docker的機器上能夠看到有docker0,這裏在啓動服務以前須要刪掉docker0配置,在命令行運行:sudo ip link delete docker0mysql
3.配置flannel網絡linux
1
2
3
|
#vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS=
"http://10.0.0.81:2379"
FLANNEL_ETCD_PREFIX=
"/atomic.io/network"
|
1
|
# for SERVICES in flanneld kube-proxy kubelet docker; do systemctl restart $SERVICES systemctl enable $SERVICES systemctl status $SERVICES done
|
1
2
3
4
|
# kubectl get nodes
NAME STATUS AGE
10.0.0.82 Ready 1m
10.0.0.83 Ready 1m
|
能夠看到配置的兩臺minion已經在master的node列表中了。若是想要更多的node,只須要按照minion的配置,配置更多的機器就能夠了。nginx
3、Kubernetes之深刻了解Pod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
# 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
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
apiVersion:v1
kind: Pod
metadata:
name: redis-php
label:
name: redis-php
spec:
containers:
- name: frontend
image: kubeguide
/guestbook-php-frontend
:localredis
ports:
- containersPort: 80
- name: redis-php
image:kubeguide
/redis-master
ports:
- containersPort: 6379
|
1
2
3
|
#kubectl get gods
NAME READY STATUS RESTATS AGE
redis-php 2
/2
Running 0 10m
|
能夠看到READY信息爲2/2,表示Pod中的兩個容器都成功運行了.git
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
[root@kubernetes-master ~]
# kubectl describe redis-php
the server doesn't have a resource
type
"redis-php"
[root@kubernetes-master ~]
# kubectl describe pod redis-php
Name: redis-php
Namespace: default
Node: kubernetes-minion
/10
.0.0.23
Start Time: Wed, 12 Apr 2017 09:14:58 +0800
Labels: name=redis-php
Status: Running
IP: 10.1.24.2
Controllers: <none>
Containers:
nginx:
Container ID: docker:
//d05b743c200dff7cf3b60b7373a45666be2ebb48b7b8b31ce0ece9be4546ce77
Image: nginx
Image ID: docker-pullable:
//docker
.io
/nginx
@sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582
Port: 80
/TCP
State: Running
Started: Wed, 12 Apr 2017 09:19:31 +0800
|
1
2
3
4
5
|
#kubetctl delete pod static-web-node1
pod
"static-web-node1"
deleted
#kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web-node1 0
/1
Pending 0 1s
|
1
2
|
#rm -f /etc/kubelet.d/static-web.yaml
#docker ps
|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
apiVersion:v1
kind: Pod
metadata:
name: redis-php
label:
name: volume-pod
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containersPort: 8080
volumeMounts:
- name: app-logs
mountPath:
/usr/local/tomcat/logs
- name: busybox
image:busybox
command
: [
"sh"
,
"-C"
,
"tail -f /logs/catalina*.log"
]
volumes:
- name: app-logs
emptyDir:{}
|
1
|
#kubectl logs volume-pod -c busybox
|
1
|
#kubectl exec -ti volume-pod -c tomcat -- ls /usr/local/tomcat/logs
|
1
2
3
4
5
6
7
8
|
# vim cm-appvars.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-appvars
data:
apploglevel: info
appdatadir:
/var/data
|
1
2
|
#kubectl create -f cm-appvars.yaml
configmap
"cm-appvars.yaml"
created
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#kubectl get configmap
NAME DATA AGE
cm-appvars 2 3s
[root@kubernetes-master ~]
# kubectl describe configmap cm-appvars
Name: cm-appvars
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
appdatadir: 9 bytes
apploglevel: 4 bytes
[root@kubernetes-master ~]
# kubectl get configmap cm-appvars -o yaml
apiVersion: v1
data:
appdatadir:
/var/data
apploglevel: info
kind: ConfigMap
metadata:
creationTimestamp: 2017-04-14T06:03:36Z
name: cm-appvars
namespace: default
resourceVersion:
"571221"
selfLink:
/api/v1/namespaces/default/configmaps/cm-appvars
uid: 190323cb-20d8-11e7-94ec-000c29ac8d83
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-appvars
data:
key-serverxml:
<?xml Version=
'1.0'
encoding=
'utf-8'
?>
<Server port=
"8005"
shutdown
=
"SHUTDOWN"
>
.....
<
/service
>
<
/Server
>
key-loggingproperties:
"handlers=lcatalina.org.apache.juli.FileHandler,
...."
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#vim cm-test-app.yaml
apiVersion: v1
kind: Pod
metadata:
name: cm-
test
-app
spec:
containers:
- name: cm-
test
-app
image: tomcat-app:v1
ports:
- containerPort: 8080
volumeMounts:
- name: serverxml
#引用volume名
mountPath:
/configfiles
#掛載到容器內部目錄
configMap:
name: cm-
test
-appconfigfile
#使用configmap定義的的cm-appconfigfile
items:
- key: key-serverxml
#將key=key-serverxml
path: server.xml
#value將server.xml文件名進行掛載
- key: key-loggingproperties
#將key=key-loggingproperties
path: logging.properties
#value將logging.properties文件名進行掛載
|
1
2
|
#kubectl create -f cm-test-app.yaml
Pod
"cm-test-app"
created
|
1
2
3
|
#kubectl exec -ti cm-test-app -- bash
root@cm-rest-app:/
# cat /configfiles/server.xml
root@cm-rest-app:/
# cat /configfiles/logging.properties
|
-
- configmap必須在pod之間建立
- configmap也能夠定義爲屬於某個Namespace,只有處於相同namespaces中的pod能夠引用
- configmap中配額管理還未能實現
- kubelet只支持被api server管理的pod使用configmap,靜態pod沒法引用
- 在pod對configmap進行掛載操做時,容器內部職能掛載爲目錄,沒法掛載文件。

-
- RC和DaemonSet:必須設置爲Always,須要保證該容器持續運行
- Job:OnFailure或Nerver,確保容器執行完成後再也不重啓
- kubelet:在Pod失效時重啓他,不論RestartPolicy設置什麼值,而且也不會對Pod進行健康檢查
-
- LivenessProbe探針:用於判斷容器是否存活(running狀態),若是LivenessProbe探針探測到容器不健康,則kubelet殺掉該容器,並根據容器的重啓策略作響應處理
- ReadinessProbe探針:用於判斷容器是否啓動完成(ready狀態),能夠接受請求。若是ReadinessProbe探針探測失敗,則Pod的狀態被修改。Endpoint Controller將從service的Endpoint中刪除包含該容器所在的Pod的Endpoint。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
apiVersion:v1
kind: Pod
metadata:
name: liveness-
exec
label:
name: liveness
spec:
containers:
- name: tomcat
image: grc.io
/google_containers/tomcat
args:
-
/bin/sh
- -c
-
echo
ok >
/tmp
.health;
sleep
10;
rm
-fr
/tmp/health
;
sleep
600
livenessProbe:
exec
:
command
:
-
cat
-
/tmp/health
initianDelaySeconds:15
timeoutSeconds:1
|
1
2
3
4
5
6
7
8
9
10
11
12
|
kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
tcpSocket:
port: 80
initianDelaySeconds:30
timeoutSeconds:1
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
apiVersion:v1
kind: Pod
metadata:
name: pod-with-healthcheck
spec:
containers:
- name: nginx
image: nginx
livenessProbe:
httpGet:
path:
/_status/healthz
port: 80
initianDelaySeconds:30
timeoutSeconds:1
|
- initialDelaySeconds:啓動容器後首次監控檢查的等待時間,單位秒
- timeouSeconds:健康檢查發送請求後等待響應的超時時間,單位秒。當發生超時就被認爲容器沒法提供服務無,該容器將被重啓
1
|
#kubectllabel nodes k8s-node-1 zonenorth
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
apiVersion:v1
kind: Pod
metadata:
name: redis-master
label:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
labels:
name: redis-master
spec:
containers:
- name: redis-master
images: kubeguide
/redis-master
ports:
- containerPort: 6379
nodeSelector:
zone: north
|

- 在每一個Node上運行個以GlusterFS存儲或者ceph存儲的daemon進程
- 在每一個Node上運行一個日誌採集程序,例如fluentd或者logstach
- 在每一個Node上運行一個健康程序,採集Node的性能數據。
1
2
3
4
5
6
7
|
#kubectl scale rc redis-slave --replicas=3
ReplicationController
"redis-slave"
scaled
#kubectl get pods
NAME READY STATUS RESTARTS AGE
redis-slave-1sf23 1
/1
Running 0 1h
redis-slave-54wfk 1
/1
Running 0 1h
redis-slave-3da5y 1
/1
Running 0 1h
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
apiVersion: v1
kind: replicationController
metadata:
name: redis-master-v2
labels:
name: redis-master
Version: v2
spec:
replicas: 1
selector:
name: redis-master
Version: v2
template:
labels:
name: redis-master
Version: v2
spec:
containers:
- name: master
images: kubeguide
/redis-master
:2.0
ports:
- containerPort: 6379
|
須要注意的點:golang
1
|
#kubectl rolling-update redis-master -f redis-master-controller-v2.yaml
|
1
|
#kubectl rolling-update redis-master --image=redis-master:2.0
|