小知识:一篇文章搞懂K8S高级特性

目录 K8S高级特性 高级特性 总结 kubectl排查服务问题 K8S真的放弃Docker了吗?

K8S高级特性

K8S中还有一些高级特性有必要了解下,比如弹性扩缩应用(见上文)、滚动更新(见上文)、配置管理、存储卷、网关路由等。

在了解这些高级特性之前有必要先看几个K8S的核心概念:

ReplicaSet

ReplicaSet确保任何时间都有指定数量的Pod副本在运行。通常用来保证给定数量的、完全相同的Pod的可用性。建议使用Deployment来管理ReplicaSet,而不是直接使用。

ConfigMap

ConfigMap是一种API对象,用来将非机密性的数据保存到键值对中。使用时,Pod可以将其用作环境变量、命令行参数或者存储卷中的配置文件。使用ConfigMap可以将你的配置数据和应用程序代码分开。

Volume

Volume指的是存储卷,包含可被Pod中容器访问的数据目录。容器中的文件在磁盘上是临时存放的,当容器崩溃时文件会丢失,同时无法在多个Pod中共享文件,通过使用存储卷可以解决这两个问题。

常用的存储卷有如下几种: configMap:configMap卷提供了向Pod中注入配置数据的方法。ConfigMap对象中存储的数据可以被configMap类型的卷引用,然后被Pod中运行的容器化应用使用。 emptyDir:emptyDir卷可用于存储缓存数据。当Pod分派到某个Node上时,emptyDir卷会被创建,并且Pod在该节点上运行期间,卷一直存在。当Pod被从节点上删除时emptyDir卷中的数据也会被永久删除。 hostPath:hostPath卷能将主机节点文件系统上的文件或目录挂载到你的Pod中。在Minikube中的主机指的是Minikube所在的虚拟机。 local:local卷所代表的是某个挂载的本地设备,例如磁盘、分区或者目录。local卷只能用作静态创建的持久卷,尚不支持动态配置。 nfs:nfs卷能将NFS(网络文件系统)挂载到你的Pod中。 persistentVolumeClaim:persistentVolumeClaim卷用来将持久卷(PersistentVolume)挂载到Pod中。持久卷(PV)是集群中的一块存储,可以由管理员事先供应,或者使用存储类(Storage Class)来动态供应,持久卷是集群资源类似于节点。

Ingress

Ingress 通过K8S的Ingress资源可以实现类似Nginx的基于域名访问,从而实现Pod的负载均衡访问。

%小知识:一篇文章搞懂K8S高级特性-猿站网-插图

安装Ingress

进入页面https://github.com/kubernetes/ingress-nginx/blob/nginx-0.20.0/deploy/mandatory.yaml,将里面的内容复制,保存到k8s master机器上的一个文件ingress-controller.yaml里,里面的镜像地址需要修改下,大家直接用下面这个yaml的内容:

下载地址(不需要积分):下载地址

?
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
– apiGroups:
– “”
resources:
– configmaps
– endpoints
– nodes
– pods
– secrets
verbs:
– list
– watch
– apiGroups:
– “”
resources:
– nodes
verbs:
– get
– apiGroups:
– “”
resources:
– services
verbs:
– get
– list
– watch
– apiGroups:
– “extensions”
resources:
– ingresses
verbs:
– get
– list
– watch
– apiGroups:
– “”
resources:
– events
verbs:
– create
– patch
– apiGroups:
– “extensions”
resources:
– ingresses/status
verbs:
– update
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
– apiGroups:
– “”
resources:
– configmaps
– pods
– secrets
– namespaces
verbs:
– get
– apiGroups:
– “”
resources:
– configmaps
resourceNames:
# Defaults to “<election-id>-<ingress-class>”
# Here: “<ingress-controller-leader>-<nginx>”
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
– “ingress-controller-leader-nginx”
verbs:
– get
– update
– apiGroups:
– “”
resources:
– configmaps
verbs:
– create
– apiGroups:
– “”
resources:
– endpoints
verbs:
– get
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
– kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
– kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: “10254”
prometheus.io/scrape: “true”
spec:
hostNetwork: true
serviceAccountName: nginx-ingress-serviceaccount
containers:
– name: nginx-ingress-controller
image: siriuszg/nginx-ingress-controller:0.20.0
args:
– /nginx-ingress-controller
– –configmap=$(POD_NAMESPACE)/nginx-configuration
– –tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
– –udp-services-configmap=$(POD_NAMESPACE)/udp-services
– –publish-service=$(POD_NAMESPACE)/ingress-nginx
– –annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
– ALL
add:
– NET_BIND_SERVICE
# www-data -> 33
runAsUser: 33
env:
– name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
– name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
– name: http
containerPort: 80
– name: https
containerPort: 443
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
ports:
– name: http
port: 80
targetPort: 80
protocol: TCP
– name: https
port: 443
targetPort: 443
protocol: TCP
selector:
app.kubernetes.io/name: default-http-backend
app.kubernetes.io/part-of: ingress-nginx

