# kubernetes概述

# kubernetes是什么

  • 由 google开源的一个容器编排引擎
  • 简称k8s,是一个开源的,管理云平台中,多个主机上容器化的应用
  • 通过部署容器,每个应用被打包成一个容器镜像,更方便进行迁移,实现应用的部署/升级/回滚等操作

# kubernetes的发布历史

  • 2014年9月,kubernetes 0.2 版本发布
  • 2015年7月, kubernetes 1.0 版本发布
  • 2016年11月, kubernetes 1.5 版本发布
  • 2017年11月, kubernetes 1.9 版本发布
  • 2019年6月, kubernetes 1.15 版本发布
  • 2020年5月,kubernetes 1.18 版本发布
  • 2021年4月, kubernetes 1.21 版本发布
  • 2022年5月, kubernetes 1.24 版本发布

# kubenetes的搭建

# docker

  • 容器环境,注意,只要能够提供容器环境的都可,不限制是否是docker

# kubectl命令行

  • 操作k8s集群的命令行工具;
  • 命令行格式规则:kubectl [command] [TYPE] [NAME] [flags]

# kubeadm工具

  • 快捷搭建k8s的工具;

# 安装说明

  • 版本更新频繁,安装时最好指定兼容各自兼容的版本号

  • kubeletdocker安装为宿主机系统的守护进程;

  • k8s一般为集群,分为n个master节点,n个worker节点

  • master节点的操作为:

    • kubeadm init 初始化,如

      kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=1.21.3 --pod-network-cidr=10.0.0.0/24 --apiserver-advertise-address=192.168.28.128
      
    • 安装Pod网络插件,如

      kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
      
  • worker节点的操作为:

    • kubeadm join加入集群,如这个init命令由master的init后给出

      kubeadm join 192.168.28.128:6443 --token 6nw1nx.z2u8dv4gimbkhubm \
              --discovery-token-ca-cert-hash sha256:8806b5e7ac7f759a9ba00c132b8cead742f08c97fa5fb468b350e5434efe848e 
      
  • 安装参考网址:简书博文 (opens new window)

# k8s的资源

  • k8s中所有的内容,都抽象为资源,资源实例化后,称为对象
分类 说明
工作型资源 Pod
ReplicaSet
Deployment
StatefulSet
DaemenSet
Job
CronJob
服务发现与负载均衡资源 Service
Ingress
配置与存储型资源 Volume(存储卷)
ConfigMap
Secret

# Pod资源

  • Pod是k8s的最小资源单位
  • 是一个或多个容器的组合,这些容器共享存储、网络、和命名空间

# ReplicaSet资源

  • 作用是确保Pod以指定的副本个数运行

# Deployment资源

  • 用于管理Pod、ReplicaSet
  • 可以实现滚动升级和回滚应用,扩容和缩容;

# Service资源

  • 定义服务的访问入口地址
  • 前端应用通过入口地址,访问其背后的一组由Pod副本组成的集群实例;
  • 来自外部的访问请求被负载均衡到后端的各个容器应用上;

# ConfigMap资源

  • 用于将配置信息,促成你护卫Kubernetes对象的资源
  • 可存储各种类型的数据,如字符串、整数、文件等;

# Secret资源

  • 用于将敏感信息存储为k8s对象的资源;

# Volume资源

  • Pod中容器持久化数据的一种方式;
  • 可将容器中的数据存储到本地磁盘、网盘或者其它存储介质中

# Namespace资源

  • 对集群中资源的逻辑分组,用于隔离和管理资源

# kubectl命令

命令 描述
kubectl apply -f <filename.yaml> 使用yaml文件创建或更新资源
kubectl get <resource> 获取资源信息,如pod、deployment、service等
kubectl describe <resource> <resource-name> 查看指定资源的详细信息
kubectl delete <resource> <resource-name> 删除指定资源
kubectl logs <pod-name> 查看pod的日志
kubectl exec -it <pod-name> <command> 在pod中执行命令
kubectl port-forward <pod-name> <local-port>:<pod-port> 将pod的端口映射到本地端口
kubectl scale <resource> <resource-name> --replicas=<number> 扩容或缩容指定资源
kubectl rollout status <resource-name> 查看滚动更新的状态
kubectl create secret <secret-type> <secret-name> --from-literal=<key>=<value> 创建加密的secret
kubectl create configmap <configmap-name> --from-literal=<key>=<value> 创建configmap
kubectl label <resource> <resource-name> <label-key>=<label-value> 给资源打标签
kubectl annotate <resource> <resource-name> <annotation-key>=<annotation-value> 给资源添加注释信息
kubectl apply -f <filename.yaml> --dry-run 检查yaml文件是否正确,不会真正执行
kubectl top <resource> <resource-name> 查看资源的CPU和内存使用情况

