Kubernetes入门
Kubernetes入门
介绍
Kubernetes 是谷歌开源的容器集群管理系统,主要功能包括:
- 基于容器的应用部署、维护和滚动升级
- 负载均衡和服务发现
- 跨机器和跨地区的集群调度自动伸缩
- 无状态服务和有状态服务
- 广泛的 Volume 支持
- 插件机制保证扩展性
核心组件
Master
- etcd 保存了整个集群的状态;
- apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
- controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
Node
- kubelet 负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
- Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
- kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡
术语
Container
Container(容器)是一种便携式、轻量级的操作系统级虚拟化技术。它使用 namespace 隔离不同的软件运行环境,并通过镜像自包含软件的运行环境,从而使得容 器可以很方便的在任何地方运行。Pod
Kubernetes的最小单元,Pod 用来管理容器,每个 Pod 可以包含一个或多个紧密关联的容器。Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace, 是 Kubernetes 调度的基本单位。Pod 内的多个容器共享网络和文件系统,可以通过进 程间通信和文件共享这种简单高效的方式组合完成服务。Node
Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。为了管理 Pod,每个 Node 节点上至少要运行 container runtime(比如 docker 或者 rkt)、 kubelet 和 kube-proxy 服务。Namespace
Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为 不同的项目组或用户组。Service
Service 是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的入口。借助 Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service 有四种类型,其中两种为:
- ClusterIP:默认类型,自动分配一个仅 cluster 内部可以访问的虚拟IP
- NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过 :NodePort 来访问该服务。如果 kube-proxy 设置了 -- nodeport-addresses=10.240.0.0/16 (v1.10 支持),那么仅该 NodePort 仅对 设置在范围内的 IP 有效。
- Controller
- ReplicaSet
用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而异常多出来的容器也 会自动回收。典型应用场景包括:
- 确保健康 Pod 的数量、弹性伸缩
- 滚动升级以及应用多版本发布跟踪等。
- Deployment
Deployment 为 Pod(无状态) 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法, 典型应用场景包括:
- 定义 Deployment 来创建 Pod 和 ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续 Deployment
- StatefulSet
StatefulSet 是为了解决有状态服务的问题(对应 Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括:
- 稳定的持久化存储,即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现
- 稳定的网络标志,即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service(即没有 Cluster IP 的 Service)来实现
- 有序部署,有序扩展,即 Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依序进行(即从 0 到 N-1,在下一个 Pod 运行之前所有之前的 Pod 必须都 是 Running 和 Ready 状态),基于 init containers 来实现
- 有序收缩,有序删除(即从 N-1 到 0)
部署
安装k8s
- 添加源
# 添加 k8s 安装源
cat <<EOF > kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
mv kubernetes.repo /etc/yum.repos.d/
- 所有节点安装与启动
# 安装所需组件
yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4 docker-ce
# 启动
systemctl enable kubelet
systemctl start kubelet
systemctl enable docker
systemctl start docker
- 初始化集群(master)
# 初始化集群控制台 Control plane
# 失败了可以用 kubeadm reset 重置
kubeadm init --image-repository=registry.aliyuncs.com/google_containers
# 记得把 kubeadm join xxx 保存起来
# 忘记了重新获取:kubeadm token create --print-join-command
# 复制授权文件,以便 kubectl 可以有权限访问集群
# 如果你其他节点需要访问集群,需要从主节点复制这个文件过去其他节点
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 在其他机器上创建 ~/.kube/config 文件也能通过 kubectl 访问到集群
- 加入工作节点(worker)
kubeadm join 172.16.32.10:6443 --token xxx --discovery-token-ca-cert-hash xxx
工作荷载
工作荷载分为:
- Deployment
适合无状态应用,所有pod等价,可替代 - StatefulSet
有状态的应用,适合数据库这种类型。 - DaemonSet
在每个节点上跑一个 Pod,可以用来做节点监控、节点日志收集等 - Job & CronJob
Job 用来表达的是一次性的任务,而 CronJob 会根据其时间规划反复运行。
Deployment
- 配置文件
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: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
- 部署及运维
# 部署应用
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
Service
- 配置文件
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: ClusterIP
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
- 部署及运维
# 部署
kubectl apply -f service.yaml
# 查看
kubectl get svc
# 查看服务详情,Endpoints 是各个 Pod 的 IP
kubectl describe svc test-k8s
# 如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 8888:8080
- 直接把集群服务暴露出来,使用
NodePort
和Loadbalancer
类型的 Service
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
StatefulSet
StatefulSet 是用来管理有状态的应用,例如数据库,StatefulSet 会固定每个 Pod 的名字
- 配置文件
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
# Endpoints 会多一个 hostname,要连接指定 Pod,使用
pod-hostname.service-name # mongodb-0.mongodb
- 特性
- Service 的
CLUSTER-IP
是空的,Pod 名字也是固定的。 - Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
- Pod 重建不会改变名字,除了IP
数据持久化
Storage Class (SC)
将存储卷划分为不同的种类,例如:SSD,普通磁盘,本地磁盘,按需使用。
Persistent Volume (PV)
描述卷的具体信息
Persistent Volume Claim (PVC)
pod要使用存储时,需要对存储需求进行声明,可以理解为一个申请单,系统根据这个申请单去找一个合适的 PV,还可以根据 PVC 自动创建 PV。
- 在文件存储服务器上安装nfs服务端
yum install nfs-utils rpcbind -y
mkdir -p /data/nfs
vim /etc/exports
# /data/nfs *(rw,sync)
systemctl start nfs-server.service
- 在worker上安装nfs客户端:
yum install nfs-utils -y
- 创建PV资源
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfspv1
spec:
# 指定 PV 的容量为1Gi
capacity:
storage: 1Gi
# 指定访问模式
accessModes:
# PV 能以 readwrite 模式 mount 到单个节点
- ReadWriteOnce
# 指定 PV 的回收策略,即 PVC 资源释放后的事件,recycle (不建议,使用动态供给代替)删除 PVC 的所有文件
persistentVolumeReclaimPolicy: Recycle
# 指定 PV 的 class 为 mynfs,相当于为 PV 分类,PVC 将指定 class 申请 PV
storageClassName: mynfs
# 指定 PV 为 nfs 服务器上对应的目录
nfs:
path: /data/nfs
server: xxx(nfs server ip)
- 创建PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nfspvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: mynfs
ConfigMap & Secret
数据库连接地址,这种可能根据部署环境变化的,不应该写死在代码里
ConfigMap
可以方便的配置一些变量
- 配置
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
数据要进行 Base64 编码
- 配置
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
参考
[ 1 ] 尚硅谷Kubernetes教程
[ 2 ] https://k8s.easydoc.net/docs/dRiQjyTY/28366845/6GiNOzyZ/9EX8Cp45
[ 3 ] https://pan.baidu.com/s/1C7FC9R36qg0stixPdyrKCA?pwd=pqyy
[ 4 ] https://juejin.cn/post/6962417834425057310
[ 5 ] https://blog.51cto.com/liubin0505star/2639495
文章标题:Kubernetes入门
文章链接:http://120.46.217.131:82/archives/42/
最后编辑:2022 年 10 月 4 日 21:04 By Yang
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)