查看是否安装成功

?
1
kubectl get pods -n ingress-nginx -o wide

%小知识:一篇文章搞懂K8S高级特性-1猿站网-插图

配置ingress访问规则(就是类似配置nginx的代理转发配置),让ingress将域名 tomcat.core.com转发给后端的tomcat-service-yaml 服务,新建一个文件ingress- tomcat.yaml,内容如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: web-ingress
spec:
rules:
– host: tomcat.core.com # 转发域名
http:
paths:
– path: /
backend:
serviceName: tomcat-service-yaml
servicePort: 80 # service的端口

%小知识:一篇文章搞懂K8S高级特性-2猿站网-插图

查看生效的ingress规则:

?
1
kubectl get ing

%小知识:一篇文章搞懂K8S高级特性-3猿站网-插图

在访问机器配置host,master目录:/etc/hosts,在 host里增加如下host(ingress部署的机器ip对应访问的域名)

?
1
2
3
192.168.159.131 tomcat.core.com
或者
192.168.159.132 tomcat.core.com

配置完后直接在客户机浏览器访问http://tomcat.core.com/ ,能正常访问tomcat。

%小知识:一篇文章搞懂K8S高级特性-4猿站网-插图

高级特性

配置管理

ConfigMap允许你将配置文件与镜像文件分离,以使容器化的应用程序具有可移植性。接下来我们演示下如何将ConfigMap的的属性注入到Pod的环境变量中去。

添加配置文件nginx-config.yaml用于创建ConfigMap,ConfigMap名称为nginx-config,存储信息放在data节点下:

?
1
2
3
4
5
6
7
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
data:
nginx-env: test

应用nginx-config.yaml文件创建ConfigMap:

?
1
kubectl create -f nginx-config.yaml

获取所有ConfigMap:

?
1
kubectl get configmap

%小知识:一篇文章搞懂K8S高级特性-5猿站网-插图

通过yaml格式查看ConfigMap中的内容:

?
1
kubectl get configmaps nginx-config -o yaml

%小知识:一篇文章搞懂K8S高级特性-6猿站网-插图

添加配置文件nginx-deployment.yaml用于创建Deployment,部署一个nginx服务,在Nginx的环境变量中引用ConfigMap中的属性:

?
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
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
– name: nginx
image: nginx:1.10
ports:
– containerPort: 80
env:
– name: NGINX_ENV # 在Nginx中设置环境变量
valueFrom:
configMapKeyRef:
name: nginx-config # 设置ConfigMap的名称
key: nginx-env # 需要取值的键

应用配置文件创建Deployment:

?
1
kubectl apply -f nginx-deployment.yaml

创建成功后查看Pod中的环境变量,发现NGINX_ENV变量已经被注入了;

?
1
kubectl get pod -o wide

%小知识:一篇文章搞懂K8S高级特性-7猿站网-插图

?
1
2
3
kubectl exec -it nginx-deployment-5ff74658b6-rlft8 — sh
# 进入容器控制台执行,下面命令
ECHO $NGINX_ENV

存储卷使用

通过存储卷,我们可以把外部数据挂在到容器中去,供容器中应用访问,这样就算容器崩溃了,数据依然可以存在。

记得之前我们使用Docker部署Nginx的时候,将Nginx的html、logs、conf目录从外部挂载到了容器中;

?
1
2
3
4
5
docker run -p 80:80 –name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10

Minikube 可以认为是一台虚拟机,我们可以用Minikube的ssh命令来访问它

?
1
minikube ssh

Minikube中默认有一个docker用户,我们先重置下它的密码

?
1
sudo passwd docker

在Minikube中创建mydata目录

?
1
mkdir /home/docker/mydata

我们需要把nginx的目录复制到Minikube中去,才能实现目录的挂载,注意docker用户只能修改/home/docker目录中的文件,我们通过scp命令来复制文件

?
1
scp -r /home/macro/mydata/nginx docker@127.0.0.1:/home/docker/mydata/nginx

添加配置文件nginx-volume-deployment.yaml用于创建Deployment:

?
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
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-volume-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
– name: nginx
image: nginx:1.10
ports:
– containerPort: 80
volumeMounts:
– mountPath: /usr/share/nginx/html
name: html-volume
– mountPath: /var/logs/nginx
name: logs-volume
– mountPath: /etc/nginx
name: conf-volume
volumes:
– name: html-volume
hostPath:
path: /home/docker/mydata/nginx/html
type: Directory
– name: logs-volume
hostPath:
path: /home/docker/mydata/nginx/logs
type: Directory
– name: conf-volume
hostPath:
path: /home/docker/mydata/nginx/conf
type: Directory

