K8s介绍

官网

用官网的话术介绍K8s: Kubernetes(K8s),是用于自动部署、扩容、缩容和管理容器化应用程序的开源系统。它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现。Kubernetes源自google 15年生产环境的运维经验,同时凝聚了社区最佳创意和实践。

简单讲,K8s就是一个生产级别的容器编排平台和集群管理系统,不仅能够创建、调度容器,还能够监控、管理服务器,它凝聚了 Google 等大公司和 开源社区的集体智慧,从而让中小型公司也可以具备轻松运维海量计算节点——也就是“云计算”的能力。

K8s核心组件

1.Master节点

API Server Apiserver是整个K8s系统的唯一入口,以RESTful API提供接口服务,并且加上了验证、授权等功能,所有其他组件都只能和它直接通信,可以说是 K8s里的联络员。

Controller-manager 控制中心,负责维护容器和节点等资源的状态,实现故障检测、服务迁移、应用伸缩等功能。 因为节点状态和Pod信息都存储在etcd里,所以要通过apiserver获得信息,才能够实现对资源的各种操作。

Scheduler 调度器,负责容器的编排工作,检查节点的资源状态,把Pod调度到最适合的节点上运行。

Etcd 是一个高可用的分布式Key-Value数据库,用来持久化存储系统里的各种资源对象和状态。 注意它只与apiserver有直接联系,也就是说任何其他组件想要读写etcd里的数据都必须经过apiserver。

2.Node节点

Kubelet 是Master在Node节点上的Agent,通过指挥容器引擎实现管理本机运⾏容器,⽐如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等⼯作。

Kube-proxy 在Node节点上实现Pod⽹络代理,维护⽹络规则和四层负载均衡⼯作。

Container-runtime 容器运行时,即容器引擎,例如docker、containerd、podman。是容器和镜像的实际使用者,在 kubelet 的指挥下创建容器,管理Pod的生命周期。

K8s单机板搭建 基于containerd

准备工作

关闭防火墙firewalld

systemctl stop firewalld
systemctl disable firewalld

关闭selinux

sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
setenforce 0

设置主机名

hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2

设置/etc/hosts

cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.159.105 k8s-master
192.168.159.106 k8s-node01
192.168.159.107 k8s-node02

关闭swap

swapoff -a 
永久关闭,vi  /etc/fstab 注释掉swap那行

将桥接的ipv4流量传递到iptables链

modprobe br_netfilter   ##生成bridge相关内核参数

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

sysctl --system # 生效

时间同步

yum install -y chrony;
systemctl start chronyd;
systemctl enable chronyd

安装containerd

安装yum-utils工具

yum install -y yum-utils  

配置Docker官方的yum仓库,如果做过,可以跳过

yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

安装containerd

yum install containerd.io -y

启动服务

systemctl enable containerd
systemctl start containerd

生成默认配置

containerd  config default > /etc/containerd/config.toml

修改配置

vi  /etc/containerd/config.toml
sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.8"   # 修改为阿里云镜像地址
SystemdCgroup = true                                                              # 使用systemd cgroup

重启containerd服务

systemctl restart containerd

安装kubeadm、kubelet和kubectl

由于官方k8s源在google,国内无法访问,这里使用阿里云yum源

# 执行配置k8s阿里云源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

# 安装kubeadm和kubelet,启动kubelet
yum install -y kubelet-1.25.4 kubeadm-1.25.4 kubectl-1.25.4;
systemctl start kubelet.service;
systemctl enable kubelet.service

# 设置crictl连接 containerd
crictl config --set runtime-endpoint=unix:///run/containerd/containerd.sock

初始化集群

kubeadm init --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --apiserver-advertise-address=192.168.1.132 --kubernetes-version=v1.25.4  --service-cidr=10.15.0.0/16  --pod-network-cidr=10.18.0.0/16

# 创建目录
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 获取节点信息
kubectl get node 
kubectl get pod --all-namespaces

安装calico网络

curl https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/calico.yaml -O