# 关于Pod资源的操作

# 创建Pod

kubectl apply -f pod.yaml
kubectl run nginx --image=nginx

# 查看Pod

kubectl get pods
kubectl describe pod <pod名称>

# 查看日志

kubectl logs  <pod名称> [-c CONTAINER]
kubectl logs <pod名称> [-c CONTAINER] -f

# 进入终端容器

kubectl exec <pod名称> [-c CONTAINER] --bash

# 删除Pod

kubectl delete pod <pod名称>

# 导出pod的yaml配置文件

kubectl get pods web-sfsadfsd-fsdf -o yaml > web-pod.yaml

# 宿主机与pod文件交互

kubectl -n 分区名 cp ./project_extend.sql pod名字:/
kubectl -n 分区名 cp pod_name:文件/目录 ./文件名字

# Pod控制器

# 无状态服务

# ReplicationController

  • 用来确保容器应用的副本数始终保持在用户定义的副本数,有异常退出的容器,则创建新pod来替代,有多的pod则回收;
  • 新版本中建议使用ReplicaSet来取代ReplicationController

# ReplicaSet

  • 支持集合式的selector
  • 虽然RS可以单独使用,但一般建议使用Deployment来自动管理RS,如deployment支持滚动更新,但RS不支持;

# Deployment

  • 为Pod和ReplicaSet提供了声明式定义方法;
  • 支持通过定义Deployment来创建Pod和ReplicaSet;
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment;

# 有状态服务

# StatefulSet

  • 稳定的持久化存储,即pod重新调度后,还是能访问到相同的持久化数据,基于PVC实现
  • 稳定的网络标识,即Pod重新调度后,其PodName和HostName不变,基于Headless Service即没有ClusterIP的Service来实现;
  • 有序部署,有序扩展,即Pod是有顺序的,基于init containers实现
  • 有序收缩,有序删除;

# daemonSet

  • 用于确保全部Node上运行一个Pod的副本;
  • 当有Node加入集群时,也会为他们新增一个Pod;

# 任务

# Job

  • 仅执行一次的任务,用于确保批处理任务的一个或多个Pod成功结束

# CronJob

  • 管理基于时间的Job;
  • 典型场景如数据库定时备份;

# 网络通讯方式

  • Flannel时CoreOS团队针对k8s设计的网络规划服务,它让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址

# Pod内部通讯

  • 同一个Pod共享同一个网络命名空间,共享同一个Linux协议栈;

# Pod之间通讯

# 不在同一台主机时

  • 将Pod的IP和所在Node的IP关联起来,通过关联可以让Pod互相访问;

# 在同一台主机时

  • 由Docker0网桥直接转发请求至目标Pod,不需要经过Flannel

# Pod至Service网络

  • 由iptables维护和转发;
  • Service的负载为四层负载

# Pod至外网

  • 转发数据包到宿主机的网卡,宿主网卡完成路由选择后,iptables执行masquerade,把源IP改为宿主机网卡的IP,然后向外网发送请求

# 外网至Pod

  • 通过Service

# 存储

# ConfigMap

  • 可以通过ConfigMap设置环境变量,命令行参数,数据卷插件使用
apiVersion: v1
kind: ConfigMap
metadata:
	name: automannn-config
	namespace: default
data:
	log_level: INFO
---
apiVersion: v1
kind: Pod
metadata:
	name: automannn-test-pod
spec:
	containers:
		-name: test-container
		 image: xxxappName:xxxversipn
		 command: ["/bin/sh","-c","cat /etc/config/log_level"]
		 volumeMounts:
		 	- name: config-volume
		 	  mountPath: /etc/config
	volumes:
		- name: config-volume
		  configMap:
		  	name: automannn-config
  • 可以实现热更新,但是需要注意,挂载卷会更新,但是不会触发pod的滚动更新;

