Kubernetes:环境搭建

1、k8s 概念

1.1、基本概念

Kubernetes 是谷歌开源的基于容器技术的分布式架构方案,用于管理容器化的工作负载和服务,促进声明式配置和自动化。

Kubernetes 的功能有

  • 服务发现和负载均衡:使用 ip 地址或 dns 名称来暴露容器,并实现负载均衡分配网络流量
  • 部署和回滚:通过配置文件描述容器的期望状态,支持回滚到指定部署版本
  • 弹性伸缩:可根据指标配置自动伸缩策略,以应对突发流量
  • 容器配额管理:允许为每个容器指定所需的CPU和内存
  • 故障发现和自我修复:监控容器的运行状态,并尝试重启替换状态异常的容器
  • 密钥和配置管理:secret 和 configMap,两种资源来分别管理密钥信息和配置信息
  • 支持多种数据卷类型:例如:本地存储、公有云提供商、分布式存储系统等

1.2、基本术语

Pod

pod:最小可部署单元,调度的最小基本单位,代表集群上正在运行的一个进程。

k8s 为每个 pod 分配唯一的 pod ip,每个 pod 有一个 pause 容器( 根容器)。pod 内的多个容器,共享 pause 容器的 ip 和 volume;同时 pause 容器的状态代表整个 pod 的状态。

Label

label:kv 键值对,通过给指定资源对象绑定 label 来实现对资源对象的分组管理。

通过 label 为资源对象贴上相对应的标签,然后通过 Label Selector(标签选择器)查询和筛选拥有某些 label 的资源对象。

例如:

# 标签选择器
selector:  
# 1、标签匹配
matchLabels: 
  app: myweb # 选择标签 key-app,value-myweb 资源
 # 2、表达式匹配
matchExpressions:
  # 选择标签 key-tier, value-in (frontend, backend) 
  - {key: tier, operator: In, values: [frontend,backend]} 
  # 或使用以下写法,操作:In, NotIn, Exists and DoesNotExist
  - key: tier
    operator: In 
    values: ["frontend","backend"]

RC

Repliacation Controller,RC 副本控制器。保持 pod 的副本数量与预期数量一致。deployment 内部包含该功能,所以不推荐使用。

RS

Replica Set,RS 副本控制器。RC 的升级版本,区别在于:

  • RC 的 Label Selector 仅支持基于等式的表达式,RS 的 Label Selector 可以支持基于集合的表达式。
  • 在线编辑后,RS 自动更新 pod,RC 不会自动更新现有 pod。

Deployment

deployment:部署,副本控制器,用于更好的解决 pod 的部署、升级、回滚等问题。内部会自动创建 RS 用于pod 的副本控制。

deployment 相较于 RC/RS 具有以下优势:

  • deployment 资源对象会自动创建 RS 资源对象来完成部署,对 deployment 的修改并发布会产生新的 RS 资源对象,为新的发布版本服务。
  • 支持查看部署进度,以确定部署操作是否完成
  • 更新 deployment,会触发部署从而更新 pod
  • 支持 pause | resume 操作,暂停后修改不会触发发布,恢复后发布新的 deployment
  • 支持回滚操作
  • 支持重新启动操作,触发 pod 更新。
  • 自动清理不需要的 RS

StatefulSet

StatefulSet:管理有状态应用的 pod,例如 Kafka 集群、Mysql 集群、MongoDB集群等。与无状态的服务不同的是:无论怎么调度,每个 pod 都有一个永久不变的ID。

面向无状态的应用:RC、Deployment、DaemonSet、Job等。

DaemonSet

副本控制器,每个节点只运行一个 pod 副本。区分 deployment 多副本。

应用:每个节点上运行集群守护进程、日志收集守护进程和监控守护进程。

Service

Service:微服务,将运行在一组 pods 上的应用程序公开为网络服务。通过 service 资源对象定义一个 service 的访问入口地址 。前端应用通过访问这个入口,从而访问其背后的一组有 pod 副本组成的集群实例。service 所针对的目标 pods 集合通常通过 label selector来确定。service 一旦被定义,就被分配了一个不可变更的 cluster ip,在整个 service的生命周期内,该 ip 地址都不会发生改变。

在这里插入图片描述

Namespace

namespace:命名空间,提供资源隔离。通过命名空间可以将同一个集群中的资源划分为相互隔离的组。同一命名空间下的资源名称必须唯一,但是不同命名空间下的资源名称可以一样。

其他概念

  • Resource:k8s 是一个高度自动化的资源控制系统,大部分概念都可以看作资源对象。
  • HPA:Horizontal Pod Autoscale,pod 横向自动伸缩。根据目标 pod 的负载变化,针对性调整目标 pod 的副本数量。
  • Job:工作任务
  • Volume:数据卷
  • ConfigMap:管理非机密的配置项的数据
  • Secret:管理密钥数据