注意:下载需要外网。
可手动导入文件(复制粘贴) calico.yaml

下载完后还需要修改里面定义 Pod 网络(CALICO_IPV4POOL_CIDR),与前面 kubeadm init 的 –podnetwork-cidr 指定的一样

vim calico.yaml
# - name: CALICO_IPV4POOL_CIDR
# value: "192.168.0.0/16"
#取消注释,修改为如下:
- name: CALICO_IPV4POOL_CIDR
  value: "10.18.0.0/16"


# 部署
kubectl apply -f calico.yaml

# 查看
kubectl get pods -n kube-system

安装dashboard(可视化管理集群)

# 下载yaml文件
curl -O https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml

注意:下载需要外网。
可手动导入文件(复制粘贴) recommended.yaml

# 修改配置文件
vi  recommended.yaml
#修改内如
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard  ##这是第38行
spec:
  type: NodePort  ###添加这行
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30002  ###添加这行
  selector:
    k8s-app: kubernetes-dashboard

# 创建pod
kubectl apply -f recommended.yaml 

# 查看
kubectl get pod -n kubernetes-dashboard
kubectl get svc -n kubernetes-dashboard

注意: 如果kubectl get pod -n kubernetes-dashboard查看的状态一直是pendding,说明有问题:

# 查看原因
kubectl describe pod kubernetes-dashboard -n kubernetes-dashboard

Warning  FailedScheduling  4m31s (x18 over 89m)  default-scheduler  0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.

# 这是因为master节点上不允许该pod部署,需要解除限制:
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

浏览器访问:https://192.168.1.132:30002

注意:chrome浏览器访问有时候会出现“该网站发回了异常的错误凭据。这可能是因为有攻击者在试图冒充”。
解决:空白地方输入: thisisunsafe
或者更换浏览器,如:火狐浏览器

创建 service account 并绑定默认 cluster-admin 管理员集群⻆色:

# 创建用户
kubectl create serviceaccount dashboard-admin -n kubernetes-dashboard
# 用户授权
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:dashboard-admin
# 获取用户Token
kubectl create token dashboard-admin -n kubernetes-dashboard

使用输出的token登陆Dashboard

(Containerd)crictl命令用法

镜像相关

镜像相关功能 Docker Containerd
镜像拉取 docker pull crictl pull
镜像推送 docker push 无,例如buildk
镜像删除 docker rmi crictl rmi
镜像列表 docker images crictl images
镜像搜索 docker search crictl search
镜像详情 docker inspect IMAGE-ID crictl inspect IMAGE-ID
镜像加载 docker load crictl load
镜像导出 docker save crictl save
镜像导入 docker load crictl load

容器相关

容器相关功能 Docker Containerd
显示容器列表 docker ps crictl ps
创建容器 docker create crictl create
启动容器 docker start crictl start
停止容器 docker stop crictl stop
删除容器 docker rm crictl rm
容器详情 docker inspect crictl inspect
附加容器 docker attach crictl attach
执行命令 docker exec crictl exec
查看日志 docker logs crictl logs
查看容器资源 docker stats crictl stats

pod相关

pod相关功能 Docker Containerd
显示pod列表 crictl pods
查看pod详情 crictl inspectp
运行pod crictl runp
停止pod crictl stopp

在K8s里快速部署一个应用

# 创建deployment
#deploymnet名字为testdp  镜像为nginx:1.23.2
kubectl create deployment testdp --image=nginx:1.23.2

# 查看deployment
kubectl get deployment

# 查看pod
kubectl get pods

# 查看pod详情
kubectl describe pod testdp-786fdb4647-pbm7b

# 创建service,暴漏pod端口到node节点上
kubectl expose deployment testdp --port=80 --type=NodePort --target-port=80  --name=testsvc

# 查看service
#可以看到暴漏端口为一个大于30000的随机端口,浏览器里访问 192.168.0.14:31693
kubectl get svc

K8s主要资源罗列

pod

