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 | 删除一个命名空间 |