1. 什么是k8s?
一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。
2. k8s核心功能
•自动化部署与伸缩:自动部署容器化应用,并根据负载动态调整副本数量。
•自我修复:当容器或节点故障时,自动重启或替换容器,确保应用高可用。
•服务发现与负载均衡:通过 Service 提供稳定的访问入口,并在多个 Pod 间分配流量。
•滚动更新与回滚:支持无缝更新应用,并在出现问题时快速回滚。
•存储编排:自动挂载存储系统(如本地磁盘、云存储),并提供持久化存储管理。
•配置与密钥管理:通过 ConfigMap 和 Secret 管理应用配置和敏感数据。
3. k8s架构与核心组件
K8s 集群采用主从架构,分为控制平面(Control Plane)和节点(Node)。
控制平面(Master 节点)
负责集群的管理和调度:
•kube-apiserver:集群的入口,处理所有 RESTful API 请求。
•etcd:分布式键值存储,保存集群的所有状态数据。
•kube-scheduler:负责将 Pod 调度到合适的 Node 上运行。
•kube-controller-manager:运行控制器(如 Node Controller、ReplicaSet Controller),确保集群状态符合预期。
•cloud-controller-manager(可选):用于与云服务商集成,管理云资源(如负载均衡器)。
工作节点(Node)
运行容器化应用:
•kubelet:负责管理节点上的 Pod 和容器,与控制平面通信。
•kube-proxy:实现 Service 的网络代理和负载均衡。
•容器运行时(如 containerd、CRI-O):负责运行容器。
4. 实战操作
4.1 配置linux主机操作
设置master、worker1和worker2三个机器,为了区分三个主机,分别设置三个主机名
hostnamectl set-homename master
hostnamectl set-homename worker1
hostnamectl set-homename worker2
之后需要设置IP地址段,根据自己的实际情况去配置,具体需要配置的是IPADDR、NETMASK、GATEWAY和DNS1。可以使用以下命令查看。
cat /etc/sysconfig/network-scripts/ifcfg-ens33
配置完成之后需要重新启动。
systemctl restart network
接着,配置主机操作文件,添加主机,使其可以相互连通。
vim /etc/hosts
然后需要关闭防火墙和配置selinux。
systemctl status firewalld
systemctl stop firewalld
systemctl disable firewalld #开机禁用
firewall-cmd --state
cat /etc/selinux/config
sed -ri 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
reboot
然后,设置主机的同步时间
yum -y install ntpdate
ntpdate time1.aliyun.com #立即同步
crontab -e
#crontab内容,定时进行时间同步
0 */1 * * * ntpdate time1.aliyun.com
如果使用kubeadm部署方式,则必须要关闭swap分区
vim /etc/fstab
free -m
reboot
接着,添加网桥过滤
vim /etc/sysctl.d/k8s.conf
#添加内容
net.bridge.bridge-nf-ca11-ip6tables=1
net.bridge.bridge-nf-ca11-iptables=1
net.ipv4.ip_forward =1
vm.swappiness= 0
#接着加载br_netfilter模块
modprobe br_netfilter
#查看是否加载
lsmod | grep br_netfilter
#加载网桥过滤配置文件
sysctl -p /etc/sysctl.d/k8s.conf
接着,安装并开启ipvs
yum -y install ipset ipvsadm
#添加需要加载的模块
cat > /etc/sysconfig/modules/ipvs.modules << EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
#授权、运行、检查是否加载
chmod 750 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
接着,需要安装docker-ce
#获取docker
wget -O /etc/yun.repos.d/docker-ce.repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
#查看docker版本
yum list docker-ce.x86_64 --showduplicates | sort -r
#安装docker
yum -y install --setopt=obsoletes=0 docker版本
#要修改docker配置文件
cat /usr/lib/systemd/system/docker.service
#如果在[Service]中的ExecStart中有 -H ,则删除-H后面的内容
#在docker的daemon文件中添加内容
cat /etc/docker.daemon.json
vim /etc/docker.daemon.json
#内容
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
4.2 安装k8s
vim /etc/yum.repos.d/k8s.repo
#添加以下配置信息
[kubernetes]
name=Kubernetes
baseur1=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-e17-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
#查看是否可有
yum list | grep kubeadm
#如果出现import gpg,则输入y进行确认
#三个host都进行安装,可以重复上述操作,或者是哦那个scp path hostname:path的操作进行复制
yum -y install kubeadm kubelet kubectl
安装完成之后,需要配置kubelet
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
systemctl enable kubelet
4.3 k8s镜像准备
master安装镜像
#查看集群使用的容器镜像
kubeadm config images list
#将其写入文件中方便下载
kubeadm config images list >> image.list
#对文件进行更改设置
vim image.list
#更改内容为如下格式;
#!/bin/bash
img_list = '
镜像列表
'
for img in ${img_list}
do
docker pull $img
done
#保存退出执行该文件
sh image.list
#查看安装的镜像
docker images
worker主机的镜像复制
#在master下保存worker中需要的镜像文件
docker save -o name.tar 要保存的镜像名
#然后使用scp进行拷贝
scp name.tar worker:path
#worker中加载拷贝的文件
docker load -i name.tar
4.4 集群初始化
在master节点操作,需保存初始化时的连接信息。
kubeadm init --kubernetes-version=v1.17.2 --pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=主机ip
#初始化之后创建kube文件
mkdir .kube
cp -i /etc/kubernetes/admin.conf .kube/config
接着,网络配置官网为https://kubernetes.io/docs/concepts/cluster-administration/addons,但是学习时讲的是calico,所以就以calico为例,具体到时候可以根据自己需求替换即可。依次使用docker load -i tar名字进行加载,master和worker1/2均要进行操作。
进行calico.yml文件的加载
kubectl apply -f calico.yml
最后,进行worker1和worker2与master的连接,这一个信息在master初始化是会给出,需要保存。
kubeadm join 192.168.216.100:6443 --token uahni7.2wz17nyx8obxhfnh --discovery-token-ca-cert-hash
sha256:48486b2cd572881fa28184177d331353146f2692744d2cc6bfa21132f01c4478
验证k8s集群是否可用
kubectl get nodes #查看节点状态
kubectl get cs #查看master组件信息
kubectl cluster-info #查看集群信息
kubectl get pods --namespace kube-system
5. kubectl的使用
5.1 kubectl的帮助
rpm -a | grep kubectl
kubectl --help
5.2 kubectl的子命令
类型 | 命令 | 描述 |
基础命令 | create | 通过文件名或标准输入创建资源 |
expose | 将一个资源公开为一个新的Service | |
run | 在集群中运行一个特定的镜像 | |
set | 在对象上设置特定的功能 | |
get | 显示一个或多个资源 | |
explain | 文档参考资料 | |
edit | 使用默认的编辑器编辑一个资源 | |
delete | 通过文件名、标准输入、资源名称或标签选择器来删除资源 | |
部署命令 | rollout | 管理资源分布 |
rolling-update | 对给定的复制控制器滚动更新 | |
scale | 扩容或缩容pod数量,Deployment、ReplicaSet等 | |
autoscale | 创建一个自动扩容或缩容并设置pod数量 | |
集群管理命令 | certificate | 修改证书资源 |
cluster-info | 显示集群信息 | |
top | 显示资源使用,需要heapster运行 | |
cordon | 标记节点不可调度 | |
uncordon | 标记节点可调度 | |
drain | 驱逐节点上的应用,准备下线维护 | |
taint | 修改节点taint标记 |
|
故障诊断和调式命令 | describe | 显示特定资源的详细信息 |
logs | 在一个pod中打印一个容器日志 | |
attach | 附加到一个运行的容器 |
|
exec | 执行命令到容器 | |
port-forward | 转发一个或多个本地端口到一个pod | |
proxy | 运行一个proxy到Kubernetes_API_server | |
cp | 拷贝文件或目录到容器中 | |
auth | 检查授权 | |
高级命令 | apply | 通过文件名或标准输入对资源应用进行配置 |
patch | 使用补丁修改、更新资源的字段 | |
replace | 通过文件名或标准输入替换一个资源 | |
convert | 不同API版本之间转换配置文件 | |
设置命令 | label | 更新资源上的标签 |
annotate | 更新资源上的注释 | |
completion | 实现kubectl工具的自动补全 | |
其他命令 | api-versions | 打印受支持的API版本 |
config | 修改kubeconfig文件 | |
help | 所有命令帮助 | |
plugin | 运行一个命令行插件 | |
version | 打印版本信息 |
5.3 worker节点
#准备集群管理配置文件
mkdir .kube
scp master:path/.kube/config .kube/
#验证
kubectl get nodes
6. yaml的写法
k8s集群中对资源管理和资源对象编排部署都可以通过yaml文件来解决,这种格式的文件又称为资源清单文件,通过kubectl命令执行yaml文件就可以对资源对象进行部署编排。
6.1 基本语法
使用空格作为缩进,缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
低版本缩进时不允许使用tab键,只能使用空格
使用#标识注释
数据结构为 键值对 的形式
6.2 常用字段
参数名 | 字段类型 | 说明 |
version | string | K8S API的版本,可以使用kubectl api-version查看 |
kind | string | yaml文件定义的资源类型和角色 |
metadata | object | 元数据对象,固定值就写metadata |
metadata.name |
string | 元数据对象的名字,如命名pod名字 |
metadata.namespace | string | 元数据对象的命名空间 |
spec | object | 详细定义对象,固定值就写spec |
举例说明:
创建一个namespace
apiVersion: v1
kind: Namespace
metadata:
name: test
创建一个pod
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: nginx-containers
image: nginx:latest
7. Namespace
命名空间。多租户情况下,实现资源隔离,该隔离属于逻辑隔离,属于管理边界,不属于网络边界。
7.1 查看namespace
kubectl get ns
#输出说明
default 用户创建的pod默认在此命名空间
kube-public 所有用户均可以访问
kube-node-lease k8s集群节点租约状态
kube-system k8s集群在使用
7.2 创建namespace
方式一:使用create
kubectl create namespace test
方式二:使用资源清单yaml,yaml格式如下
apiVersion: v1
kind: Namespace
metadata:
name: test2
kubectl apply -f create_ns.yaml
7.3 删除namespace
方式一:使用namespace名字删除
kubectl delete namespace test
方式二:使用yaml删除
kubectl delete -f create_test.yaml
8. pod概念
pod是k8s集群能调度的最小单元
8.1 查看pod
kubectl get pods
#查看指定namespace中的pod
kubectl get pods -n default
8.2 创建pod
kubectl apply -f create_pod.yaml
8.3 pod访问
使用kubectl get pod -owide查看pod的ip地址
curl http://IP
8.4 删除pod
kubectl delete pods pod_name -n namespace
#如果pod有控制器则需要使用yaml删除
kubectl delete -f create_pod.yaml
9. controller概念
控制器在k8s集群中,以loop方式监视pod状态,使pod一直处于用户期望状态。
常见的pod控制器:
Deployment:声明式更新控制器,用于发布无状态应用,默认为此版本
ReplicaSet:副本集控制器,用于对pod进行副本规模扩展或者裁剪
StatefulSet:有状态副本集,用于发布有状态应用
DaemonSet:在k8s集群每一个node上运行一个副本,用于发布监控或日志收集类等应用
Job:运行一次性作业任务
CronJob:运行周期性作业任务
9.1 Deployment介绍
具有上线部署、滚动升级、创建副本、回滚某一版本等功能
创建及查看方式
kubectl run nginx-app --image:nginx:latest --image-pull-policy=IfNotPresent --replicas=2
#查看
kubectl get deployment
#使用yaml创建
#create-nginx-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata: nginx-app2
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginxapp2-container
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- name: nginxapp2
containerPort: 80
#创建应用指令
kubectl apply -f create-nginx-app.yaml
删除时不能直接删除pod名称,pod会被重新拉起,需要删除部署的模式
#通过删除部署模式
kubectl delete deployment.app app名称
#通过资源清单删除
kubectl delete create-nginx-app.yaml
10. Service
service是不是实体服务,是一条iptables或ipvs的转发规则。
作用:通过service为pod客户端提供访问pod方法,通过使用pod标签与pod关联。
10.1 service类型
ClusterIP:默认,分配一个集群内部可以访问的虚拟IP
NodePort:在每个Node上分配一个端口作为外部访问入口
LoadBalancer:工作在特定的Cloud Provider上
ExternalName:表示把集群外部的服务引入集群内部中来,实现集群内部pod和外部服务的通信。
10.2 service参数
port:访问serivce使用的端口
targetPort:pod中容器端口
NodePort:通过Node实现外网用户访问K8s集群内service
10.3 创建service与deployment类型应用关联
在9.1创建deployment基础上进行
kubectl expose deployment.apps nginx-app --type=ClusterIP --target-port=80 --port=80
10.4 service查看命令
kubectl get svc
#查看端点
kubectl get endpoints
10.5 通过yaml资源清单创建ClusterIP类型的service
#deployment-service-clusterip.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-apps
labels:
apps: nginx
spec:
replicas: 1
selector:
matchLables:
apps: nginx
template:
metadata:
labels:
apps: nginx
spec:
containers:
- name: nginxapp2
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-app2-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
apps: nginx
使用yaml创建
kubectl apply -f deployment-service-clusterip.yaml
10.6 创建NodePort的service
#deployment-service-clusterip.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-apps
labels:
apps: nginx
spec:
replicas: 1
selector:
matchLables:
apps: nginx
template:
metadata:
labels:
apps: nginx
spec:
containers:
- name: nginxapp2
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-app2-svc
spec:
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30001
selector:
apps: nginx