(k8s配置Ingress-nginx做爲服務發現)php
(服務網格lstio)html
(日誌和監控Helm+PrometheusGrafna看板)前端
(服務調度與編排Scheduler玩轉pod調度)node
(共享存儲PV/PVC/StorageClass)mysql
(Harbor Docker鏡像倉庫)linux
(k8s重點對象概念:Namespace、Resources、Label)nginx
1
2
|
#setenforce 0
#sed -i '/^SELINUX=/cSELINUX=disabled' /etc/sysconfig/selinux
|
1
|
# yum -y install etcd kubernetes
|
配置etcd。確保列出的這些項都配置正確而且沒有被註釋掉,下面的配置都是如此 git
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"
|
配置kubernetesweb
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網絡redis
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鏈接的服務端IP
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)
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 docker0
3.配置flannel網絡
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的配置,配置更多的機器就能夠了。
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中的兩個容器都成功運行了.
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
|
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
|
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
|
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
|
須要注意的點:
1
|
#kubectl rolling-update redis-master -f redis-master-controller-v2.yaml
|
1
|
#kubectl rolling-update redis-master --image=redis-master:2.0
|
https://blog.csdn.net/Real_Myth/article/details/78719244
序言
沒等到風來,綿綿小雨,因此寫個隨筆,聊聊k8s的基本概念。
k8s是一個編排容器的工具,其實也是管理應用的全生命週期的一個工具,從建立應用,應用的部署,應用提供服務,擴容縮容應用,應用更新,都很是的方便,並且能夠作到故障自愈,例如一個服務器掛了,能夠自動將這個服務器上的服務調度到另一個主機上進行運行,無需進行人工干涉。那麼,問題來了,要運維何用?
k8s能夠更快的更新新版本,打包應用,更新的時候能夠作到不用中斷服務,服務器故障不用停機,從開發環境到測試環境到生產環境的遷移極其方便,一個配置文件搞定,一次生成image,處處運行。。。
k8s的全生命週期管理
在k8s進行管理應用的時候,基本步驟是:建立集羣,部署應用,發佈應用,擴展應用,更新應用。
一、建立集羣:爲何要使用集羣?
有一句古話叫作三個臭皮匠,勝過諸葛亮,這就是建立集羣的緣由。。。
使用集羣,create cluster是爲了掩蓋底層的無能,在各類環境中,底層的硬件各不相同,有的是各類低廉的服務器,有的各類雲環境,有的是各類vm,有的各類host machine,要想屏蔽底層的細節,加強可靠性和穩定性,從而須要建立集羣。
建立集羣的好處就是,統一對外提供接口,無須進行各類複雜的調用;提供更好的可靠性,服務器宕機那麼頻繁,物理磁盤那麼容易損壞,無須擔憂,集羣統一進行調配;提供更好的性能,組合集羣中各個機器的計算存儲網絡資源,提供更好的TPS和PS;提供橫向擴容的能力,在進行橫向擴容的時候,性能基本上能呈線性增加。
集羣看起來很牛,那麼建立起來很複雜麼?並不會,在k8s只要使用兩條指令就能夠建立一個集羣,一個是kubectl init進行初始化,建立一個master節點,第二條指令就是kubectl join xxx建立一個node節點,加入這個集羣。
在這邊能夠看到k8s在物理上進行劃分的時候,劃分了兩種類型的主機,一個master節點,主要用來調度,控制集羣的資源等功能;而node節點,主要是用來運行容器的節點,也就是運行服務的節點。
其實集羣都差很少,master用來控制,用來存儲各類元數據,node節點是一個工做節點,真正來幹活的;node節點定時與master進行通訊,經過kubelet進程來彙報信息。
建立了集羣,我要怎麼看信息?以下:
二、 部署應用
使用集羣的主要目標是啥?用來提供服務,讓開發開發的應用程序能在集羣上運行,從而須要讓開發能運行一個應用來進行測試。
一條指令就能運行一個服務,有了image以後就是這麼簡單。因此,在開發完成程序以後,須要將程序打包成image,而後放到registry中,而後就可以運行應用了。
在部署完成應用以後,就能夠看到應用的名稱,指望狀態是運行一個pod,當前有一個pod,活動的也是一個,還有啓動的時間,那麼什麼是pod呢?
在k8s裏面,集羣調度的最小單元就是一個pod,一個pod能夠是一個容器,也能夠是多個容器,例如你運行一個程序,其中使用了nginx,使用mysql了,使用了jetty,那麼能夠將這三個使用在同一個pod中,對他們提供統一的調配能力,一個pod只能運行在一個主機上,而一個主機上能夠有多個pod。
那麼有人會問,爲何要使用pod,爲何不能直接使用容器呢?使用pod,至關與一個邏輯主機,還記得建立一個vm,在vm上運行幾個進程麼,其實道理是同樣的,pod的存在主要是讓幾個緊密鏈接的幾個容器之間共享資源,例如ip地址,共享存儲等信息。若是直接調度容器的話,那麼幾個容器可能運行在不一樣的主機上,這樣就增長了系統的複雜性。
三、發佈應用
發佈應用主要就是對外提供服務,可能會有人提出疑問,我都運行了服務,爲何還不能提供服務,這是由於在集羣當中,建立的ip地址等資源,只有在同一個集羣中才能訪問,每一個pod也有獨一的ip地址,當有多個pod提供相同的服務的時候,就須要有負載均衡的能力,從而這裏就涉及到一個概念就是service,專門用來提供服務的。
服務主要是用來提供外界訪問的接口,服務能夠關聯一組pod,這些pod的ip地址各不相同,而service至關於一個複雜均衡的vip,用來指向各個pod,當pod的ip地址發生改變以後,也能作到自動進行負載均衡,在關聯的時候,service和pod之間主要經過label來關聯,也就是標籤(-l表示爲label)。
從而外界就能夠訪問此應用了,以下:
四、 擴容縮容
在業務上線以後,碰到了雙十一怎麼辦?擴容。。。萬劍歸宗,只要有一個pod,那麼就能夠產生無數個pod。。。。
過了雙十一怎麼辦,縮容。。。
橫向擴展的能力。。每次擴容縮容的時候,這種會不會以爲很方便,一句話的事兒。。不用建立vm,不用去部署中間件,不用去各類修改配置,這就是自動化。。。
五、 更新
有新版本了,我要發佈。。。那麼。。。
滾動更新。。。根據新的image建立一個pod,分配各類資源,而後自動負載均衡,刪除老的pod,而後繼續更新。。。。不會中斷服務。。。
更新錯了怎麼辦,不慫,不會影響生產業務,回滾就行了。。。幾秒鐘的事兒。。。
後話
k8s的基本入門,其實算是一種用戶視角,只是用來演示如何使用k8s,怎麼提升了生產力而已。
在給客戶演示的時候,爲啥要選擇k8s?主要就是如何提升了發佈的效率,更新版本的效率,更方便更快捷的上線新版本。
可是在運維關注的視角下,這些遠遠不夠。。。master?存儲了哪些元數據,存儲在etcd中?如何來進行監控?在不少不少系統狀況下,怎麼來部署k8s,是一個項目一個k8s仍是一個k8s多個項目?等等一系列的問題。。。
原文:https://blog.csdn.net/TM6zNf87MDG7Bo/article/details/79621510
Kubernetes解決的問題:
1. 調度 - 容器應該在哪一個機器上運行
2. 生命週期和健康情況 - 容器在無錯的條件下運行
3. 服務發現 - 容器在哪,怎樣與它通訊
4. 監控 - 容器是否運行正常
5. 認證 - 誰能訪問容器
6. 容器聚合 - 如何將多個容器合併成一個工程
Kubernetes組件組成:
1. kubectl
客戶端命令行工具,將接受的命令格式化後發送給kube-apiserver,做爲整個系統的操做入口。
2. kube-apiserver
做爲整個系統的控制入口,以REST API服務提供接口。
3. kube-controller-manager
用來執行整個系統中的後臺任務,包括節點狀態情況、Pod個數、Pods和Service的關聯等。
4. kube-scheduler
負責節點資源管理,接受來自kube-apiserver建立Pods任務,並分配到某個節點。
5. etcd
負責節點間的服務發現和配置共享。
6. kube-proxy
運行在每一個計算節點上,負責Pod網絡代理。定時從etcd獲取到service信息來作相應的策略。
7. kubelet
運行在每一個計算節點上,做爲agent,接受分配該節點的Pods任務及管理容器,週期性獲取容器狀態,反饋給kube-apiserver。
8. DNS
一個可選的DNS服務,用於爲每一個Service對象建立DNS記錄,這樣全部的Pod就能夠經過DNS訪問服務了。
---------------------
--------------------------------------------------------------------------------------------------