应用配置文件创建Deployment

?
1
kubectl apply -f nginx-volume-deployment.yaml

添加配置文件nginx-service.yaml用于创建Service

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
– name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30080

查看下Service服务访问端口

?
1
kubectl get services

%小知识:一篇文章搞懂K8S高级特性-8猿站网-插图

通过CURL命令访问Nginx首页信息。

%小知识:一篇文章搞懂K8S高级特性-9猿站网-插图

总结

Service是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了“微服务”。举个例子,我们的一个服务 A,部署了 3 个备份,也就是 3 个 Pod;对于用户来 说,只需要关注一个 Service 的入口就可以,而不需要操心究竟应该请求哪一个 Pod。优 势非常明显:一方面外部用户不需要感知因为 Pod 上服务的意外崩溃、K8S 重新拉起 Pod 而造成的 IP 变更,外部用户也不需要感知因升级、变更服务带来的 Pod 替换而造成的 IP 变化,另一方面,Service 还可以做流量负载均衡。

但是,Service 主要负责 K8S 集群内部的网络拓扑。那么集群外部怎么访问集群内部呢?这个时候就需要 Ingress 了,官方文档中的解释是:

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。

ngress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

翻译一下:Ingress 是整个 K8S 集群的接入层,复杂集群内外通讯。

Ingress 和 Service 的网络拓扑关系图如下:

%小知识:一篇文章搞懂K8S高级特性-10猿站网-插图

kubectl排查服务问题

K8S 上部署服务失败了怎么排查?

用这个命令:

?
1
kubectl describe ${RESOURCE} ${NAME}

拉到最后看到Events部分,会显示出 K8S 在部署这个服务过程的关键日志。

一般来说,通过kubectl describe pod ${POD_NAME}已经能定位绝大部分部署失败的问题 了,当然,具体问题还是得具体分析。

K8S 上部署的服务不正常怎么排查?

如果服务部署成功了,且状态为running,那么就需要进入 Pod 内部的容器去查看自己的服 务日志了:

查看 Pod 内部某个 container 打印的日志:

?
1
kubectl log ${POD_NAME} ‐c ${CONTAINER_NAME}。

进入 Pod 内部某个 container:

?
1
kubectl exec ‐it [options] ${POD_NAME} ‐c ${CONTAINER_NAME} [args]

这个命令的作用是通过 kubectl 执行了docker exec xxx进入到容器实例内部。之后,就是 用户检查自己服务的日志来定位问题。

K8S真的放弃Docker了吗?

Docker作为非常流行的容器技术,之前经常有文章说它被K8S弃用了,取而代之的是另一 种容器技术containerd!其实containerd只是从Docker中分离出来的底层容器运行时,使 用起来和Docker并没有啥区别,从Docker转型containerd非常简单,基本没有什么门槛。 只要把之前Docker命令中的docker改为crictl基本就可以了,都是同一个公司出品的东西, 用法都一样。所以不管K8S到底弃用不弃用Docker,对我们开发者使用来说,基本没啥影响!

K8S CRI

K8S发布CRI(Container Runtime Interface),统一了容器运行时接口,凡是支持CRI的 容器运行时,皆可作为K8S的底层容器运行时。

K8S为什么要放弃使用Docker作为容器运行时,而使用containerd呢?

如果你使用Docker作为K8S容器运行时的话,kubelet需要先要通过dockershim去调用 Docker,再通过Docker去调用containerd。

如果你使用containerd作为K8S容器运行时的话,由于containerd内置了CRI插件, kubelet可以直接调用containerd。

使用containerd不仅性能提高了(调用链变短了),而且资源占用也会变小(Docker不是 一个纯粹的容器运行时,具有大量其他功能)。

当然,未来Docker有可能自己直接实现K8S的CRI接口来兼容K8S的底层使用。

到此这篇关于K8S高级特性的文章就介绍到这了,更多相关K8S高级特性内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/taotao_guiwang/article/details/121126606

声明: 猿站网有关资源均来自网络搜集与网友提供,任何涉及商业盈利目的的均不得使用,否则产生的一切后果将由您自己承担! 本平台资源仅供个人学习交流、测试使用 所有内容请在下载后24小时内删除,制止非法恶意传播,不对任何下载或转载者造成的危害负任何法律责任!也请大家支持、购置正版! 。本站一律禁止以任何方式发布或转载任何违法的相关信息访客发现请向站长举报,会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。本网站的资源部分来源于网络,如有侵权烦请发送邮件至:2697268773@qq.com进行处理。
建站知识

小知识:docker overlay实现跨主机的容器互通的方法

2023-3-14 18:45:42

建站知识

小知识:Docker微服务的ETCD集群搭建教程详解

2023-3-14 19:00:54

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索