2、k8s 架构

在这里插入图片描述

2.1、k8s 节点

k8s 集群由 master 节点和 node 节点组成

  • master 节点:集群控制节点,为集群做出全局决策,不运行任何工作负载。
  • node 节点:集群工作 worker 节点

2.2、k8s 组件

master 节点运行 master 组件 + node 组件,node 节点只运行 node 组件。

2.2.1、master 组件
  • kube-controller-manager:负责运行控制器进程。包括节点控制器、任务控制器、端点控制器、副本控制器、服务账户和令牌控制器。
  • kube-scheduler:负责监视新创建的、未指定运行节点的 pod,并选择节点来运行 pod。
  • kube-apiserver:负责公开 k8s API,处理接受请求的工作,支持高可用部署。
  • etcd:兼顾一致性与高可用的键值数据库,用来保存 k8s 集群数据。
2.2.2、node 组件
  • kubelet:节点代理,监视分配给节点的 pod
  • kube-proxy:网络代理,维护节点上的网络规则,允许 pod 网络通信
  • docker:运行容器,例:docker engine + cri-dockerd

3、k8s 集群安装配置

3.1、docker

首先安装并运行 docker。参考文章:Docker: 容器与镜像

在 docker 运行时安装 cri-dockerd

cri-dockerd 安装

# 下载
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.6/cri-dockerd-0.2.6.amd64.tgz
# 解压到 /tmp 目录
tar -zxvf cri-dockerd-0.2.6.amd64.tgz -C /tmp
# 安装
sudo cp /tmp/cri-dockerd/cri-dockerd /usr/bin/

cri-dockerd 配置

