-
minikube
K8S 集群模拟器安装文档:https://minikube.sigs.k8s.io/docs/start/
https://github.com/kubernetes/minikube/releases?page=2
https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/nd7yOvdY
-
直接用云平台 Kubernetes
可视化搭建,只需简单几步就可以创建好一个集群。
优点:安装简单,生态齐全,负载均衡器、存储等都给你配套好,简单操作就搞定 -
裸机安装(Bare Metal)
至少需要两台机器(主节点、工作节点个一台),需要自己安装 Kubernetes 组件,配置会稍微麻烦点。
可以到各云厂商按时租用服务器,费用低,用完就销毁。
缺点:配置麻烦,缺少生态支持,例如负载均衡器、云存储。
#kubectl 安装
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl
minikube start --driver=docker --registry-mirror=https://registry.docker-cn.com --force
#
minikube start --image-mirror-country='cn' --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --registry-mirror=https://ovfftd6p.mirror.aliyuncs.com --driver=docker --kubernetes-version v1.23.7 --force
#
minkube kubectl -- get pods -A
命令行启动pod
#运行pod
kubectl run nginx --image=registry.cn-hangzhou.aliyuncs.com/heliang230/nginx:1.8.1
#查看pod
kubectl get pod -A
yml文件启动pod
vi pod.yml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
# 定义容器,可以多个
containers:
- name: nginx-k8s # 容器名字
image: registry.cn-hangzhou.aliyuncs.com/heliang230/nginx:1.8.1 # 镜像
#启动pod
kubectl apply -f pod.yml
#查看pod
kubectl get pod
Deployment启动pod
vi deployment.yml
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: test-k8s # 容器名字
image: registry.cn-hangzhou.aliyuncs.com/heliang230/nginx:1.8.1 # 镜像
#启动pod
kubectl apply -f deployment.yml
常用命令
# 部署应用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看 pod
kubectl get pod -o wide
# 查看 pod 详情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name
# 进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。
kubectl exec -it pod-name -- bash
# 伸缩扩展副本
kubectl scale deployment test-k8s --replicas=5
# 把集群内端口映射到节点
kubectl port-forward pod-name 8090:8080
# 查看历史
kubectl rollout history deployment test-k8s
# 回到上个版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision=2
# 删除部署
kubectl delete deployment test-k8s
#删除pod
kubectl delete pod test-k8s
#扩缩容-容器
kubectl scale --help
kubectl scale -replicas=3 pod名称
kubectl scale -replicas=3 pod名称 -f foo.yaml
kubectl scale --replicas=3 deploy my-nginx
更多命令
# 查看全部
kubectl get all
# 重新部署
kubectl rollout restart deployment test-k8s
# 命令修改镜像,--record 表示把这个命令记录到操作历史中
kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record
# 暂停运行,暂停后,对 deployment 的修改不会立刻生效,恢复后才应用设置
kubectl rollout pause deployment test-k8s
# 恢复
kubectl rollout resume deployment test-k8s
# 输出到文件
kubectl get deployment test-k8s -o yaml >> app2.yaml
# 删除全部资源
kubectl delete all --all
Service
- Service 通过 label 关联对应的 Pod
- Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重创改变 IP
- 提供了负载均衡功能,自动转发流量到不同 Pod
- 可对集群外部提供访问端口
- 集群内部可通过服务名字访问
vi service.yaml
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: ClusterIP
ports:
- port: 80 # 本 Service 的端口
targetPort: 80 # 容器端口
应用配置 kubectl apply -f service.yaml
查看服务 kubectl get svc
查看服务详情 kubectl describe svc test-k8s
如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 80:80
对外暴露服务
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
多端口
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
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 的名字
部署 StatefulSet 类型的 Mongodb
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:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
targetPort: 27017
kubectl apply -f mongo.yaml
StatefulSet 特性
Service 的 CLUSTER-IP 是空的,Pod 名字也是固定的。
Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
Pod 重建不会改变名字,除了IP,所以不要用IP直连
数据持久化
介绍
kubernetes 集群不会为你处理数据的存储,我们可以为数据库挂载一个磁盘来确保数据的安全。
你可以选择云存储、本地磁盘、NFS。
本地磁盘:可以挂载某个节点上的目录,但是这需要限定 pod 在这个节点上运行
云存储:不限定节点,不受集群影响,安全稳定;需要云服务商提供,裸机集群是没有的。
NFS:不限定节点,不受集群影响
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data/db # 容器里面的挂载路径
name: mongo-data # 卷名字,必须跟下面定义的名字一致
volumes:
- name: mongo-data # 卷名字
hostPath:
path: /data/mongo-data # 节点上的路径
type: DirectoryOrCreate # 指向一个目录,不存在时自动创建
Storage Class (SC)
将存储卷划分为不同的种类,例如:SSD,普通磁盘,本地磁盘,按需使用。文档
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
Persistent Volume (PV)
描述卷的具体信息,例如磁盘大小,访问模式。文档,类型,Local 示例
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodata
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem # Filesystem(文件系统) Block(块)
accessModes:
- ReadWriteOnce # 卷可以被一个节点以读写方式挂载
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /root/data
nodeAffinity:
required:
# 通过 hostname 限定在某个节点创建存储卷
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
Persistent Volume Claim (PVC)
对存储需求的一个申明,可以理解为一个申请单,系统根据这个申请单去找一个合适的 PV
还可以根据 PVC 自动创建 PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-storage"
resources:
requests:
storage: 2Gi
为什么要这么多层抽象
- 更好的分工,运维人员负责提供好存储,开发人员不需要关注磁盘细节,只需要写一个申请单。
- 方便云服务商提供不同类型的,配置细节不需要开发者关注,只需要一个申请单。
- 动态创建,开发人员写好申请单后,供应商可以根据需求自动创建所需存储卷。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
image: mongo:5.0
imagePullPolicy: IfNotPresent
name: mongo
volumeMounts:
- mountPath: /data/db
name: mongo-data
volumes:
- name: mongo-data
persistentVolumeClaim:
claimName: mongodata
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
clusterIP: None
ports:
- port: 27017
protocol: TCP
targetPort: 27017
selector:
app: mongodb
type: ClusterIP
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mongodata
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem # Filesystem(文件系统) Block(块)
accessModes:
- ReadWriteOnce # 卷可以被一个节点以读写方式挂载
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /root/data
nodeAffinity:
required:
# 通过 hostname 限定在某个节点创建存储卷
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongodata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-storage"
resources:
requests:
storage: 2Gi
ConfigMap & Secret
数据库连接地址,这种可能根据部署环境变化的,我们不应该写死在代码里。
Kubernetes 为我们提供了 ConfigMap,可以方便的配置一些变量。文档
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mongo-config
data:
mongoHost: mongodb-0.mongodb
# 应用
kubectl apply -f configmap.yaml
# 查看
kubectl get configmap mongo-config -o yaml
Secret
一些重要数据,例如密码、TOKEN,我们可以放到 secret 中。文档,配置证书
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
# 应用
kubectl apply -f secret.yaml
# 查看
kubectl get secret mongo-secret -o yaml
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
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
网友评论