抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

k8s是啥

容器化应用提供集群部署和管理的开源工具

集群由master和node组成

Kubernetes 组件

kube-apiserver API 服务器,公开了 Kubernetes API
etcd 键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库
kube-scheduler 调度 Pod 到哪个节点运行
kube-controller 集群控制器
cloud-controller 与云服务商交互

node 组件

Kubelet 负责当前 Node 节点的 Pod 的创建、监控、修改和删除等

Proxy 负责 Service 代理,同时也是软件模式的负载均衡器

基本概念

pod

Kubernetes 中创建和管理的、最小的可部署的计算单元。安排在节点上,包含一组容器和卷。同一个Pod里的容器共享同一个网络命名空间,可以使用localhost互相通信。

一个pod内共享内部的所有资源。

lable

Label是attach到Pod的一对键/值对,用来传递用户定义的属性。Label Selector。

replication controller(RC)

Replication Controller确保任意时间都有指定数量的Pod“副本”在运行。如果为某个Pod创建了Replication Controller并且指定3个副本,它会创建3个Pod,并且持续监控它们。如果某个Pod不响应,那么Replication Controller会替换它,保持总数为3

(管理pod生命周期)

service

每个 Pod 都会被分配一个唯一的 IP, 不过缺点就是这个 IP 会随着 Pod 的销毁而消失。

一个 Service 可以视为是一组提供相同服务的 Pod 的对外访问接口

deploy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: test-k8s
spec:
replicas: 2
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: test-k8s
# 定义 Pod 相关数据
template:
metadata:
labels:
app: test-k8s
spec:
# 定义容器,可以多个
containers:
- name: nginx # 容器名字
image: nginx:latest # 镜像
ports:
- containerPort: 8080

单独配置 pod :

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
# 定义容器,可以多个
containers:
- name: nginx # 容器名字
image: nginx:latest # 镜像

service

  • Service 通过 label 关联对应的 Pod
  • Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重创改变 IP
  • 提供了负载均衡功能,自动转发流量到不同 Pod
  • 可对集群外部提供访问端口
  • 集群内部可通过服务名字访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
name: test-k8s # 必须配置
targetPort: 8080 # 容器端口
# nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
- port: 8090
name: test-other
targetPort: 8090
# nodePort: 32000

StatefulSet

StatefulSet 是用来管理有状态的应用,例如数据库。
前面我们部署的应用,都是不需要存储数据,不需要记住状态的,可以随意扩充副本,每个副本都是一样的,可替代的。
而像数据库、Redis 这类有状态的,则不能随意扩充副本。
StatefulSet 会固定每个 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
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
serviceName: mongodb
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:latest
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data/db
name: mongo-data
volumes:
- name: mongo-data
persistentVolumeClaim:
claimName: mongodata
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess (不分配ip)
clusterIP: None
ports:
- port: 27017
targetPort: 27017

  • Service 的 CLUSTER-IP 是空的,Pod 名字也是固定的。
  • Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
  • Pod 重建不会改变名字,除了IP,所以不要用IP直连

如果直接使用 Service 名字连接,会随机转发请求,要连接指定 Pod,可以这样pod-name.service-name,比如mongodb-0.mongodb

ConfigMap & Secret

1
2
3
4
5
6
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-config
data:
mongoHost: mongodb-0.mongodb

密码、TOKEN,我们可以放到 secret 中。(数据需要Base64编码)

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
# Opaque 用户定义的任意数据 https://kubernetes.io/zh/docs/concepts/configuration/secret/#secret-types
type: Opaque
data:
# 数据要 base64。https://tools.fun/base64.html
mongo-username: bW9uZ291c2Vy
mongo-password: bW9uZ29wYXNz

作为环境变量

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
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 3
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
# Secret 的所有数据定义为容器的环境变量,Secret 中的键名称为 Pod 中的环境变量名称
# envFrom:
# - secretRef:
# name: mongo-secret

或者挂载为文件(不展开了)

1
2
3
4
5
6
7
8
9
10
11
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret

ingress

Ingress 为外部访问集群提供了一个 统一 入口,避免了对外暴露集群端口;
功能类似 Nginx,可以根据域名、路径把请求转发到不同的 Service。
可以配置 https

跟 LoadBalancer 有什么区别?
LoadBalancer 需要对外暴露端口,不安全;
无法根据域名、路径转发流量到不同 Service,多个 Service 则需要开多个 LoadBalancer;
功能单一,无法配置 https

要使用 Ingress,需要一个负载均衡器 + Ingress Controller。

负载均衡插件,可以安装 METALLB

NGINX Ingress https://kubernetes.io/zh-cn/docs/tasks/access-application-cluster/ingress-minikube/

配置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
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-example
spec:
ingressClassName: nginx
rules:
- host: hello-world.info
http:
paths:
- path: /doc
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /svnbucket
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080

评论