# 获取源码
git clone https://github.com/Mirantis/cri-dockerd.git
# 将源码中systemd配置文件拷贝到相应目录
sudo cp cri-dockerd/packaging/systemd/* /etc/systemd/system/

# 配置
sudo vim /etc/systemd/system/cri-docker.service
# 在 [Service] ExecStart 配置项添加:
# --network-plugin 自定义容器网络
# --pod-infra-container-image 根容器镜像
[Service]
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.7

启动服务

# 重新加载配置
sudo systemctl daemon-reload
# 设置为开机自启动
sudo systemctl enable cri-docker
# 启动服务
sudo systemctl start cri-docker
# 检查服务状态
sudo systemctl status cri-docker

3.2、主机环境调整

修改节点 docker 的 cgroup driver

由于 k8s 中 kubelet 组件默认使用的 cgroupdriver 为 systemd,所以将 docker 的 cgroup driver 为 systemd。

sudo vim /etc/docker/daemon.json
# 增加配置内容
"exec-opts": [
	"native.cgroupdriver=systemd"
]

# 重新加载配置并重启 docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker

关闭防火墙

sudo systemctl stop firewalld
sudo systemctl disable firewalld

禁用 Selinux

# 查看 selinux 状态
sudo apt install selinux-utils
getenforce

# 禁用
sudo setenforce 0

禁用 swap

# 禁用交换区
sudo swapoff -a
# 打开文件注释交换区定义
sudo vim /etc/fstab
# /swap.img		none	swap	sw	0	0

# 查看交换区
free
# 显示
交换:          0           0           0

修改主机名

# 1、增加主机名与本机ip映射
sudo vim /etc/hosts
# 2、修改系统主机名
# 修改主机名
sudo hostnamectl set-hostname k8s-master1
# 查看主机名
hostname

3.3、安装 kube 工具

# 1、更新包管理索引
sudo apt-get update
# 支持 https 访问
sudo apt-get install -y apt-transport-https ca-certificates curl

# 2、下载 gpg 秘钥
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg

# 3、设置 k8s 镜像源
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 查看设置好的镜像源
ls /etc/apt/sources.list.d/

# 4、更新apt软件索引,并查看相关软件的可用版本
sudo apt-get update
apt-cache madison kubelet kubeadm kubectl

# 5、安装指定版本
# sudo apt-get install -y kubelet=<VERSION_STRING> kubeadm=<VERSION_STRING> kubectl=<VERSION_STRING>
sudo apt-get install -y kubelet=1.24.1-00 kubeadm=1.24.1-00 kubectl=1.24.1-00

# 6、锁定软件版本(防止自动升级)
sudo apt-mark hold kubelet kubeadm kubectl

# 7、检查kubelet状态
systemctl status kubelet

# 卸载
sudo apt-get remove kubelet kubectl kubeadm

3.4、Master 节点初始化

生成默认配置文件

kubeadm config print init-defaults > init.default.yaml

修改配置文件

vim init.default.yaml

# 1、修改节点IP地址
localAPIEndpoint.advertiseAddress: 192.168.88.132
# 2、修改套接字
nodeRegistration.criSocket: unix:///var/run/cri-dockerd.sock
# 3、修改节点名称
nodeRegistration.name: k8s-master1
# 4、修改镜像仓库地址为国内开源镜像库
imageRepository: registry.aliyuncs.com/google_containers
# 5、修改版本号
kubernetesVersion: 1.24.1
# 6、增加 podSubnet。安装 flannel 网络插件,必须在集群初始化时指定 pod 地址
# 10.244.0.0/16 为 flannel 组件 podSubnet 默认值,集群与组件配置保持一致。
networking.podSubnet: 10.244.0.0/16

拉取相关镜像

sudo kubeadm config images pull --config=init.default.yaml

初始化集群

# 通过配置文件初始化集群,建议选择配置文件初始化
sudo kubeadm init --config=init.default.yaml

初始化成功,返回提示信息:根据当前用户的类型,二选其一,执行相应的操作

普通用户执行

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

root 用户执行

export KUBECONFIG=/etc/kubernetes/admin.conf
source /etc/profile

查看集群状态

# 查看 pod
kubectl get pod -A
# 查看节点
kubectl get node
# 查看所有组件
kubectl get cs

添加 pod 网络组件

下载 flannel 网络组件定义文件 到本地,也可以将文件内容拷贝到本地新建的 flannel.yml 文件

---
kind: Namespace
apiVersion: v1
metadata:
  name: kube-flannel
  labels:
    pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
- apiGroups:
  - "networking.k8s.io"
  resources:
  - clustercidrs
  verbs:
  - list
  - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
        #image: flannelcni/flannel-cni-plugin:v1.1.2 #for ppc64le and mips64le (dockerhub limitations may apply)
        image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.2
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
       #image: flannelcni/flannel:v0.20.2 #for ppc64le and mips64le (dockerhub limitations may apply)
        image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
       #image: flannelcni/flannel:v0.20.2 #for ppc64le and mips64le (dockerhub limitations may apply)
        image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-plugin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate

应用资源

kubectl apply -f kube-flannel.yml

开启 kube-proxy 的 ipvs 模式

# 修改 mode: "ipvs"
kubectl edit -n kube-system cm kube-proxy
# 重启kube-proxy 守护进程
kubectl rollout restart -n kube-system daemonset kube-proxy

3.5、node 节点初始化

下列步骤同上

  • 环境安装:docker,cri-dockerd,kubeadm、kubelet、kubectl 等工具
  • 节点环境修改:修改 docker 的 cgroup driver,关闭防火墙,禁用 selinux,禁用 swap

将节点添加到集群

# master 节点执行
kubeadm token create --print-join-command
# 获得加入集群的命令
# 在命令上附加参数 --cri-socket unix:///var/run/cri-dockerd.sock,指定容器套接字
# 例如:
sudo kubeadm join 192.168.88.132:6443 --token 0dl98k.x44gmzyqy4b9h5gt --discovery-token-ca-cert-hash sha256:707002c5b13f2adc0facaf6e7b514b72dc0f8e7085925988daf5e99caf77a9c9 --cri-socket unix:///var/run/cri-dockerd.sock

3.6、重置节点

# 重置节点
sudo kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock
sudo rm -rf /var/lib/kubelet /var/lib/dockershim /var/run/kubernetes /var/lib/cni/etc/cni/net.d $HOME/.kube/config
sudo ipvsadm --clear

# 删除网络
sudo ifconfig cni0 down
sudo ip link delete cni0

4、k8s 集群升级

升级 k8s 集群到 1.25 版本。

4.1、升级 Master 节点

kubeadm 升级

# 更新包管理器
sudo apt-get update
# 查看可用版本
apt-cache madison kubeadm

# 解除 kubeadm 软件包保留状态
sudo apt-mark unhold kubeadm
# 安装
sudo apt-get install -y kubeadm=1.25.5-00
# 设置为保留,即不自动更新
sudo apt-mark hold kubeadm

# 验证版本
kubeadm version

验证升级计划

# 验证升级计划
sudo kubeadm upgrade plan

返回的信息包括:检查可升级的版本,并查看需要手动升级的部分。

节点升级

1、升级 master 组件

根据升级计划,执行指定版本的升级命令,例如:v1.25.5

sudo kubeadm upgrade apply v1.25.5

2、升级 node 组件

2.1 & 2.2、调度保护 | 排空节点

开启调度保护,并将节点上除守护进程之外的其他进程调度到其他节点,不影响正常使用。

kubectl drain <nodename> --ignore-daemonsets
# 腾空节点
kubectl drain k8s-master1 --ignore-daemonsets
# 查看节点
kubectl get pod -A  # pod状态:pending
kubectl get node # 节点状态:SchedulingDisabled

2.3、node 组件升级

# 组件升级
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.25.5-00 kubectl=1.25.5-00
sudo apt-mark hold kubelet kubectl

# 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet

2.4、解除保护

kubectl uncordon <nodename>
kubectl uncordon k8s-master1

4.2、升级 node 节点

kubeadm 升级

# 更新包管理器
sudo apt-get update
# 查看可用版本
apt-cache madison kubeadm

# 解除 kubeadm 软件包保留状态
sudo apt-mark unhold kubeadm
# 安装
sudo apt-get install -y kubeadm=1.25.5-00
# 设置为保留,即不自动更新
sudo apt-mark hold kubeadm

# 验证版本
kubeadm version

节点升级

sudo kubeadm upgrade node
# master 节点操作:腾空节点,开启调度保护
kubectl drain <nodename> --ignore-daemonsets
# node 组件升级
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet=1.25.5-00 kubectl=1.25.5-00
sudo apt-mark hold kubelet kubectl
# 重启 kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# master 节点操作:解除调度保护
kubectl uncordon <nodename>

5、kubectl 常用命令

5.1、准备工作

5.1.1、kubectl 命令补全
# 安装命令自动补全插件
sudo apt-get install -y bash-completion
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
5.1.2、安装 metric-server

metric-server 用于获取节点指标。

metrics server 获取 components.yaml 文档,并修改两处:

  • spec.template.containers.args 字段中添加 --kubelet-insecure-tls 选项,不验证客户端证书。
  • spec.template.containers.image字段替换为registry.aliyuncs.com/google_containers/metrics-server:v0.6.2

5.2、kubectl 语法

kubectl [command] [TYPE] [NAME] [flags]
  • command:指定对资源的操作。
  • TYPE:指定资源类型。资源类型不区分大小写,可以指定单数、复数或缩写形式
  • NAME:指定资源名称。资源名称区分大小写,若省略名称,则显示所有资源的详细信息。
  • flags:指定可选的参数

具体命令使用可以通过 -h 来查看

5.3、基础操作命令

# 创建资源
kubectl create -f FILENAME

# 创建服务,通过现有资源对象的配置信息将新的 service 与原有资源背后的 pod做关联
kubectl expose 

# 在集群中使用指定镜像启动容器
kubectl run 

# 为对象设置功能特性:env, img, resources, select
kubectl set SUBCOMMAND

# 显示资源文档说明
kubectl explain RESOURC

# 显示资源信息
kubectl get

# 修改服务器线上资源(已部署)
kubectl edit (RESOURCE/NAME | -f FILENAME)

# 删除资源
kubectl delete

# 更新资源的标签
kubectl label

# 更新资源所关联的注解
kubectl annotate

5.4、应用部署命令

# 显示目前版本与将要应用的版本之间的差异
kubectl diff -f FILENAME

# 将新的配置应用到资源上,旧的配置不改变
kubectl apply -f FILENAME

# 将新的配置已替换的方式应用到资源上,旧的配置覆盖
kubectl replace -f FILENAME

# 管理资源的上线
kubectl rollout SUBCOMMAND
# 查看历史修订版本和配置
kubectl rollout history (TYPE NAME | TYPE/NAME) [flags]
# 暂停标记的资源,目前仅支持 deployment 资源对象
kubectl rollout pause RESOURCE
# 恢复暂停的资源
kubectl rollout resume RESOURCE
# 重启资源对象
kubectl rollout restart RESOURCE
# 查看发布状态
kubectl rollout status (TYPE NAME | TYPE/NAME) [flags]
# 回滚之前的版本
kubectl rollout undo (TYPE NAME | TYPE/NAME) [flags]

# 伸缩容,设置 pod 的副本数
kubectl scale

# 创建自动缩放器,自动选择和设置在 k8s 集群集中运行的 pod 数。
kubectl autoscale

5.5、集群管理命令

# 显示节点或 pod 的资源(cpu/memory)使用情况
kubectl top

# 标记节点为不可调度
kubectl cordon <nodename>

# 标记节点为可调度的
kubectl uncordon <nodename>

# 腾空指定节点
kubectl drain <nodename>

# 更新节点污点。
# 污点 taint 和容忍度 toleration 相互配合,可以避免 pod 被分配到不合适的节点。
kubectl taint

5.6、故障排除和调试

# 显示某个资源或某组资源的详细信息
kubectl describe

# 输出 pod 中某容器的日志
kubectl logs

# 连接到一个正在运行的容器
kubectl attach

# 在容器中执行相关命令
kubectl exec

# 将一个或者多个本地端口转发到 pod
kubectl port-forward

# 代理网关
kubectl proxy

# 将文件和目录拷入/拷出容器
kubectl cp

# 创建用于排查工作负载和节点故障的调试会话
kubectl debug
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值