(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访问服务了。
---------------------
--------------------------------------------------------------------------------------------------