Kubernetes入门

  11 分钟   13720 字    |    

Kubernetes入门

介绍

Kubernetes 是谷歌开源的容器集群管理系统,主要功能包括:

  • 基于容器的应用部署、维护和滚动升级
  • 负载均衡和服务发现
  • 跨机器和跨地区的集群调度自动伸缩
  • 无状态服务和有状态服务
  • 广泛的 Volume 支持
  • 插件机制保证扩展性

核心组件

Master

  • etcd 保存了整个集群的状态;
  • apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
  • controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;

Node

  • kubelet 负责维护容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
  • Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI);
  • kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡

术语

  1. Container
    Container(容器)是一种便携式、轻量级的操作系统级虚拟化技术。它使用 namespace 隔离不同的软件运行环境,并通过镜像自包含软件的运行环境,从而使得容 器可以很方便的在任何地方运行。

  2. Pod
    Kubernetes的最小单元,Pod 用来管理容器,每个 Pod 可以包含一个或多个紧密关联的容器。Pod 是一组紧密关联的容器集合,它们共享 PID、IPC、Network 和 UTS namespace, 是 Kubernetes 调度的基本单位。Pod 内的多个容器共享网络和文件系统,可以通过进 程间通信和文件共享这种简单高效的方式组合完成服务。

  3. Node
    Node 是 Pod 真正运行的主机,可以是物理机,也可以是虚拟机。为了管理 Pod,每个 Node 节点上至少要运行 container runtime(比如 docker 或者 rkt)、 kubelet 和 kube-proxy 服务。

  4. Namespace
    Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为 不同的项目组或用户组。

  5. 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 有效。
  1. 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

  1. 添加源
# 添加 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/
  1. 所有节点安装与启动
# 安装所需组件
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
  1. 初始化集群(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 访问到集群
  1. 加入工作节点(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

  1. 配置文件
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 # 镜像
  1. 部署及运维
# 部署应用
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

  1. 配置文件
apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  type: ClusterIP
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口
  1. 部署及运维
# 部署
kubectl apply -f service.yaml
# 查看
kubectl get svc
# 查看服务详情,Endpoints 是各个 Pod 的 IP
kubectl describe svc test-k8s
# 如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 8888:8080
  1. 直接把集群服务暴露出来,使用NodePortLoadbalancer 类型的 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 的名字

  1. 配置文件
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
  1. 部署与应用
# 部署
kubectl apply -f mongo.yaml
# Endpoints 会多一个 hostname,要连接指定 Pod,使用
pod-hostname.service-name # mongodb-0.mongodb
  1. 特性
  • Service 的 CLUSTER-IP 是空的,Pod 名字也是固定的。
  • Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
  • Pod 重建不会改变名字,除了IP

数据持久化image-20220930155042852

Storage Class (SC)

将存储卷划分为不同的种类,例如:SSD,普通磁盘,本地磁盘,按需使用。

Persistent Volume (PV)

描述卷的具体信息

Persistent Volume Claim (PVC)

pod要使用存储时,需要对存储需求进行声明,可以理解为一个申请单,系统根据这个申请单去找一个合适的 PV,还可以根据 PVC 自动创建 PV。

  1. 在文件存储服务器上安装nfs服务端
yum install nfs-utils rpcbind -y
mkdir -p /data/nfs
vim /etc/exports
# /data/nfs *(rw,sync)
systemctl start nfs-server.service
  1. 在worker上安装nfs客户端:yum install nfs-utils -y
  2. 创建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)
  1. 创建PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nfspvc1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: mynfs

ConfigMap & Secret

数据库连接地址,这种可能根据部署环境变化的,不应该写死在代码里

ConfigMap

可以方便的配置一些变量

  1. 配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: mongo-config
data:
  mongoHost: mongodb-0.mongodb
  1. 使用
# 应用
kubectl apply -f configmap.yaml
# 查看
kubectl get configmap mongo-config -o yaml

Secret

数据要进行 Base64 编码
  1. 配置
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. 应用
# 应用
kubectl apply -f secret.yaml
# 查看
kubectl get secret mongo-secret -o yaml
  1. 使用
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

~  ~  The   End  ~  ~


 赏 
感谢您的支持,我会继续努力哒!
支付宝收款码
tips
文章二维码 分类标签:技术dockerk8s
文章标题:Kubernetes入门
文章链接:http://120.46.217.131:82/archives/42/
最后编辑:2022 年 10 月 4 日 21:04 By Yang
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
(*) 4 + 9 =
快来做第一个评论的人吧~