目录
1.kubernetes简介
1.1 什么是k8s
kubernetes是谷歌公司开源的一个容器管理平台。 Kubernetes 就是将 Borg 项目最精华的部分提取出来,使现在的开发者能够更简单、直接地去应用它。
1.2 k8s发展史
Kubernetes 希腊语 :舵手
2014 年,kubernetes正式对外开源
2015年7月,正式对外发布v1.0版,随后加入CNCF基金会
2017年,kubernetes正式战胜swarm和mesos,成为领域老大
2018年,CNCF基金会宣布:Kubernetes成为首个”毕业”项目
2.kubernetes核心功能
1 自我修复
2 服务发现和负载均衡
3 自动部署和回滚
4 弹性伸缩
3.kubernetes应用场景
4.kubernetes核心组件
组件名称 | 说明 |
etcd | 保存整个集群的状态 |
apiserver | 提供资源操作的唯一入口,并提供认证,授权,访问控制,API注册和发现等机制 |
controller manager | 负责维护集群的状态,比如故障检测,自动扩展,滚动更新等 |
scheduler | 负责资源的调度,按照预定的调度策略将pod调度到相应的机器上 |
kubelet | 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理 |
Container runtime | 负责镜像管理以及pod和容器的真正运行(CRI) |
kube-proxy | 负责为service提供cluster内部的服务发现和负载均衡 |
4.1 etcd服务
4.1.1 etcd是什么
Etcd 是一个使用一致性哈希算法(Raft)在分布式环境下的 key/value 存储服务。利用 Etcd 的特性,应用程序可以在集群中共享信息、配置或作服务发现,Etcd 会在集群的各个节点中复制这些数据并保证这些数据始终正确。
4.1.2 etcd常用配置
--name #指定节点名称
--data-dir #指定节点的数据存储目录,用于保存日志和快照
--addr #公布的 IP 地址和端口;默认为 127.0.0.1:2379
--bind-addr #用于客户端连接的监听地址;默认为–addr 配置
--peers #集群成员逗号分隔的列表;例如 127.0.0.1:2380,127.0.0.1:2381
--peer-addr #集群服务通讯的公布的 IP 地址;默认为 127.0.0.1:2380
-peer-bind-addr #集群服务通讯的监听地址;默认为-peer-addr 配置
--wal-dir #指定节点的 wal 文件的存储目录,若指定了该参数 wal 文件会和其他数据文件分开存储
--listen-client-urls #监听 URL;用于与客户端通讯
--listen-peer-urls #监听 URL;用于与其他节点通讯
--initial-advertise-peer-urls #告知集群其他节点 URL
--advertise-client-urls #告知客户端 URL
--initial-cluster-token #集群的 ID
--initial-cluster #集群中所有节点
--initial-cluster-state new #表示从无到有搭建 etcd 集群
--discovery-srv #用于 DNS 动态服务发现,指定 DNS SRV 域名
--discovery #用于 etcd 动态发现,指定 etcd 发现服务的 URL
4.1.3 etcd数据存储
etcd 的数据存储有点像 PG 数据库的存储方式
etcd 目前支持 V2 和 V3 两个大版本,这两个版本在实现上有比较大的不同,一方面是对外提供接口的方式,另一方面就是底层的存储引擎,V2 版本的实例是一个纯内存的实现,所有的数据都没有存储在磁盘上,而 V3 版本的实例就支持了数据的持久化。
# 设置键值对
$ etcdctl set name escape
# 获取方式
$ etcdctl get name
escape
使用 etcd 之后,我们会疑问数据都存储到的那里呢?数据默认会存放在 /var/lib/etcd/default/ 目录。我们会发现数据所在的目录,会被分为两个文件夹中,分别是 snap 和 wal目录。
snap
存放快照数据,存储etcd的数据状态
etcd防止WAL文件过多而设置的快照
wal
存放预写式日志
最大的作用是记录了整个数据变化的全部历程
在etcd中,所有数据的修改在提交前都要先写入到WAL中
# 目录结构
$ tree /var/lib/etcd/default/
default
└── member
├── snap
│ ├── 0000000000000006-0000000000046ced.snap
│ ├── 0000000000000006-00000000000493fe.snap
│ ├── 0000000000000006-000000000004bb0f.snap
│ ├── 0000000000000006-000000000004e220.snap
│ └── 0000000000000006-0000000000050931.snap
└── wal
└── 0000000000000000-0000000000000000.wal
使用 WAL 进行数据的存储使得 etcd 拥有两个重要功能,那就是故障快速恢复和数据回滚/重做。
-
故障快速恢复就是当你的数据遭到破坏时,就可以通过执行所有 WAL 中记录的修改操作,快速从最原始的数据恢复到数据损坏前的状态。
-
数据回滚重做就是因为所有的修改操作都被记录在 WAL 中,需要回滚或重做,只需要方向或正向执行日志中的操作即可。
既然有了 WAL 实时存储了所有的变更,为什么还需要 snapshot 呢?随着使用量的增加,WAL 存储的数据会暴增。为了防止磁盘很快就爆满,etcd 默认每 10000 条记录做一次 snapshot 操作,经过 snapshot 以后的 WAL 文件就可以删除。而通过 API 可以查询的历史 etcd 操作默认为 1000 条。
首次启动时,etcd 会把启动的配置信息存储到 data-dir 参数指定的数据目录中。配置信息包括本地节点的ID、集群ID和初始时集群信息。用户需要避免 etcd 从一个过期的数据目录中重新启动,因为使用过期的数据目录启动的节点会与集群中的其他节点产生不一致。所以,为了最大化集群的安全性,一旦有任何数据损坏或丢失的可能性,你就应该把这个节点从集群中移除,然后加入一个不带数据目录的新节点。
4.1.4 Raft 算法
保证一致性的共识算法
在每一个分布式系统中,etcd 往往都扮演了非常重要的地位,由于很多服务配置发现以及配置的信息都存储在 etcd 中,所以整个集群可用性的上限往往就是 etcd 的可用性,而使用 3 ~ 5 个 etcd 节点构成高可用的集群往往都是常规操作。
正是因为 etcd 在使用的过程中会启动多个节点,如何处理几个节点之间的分布式一致性就是一个比较有挑战的问题了。解决多个节点数据一致性的方案其实就是共识算法,etcd 使用的就是 Raft 共识算法。
Raft 从一开始就被设计成一个易于理解和实现的共识算法,它在容错和性能上与 Paxos 协议比较类似,区别在于它将分布式一致性的问题分解成了几个子问题,然后一一进行解决。
每一个 Raft 集群中都包含多个服务器,在任意时刻,每一台服务器只可能处于 Leader、Follower 以及 Candidate 三种状态;在处于正常的状态时,集群中只会存在一个 Leader 状态,其余的服务器都是 Follower 状态
所有的 Follower 节点都是被动的,它们不会主动发出任何的请求,只会响应 Leader 和 Candidate 发出的请求。对于每一个用户的可变操作,都会被路由给 Leader 节点进行处理,除了 Leader 和 Follower 节点之外,Candidate 节点其实只是集群运行过程中的一个临时状态。
Raft 集群中的时间也被切分成了不同的几个任期(Term),每一个任期都会由 Leader 的选举开始,选举结束后就会进入正常操作的阶段,直到 Leader 节点出现问题才会开始新一轮的选择。
每一个服务器都会存储当前集群的最新任期,它就像是一个单调递增的逻辑时钟,能够同步各个节点之间的状态,当前节点持有的任期会随着每一个请求被传递到其他的节点上。Raft 协议在每一个任期的开始时都会从一个集群中选出一个节点作为集群的 Leader 节点,这个节点会负责集群中的日志的复制以及管理工作。
我们将 Raft 协议分成三个子问题:节点选举、日志复制以及安全性。
4.1.5 服务发现
服务发现是 etcd 服务的主要的用途之一
服务发现要解决的也是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务,要如何才能找到对方并建立连接。本质上来说,服务发现就是想要了解集群中是否有进程在监听 UDP 或 TCP 端口,并且通过名字就可以查找和连接。要解决服务发现的问题,需要有下面三大支柱,缺一不可。
-
一个强一致性、高可用的服务存储目录
-
-
基于 Raft 算法的 etcd 天生就是这样一个强一致性高可用的服务存储目录
-
-
一种注册服务和监控服务健康状态的机制
-
-
用户可以在 etcd 中注册服务,并且对注册的服务设置 key TTL 值,定时保持服务的心跳以达到监控服务健康状态的效果。
-
-
一种查找和连接服务的机制
-
-
为了确保连接,我们可以在每个服务机器上都部署一个 Proxy 模式的 etcd,这样就可以确保能访问 etcd 集群的服务都能互相连接。
-
日常开发集群管理功能中,如果要设计可以动态调整集群大小。那么首先就要支持服务发现,就是说当一个新的节点启动时,可以将自己的信息注册给 master,然后让 master 把它加入到集群里,关闭之后也可以把自己从集群中删除。etcd 提供了很好的服务注册与发现的基础功,我们采用 etcd 来做服务发现时,可以把精力用于服务本身的业务处理上。
4.1.6 使用方法
etcd 在键的组织上采用了层次化的空间结构,类似于文件系统中目录的概念,数据库操作围绕对键值和目录的 CRUD 完整生命周期的管理。etcdctl 是一个命令行的客户端,它提供了一下简洁的命令,可理解为命令工具集,可以方便我们在对服务进行测试或者手动修改数据库内容。etcdctl 与其他 xxxctl 的命令原理及操作类似,如 systemctl 等等。
1. 对象为键值
操作 | 解释说明 | 操作演示 |
set | 增:无论是否存在 | etcdctl set key value |
mk | 增:必须不存在 | etcdctl mk key value |
rm | 删:必须存在 | etcdctl rm key |
update | 改:必须存在 | etcdctl update key value |
get | 查:必须存在 | etcdctl get key |
2. 对象为目录
操作 | 解释说明 | 实例演示 |
setdir | 增:无论是否存在 | etcdctl setdir dir |
mkdir | 增:必须不存在 | etcdctl mkdir dir |
rmdir | 删:必须存在 | etcdctl rmdir dir |
updatedir | 改:必须存在 | etcdctl updatedir dir |
ls | 查:必须存在 | etcdctl ls |
3. 非数据库操作命令
操作 | 解释说明 | 实例演示 |
backup | 备份etcd数据 | etcdctl backup |
watch | 检查一个键值变化,更新则输出退出 | etcdctl watch key |
exec-watch | 监测一个键值变化,如果更新则执行给定命令 | etcdctl exec-watch key sh -c "ls" |
member | 增删改查集群中对象 | etcdctl member list/add/remove/update |
cluster | 检查集群健康状态 | etcdctl cluster-health |
4.1.7 灾备恢复
Etcd 集群备份和数据恢复以及优化运维
etcd 被设计为能承受集群自动从临时失败(例如机器重启)中恢复,而且对于一个有 N 个成员的集群能容许 (N-1)/2 的持续失败。当一个成员持续失败时,不管是因为硬件失败或者磁盘损坏,它丢失到集群的访问。如果集群持续丢失超过 (N-1)/2 的成员,则它只能悲惨的失败,无可救药的失去法定人数(quorum)。一旦法定人数丢失,集群无法达到一致性而导致无法继续接收更新。为了从灾难失败中恢复数据,etcd v3 提供快照和修复工具来重建集群而不丢失 v3 键数据。
4.1.8 etcd证书制作
由于 v3 版本的 etcd 证书是基于 IP 的,所以每次新增 etcd 节点都需要重新制作证书。为了我们更方便的使用,可以查看这个链接来 etcd 证书制作。详情: https://github.com/cloudflare/cfssl。
4.1.9 快照键空间
恢复集群,首先需要来自 etcd 成员的键空间的快照。快速可以是用 etcdctl snapshot save 命令从活动成员中获取。或者是从 etcd 数据目录复制 member/snap/db 文件。例如,下列命令快照在 $ENDPOINT 上服务的键空间到文件 snapshot.db。
# 集群备份etcd数据快照
# $ENDPOINT => http://10.20.30.1:2379
$ ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshot.db
# 在单节点etcd上执行下面的命令就可以对etcd进行数据备份
# 每两个小时备份一次数据并上传到S3上,并保留最近两天的数据
$ ETCDCTL_API=3 etcdctl snapshot save /var/lib/etcd_backup/etcd_$(date "+%Y%m%d%H%M%S").db
4.1.10 恢复集群
为了恢复集群,使用之前任意节点上备份的快照 "db" 文件。恢复的手,可以使用 etcdctl snapshot restore 命令来恢复 etcd 数据目录,此时所有成员应该使用相同的快照恢复。因为恢复数据死后,会覆盖某些快照元数据(特别是成员ID和集群ID)信息,集群内的成员可能会丢失它之前的标识。因此为了从快照启动集群,恢复必须启动一个新的逻辑集群。
在恢复时,快照完整性的检验是可选的。如果快照是通过 etcdctl snapshot save 得到的话,使用 etcdctl snapshot restore 命令恢复的时候,会检查 hash 值的完整性。如果快照是从数据目录复制而来,则没有完整性校验,因此它只能通过使用 --skip-hash-check 来恢复。
下面为一个 3 成员的集群创建新的 etcd 数据目录:
$ etcdctl snapshot restore snapshot.db \
--name m1 \
--initial-cluster m1=http:/host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-advertise-peer-urls http://host1:2380
$ etcdctl snapshot restore snapshot.db \
--name m2 \
--initial-cluster m1=http:/host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-advertise-peer-urls http://host2:2380
$ etcdctl snapshot restore snapshot.db \
--name m3 \
--initial-cluster m1=http:/host1:2380,m2=http://host2:2380,m3=http://host3:2380 \
--initial-cluster-token etcd-cluster-1 \
--initial-advertise-peer-urls http://host3:2380
下一步, 用新的数据目录启动 etcd 服务,现在恢复的集群可以使用并提供来自快照的键空间服务。
$ etcd \
--name m1 \
--listen-client-urls http://host1:2379 \
--advertise-client-urls http://host1:2379 \
--listen-peer-urls http://host1:2380 &
$ etcd \
--name m2 \
--listen-client-urls http://host2:2379 \
--advertise-client-urls http://host2:2379 \
--listen-peer-urls http://host2:2380 &
$ etcd \
--name m3 \
--listen-client-urls http://host3:2379 \
--advertise-client-urls http://host3:2379 \
--listen-peer-urls http://host3:2380 &
原文参考:etcd 服务入门指南_民工哥的博客-CSDN博客
5.kubernetes架构图
6.kuberbetes扩展组件
组件名称 | 说明 |
kube-dns | 负责为整个集群提供DNS服务 |
Ingress-controller | 为服务提供外网入口 |
Heapster | 提供资源监控 |
Dashboard | 提供GUI |
Federation | 提供跨可用区的集群 |
Fluentd-elasticsearch | 提供集群日志采集、存储与查询 |
7.k8s的安装与部署
7.1 主节点
7.1.1 etcd
1.安装etcd
yum install etcd -y
安装过程中需要安装其他组件,如果拉取失败会去其他镜像拉取
2.配置etcd参数信息
vim /etc/etcd/etcd.conf
3.启动etcd服务
systemctl start etcd
4.设置开机启动
systemctl enable etcd
5.说明
服务启动后会启动两个端口
1. 2379端口对外提供服务
2. 2380端口同步存储数据使用
6.安装master节点
yum install kubernetes-master.x86_64 -y
# 查看kubernetes目录下的配置文件
ll /etc/kubernetes/
# 配置apiserver
vim /etc/kubernetes/apiserver
# 配置controller-manager,scheduler,共用一个配置,用来发现apiserver服务
vim /etc/kubernetes/config
# 启动apiserver,controller-manager,scheduler服务
systemctl start kube-apiserver.service
systemctl start kube-controller-manager.service
systemctl start kube-scheduler.service# 设置为开机自启
systemctl enable kube-apiserver.service
systemctl enable kube-controller-manager.service
systemctl enable kube-scheduler.service
查看服务状态
kubectl get componentstatus
注意: 这里如果配置etcd的访问地址为公网ip就会出问题,可能是因为没开端口,待测试
7.1.2 api-service
7.1.3 controller-manager
7.1.4 scheduler
7.2 node节点
node节点包含一下几个工具
node节点安装kubeket会自动安装
kubelet
kube-proxy
docker
7.2.1. 安装
yum install kubernetes-node.x86_64 -y
7.2.2 更改配置
1.配置master节点
vim /etc/kubernetes/config
# 设置为主节点apiserver中的访问地址和端口号
KUBE_MASTER="--master=http://master_ip:port"
查看主节点服务端口号
less /etc/kubernetes/apiserver
7.2.3 配置访问控制
vim /etc/kubernetes/kubelet
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"# The port for the info server to serve on
KUBELET_PORT="--port=10250"# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=本机地址"# location of the api-server
KUBELET_API_SERVER="--api-servers=http://master_ip:port"
7.2.4 启动node节点服务
systemctl start kubelet.service
systemctl start kube-proxy.service
7.2.5 所有节点安装 flannel 插件
yum install flannel -y
修改flanneld配置
vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://master_ip:2379"
# master节点
etcdctl mk /atomic.io/network/config '{ "Network": "172.16.0.0/16" }'
service docker restart
systemctl restart kube-apiserver.service
systemctl restart kube-controller-manager.service
systemctl restart kube-scheduler.service
# node节点
systemctl start flanneld.service
service docker restart 或者 systemctl daemon-reload
systemctl restart kubelet.service
systemctl restart kube-proxy.service
8.常见问题总结
8.1 安装k8s失败
Error: docker-ce conflicts with 2:docker-1.13.1-209.git7d71120.el7.centos.x86_64
Error: docker-ce-cli conflicts with 2:docker-1.13.1-209.git7d71120.el7.centos.x86_64
解决办法:
# 查看已安装的工具
yum list installed | grep docker
containerd.io.x86_64 1.4.12-3.1.el7 @docker-ce-stable
docker-ce.x86_64 3:20.10.12-3.el7 @docker-ce-stable
docker-ce-cli.x86_64 1:20.10.12-3.el7 @docker-ce-stable
docker-ce-rootless-extras.x86_64 20.10.12-3.el7 @docker-ce-stable
docker-scan-plugin.x86_64 0.12.0-3.el7 @docker-ce-stable
# 移除匹配的工具
yum remove -y docker*
再次安装
Transaction check error:
file /usr/bin/kubectl from install of kubernetes-client-1.5.2-0.7.git269f928.el7.x86_64 conflicts with file from package kubectl-1.23.3-0.x86_64
file /usr/bin/kubelet from install of kubernetes-node-1.5.2-0.7.git269f928.el7.x86_64 conflicts with file from package kubelet-1.23.3-0.x86_64
file /usr/lib/systemd/system/kubelet.service from install of kubernetes-node-1.5.2-0.7.git269f928.el7.x86_64 conflicts with file from package kubelet-1.23.3-0.x86_64Error Summary
由于刚刚安装kubernates没有常规,有很对依赖包又进来了不完整,所以再次清除一下
# 查看已安装并条件过滤
yum list installed | grep kube
cri-tools.x86_64 1.19.0-0 @kubernetes
kubeadm.x86_64 1.23.3-0 @kubernetes
kubectl.x86_64 1.23.3-0 @kubernetes
kubelet.x86_64 1.23.3-0 @kubernetes
kubernetes-cni.x86_64 0.8.7-0 @kubernetes
# 移除
yum remove -y kube*
再次安装成功
yum install kubernetes-node.x86_64 -y
8.2 node节点提示连接本地8080服务失败
The connection to the server localhost:8080 was refused - did you specify the right host or port?
8.3 拉取镜像失败
解决办法:
8.3.1 修改k8s配置
vim /etc/kubernetes/kubelet
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=docker.io/tianyebj/pod-infrastructure:latest"
8.3.2 添加docker镜像仓库
vim /etc/sysconfig/docker
OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --registry-mirror=https://registry.docker-cn.com'
8.3.3 重启docker
systemctl restart docker
8.3.4 删除错误的pod并重新创建
# 删除pod
kubectl delete pod nginx
# 重新创建资源
kubectl create -f nginx_pod.yaml
9.常用命令
9.1 创建资源
# 创建一个nginx的pod资源
kubectl create -f nginx_pod.yaml
9.2 查看资源详情
# 指定资源类型pod和资源名nginx
kubectl describe pod nginx
9.3 删除资源
# 指定资源类型pod和资源名nginx
kubectl delete pod nginx
10.创建资源
创建资源一般在master节点操作
pod定义详解
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #必选,Pod所属的命名空间
labels: #自定义标签
- name: string #自定义标签名字
annotations: #自定义注释列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口号名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同,设置hostPort时,同一台宿主机上将无法启动容器的第2分副本。
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存清楚,容器启动的初始可用数量
livenessProbe: #对Pod内的容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
10.1 创建一个pod
# 创建一个资源文件
vim nginx_pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.13
ports:
- containerPort: 80
# 创建资源
kubectl create -f nginx_pod.yaml
10.2 创建一个rc
# 创建一个rc文件
vim nginx-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: nginx:1.13
ports:
- containerPort: 80
# 创建rc资源
kubectl create -f nginx-rc.yaml
10.3 创建service
运行在docker中的业务,想要被外界访问,我们需要为它做端口映射才能被访问,那么运行在k8s中的容器,为什么不能直接为它做端口映射呢?
service 是微服务架构中的微服务。
service 定义了一个服务的访问入口地址,前端的应用(pod)通过这个入口访问其背后的一组由pod副本组成的集群实例,service与其后端pod副本集群之间是通过label seletor 实现无缝对接的。
通常我们的系统是由多个提供不同业务能力而又彼此独立的微服务单元所组成,服务之间通过tcp/ip进行通信,从而形成了强大而又灵活的弹性网络,拥有了强大的分布式能力,弹性扩展能力,容错能力。
众所周知,pod生命周期短,状态不稳定,pod异常后新生成的pod ip会发生变化,之前pod的访问方式均不可达。
通过service对pod做代理,service有固定的ip和port,ip:port组合自动关联后端pod,即使pod发生改变,kubernetes内部更新这组关联关系,使得service能够匹配到新的pod。
这样,通过service提供的固定ip,用户再也不用关心需要访问哪个pod,以及pod是否发生改变,大大提高了服务质量。
如果pod使用rc创建了多个副本,那么service就能代理多个相同的pod,通过kube-proxy,实现负载均衡。
10.3.1 k8s中三种ip地址类型
1.nodeip
是k8s集群中每个节点的物理网卡的ip地址,是真实存在的物理地址,所有属于这个网络的服务器之间都能通过这个网络直接通信,
不管它们中是否有部分节点不属于这个集群,这也表明集群之外的节点访问k8s集群之内的某个节点或者tcp/ip服务的时候,必须通过nodeip进行通信
2.clusterip
全局的唯一的虚拟ip,在整个service的声明周期内,一旦创建,就不会改变;
仅仅作用于service对象,由k8s管理和分配ip地址;
无法被ping,没有实体网络对象来响应;
必须结合service port 组成一个具体的通信端口,单独的clusterip不具备tcp/ip通信协议
3.podip
是每个pod的ip地址,是docker engine根据docker0网桥的ip地址段进行分配的,是一个虚拟的二层网络,k8s里面的一个pod里面的容器访问另外一个容器,就是通过podip所在的虚拟二层网络进行通信的。
每个会被分配一个单独的ip,每个pod都提供了一个独立的Endpoint( Pod ip + Container port )以被客户端访问
原文参考:简单操作:10分钟实现在kubernetes(k8s)里面部署服务器集群并访问项目(docker三) - 熊泽-学习中的苦与乐 - 博客园
10.3.2 创建资源文件
# 创建资源文件
vim nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 80
nodePort: 30000
targetPort: 80
selector:
app: myweb
# 创建资源
kubectl create -f nginx-svc.yaml
查看资源 kubectl describe service myweb
或者 kubectl get svc
10.3.3 访问资源
1.nginx-pod.yaml
[root@k8s-master-01 test]# cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod ###pod名称
labels:
app: nginx ###写上这个pod的标签,方便svc连接
spec:
containers:
- name: nginx-pod ##pod容器名称
image: nginx:latest ###镜像
imagePullPolicy: IfNotPresent ###镜像拉取策略
ports:
- containerPort: 80 ###容器端口
2.nginx-svc.yaml
[root@k8s-master-01 test]# cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx ###关联容器标签
ports:
- port: 80 ###容器端口
nodePort: 30002 ###nodeport映射为30002端口,便于外部主机访问
type: NodePort ###svc类型为nodeport
创建资源省略...
3.查看资源信息
# 查看指定的资源信息
kubectl get svc nginx-svc
4.访问svc
curl 10.254.75.119:80
其中80:30002的80为内部集群端口,而30002为公网ip/NodeIP端口
访问正常
k8s-svc外界访问pod容器服务-4_Bruce小鬼的博客-CSDN博客_k8s查看svc对应的pod
原文参考:k8s中Service(svc)的类型使用_devops_sre的博客-CSDN博客_k8s svc类型
10.3.4 外网访问
问题描述:
部署好服务后外网不能访问,查了很多资料发现一行命令搞定
解决方法:
iptables -P FORWARD ACCEPT
10.4 创建deployment
deployment也是保证pod高可用的一种方式,明明已经有RC,为什么还要引入deployment呢? 因为deployment解决了RC的一个痛点
10.4.1 创建deployment资源
# 创建资源文件
vim nginx-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: 10.0.0.11:5000/nginx:1.13
ports:
- containerPort: 80
# 创建资源
kubectl create -f nginx-deploy.yaml
查看资源 kubectl get pods
10.4.2 关联service
kubectl expose deployment nginx-deployment --port=80 --type=NodePort
10.4.3 deployment升级
kubectl edit deploy nginx-deploy
10.4.4 deployment回滚
kubectl rollout undo deployment nginx-deploy
10.4.5 deployment最佳实践
# 版本发布
kubectl run nginx --image=10.0.0.11:5000/nginx:1.13 --replicas=3 –record
# 版本升级
kubectl set image deploy nginx nginx=10.0.0.11:5000/nginx:1.15
# 历史版本查询
[root@k8s-master deploy]# kubectl rollout history deployment nginx
deployments "nginx"
REVISION CHANGE-CAUSE
1 kubectl run nginx --image=10.0.0.11:5000/nginx:1.13 --replicas=3 --record
2 kubectl set image deploy nginx nginx=10.0.0.11:5000/nginx:1.15
10.5 镜像拉取策略
imagePullPolicy,用于设置镜像拉取策略,kubernetes支持配置三种拉取策略:
Always:总是从远程仓库拉取镜像(一直远程下载)
IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像(本地有就本地 本地没远程下载)
Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错 (一直使用本地)
原文链接:https://blog.csdn.net/qq_43692950/article/details/119743072
11.升级资源
11.1 滚动升级
# 更新资源文件
vim nginx-rc2.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb2
spec:
replicas: 5
selector:
app: myweb2
template:
metadata:
labels:
app: myweb2
spec:
containers:
- name: myweb
image: nginx:1.13
ports:
- containerPort: 80
# 滚动升级
kubectl rolling-update myweb -f nginx-rc2.yaml --update-period=10s
查看所有资源,发现刚刚修改的资源 已经生效
# 查看所有资源
kubectl get pods
升级过程中,发生了错误中途退出时,可以选择继续升级。Kubernetes能够智能的判断升级中断之前的状态,然后紧接着继续执行升级。当然,也可以进行回退,命令如下
kubectl rolling-update myweb myweb2 --update-period=10s --rollback
12.资源分类
K8s中所有的内容都抽象为资源 资源实例化之后,叫做对象
原文链接:https://blog.csdn.net/Hmj050117/article/details/116572228
12.1 名称空间级别
仅在此名称空间下生效
举个列子:我们在安装kubeadm,通过kubeadm安装k8s集群的时候,它会默认的把所有系统组件放到kube-system名称空间下去运行,当我们使用命令kubectl get pod去获取系统安装pod信息时获取不到,原因是因为当我们使用 kubectl get pod 命令 后面什么都不加的话,默认是 kubectl get pod -n default ,也就是默认是default空间下,所以才看不到系统kube-system名称空间下的资源
1.工作负载型资源(workload):Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、 CronJob(ReplicationController在v1.11版本被废弃)
2.服务发现及负载均衡型资源(ServiceDiscovery LoadBalance): Service、Ingress、
配置与存储型资源:Volume(存储卷)、CSI(容器存储接口可以扩展各种各样的第三方存储卷)
3.特殊类型的存储卷:ConfigMap(当配置中心来使用的资源类型)、Secret(保存敏感数据)、 DownwardAPI(把外部环境中的信息输出给容器)
12.2 集群级别
Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding
12.3 元数据型
HPA、PodTemplateLimitRange
13.jenkins流水线搭建
13.1 jenkins集成k8s
原文参考:Jenkins master位于k8s集群外,实现jenkins slave的动态构建 - 流年晕开时光 - 博客园
14.常用插件
14.1 自动补全
# 安装bash-completion
yum -y install bash-completion
要找出答案,请重新加载您的 shell 并运行type _init_completion
. 如果命令成功,则您已经设置好,否则将以下内容添加到您的 ~/.bashrc
文件中:
source /usr/share/bash-completion/bash_completion