k8s
介绍
pad控制器
掌握各种控制器的特点以及使用定义方式
服务发现
掌握svc原理以及构建方式
存储
掌握多种存储类型的特点
调度器
掌握调度器原理,能根据要求把pod定义到想要的节点运行
安全
集群的认证 鉴权 访问控制原理及其流程
helm
掌握helm原理 helm模板自定义,helm模板自定义,helm部署一些常用插件
主要组件
apiserver
所有服务访问统一入口CrontrollerManager
维护副本期望数目scheduler
负责介绍任务,选择合适的节点进行分配任务etcd
键值对数据库,存储k8s集群所有重要的信息(持久化)kubelet
直接跟容器引擎交互实现的生命周期管理kube-proxy
负责写入规则至iptables,ipvs实现服务映射访问的
其他插件
-
CireDNS
可以为集群中的svc创建一个域名ip的对应解析
Dashboard
给k8s集群提供一个b/s结构的访问体系incresss controller
官方只能实现四成代理,ingess可以实现七成代理federation
提供一个可以跨集群中心多k8s统一管理功能Prometheus
提供k8s集群的监控能力elk
提供k8s集群日志统一分析继而平台
kubernetes资源类别介绍
类别 | 名称 |
---|---|
资源对象 | Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling |
配置对象 | Node、Namespace、Service、Secret、ConfigMap、Ingress、Label、ThirdPartyResource、 ServiceAccount |
存储对象 | Volume、Persistent Volume |
策略对象 | SecurityContext、ResourceQuota、LimitRange |
pod
pod介绍
在Kubernetes集群中,Pod是所有业务类型的基础,也是K8S管理的最小单位级,它是一个或多个容器的组合。这些容器共享存储、网络和命名空间,以及如何运行的规范。在Pod中,所有容器都被同一安排和调度,并运行在共享的上下文中。对于具体应用而言,Pod是它们的逻辑主机,Pod包含业务相关的多个应用容器。
ped控制器类型
ReplicationController(新版本已抛弃)
它能够保证Pod持续运行,并且在任何时候都有指定数量的Pod副本,在此基础上提供一些高级特性,比如滚动升级和弹性伸缩ReplicaSet
是ReplicationController的代替物,因此用法基本相同,唯一的区别在于ReplicaSet支持集合式的selectorDeployment
是用来管理无状态应用的,面向的集群的管理,而不是面向的是一个不可变的个体
它可以实现对template模板进行实时滚动更新,更加方便的管理Pod和Replica SetHorizontal Pod Autoscaler
根据观察到的CPU使用率(或使用自定义指标 支持,基于某些其他应用程序提供的指标)自动缩放复制控制器statefulset
为解决有有状态服务问题,StatefulSet为其每个Pod维护一个粘性身份。这些Pod是根据相同的规范创建的,但不可互换:每个Pod都有一个永久性标识符,该标识符在任何重新计划中都会维护。
稳定的唯一网络标识符:pod重新调度后其podname和hostname不变,基于headless service实现
稳定,持久的存储:pod重新调动后还是能访问到相同的持久化数据,基于pvc实现
有序,顺畅的部署和扩展:在扩展或者部署时按定义的顺序依次进行,基于init containers来实现
有序的自动滚动更新:有序收缩删除
- daemonset
DaemonSet确保集群中每个(部分)node运行一份pod副本,当node加入集群时创建pod,当node离开集群时回收pod。如果删除DaemonSet,其创建的所有pod也被删除,
运行集群存储daemon,例如在每个node上运行glusterfs,ceph
在每个node上运行日志收集daemon,例如fluentd,logstash
在每个node上运行监控daemon,例如promethus
7.job
负责批量处理任务,即执行一次任务,它保证批量处理任务的一个或多个pod成功结束
Job 会创建一个或者多个 Pods,并确保指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。
8.CronJob
创建基于时间调度的 Job
对于创建周期性的、反复重复的任务很有用,例如执行数据备份
安装
设置系统主机名以及Host文件的相互解析
系统最低配置,两核2G
hostname | ip |
---|---|
k8s-master01 | 10.0.0.2 |
k8s-slave01 | 10.0.03 |
k8s-slave02 | 10.0.0.4 |
系统升级优化
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
# 查看可用的系统内核包
# yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
yum --enablerepo=elrepo-kernel install kernel-lt
# 查看系统上的所有可以内核
awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
grub2-set-default 0 # 选着相应标号
init 6
cat >/etc/sysctl.d/kubernetes.conf<<-EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
# 允许的最大跟踪连接条目,是在内核内存中 netfilter 可以同时处理的“任务”(连接跟踪条目)
net.netfilter.nf_conntrack_max=10485760
net.netfilter.nf_conntrack_tcp_timeout_established=300
# 哈希表大小(只读)(64位系统、8G内存默认 65536,16G翻倍,如此类推)
net.netfilter.nf_conntrack_buckets=655360
# 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog=10000
# 表示socket监听(listen)的backlog上限,也就是就是socket的监听队列,当一个tcp连接尚未被处理或建立时(半连接状态),会保存在这个监听队列
net.core.somaxconn=32768
# 没有启用syncookies的情况下,syn queue(半连接队列)大小除了受somaxconn限制外,也受这个参数的限制,默认1024,优化到8096,避免在高并发场景下丢包
net.ipv4.tcp_max_syn_backlog=8096
# 表示同一用户同时最大可以创建的 inotify 实例 (每个实例可以有很多 watch)
fs.inotify.max_user_instances=8192
# max-file 表示系统级别的能够打开的文件句柄的数量, 一般如果遇到文件句柄达到上限时,会碰到
# Too many open files 或者 Socket/File: Can’t open so many files 等错误
fs.file-max=2097152
# 表示同一用户同时可以添加的watch数目(watch一般是针对目录,决定了同时同一用户可以监控的目录数量) 默认值 8192 在容器场景下偏小,在某些情况下可能会导致 inotify watch 数量耗尽,使得创建 Pod 不成功或者 kubelet 无法启动成功,将其优化到 524288
fs.inotify.max_user_watches=524288
net.core.bpf_jit_enable=1
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 12582912 16777216
net.ipv4.tcp_wmem=4096 12582912 16777216
net.core.rps_sock_flow_entries=8192
# 以下三个参数是 arp 缓存的 gc 阀值,相比默认值提高了,当内核维护的 arp 表过于庞大时候,可以考虑优化下,避免在某些场景下arp缓存溢出导致网络超时,参考:https://k8s.imroc.io/avoid/cases/arp-cache-overflow-causes-healthcheck-failed
# 存在于 ARP 高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行。缺省值是 128
net.ipv4.neigh.default.gc_thresh1=2048
# 保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒。缺省值是 512
net.ipv4.neigh.default.gc_thresh2=4096
# 保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是 1024
net.ipv4.neigh.default.gc_thresh3=8192
net.ipv4.tcp_max_orphans=32768
net.ipv4.tcp_max_tw_buckets=32768
vm.max_map_count=262144
kernel.threads-max=30058
net.ipv4.ip_forward=1
# 避免发生故障时没有 coredump
kernel.core_pattern=core
# 禁用ipv6
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 180
net.ipv4.tcp_max_tw_buckets = 6000
vm.swappiness = 0
EOF
sysctl -p /etc/sysctl.d/kubernetes.conf
cat >>/etc/security/limits.conf<<-EOF
* - nofile 204800
EOF
ulimit -n 204800
ulimit -u 204800
systemctl stop firewalld postfix
systemctl disable firewalld postfix
init 6
uname -a
系统准备
cat >>/etc/hosts<>/var/spool/cron/root<<-EOF
PATH=/bin:/sbin:/usr/bin:/usr/sbin
# ntpdate
0 */2 * * * ntpdate time1.aliyun.com &>/dev/null && hwclock --systohc
EOF
crontab -u root /var/spool/cron/root
crontab -l -u root
kubeadm 安装
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
cat < /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
EOF
yum clean all && yum repolist && yum makecache
yum install -y kubelet kubeadm kubectl
# 编辑 vim /etc/sysconfig/kubelet配置:
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
systemctl enable kubelet && systemctl restart kubelet
systemctl enable docker && systemctl start docker
从kubernetes1.8版本开始,新增了kube-proxy对ipvs的支持
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
容器日志配置
配置Journal1日志管理
mkdir /etc/systemd/journald.conf.d
cat >/etc/systemd/journald.conf.d/99-prophet.cong<<-EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec= 5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间10G
SystemMaxUse=10G
# 单日志文件最大200M
SystemMaxFileSize=200M
# 日志保存时间2周
MaxRetentionsec=2week
# 不将日志转发到syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
json-file 会将容器的日志保存在.json文件中,日志路径为 /var/lib/docke/container/ID/ID.json.log
Docker 默认的日志驱动程序json-file
centos7的cgroup driver为systemd,docker默认的cgroup driver为cgroupfs,使用两种cgroup driver控制资源的话会导致资源分配不均。
cat >/etc/docker/daemon.json<<-EOF
{
"registry-mirrors": [
"https://6zmzhe7k.mirror.aliyuncs.com"
],
"insecure-registries": [
"www.harbor.com"
],
"dns": ["8.8.8.8","8.8.4.4"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": { "max-size" :"100m","max-file":"3"}
}
EOF
master安装
查看此版本的容器镜像版本
kubeadm config images list
初始化主节点 kubeadm reset
- --apiserver-advertise-address:指定用 Master 的哪个IP地址与 Cluster的其他节点通信。
- --service-cidr:指定Service网络的范围,即负载均衡VIP使用的IP地址段。
- --pod-network-cidr:指定Pod网络的范围,即Pod的IP地址段。
- --image-repository:指定镜像地址
- --kubernetes-version:指定要安装的版本号
kubeadm config print init-defaults
kubeadm init --upload-certs \
--apiserver-advertise-address=10.0.0.2 \
--pod-network-cidr=10.244.0.0/16 \
--kubernetes-version=v1.19.1 \
--image-repository=www.harbor.com/google_containers \
|tee kubeadm-init.log
mkdir $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 配置lpvs
kubectl edit configmap kube-proxy -n kube-system
kubectl delete pod kube-proxy-xxx -n kube-system
ipvsadm -ln
wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml
kubectl apply -f calico-3.13.1.yaml
calico-kube 状态CrashLoopBackOff
kubectl logs -n kube-system calico-kube-controllers-XXX
journalctl -f -u kubelet
iptables --flush
iptables -tnat --flush
客户端加入节点
token信息在master初始化日志中
kubeadm token create --print-join-command
kubeadm join 10.0.0.2:6443 --token 54837b.sxu1i7bq67zpehhh \
--discovery-token-ca-cert-hash \
sha256:37f8d8328c5243a7acd1ba652c4173c181795e33f692eb99d6cc45e150a0203f \
--ignore-preflight-errors=swap
# 添加节点后,节点会从master下载镜像并启动(kubectl get nodes Ready代表成功)
# 查看pod: kubectl get pods -n kube-system -o wide 查看pod
kubectl get nodes
加入失败
kubeadm reset
# If you wish to reset iptables, you must do so manually.For example:
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
# If your cluster was setup to utilize IPVS, run
ipvsadm --clear
# 再次加入
验证节点
kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready master 27m v1.19.2
k8s-slave01 Ready 2m54s v1.19.2
k8s-slave02 Ready 5m36s v1.19.2
资源清单
Yaml格式
简单说明
YAML是一个类似 XML、JSON 的标记性语言。YAML 强调以数据为中心,并不是以标识语言为重点。因而 YAML 本身的定义比较简单,号称“一种人性化的数据格式语言”。
基本语法
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格。
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
数据类型
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(scalars):单个的、不可再分的值。字符串,布尔值,整数浮点数,null,时间日期
对象
对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。
也可以使用 key:{key1: value1, key2: value2, ...}。
key:
child-key: value
child-key2: value2
数组
以 - 开头的行表示构成一个数组:
animal
- cat
- dog
可以使用行内表示
animal: [cat, dog]
k8s yaml文件规格参数
kubectl explain pod 查看参数
必要属性
参数名 | 字段类型 | 说明 |
---|---|---|
version | string | 指k8s api版本,目前基本上是v1,可以用kubectl api-versions命令查询 |
kind | string | 指yaml文件定义的资源类型和角色,如pod |
metadata | object | 元数据对象,固定值就写metadata |
metadata.name | string | 元数据对象名,命名pod的名字 |
metadata.namespace | string | 元数据对象的命名空间 |
spec | object | 详细定义对象,固定值就写spec |
spec.containers[] | list | 这里是spec对象的容器列表定义,是个列表 |
主要对象
参数名 | 字段类型 | 说明 |
---|---|---|
spec.containers[].name | stringr | 这里定义容器名字 |
spec.containers[].image | string | 这里定义要用到的镜像名称 |
spec.containers[].imagePullPolicy | string | 定义镜像拉取策略,Alawys每次拉取新镜像,IfnotPresent表示优先使用本地镜像,Never仅用本地镜像 |
spec.containers[].command[] | list | 指定容器启动命令,应为是数组可以指定多个,不指定使用镜像打包时使用的启动命令 |
spec.containers[].args[] | list | 指定容器启动命令参数,因为是数组可以指定多个 |
spec.containers[].workingdir | string | 指定容器的工作目录 |
spec.containers[].volumeMounts[] | string | 挂载到容器内部的存储卷配置 |
spec.containers[].volumeMounts[].name | string | 引用pod定义的共享存储卷的名称 |
spec.containers[].volumeMounts[].mountPath | string | 存储卷在容器内mount的绝对路径 |
spec.containers[].volumeMounts[].readOnly | Boolean | 是否为只读模式,ture.false 默认读写 |
spec.containers[].ports[] | list | 需要暴露的端口库号列表 |
spec.containers[].ports[].name | string | 端口的名称 |
spec.containers[].ports[].containerPort | string | 容器需要监听的端口号 |
spec.containers[].ports[].hostPort | string | 容器所在主机需要监听的端 |
spec.containers[].ports[].protocol | string | 端口协议,支持TCP和UDP,默认TCP |
spec.containers[].env[] | list | 容器运行前需设置的环境变量列表 |
spec.containers[].env[].name | string | 环境变量名称 |
spec.containers[].env[].value | string | 环境变量的值 |
spec.containers[].resources | object | 资源限制和请求的设置 |
spec.containers[].resources.limits | object | 资源限制的设置 |
spec.containers[].resources.limits.cpu | string | Cpu的限制,单位为core数,将用于docker run --cpu-shares参数 |
spec.containers[].resources.limits.memory | string | 内存限制,单位可以为Mib/Gib,将用于docker run --memory参数 |
spec.containers[].resources.requests | object | 指定容器启动和调度时的限制设置 |
spec.containers[].resources.requests.cpu | string | Cpu请求,容器启动的初始化可用数量 |
spec.containers[].resources.requests.memory | string | 内存请求,容器启动的初始化可用数量 |
额外参数项
参数名 | 字段类型 | 说明 |
---|---|---|
spec.restartPolicy | string | Pod的重启策略,Always不管以何种方式终止 都将重启 /OnFailure只有Pod以非0退出码退出才重启 /Nerver不再重启该Pod |
spec.nodeSelector | object | 将该Pod调度到包含这个label的node上,以key:value的格式指定 |
spec.imagePullSecrets | object | Pull镜像时使用的secret名称,以key:secretkey格式指定 |
spec.hostNetwork | Boolean | 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络 不使用docker网桥并且无法在同一宿主机启动第二个副本 |