# Secret

  • 用法同configMap

# Volume

# emptyDir

  • 与pod的生命周期一致,最初是空的,pod中的容器可以读取和写入emptyDir卷中的文件;

  • apiVersion: v1
    kind: Pod
    metadata:
    	name: test-pd
    spec:
    	containers:
    		- image: xxxAppName:appVersion
    		  name: testContainer
    		  valueMounts:
    		  	- mountPath: /cache
    		  	  name: cache-volume
    	valumes:
    		- name: cache-volume
    		  emptyDir: {}
    

# hostPath

  • 将主机节点的文件系统中的文件或目录挂载到集群中;

  • apiVersion: v1
    kind: Pod
    metadata:
    	name: test-pd
    spec:
    	containers:
    		- image: xxxAppName:appVersion
    		  name: test-container
    		  volumeMounts:
    		  	- mountPath: /test-pd
    		  	  name: test-volume
    	volumes:
    		- name: test-volume
    		  hostPath: 
    		  	# directory location on host
    		  	path: /data
    		  	# this field is optional
    		  	type: Directory
    

# PersistenceVolume

  • 由管理员设置的存储,为集群的一部分,以资源的方式进行提供
  • 与pod类似,Pod消耗节点资源,PVC消耗PV资源;

# k8s安装

# 安装容器运行时,及环境准备

# 安装k8s集群

vim /etc/yum.repos.d/kubernetes.repo

[kubernetes]
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/
enabled=1 
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key
yum install -y kubeadm-1.28.12 kubelet-1.28.12 kubectl-1.28.12
systemctl enable kubelet


  • vim kubeadm-ipvs.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.12
networking:
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/12
apiServer:
  extraArgs:
    advertise-address: 192.168.10.7
imageRepository: registry.aliyuncs.com/google_containers
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs  # 核心配置:强制启用IPVS模式
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock  # 关键:在此处定义 cri-socket
kubeadm init  --config=kubeadm-ipvs.yaml #注意,一定要开启 ipvs,否则无法使用 stun协议进行暴露(在同一台主机的情况下)
# 初始化成功后会有这个命令提示,直接复制即可
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
#安装calico
wget https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/tigera-operator.yaml
wget https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/custom-resources.yaml
kubectl create -f tigera-operator.yaml

vim custom-resources.yaml
#改以下两个参数
blockSize: 24
cidr: 10.244.0.0/16

kubectl create -f custom-resources.yaml
#查看状态,会拉取失败,镜像拉取失败,需要设置代理,但是不能用常规的代理,有坑!
kubectl get pods -n calico-system
#---------------------------------
#-------配置containerd代理开始---------------
#---------------------------------
systemctl edit containerd

#代理不能用127.0.0.1,大坑!
[Service]
Environment="HTTP_PROXY=http://192.168.10.7:7890"
Environment="HTTPS_PROXY=http://192.168.10.7:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.cluster.local,.svc,node1,192.0.0.0/24,10.0.0.0/24"


systemctl daemon-reload
systemctl restart containerd
#---------------------------------
---------配置containerd代理结束--------------
#---------------------------------

#---------------------------------
#-------配置kubelet代理开始--------------- 这个也许不用配置,等后续实践;    这个已经证实不用配置,此处仅作存档
#---------------------------------
systemctl edit kubelet

#代理不能用127.0.0.1,大坑!
[Service]
Environment="HTTP_PROXY=http://192.168.10.7:7890"
Environment="HTTPS_PROXY=http://192.168.10.7:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.cluster.local,.svc,node1,192.0.0.0/24,10.0.0.0/24"


systemctl daemon-reload
systemctl restart kubelet
#---------------------------------
---------配置kubelet代理结束--------------
#---------------------------------

kubectl get pods --all-namespaces
#所有的Pod都为running之后,就是成功了

# 卸载集群

kubeadmin reset -f  #重置k8s集群

#清除配置文件
rm -rf ~/.kube/config
#删除cni插件文件
rm -rf /etc/cni/net.d/*
#清理数据目录
rm -rf /var/lib/etcd/
rm -rf /var/lib/kubelet/