K8s里最小部署单元,是整个K8s最核心的资源对象,它是一组容器的集合,可以只是单个容器,也可以多个容器。

pod相关操作命令:

命令 说明
kubectl run podname --image=镜像 启动容器
kubectl get pods 查看pod列表
kubectl describe pod podname 查看pod详情
kubectl exec -it podname -- /bin/bash 进入pod容器
kubectl delete pod podname 删除pod
kubectl logs podname 查看pod日志

Deployment

比pod更高一层及的资源对象,它提供了一种对pod的管理方式,它可以很方便地实现pod的扩容、缩容、升级、回滚。

Deployment相关操作命令:

命令 说明
kubectl create deployment dpname --image=镜像 创建deployment
kubectl get deployment 查看deployment列表
kubectl describe deployment dpname 查看deployment详情
kubectl delete deployment dpname 删除deployment
kubectl scale deployment dpname --replicas=n 扩容deployment
kubectl rollout undo deployment dpname 回滚deployment

Service

为pod提供负载均衡、对外统一访问入口,用户访问具体pod时,不需要关心pod地址,而只需要通过这个固定的Service地址来访问

Service相关操作命令:

命令 说明
kubectl expose deployment dpname --port=service端口 --type=NodePort --target-port=pod监听端口 --name=svcname 创建service,同时定义暴漏port
kubectl get svc 查看service列表
kubectl describe svc svcname 查看service详情
kubectl delete svc svcname 删除service

service 的类型:

  • ClusterIP:提供一个集群内部的虚拟IP以供Pod访问(service默认类型)

  • NodePort:在每个Node上打开一个端口以供外部访问,Kubernetes将会在每个Node上打开一个端口并且每个kocde的端口都是一样的,通过NodeIp:NodePort的方式Kubernetes集群外部的程序可以访问Service。
    注:每个端口只能是一种服务,端口范围只能是 30000-32767。

  • LoadBalancer:通过外部的负载均衡器来访问,通常在云平台部署LoadBalancer还需要额外的费用。

Label

Label是一个键值对,其中键和值都由用户自定义,Label可以附加在各种资源对象上,如Node、Pod、Service、Deployment等。
一个资源对象可以定义多个Label,同一个Label也可以被添加到任意数量的资源对象上。Label可以在定义对象时定义,也可以在对象创建完后动态添加或删除。

Volume

Volume是pod中能够被多个容器访问的共享目录,kubernetes中的volume和docker中的volume不一样,主要有以下几个方面:

  • kubernetes的volume定义在pod上,然后被一个pod里的多个容器挂载到具体的目录下

  • kubernetes的volume与pod生命周期相同,但与容器的生命周期没关系,当容器终止或者重启时,volume中的数据并不会丢失

  • kubernetes支持多种类型的volume,如glusterfs,ceph等先进的分布式文件系统

PV(persistent volume)

PV可以理解成kubernetes集群中某个网络存储中对应的一块存储,它与volume类似,但有如下区别:

  • PV只能是网络存储,不属于任何Node,但可以在每个Node上访问到

  • PV并不是定义在pod上,而是独立于pod之外定义

  • PV目前只有几种类型:GCE Persistent Disk、NFS、RBD、iSCSCI、AWS ElasticBlockStore、GlusterFS

PVC(PersistentVolumeClaim)

如果某个pod想申请某种条件的PV,首先需要定义一个PVC对象

NameSpace

当kubernetes集群中存在多租户的情况下,就需要有一种机制实现每个租户的资源隔离。而namespace的目的就是为了实现资源隔离。

Namespace相关操作命令:

命令 说明
kubectl create namespace nsname 创建一个命名空间
kubectl get namespaces 查看所有命名空间。
default为默认命名空间,
kube-system:k8s系统外部的命名空间,
kube-public:公开的命名空间,谁都可以访问,
kube-node-lease:K8s 内部命名空间
kubectl -n nsname 查看资源时指定namespace
kubectl delete namespace nsname 删除一个命名空间