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 selector: matchLabels: app: test-k8s 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 type: NodePort ports: - port: 8080 name: test-k8s targetPort: 8080 - port: 8090 name: test-other targetPort: 8090
|
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 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 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
type: Opaque data: 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 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
|
或者挂载为文件(不展开了)
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
|