Docker概述:
一、Dockers介绍:
- 定义:容器是容器image运行时的实例。
- 通俗的理解:软件界的集装箱(隔离、封装)。
OCI:Open Container Initiative
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dAyu1S4q-1629344919913)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1627520721389.png)]
1、Docker Engine介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SkwTWEh5-1629344919915)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1627520861909.png)]
- Docker主要指容器引擎,即Docker engine。、
- Docker Engine是一个Client/Server应用程序。Docker engine主要组件有3部分:
- 服务器:是一个长期运行的程序,称为daemon进程。
- Docker daemon用于创建个管理docker对象,如容器镜像、容器、网络、卷。
- 命令行界面客户端(docker CLI):
- CLI使用Docker REST API通过脚本或直接的CLI命令与Docker daemon交互。
- 一个REST API:Client可以用它来与daemon进程通信交互
2、Docker架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m0pMr3g4-1629344919915)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\1627521063648.png)]
- Docker Client:Docker是个采用的C/S架构的应用程序。Docker Client一般通过Docker command来发起请求。在用户界面,支持用户与Docker Daemon之间通信。
- Docker daemon:简单地说,Docker daemon实现的功能就是接收客户端发来的请求,并实现请求所要求的功能,同时针对请求返回相应的结果。Docker daemon是驱动整个Docker功能的核心引擎。在功能的实现上,Docker daemon涉及了容器、镜像、存储等多方面的内容,涉及多个模块的实现和交互。
- Containers:
- 容器以镜像为基础,同时又为镜像提供了一个标准和隔离的运行环境。
- Docker的容器就是“软件界的集装箱”,可以安装任意的软件和库文件,做任意的运行环境配置。开发及运维人员在转移和部署应用的时候,不需关心容器里装了什么软件,也不需了解它们是如何配置的。
- Docker Image:与容器相对应,如果说容器提供了一个完整的、隔离的运行环境,那么镜像则是这个运行环境的静态体现。
- Registry:Registry是一个存放镜像的仓库。Registry本身也是一个单独的开源项目,企业可使用Registry镜像搭建私有仓库。
https://hub.docker.com提供公用镜像
二、Docker基础操作:
1、创建容器
(1)docker create
查看镜像:
docker search httpd
到https://hub.docker.com去查找
创建时,会自动下载镜像
docker create --name 容器名字 镜像名[:tag]
查看本地镜像:
docker image ls
docker images
docker seach httpd
(2)docker run ##创建并运行命令
docker run -d -p 8080:80 httpd
-d 后台运行
-p 宿主机与容器的端口映射
-it 在容器启动时,通过命令行进入容器并进行交互
2、查看容器
docker ps -a 查看所有容器
docker ps 或docker ls 查看所有运行的容器
3、启动容器
docker start name/containerid
4、停止容器
docker stop name/containerid
5、容器生命周期命令
docker create 创建容器
docker start
docker run
docker pause 暂停
docker unpause 恢复容器
docker restart 重启容器
docker stop 停止容器
docker rm 删除一个处于中止的容器,-f强制删除
docker kill 杀死容器进程
docker prune 删除所有中止的容器
6、进入容器的命令
docker attach命令
docker attach命令直接进入已启动容器的命令终端,不会启动新的进程。
Usage:docker attach [OPTIONS] CONTAINER
注意:
正确推出CTRL+P+Q,
如果使用exit,或者CTRL+d,会导致容器停止
docker exec命令
docker exec命令是在容器中打开新的终端。
Usage:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker exec -it sxq bash
三、容器镜像:
1、容器镜像结构
kernel:Linux系统内核
- boot file system (bootfs):包含boot loader和kernel。用户不会修改这个文件系统。Linux系统刚启动时会加载bootfs文件系统;而在启动完成后,整个内核都会被加载进内存,此时bootfs会被卸载掉从而释放出所占用的内存。对于同样内核版本的不同的Linux发行版的bootfs都是一致的。
- root file system (rootfs):包含典型的目录结构,包括/dev, /proc, /bin, /etc, /lib, /usr, and /tmp等,再加上要运行用户应用所需要的所有配置文件,二进制文件和库文件。这个文件系统在不同的Linux发行版中是不同的,且用户可以对这个文件进行修改。
容器镜像是容器的模板,容器是镜像的运行实例,runtime根据容器镜像创建容器
1、base镜像
- 从scratch构建,不依赖其他镜像
- scratch本身是个空镜像
- 其他镜像可在base镜像上进行扩展,创建新的镜像。
2、容器镜像分层结构:
Layer:容器层R/W
Image Layer:镜像层 R/O
- 容器由若干只读镜像层和最上面的一个可写容器层构成。
- 分层结构使镜像共享、容器创建、分发非常高效。
2、image常见命令:
docker search 搜索镜像
docker pull :下载镜像
docke push :上传镜像
docker images 或docker image ls :查看镜像
docker history nginx:v1.1 显示镜像构建过程
docker commit 构建镜像
构建镜像:
- docker commit命令:可将一个运行中的容器保存为镜像
- 运行一个容器
- 修改容器内容
- 将容器保存为镜像
docker commit [options] contianer img:tag
options:
-a :镜像作者
-m:注释信息
-p:在commit时,将容器暂停
-c:使用dockerfile创建镜像
docker commit -a Michael@huawei.com -m updatemessage nginx1 nginx:v1.1
- dockerfile文件指令集
- Dockerfile是包含若干指令的文本文件,可以通过这些指令创建出dokcer image。
- Dockerfile文件中的指令执行后,会创建一个个新的镜像层。
- Dockerfile文件中的注释以“#”开始。
- Dockerfile一般由4部分组成:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动指令
编写dockerfile文件
docker build -t http:v11 -f dockerfile1 /root
3、导入、导出镜像:
导出为tar文件:
docker image save imagename:tag > [path][flie.tar]
导入:
docker load < **.tar
4、将现有的系统打包成镜像:
tar -cvpf ubunt.tar --directory --exclude=sys --exclude=dev --exclude=run --exclude=boot
cat ubunt.tar | docker import - ubuntu:18.04
5、构建私有仓库
创建一个文件夹,作为镜像库存储空间
创建容器,使用docker hub上的registry镜像,这个镜像是用于构建本地的私有仓库
docker run -d -p 1000:5000 -v /root/myregister/:/var/lib/registry registry
镜像符合镜像库要求:
[host]:[port]/[username]/[registry:tag]
docker tag httpd:v11 127.0.0.1:1000/sxq/httpd:v12
docker push127.0.0.1:1000/sxq/httpd:v12
curl 127.0.0.1:1000/v2/_catlog
6、本地库上传至docker库
docker login
docker commitID/name dockerID/imagename:tag
docker push dockerID/imagename:tag
四、容器网络:
模型 | 说明 |
None | none网络中的容器,不能与外部通信。 |
Host | 容器加入到宿主机的Network namespace,容器直接使用宿主机网络。 |
Bridge | 默认网络驱动程序。主要用于多个容器在同一个Docker宿主机上进行通信。 |
Overlay | Overlay网络可基于Linux网桥和Vxlan,实现跨主机的容器通信。 |
Macvlan | Macvlan用于跨主机通信场景。 |
##查看容器网络
docker network ls
##查看net2详细信息
docker network inspect net2
##创建bridge子网为172.10.10.0/24网关为172.10.10.1的net2
docker network create --driver bridge --subnet 172.10.10.0/24 --gateway 172.10.10.1 net2
##创建centos2网络空间为net2
docker run --name centos2 -dit --network=net2 centos
##创建centos2网络空间为net2,固定IP172.10.10.10
docker run --name centos3 -dit --network=net2 --ip 172.10.10.10 centos
五、容器存储:
1、容器存储机制
(1)Storage driver:管理镜像层和容器层
- Storage driver处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户提供了多层数据合并后的统一视图。
- 所有Storage driver都使用可堆叠图像层和写时复制(CoW)策略。
- docker info命令可查看当前系统上的storage driver。
(2)docker容器中持久化数据一般采用两种存储方式:
- volume:默认路径挂载
- bind mount:可自行指定目录
(3)volume由Docker管理,是将特定目录挂载给容器。
- docker会在指定路径下为每个volume生成一个目录,作为mount源。
- 路径:/var/lib/docker/volumes
- 可通过-v将volume挂载给一个容器。
- -v格式::
(4) bind mount是将宿主机上已有的目录或文件mount到容器中。
- 直接挂载,使用inode节点挂载路径。
- 路径可以自定义
docker run --name huawei2 -d -p 8081:80 -v /root/htdocs:/usr/local/apache2/htdocs:ro httpd
docker run --name huawei3 -d -p 8082:80 -v /root/htdocs/:/usr/local/apache2/htdocs httpd
2.数据共享
(1)主机与容器数据共享:
- bind mount:将Host上的目录或文件mount到容器中。
- volume:将Host上的数据copy到容器的volume中。
- 使用docker cp命令在容器与Host之间复制数据。
- 使用cp命令将需要共享的数据copy到该volume的目录下。
(2)容器间数据共享
- bind mount:将Host上的目录或文件mount到多个容器中。
- volume:将volume挂载到多个容器中。
- volume:先通过volume或bind mount将数据挂载到一个container中,其他容器再引用这个container中的数据。
六、容器实现的核心技术Namespace和Cgroup
1、namespace
- Namespace:命名空间
- 作用:资源隔离
- 原理:namespace将内核的全局资源进行封装,使得每个namespace都有一份独立的资源。因此不同进程在各自namespace内对同一种资源的使用不会相互干扰。
Nmespace类型 | 系统调用参数 | 隔离内容 | 引入的内核版本 |
PID namespace | CLONE_NEWPID | 进程空间(进程ID) | Linux 2.6.24 |
Mount namespace | CLONE_NEWNS | 文件系统挂载点 | Linux 2.6.19 |
Network namespace | CLONE_NEWNET | 网络资源:网络设备、端口等 | 始于Linux 2.6.24完成于Linux 2.6.29 |
User namespace | CLONE_NEWUSER | 用户ID和用户组ID | 始于Linux 2.6.23完成于Linux 3.8 |
UTS namespace | CLONE_NEWUTS | 主机名和域名 | Linux 2.6.19 |
IPC namespace | CLONE_NEWIPC | 信号量、消息队列和共享内存 | Linux 2.6.19 |
###实践
docker run -h hwhost -it centos
[root@hwhost /]# touch sxq
[root@hwhost /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sxq sys tmp usr var
[root@hwhost /]# ps axf
PID TTY STAT TIME COMMAND
1 pts/0 Ss 0:00 /bin/bash
19 pts/0 R+ 0:00 ps axf
[root@hwhost /]# useradd sxq
[root@hwhost /]# id sxq
uid=1000(sxq) gid=1000(sxq) groups=1000(sxq)
###登录宿主主机查看
[root@localhost ~]# docker inspect 669 |grep -i pid
"Pid": 118015,
"PidMode": "",
"PidsLimit": 0,
[root@localhost ~]# ps axf |grep 118015
118015 pts/0 Ss+ 0:00 | \_ /bin/bash
126210 pts/2 S+ 0:00 | | \_ grep --color=auto 118015
2、Cgroups:Linux Control Group
- 作用:限制一个进程组对系统资源的使用上限,包括CPU、内存、Block I/O等。
- Cgroups还能设置进程优先级,对进程进行挂起和恢复等操作。
- 原理:将一组进程放在一个Cgroup中,通过给这个Cgroup分配指定的可用资源,达到控制这一组进程可用资源的目的。
- 实现:在Linux,以的cgroupcgroup
- 可通过如下参数,对容器的可用CPU资源进行限制:
- –cpu-shares:权重值,表示该进程能使用的CPU资源的权重值。以512为单位,数值越大权重越高。
- cpu.cfs_period_us和cpu.cfs_quota_us:这两个配置参数一般配合使用,表示限制进程在长度为cfs_period的一段时间内,只能被分配到总量为cfs_quota的CPU时间。
###启动容器并进行cpu测试
docker run --name sxq1 -it --cpu-shares 512 progrium/stress --cpu 1
docker run --name sxq2 -it --cpu-shares 2048 progrium/stress --cpu 1
###新开窗口使用top或docker status命令查看
top
docker status
##查看限制文件
docker ps -a
cd /sys/fs/cgroup/xcpu/docker/
ll
cd 151(sxq容器对应的id)
cat cpu.share
cd edf(sxq容器对应的id)
cat cpu.share
cat task 查看进程ID
- 默认情况下,宿主机不限制容器对内存资源的使用。可使用如下参数来控制容器对内存资源的使用:
- –memory:设置内存资源的使用限额
- –memory-swap:设置内存和SWAP资源的使用限额
- 对进程内存使用限制的详细配置参数在/sys/fs/cgroup/memory目录:
###启动容器并进行内存测试:内存为400 swap为50,--memory-swap=-1为不限制
docker run --name sxq1 -it -m 400M --memory-swap 450M centos -dit /bin/bash
- Block IO指的是磁盘的读写,可通过如下3种方式限制容器读写磁盘的带宽。
- 设置相对权重
- –blkio-weight Block IO (relative weight)
- 设置bps:每秒读写的数据量
- –device-read-bps Limit read rate (bytes per second) from a device
- –device-write-bps Limit write rate (bytes per second) to a device
- 设置iops:每秒IO次数
- –device-read-iops Limit read rate (IO per second) from a device
- –device-write-iops Limit write rate (IO per second) to a device
七、Kubernetes架构介绍
架构:
- 一个基础的kubernetes集群包含一个master节点和多个node节点。每个节点可以是一台物理机,也可以是一台虚拟机。
- 节点组件运行在每一个Node节点上,维护运行的pod并提供kubernetes运行时环境。
命名空间:
- Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为命名空间。
- 命名空间提供了良好的资源隔离,可以用于区分不通的项目、用户等。如开发测试使用的namespace,或者生产使用的namespace。
- 使用如下命令可以查看哪些对象在命名空间中
kubectl api-resoureces --namesapce=true
八、Deploment
1、Kubernete管理对象:
- Pod
- Kubernetes基本管理单元,每个Pod是一个或多个容器的一组集合。
- 一个Pod作为一个整体运行在一个节点(node)上。
- Pod内的容器共享存储和网络
- ReplicationController(简称RC)【现用RS】
- Kubernetes需要管理大量的Pod,而显而易见的是通常情况下一个应用不会以单独的一个Pod完成。比较常见的情况是使用大量的Pod组成一个简单应用。管理这些大量的Pod的一个方式就是RC。
- 【监控】RC可以指定Pod的副本数量,并且在其中有Pod故障时可以自动拉起新的Pod,大大简化了管理难度。
- ReplicaSet(简称RS)
- ReplicaSet是新一代的RC,主要功能和RC一样,维持Pod的数量稳定,指定Pod的运行位置等,使用方法也相似,主要区别是更新了api,支持更多功能。
- ReplicaSet不建议直接使用,而是用更上层的概念Deployment调用ReplicaSet。
- Deployment
- 目前最常用的控制器就是Deployment,创建Deployment时也会自动创建ReplicaSet。
- Deployment可以管理一个或多个RS,并且通过RS来管理Pod
从小到大的管理逻辑
容器<Pod<ReplicaSet<Deployment
通常情况下
Pod中包含一个容器,或关系特别紧密的几个容器。
一个ReplicaSet中包含多个相同的Pod。
Deployment中包含一个或几个不同的RS
2、创建Deploment
创建一个简单的deployment
kubectl create deployment mydep --image=nginx
完成后我们使用如下语句查看deployment的创建情况
kubectl get deployment -o wide -w
kubectl get rs
kubectl get pod
kubectl get all
kubectl describe deploment mydep
2、yaml编写规则:
- 大小写敏感
- 使用缩进关系表示层级关系
- 只允许使用空格,不允许使用tab键
- 空格数目不重要,但同层元素一定左对齐
- 列表项,通过减号加空格
- 字符串,可以不用引号标注
- 键值对,用:分隔
- #代表注释
apiVersion:版本号,固定为apps/v1,如果使用1.9.0以前版本的kubernetes,填写apps/v1beta2
Kind: 类型,选择创建资源类型,可以填写pod,replicaset等
Metadata:元数据,其中name项指定了名称,label项指定标签。
Spec:deployment规格,其中replicas指定pod副本数量,选择器选择标签匹配为app:nginx
Template:对pod模板的定义,其中至少要定义一个label
Spec:描述pod的规格
Containers:定义容器的属性,在范例中,容器名字是nginx,镜像为nginx:1.7.9,容器输入输出的端口是80端口。
最后注意格式,缩进一般使用两个空格,千万不要使用tab!
#样例
##apiVersion:1.9.0以前版本为apps/v1 beta2
apiVersion:1.9 apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
##副本数量和模板
spec:
###副本数量
replicas: 3
###匹配标签
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
###指定pod规格
spec:·
s:
- name: nginx
image: nginx:1.7.9
ports:
-Port: 80
###查询相关参数
kubectl explain Deployment.spec.replicas
3、弹性收缩
- Deployment弹性伸缩本质是Pod数量增加或减少。
- 弹性伸缩可以支持自动化部署,并在很短时间内实现数量变更。
- 弹性伸缩通过修改yaml文件中的replica参数实现。
- 修改yaml后使用scale命令应用变更完成扩容或减容。
kubectl apply -f 文件名
4、滚动升级
当使用的deployment需要升级时(如软件版本更新),可以使用rolling update功能滚动升级deployment中所有pod。
#修改镜像版本
kubectl apply -f 文件名 --record
##查看升级信息
kubectl get deployment -0 wide
kubectl get rs
##查看历史信息
kubectl describe deploment
###查看回滚信息
kubectl rollout history deployment nginx-deployment
kubectl rollout history deployment nginx-deployment --revision=2
##回滚历史版本
kubectl rollout undo deployment nginx-deployment --to--revision=2
kubectl get deployment -o wide
九、POD
- Pod是Kubernetes管理的最小基础单元。
- 一个Pod中封装了:
- 一个或多个紧耦合的应用容器
- 存储资源
- 独立的IP
- 容器运行的选项
1、POD的工作模式
- 只包含一个应用容器的pod
- “一个pod一个容器”的模式是在Kubernetes中主流的使用场景。
- 在这种场景中,pod可以被看做是一个“包装纸”包着的容器。Kubernetes不能直接管理容器,而是需要通过管理pod来管理容器
- 包含多个应用的pod
- 仅当两种容器紧耦合,且需要共享相同的资源时使用这一种模式。
- 这些在一个pod内的容器形成一个统一的服务单元。例如一个容器从共享卷提供文件,而另一个容器刷新或更新资源。Pod将这些容器和存储资源作为单个可管理的实体包装在一起。
- 一个pod中会分配一个pause容器,这也被称为根容器。
- Pause容器的状态代表整个pod的状态
- Pod中多个容器共享容器的和存储,容器间可以通过互访
2、Pod生命周期:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-phEQtUW7-1629344919917)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628489826200.png)]
挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
3、使用pod
1、创建yaml文件
kind: Pod
apiVersion: v1
metadata:
name: mypod
spec:
s:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 30000
2、创建并查看
kubectl create -f mypod.yaml
###查看podID和运行节点
kubectl get pod -o wide
###查看完整信息
kubectl describe pod mypod
3、管理pod
#进入mypod的命令行,
kubectl exec -it mypod /bin/sh
#exec命令用于在容器中执行命令
#-it参数使得用户可以直接进入容器进行操作。
#在pod中可能存在多个容器,加入“--container 容器名“参数指定进入容器。
kubectl exec -it mypod --container mypod /bin/sh
#如果希望退出当前所在容器,可以输入exit回车退出
十、 Label与Label Selector
1、Label
- 标签(Label)是附在kubernetes对象(如pod,deployment等)上的键值对(key-value),可以在创建时指定,也可以在创建后指定。
- Label的值本身不具备具体含义,但可以通过label来筛选对象特定的子集,便于管理。
- 每一个对象可以有多个标签。
2、标签语法
- 标签由一组键值对构成。
- Label key的组成:
- Key值必须是唯一的
- 不得超过63个字符
- 可以使用前缀,使用/分隔,前缀必须是DNS子域,不得超过253个字符,系统中的自动化组件创建的label必须指定前缀,kubernetes.io/由kubernetes保留
- 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
- Label value的组成:
- 不得超过63个字符
- 起始必须是字母(大小写都可以)或数字,中间可以有连字符、下划线和点
3、标签操作
kubectl get pod --show-labels
kubectl label pod labelpod time=2019
4、标签选择器(Label Selector)
标签不具备唯一性,在通常情况下,多个不同的对象有着相同的标签。
通过标签选择器,用户或客户端可以指定批量的对象进行操作。标签选择器也是kubernetes的核心分组方式。
目前支持两种标签选择器,基于等值的(equality-based)和基于集合的(set-based)。
基于等值的(equality-based)
- Equality-based标签选择器允许用标签的key和values过滤。有三种运算符可以使用,分别是“=”,“==”和“!=”。前两种运算符同义,代表相等,后一种代表不相等。
kubectl get pods -l time=2019 --show-labels
基于集合的(set-based)
- Set-based 的标签条件允许用一组value来过滤key。支持三种操作符: in , notin 和 exists(仅针对于key符号)
5、节点打标签
- 将节点2打上标签
Kubectl label nodes k8s-node2 env=test
- 查看节点上的env标签
[root@k8s-master runfile]# kubectl get node -L env
NAME STATUS ROLES AGE VERSION ENV
k8s-master Ready master 21d v1.14.1
k8s-node1 Ready <none> 21d v1.14.1
k8s-node2 Ready <none> 21d v1.14.1 test
6、 使用Nodeselector选择节点
- 编辑yaml文件,创建deployment
- 查看podpodNode2
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
s:
- name: nginx
image: nginx:1.7.9
ports:
-Port: 80
nodeSelector:
env: test
7、使用Node affinity
继续使用上一页的yaml文件,将nodeselector替换所示内容
###硬亲和
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: env
operator: In
values:
- test
###软亲和
affinity:
nodeAffinity:
perferredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: env
operator: In
values:
- test
十一、 Service服务发现
1、实现方式:
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector实现的。
- Service的实现类型
- ClusterIP:提供一个集群内部的虚拟IP地址以供Pod访问(默认模式)
- NodePort:在Node上打开一个端口以供外部访问
- LoadBalancer:通过外部的负载均衡器来访问
2、Service模型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W5C9kI83-1629344919918)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图28642936173.png)]
1、 Endpoint Controller
- 负责生成和维护所有endpoint对象的控制器
- 负责监听service和对应pod的变化
- 监听到service被删除,则删除和该service同名的endpoint对象
- 监听到新的service被创建,则根据新建service信息获取相关pod列表,然后创建对应endpoint对象
- 监听到service被更新,则根据更新后的service信息获取相关pod列表,然后更新对应endpoint对象
- 监听到pod事件,则更新对应的service的endpoint对象,将pod IP记录到endpoint中
2、 Kube-proxy
iptables
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LYtZ2yvm-1629344919919)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628643217313.png)]
IPVS
从k8s的1.8版本开始,kube-proxy引入了IPVS模式,IPVS模式与iptables实现方式类似,但是采用的hash表,因此当service数量达到一定规模时,hash查表的速度优势就会显现出来,从而提高service的服务性能 。
Service基数 | 1 | 5,000 | 20,000 |
Rules基数 | 8 | 40,000 | 160,000 |
增加1条iptables规则 | 50us | 11min | 5hour |
增加1条ipvs规则 | 30us | 50us | 70us |
(1)Cluster
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LC2vAXYh-1629344919920)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628643890821.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5saKuK4U-1629344919920)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628643911912.png)]
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
replicas: 3
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
s:
- name: httpd
image: httpd
ports:
-Port: 80
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
spec:
selector:
app: httpd
ports:
- protocol: TCP
port: 8080
targetPort: 80
- 查看service简明信息,可以获取service提供服务的ip地址和端口。
kubectl get service
kubectl get endpoint
(2)NodePoint
创建可供外部访问的Service
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MRKGobe6-1629344919921)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628644898346.png)]
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
spec:
type: NodePort
selector:
app: httpd
ports:
- protocol: TCP
port: 8080
targetPort: 80
nodePort: 30144
3、CoreDNS
- CoreDNS是一个轻量级的DNS服务器,通过插件的形式在Kubernetes集群内实现,提供服务发现功能,使得用户除了可以用IP访问服务外,也可用域名来访问服务。
- 从1.13版本的Kubernetes开始CoreDNS取代了原有的kubeDNS,成为了kubernetes集群内部的默认DNS组件。
kubectl get pod -n kube-system
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GRrZlBfT-1629344919921)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628647907600.png)]
apiVersion: v1
kind: Pod
metadata:
name: clientpod
spec:
s:
- name: clientpod
image: busybox:1.28.3
args:
- /bin/sh
- -c
- sleep 30000
- 服务的DNS记录名称为:
<服务名称>..svc.cluster.local - 服务后端的deployment中Pod的DNS记录名称为:
.<服务名称>..svc.cluster.local - ClientPod访问服务时,可以使用服务名称便捷抵达服务,甚至在与服务在同一时,直接用服务名称进行访问
4、Headless Service
- 有的时候不需要或者不想要负载均衡,以及单独的Service IP,可以通过指定Cluster IP的值为“None”来创建Headless Service。
- 对这类Service并不会分配Cluster IP,kube-proxy不会处理他们,并且平台也不会为他们进行负载均衡和路由。
- 对定义了selector的Headless Service,意味着后端有一些提供业务的Pod,Endpoint控制器在API中创建了Endpoints记录,当通过域名访问服务时,流量会被直接转发到对应的Pod上。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GKLChK94-1629344919921)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628650528149.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rw7Ue9Nc-1629344919922)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628650549158.png)]
apiVersion: v1
kind: Service
metadata:
name: headless-svc
spec:
selector:
app: httpd
ports:
- protocol: TCP
port: 80
targetPort: 80
clusterIP: None
十二、DaemonSet与Job
1、DaemonSet
- DaemonSet 部署的副本Pod会分布在各个Node上。当有 Node 加入集群时,也会为他们新增一个 Pod。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
- DaemonSet典型场景:
- 在集群的每个节点上运行存储Daemon,如glusterd,ceph。
- 在每个节点上运行日志收集Daemon,如flunentd或logstash。
- 在每个节点上运行监控Daemon,如Prometheus Node Exporter。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GtncBDbh-1629344919922)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628664184831.png)]
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonset
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
s:
- name: nginx
image: nginx:1.7.9
ports:
-Port: 80
##查看
kubectl get daemoset
kubectl get pod -o wide
##删除
kubectl delete daemoset nginx-daemoset
2、Job
通过Deployment我们可以部署常驻型应用,它可以保证pod数量保证应用的实时可用,也可以通过灵活的扩缩容让业务处于最佳状态。
通过DaemonSet我们可以部署守护进程,它使得每个node上运行着一个固定pod
相对于Deployment和DaemonSet通常提供持续的服务,Job执行一次性任务
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
s:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
- 类型(kind)选择Job。
- restartPolicy只能选择Never或OnFailure。
- backoffLimit:job
##查看
kubectl get job -w
##使用kubectl logs命令可以查看该Job运行结果。
3、CronJob
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OVKIJ3lg-1629344919923)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628666037583.png)]
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
s:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFyKxFp7-1629344919923)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628666103047.png)]
kubectl get cronjob
kubctl delete cronjobs jobname
kubctl logs 输出结果
十三、Pod健康检测
1、更准确的判断Pod状态
Kubernetes借助探针(Probes)机制,探针可以会周期性的监测容器运行的状态,返回结果。
- Liveness探针:存活探针。Liveness探针用户捕获容器的状态是否处于存活状态。如果探测失败,kubelet会根据重启策略尝试恢复容器。
- Readiness探针:就绪探针。如果readiness探针探测失败,则kubelet认为该容器没有准备好对外提供服务,则endpointcontroller会从与pod匹配的所有服务的端点中删除该Pod的地址
2、执行过程
Kubelet可以周期性的执行Container的诊断。为了执行诊断,kubelet调用Container实现的Handler,有三种Handler类型:
- ExecAction:在容器内执行指定命令,如果命令退出时返回码为0(表示命令成功执行了),则认为诊断成功。
- TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则认为诊断成功。
- HTTPGetAction: 对指定端口和路径上的容器IP地址执行HTTP Get请求。如果响应的状态码≥200且<400,则诊断认为是成功的。
3、Liveness探针
(1)ExecAction
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UPQ9otSq-1629344919923)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628729774566.png)]
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
s:
- name: liveness
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30;
rm -rf /tmp/healthy; sleep 600
image: busybox
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fGVhDGnj-1629344919924)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628730112663.png)]
在上一步骤中使用describe命令可以看到探针的一些策略。
Liveness: exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
Delay=5s表示探针在容器启动后5秒开始进行第一次探测。
Timeout=1s表示容器必须在1秒内反馈信息给探针,否则视为失败。
Period=5s表示每5秒探针进行一次探测。
#success=1表示探测连续成功1次,表示成功。
#failure=3表示探测连续失败3次,视为Pod处于failure状态,重启容器。
(2)Http探针
- HTTP方式的存活探针,通过get方法定期向容器发送http请求。方法中定义了请求路径、端口、请求头等信息。
- 由于探针仅在返回码 ≥200,小于400的情况下返回正常,10秒后探针检测失败,kubelet会重启容器。
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
labels:
app: ubuntu
spec:
s:
- name: ubuntu
image: ubuntu
args:
- /bin/sh
- -c
- apt-get update && apt-get -y install openbsd-inetd telnetd && /etc/init.d/openbsd-inetd start; sleep 30000
livenessProbe:
tcpSocket:
port: 23
initialDelaySeconds: 60
periodSeconds: 20
(3)TCP探针
TCP探针检测能否建立连接。实验中部署一个telnet服务,探针探测23端口。
- TCP探针参数与探针相似
apiVersion: v1
kind: Pod
metadata:
name: ubuntu
labels:
app: ubuntu
spec:
s:
- name: ubuntu
image: ubuntu
args:
- /bin/sh
- -c
- apt-get update && apt-get -y install openbsd-inetd telnetd && /etc/init.d/openbsd-inetd start; sleep 30000
livenessProbe:
tcpSocket:
port: 23
initialDelaySeconds: 60
periodSeconds: 20
4、Readness探针
- Pod处于存活状态并不意味着可以提供服务,创建完成后通常需要进行诸如准备数据、安装和运行程序等步骤,才能对外提供服务。
- Liveness探针指示是否处于存活状态,探针则可指示容器是否已经一切准备就绪,可以对外提供服务
- 就绪探针与存活探针一致,可以使用ExecAction,TCPSocketAction,HTTPGetAction三种方法。
- 就绪探针用于检测和显示Pod是否已经准备好对外提供业务。在实际使用场景中,就绪探针需要和业务绑定
就绪探针 | 存活探针 | |
当Pod未通过检测 | 等待 | 杀死Pod,重启一个新Pod |
服务 | 如果检测失败,则从endpoint中移除pod | Endpoint自动更新新pod信息 |
作用 | Pod是否准备好提供服务 | Pod是否存活 |
#创建Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
spec:
replicas: 3
selector:
matchLabels:
app: httpd
template:
metadata:
labels:
app: httpd
spec:
s:
- name: httpd
image: httpd
ports:
-Port: 80
readinessProbe:
exec:
command:
- cat
- /usr/local/apache2/htdocs/index.html
initialDelaySeconds: 5
periodSeconds: 5
#创建Http的svc
apiVersion: v1
kind: Service
metadata:
name: httpd-svc
spec:
selector:
app: httpd
ports:
- protocol: TCP
port: 8080
targetPort: 80
删除配置文件后,节点移除集群,保留信息,配置文件恢复后,节点加入。
十四、Kubernetes网络模型
1、 Kubernetes的网络模型设计目标
Kubernetes网络模型用于满足以下四类通信需求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vl7aN4PB-1629344919924)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628755157572.png)]
(1)同Pod内容器通信
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DlYszu5O-1629344919925)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628819167523.png)]
(2)Pod间通信
Pod的IP是集群可见的,即集群中的任何其他Pod和节点都可以通过IP直接与Pod 通信,这种通信不需要借助任何的网络地址转换、隧道或代理技术。Pod内部和外部使用的是同一个IP,这也意味着标准的命名服务和发现机制,比如DNS可以直接使用。
如下图中的Pod N和Pod M之间的通信。此网络也称为Pod网络。
运行Pod的各节点也会通过桥接设备等持有此平面网络中的一个IP地址,如下图中的cbr0接口,这就意味着Node到Pod间的通信也可在此网络上直接进行。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AcTeg3nz-1629344919925)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628819845778.png)]
(3)Service和Pod间通信
- Service资源的专用网络也称为集群网络(Cluster Network)
- Pod间可以直接通过IP地址通信,但前提是Pod得知道对方的IP。在Kubernetes 集群中,Pod可能会频繁的销毁和创建,也就是说Pod的IP不是固定的。
- 为了解决这个问题,Service提供了访问Pod的抽象层。无论后端的Pod如何变化,Service都作为稳定的前端对外提供服务。同时,Service还提供了高可用和负载均衡功能,Service负责将请求转发给正确的Pod。
(4) 集群外访问实验(NodePort方式)
编译安装NodePort
2.Pod网络实现方式
- 每个Pod对象内的基础架构容器均使用一个独立的网络名称空间。
- 该名称空间会共享给同一Pod内其他容器使用。
- 每个网络名称空间均有其专用的独立网络协议栈及其相关的网络接口设备。
- 一个网络接口仅能属于一个网络名称空间。
- 显然的,运行多个Pod必然要求使用多个网络名空间,也就需要用到多个网络接口设备。
1、虚拟网络接口的实现方式
- 用软件实现的虚拟网络接口及虚拟线缆将其连接至物理接口是一种较为流行的方案。
- 虚拟网络接口的实现方案常见的有虚拟网桥、多路复用及硬件交换三种。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WObXRlEy-1629344919925)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628823337455.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pcqt2hoC-1629344919926)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628823387440.png)]
2、容器网络模型规范CNI
Kubernetes设计了网络模型,但将其实现交给了网络插件。于是,各种解决方案不断涌现。
为了规范及兼容各种解决方案,CoreOS和Google联合制定了CNI( Container Network Interface)标准,旨在定义容器网络模型规范。它连接了两个组件:容器管理系统和网络插件。
CNI的设计思想是: 容器runtime在创建容器时,提前创建好网络的名称空间(netns),然后调用CNI插件为这个netns配置网络,而后再启动容器内的进程。
- CNI本身只是规范,付诸生产还需要有特定的实现。
- 目前,CNI提供的插件分为三类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8MKbbPM-1629344919926)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628839615004.png)]
/opt/cni/bin
- Flannel: 一个为Kubernetes提供叠加网络的网络插件,它基于Linux TUN/TAP,用UDP封装IP报文来创建叠加网络,并借助etcd维护网络的分配情况。
- Calico: 一个基于BGP的三层网络插件,并且也支持网络策略来实现网络的访问控制;它在每台机器上运行一个vRouter,利用Linux内核来转发网络数据包,并借助iptables实现防火墙等功能。
- Canal: 由Flannel和caco联合发布的一个统一网络插件,提供CN网络插件,并支持网络策略。
3、Flannel
各类CNI插件都至少要解决这两类问题:
- 各运行容器的主机在网桥上默认使用同一个子网,跨节点会面临地址冲突的问题。
- 即使跨节点时使用不同的子网,其报文也会因为缺乏路由信息而无法到达目的地址。
针对第一个问题,flannel的解决方法是预留一个大网段,如10.244.0.0/16,而后自动为每个节点的Docker容器引擎分配一个子网,如10.244.1.0/24和10.244.2.0/24。子网和子网间能正常通信。
针对第二个问题,Flannel通过各种不同的后端(网络模型)来解决
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0PrT6C7Q-1629344919926)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1628841879211.png)]
kubectl get cm kube-flannel-cfg -n kube-system -o yaml
#kubectl get cm kube-flannel-cfg -n kube-system -o yaml
apiVersion: v1
data:
cni-conf.json: |
{
"name": "cbr0",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
# flannel默认使用VXLAN作为后端
lVXLAN(Virtual extensible Local Area Network):虚拟可扩展局域网,是VLAN展方案,采用MAC in UDP的封装方式,属于NVo3( Network Virtualization overayer3)中的一种网络虚拟化技术。VXLAN广泛应用于云数据中心的软硬件SDN网络解决方案中。
具体实现方式为: 给普通数据报文添加到VXLAN报头后封装为外网可路由的UDP报文,然后以传统网络的通信方式传输该报文,待其到达目的主机后,去掉外网报头以及VXLAN报头,然后将报文转发给目的终端,整个过程中通信双方对物理网络无所感知。
上述过程相当于在传统的网络之上架起了由一条条VXLAN隧道构成的“高架”网络。
VXLAN技术的引入使得逻辑网络拓扑和物理网络拓扑实现了一定程度的解耦,网络拓扑的配置对于物理设备的配置的依赖程度有所降低,配置更灵活更方便。
传统的VXLAN后端使用隧道的通信方式会导致报文开销及流量增大。
于是flannel的VXLAN后端还支持DirectRouting模式,该模式通过添加路由信息的方式,直接使用节点的二层网络进行Pod的通信报文的交互,仅在跨网段时,才启用传统的隧道方式转发通信流量。
由于大部分场景中都省去了隧道首部开销,因此DirectRouting通信模式的性能基本接近于二层物理网络。
将 flannel项目官方提供的配置清单下载至本地:
- /etc/kubernetes/manifests/kube-flannel.yaml
卸载Flannel后将其 ConfigMap资源kube- flannel-cfg的data字段的网络配置部分修改为如下:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
"Directrouting": true
}
}
使用“ kubectl apply”命令重新应用于集群中
# kubectl apply -f kube-flannel.yaml
查看节点路由表
10.244.2.0/24 via 192.168.56.68 dev ens33
10.244.3.0/24 via 192.168.56.69 dev ens33
注意:该配置推荐在集群网络初始化时做
(2)host-gw后端
host-gw后端通过添加路由信息使节点直接发送Pod的通信报文,其工作方式类似于VXLAN后端的direct routing的功能,但不包括其 VXLAN的隧道转发能力。
配置方式类似上述direct routing配置方式:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": “host-gw"
}
}
十五:kubernetes存储
1、EmptyDir
当 Pod 指定到某个节点上时,首先创建的是一个 emptyDir 卷,并且只要 Pod 在该节点上运行,卷就一直存在。 就像它的名称表示的那样,卷最初是空的。 尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,但是这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会永久删除。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MejPV8yR-1629344919927)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1629105684444.png)]
apiVersion: v1
kind: Pod
metadata:
name: em
spec:
s:
- image: ubuntu
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
args:
- /bin/sh
- -c
- sleep 30000
volumes:
- name: cache-volume
emptyDir: {}
volumes:
- name: cache-volume
emptyDir:
sizeLimit:1Gi
2、HostPath
hostPath配置项与emptyDir类似,但类型需指定:
- hostPath。
- path参数需要配置为主机上已存在的目录。
- 指定为目录,因本次实验中挂载给的是一个文件夹
apiVersion: v1
kind: Pod
metadata:
name: hppod
spec:
s:
- image: ubuntu
name: hp-container
volumeMounts:
- mountPath: /hp-dir
name: hp-volume
args:
- /bin/sh
- -c
- sleep 30000
volumes:
- name: hp-volume
hostPath:
path: /root/runfile/hostpathdir
type: Directory
取值 | 行为 |
空字符串(默认)用于向后兼容,这意味着在安装 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate | 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 Kubelet 相同的组和所有权。 |
Directory | 在给定路径上必须存在的目录。 |
FileOrCreate | 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 Kubelet 相同的组和所有权。 |
File | 在给定路径上必须存在的文件。 |
Socket | 在给定路径上必须存在的 UNIX 套接字。 |
CharDevice | 在给定路径上必须存在的字符设备。 |
BlockDevice | 在给定路径上必须存在的块设备。 |
如果选择类型不正确,或主机上不存在对应资源(如不存在指定文件夹),kubernetes系统将无法继续创建Pod,创建步骤终止。Pod状态长时间处于ContainerCreating
3、PV和PVC
PersistentVolume(pv)和PersistentVolumeClaim(pvc)是k8s提供的两种API资源,用于抽象存储细节。管理员关注于如何通过pv提供存储功能而无需关注用户如何使用,同样的用户只需要挂载pvc到容器中而不需要关注存储卷采用何种技术实现。
- PV是集群中由管理员配置的一块存储空间。它是集群中的资源,就像节点是集群中的资源一样。PV是卷插件,和之前介绍的volumes类似,但它有一个独立于单个Pod的生命周期。PV的后端可以是NFS,iSCSI或者云存储等。
- PVC是用户的存储请求。它类似于Pod:Pod消耗节点资源,而PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和内存),PVC可以请求PV特定的接入模式(读写等)和大小。
(1)创建PV
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VA6cDUxw-1629344919927)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1629107251401.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uew6ucKQ-1629344919928)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1629107269623.png)]
(2)创建PVC
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SOhEvneR-1629344919929)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1629107842102.png)]
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc
spec:
accessModes:
- ReadWriteOnce
volumeName: mypv
resources:
requests:
storage: 1Gi
volumes:
- name: pvc-volume
persistentVolumeClaim:
claimName: mypvc
(3)删除PVC
kubectl delete pvc mypvc && kubectl get pod
删除PVC的同时,会创建容器进行回收。删除PVC,PV不受影响(recycle)。
(4)在创建PV和PVC时使用StorageClass
创建PV时指定storageClassName,可以在PVC中申请该PV。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gDbNEcjp-1629344919929)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1629108861688.png)]
storageClass除了能够用上述用法之外,主要使用场景是动态供给PV。
由于kubernetes集群中存在大量的Pod,也就意味着很可能有大量的PV和PVC,如果需要一个一个手工创建无疑是一个巨大的工程,也不符合自动化的特点。
- 以nfs为例,使用动态供给功能需要完成以下几个步骤:
- 创建nfs-provisioner,provisioner用于动态创建符合要求的PV。
- 创建StorageClass,在配置时指定使用的provisioner。
- 创建PVC,只需要指定StorageClass,容量及访问模式即可。
- 如果将一个StorageClass标注为default,则PVC在申请时可以不指定StorageClass而默认使用该defaultStorageClass。
十六、ConfigMap与Secret
当开发人员开发完成一个应用程序,比如一个Web程序,在正式上线之前需要在各种环境中运行,例如开发时的开发环境,测试环节的测试环境,直到最终的线上环境。Web程序在各种不同的环境中都需要对接不同的数据库、中间件等服务,在传统方式中我们通过配置文件来定义这些配置,而kubernetes中如果需要进入一个个Pod来配置,那将会是一个巨大的麻烦。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IdzOZWNt-1629344919929)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1629337598954.png)]
ConfigMap用于容器的配置文件管理。它作为多个properties文件的应用,类似一个专门存储配置文件的目录,里面存放着各种配置文件。
ConfigMap实现了image和应用程序的配置文件、命令行参数和环境变量等信息解耦。
ConfigMap和Secrets类似,但ConfigMap用于处理不含敏感信息的配置文件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lQLY8Rs8-1629344919930)(C:\Users\admin\Desktop\华为认证培训\HCIA云计算\笔记思维导图\1629337623080.png)]
1、从目录创建
[root@k8s-master configmap]# cat game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
[root@k8s-master configmap]# cat ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
# kubectl create configmap game-config --from-file=/runfile/configmap
configmap/game-config created
#kubectl get configmap
#kubectl describe cm game-config
2、从文件中创建
从目录创建时指定了/runfile/configmap目录,创建时使用了目录下的所有文件。如果指定的不是目录而是单独文件,即从文件创建ConfigMap
#kubectl create configmap game-config --from-file=/runfile/configmap
--from-file参数可以多次使用,用于从多个文件创建ConfigMap的场景:
# kubectl create configmap game-config-3 --from-file=/runfile/configmap/game.properties --from-file=/runfile/configmap/ui.properties
configmap/game-config-3 created
3、从literal值创建
之前的方式都需要新建配置文件,然后从文件创建ConfigMap。Kubernetes还提供使用实际配置值创建的方式,通过–from-literal参数实现。
#kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
# kubectl describe configmaps special-config
Name: special-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
special.how:
----
very
special.type:
----
charm
Events: <none>
4、通过yaml文件创建
与deployment,pod等资源对象相同,ConfigMap也可以使用Yaml文件进行创建。
Data字段中,key1的定义方式类似使用–from-iterial,pro.property的定义方式类似使用–from-file.
apiVersion: v1
kind: ConfigMap
metadata:
name: specialconfig-2
data:
key1: value1
pro.property: |
key2: value2
key3: value3
5、使用configmap
(1)通过环境变量
可以直接将ConfigMap里的参数直接做为容器的环境变量供其中程序调用。
env可以创建环境变量的键,并且引用configmap里特定参数做为值。envFrom则自动将configmap的所有的键值对自动变成环境变量。
apiVersion: v1
kind: Pod
metadata:
name: cm-test-pod
spec:
s:
- name: cm-container
image: busybox
args: ["/bin/sh", "-c", "env"]
env:
- name: special-env
valueFrom:
configMapKeyRef:
name: specialconfig-2
key: key1
envFrom:
- configMapRef:
name: specialconfig-2
restartPolicy: always
special-env=value1
key1=value1
pro.property=key2: value2
key3: value3
(2)通过Volume
使用方式和存储章节中使用emptyDir和hostPath的volume类似,configMap挂载后变成了容器内的一个目录。
在容器的/etc/db目录中,我们可以看到两个文件,分别是key1,和pro.property,对应configmap中的两个DATA。键就是文件名,值就是文件内容。
apiVersion: v1
kind: Pod
metadata:
name: cmpod2
spec:
s:
- name: cmpod2
image: busybox
args: [ "/bin/sh", "-c", "sleep 3000" ]
volumeMounts:
- name: db
mountPath: "/etc/db"
readOnly: true
volumes:
- name: db
configMap:
name: specialconfig-2
(3)使用注意事项:
ConfigMap必须在创建Pod前创建完成。如果Pod调用ConfigMap失败,则无法创建。
Pod只能使用在同一Namespace中的ConfigMap
ConfigMap创建方式通常使用文件方式。
ConfigMap使用方式通常使用volume方式。
以volume方式挂载ConfigMap,如果更新ConfigMap或删除重建ConfigMap,Pod内挂载的配置信息会热更新。
#kubectl edit cm specialconfig-2
6、Secret
1、概述
- Secret 是一种包含少量敏感信息例如密码、token 或 key 的对象。这样的信息可能会被放在 Pod spec 中或者镜像中;将其放在一个 secret 对象中可以更好地控制它的用途,并降低意外暴露的风险。
- ConfigMap主要解决配置文件的存储问题,而Secret主要用来解决密码、token、密钥等敏感数据。
- 在创建、查看和编辑Pod的流程中Secret暴露风险较小。
- 系统会对Secret对象采取额外的预防措施,例如避免将其写入磁盘中可能的位置。
- 只有Pod请求的Secret在其容器中才是可见的,一个Pod不能访问另一个Pod的Secret。
2、创建
(1) 使用kubectl命令创建
- 创建一个两个文件,写入用户名和密码。
[root@k8s-master secret]# echo -n "admin" > username.txt
[root@k8s-master secret]# echo -n "Huawei@123" > password.txt
- 使用kubectl命令创建。Secret的名称为db-user-pass
[root@k8s-master secret]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
其中generic参数代表从本地的文件、目录或实际值(literal value)
(2)使用Yaml文件创建
为避免Yaml文件中的值被查看到,因此需要先用base64编码后,将值写入Yaml
[root@k8s-master secret]# echo -n "admin" | base64
YWRtaW4=
[root@k8s-master secret]# echo -n "Huawei@123" | base64
SHVhd2VpQDEyMw==
创建yaml文件
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: SHVhd2VpQDEyMw==
3、使用
(1)volume方式
使用volume方式挂载Secret给Pod和使用ConfigMap类似。
一个Secret在容器内体现为一个目录,一对键值对是一个文件,其中键是文件名称,值是文件内容。
Secret内容在挂载给时进行解码,因此在内部是明文呈现.
apiVersion: v1
kind: Pod
metadata:
name: spod
spec:
s:
- image: busybox
name: spod
args: ["/bin/sh","-c","sleep 3000"]
volumeMounts:
- name: secrets
mountPath: "/etc/secret"
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
(2)挂载指定值
- 在挂载Secret的时候可以指定items,只将Secret中的某些参数传递到Pod中:
- Secret中password传递到了pod中,而username没有。
- 在Pod中/etc/secret/my-group有一个my-passwd文件,内容为Huawei@123。
apiVersion: v1
kind: Pod
metadata:
name: spod2
spec:
s:
- image: busybox
name: spod2
args: ["/bin/sh","-c","sleep 3000"]
volumeMounts:
- name: secrets
mountPath: "/etc/secret"
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
items:
- key: password
path: my-group/my-passwd
十七、Kubenetes中的QOS
附件:
1、docker安装过程
141 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
142 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
143 yum makecache
144 cd /etc/yum.repos.d
145 ls
146 mv Media.repo Media.repo.bak
147 ls
148 yum cleanall
149 yum clean all
150 yum make cache
151 yum makecache
152 ping baidu.com
153 yum install yum-utils device-mapper-presistent-data lvm2 -y
154 yum list
155 rpm -qa | grep yum
156 yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo
157 yum -y install docker-ce-18.06.2
158 ls
159 cat docker-ce.repo
160 yum makecache
161 yum -y install docker-ce-18.06.2
162 yum clean all
163 yum makecache
164 yum install docker-ce-18.06.2.ce -y
165 systemctl start docker
166 systemctl enable docker
167 systemctl status docker
168 docker version
169 docker info
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://m30jn00e.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
175 docker info
176 yum install bash-completion -y
177 source /usr/share/bash-completion/bash_completion
178 labs.play-with-docker
2、K8S安装过程:
K8SMaster 192.168.31.113 192.168.81.4
K8Snode1 192.168.31.114 192.168.81.5
K8Snode2 192.168.31.115 192.168.81.6
(1)修改主机名:
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2
(2)修改/etc/hosts
cat <<EOF>> /etc/hosts
192.168.81.4 k8s-master
192.168.81.5 k8s-node1
192.168.81.6 k8s-node2
EOF
(3)关闭主机防火墙:
systemctl stop firewalld
systemctl disable firewalld
(4)关闭swap分区
sed -i 's/.*swap.*/#$/' /etc/fstab
swapoff -a
(5)加载bf_netfilter
modprobe br_netfilter
(6)配置内核参数
cat <<EOF>> /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
(7)加载配置
sysctl -p /etc/sysctl.d/k8s.conf
(8)检测生成文件
ls /proc/sys/net/bridge/
##显示以下文件
bridge-nf-call-ip6tables bridge-nf-call-ip6tables
(9)添加k8s国内yum源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://repo.huaweicloud.com/kubernetes/yum/repos/kubernetes-el7-aarch64/
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://repo.huaweicloud.com/kubernetes/yum/doc/yum-key.gpg https://repo.huaweicloud.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum makecache
(10)安装依赖包和工具
yum -y install epel-release
yum -y install yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools wget vim ntpdate libseccomp libtool-ltdl tree
(11)配置时间同步
systemctl enable ntpdate.service
systemctl enable ntpdate.service
echo '*/30 * * * * /usr/sbin/ntpdate time7.aliyun.com > /dev/null 2>&1' > /tmp/crontab2.tmp
crontab /tmp/crontab2.tmp
systemctl start ntpdate.service
(12)安装docker CE
yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo
yum clean all
yum makecache
yum install docker-ce-18.06.2.ce -y
(13)使用国内的docker镜像源
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://m30jn00e.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
(14)启动docker
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
systemctl status docker
(15)下载配置文件
(16)编辑拉取K8s镜像脚本
3、配置NFS
在所有节点安装软件:
yum install nfs-utils rpcbind -y
###在server节点上进行配置
[root@k8s-master ~]# mkdir /nfs
[root@k8s-master ~]# chmod 755 /nfs
[root@k8s-master ~]# vim /etc/exports
/nfs * (rw,syns)
[root@k8s-master ~]# systemctl start nfs
[root@k8s-master ~]# systemctl enable nfs
[root@k8s-master ~]# systemctl start rpcbind
[root@k8s-master ~]# systemctl enable rpcbind
[root@k8s-master nfs]# showmount -e localhost
Export list for localhost:
/nfs *
###在客户端安装完成后,启动服务和检测
[root@k8s-node2 ~]# systemctl start nfs
[root@k8s-node2 ~]# systemctl enable nfs
[root@k8s-node2 ~]# systemctl enable rpcbind
[root@k8s-node2 ~]# systemctl start rpcbind
[root@k8s-node1 ~]# showmount -e k8s-master
Export list for k8s-master:
/nfs *
4、安装kublet,kubeadm,kubectl
(1)在所有的节点进行安装
gkey=https://repo.huaweicloud.com/kubernetes/yum/doc/yum-key.gpg https://repo.huaweicloud.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum makecache
(10)安装依赖包和工具
~~~bash
yum -y install epel-release
yum -y install yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools wget vim ntpdate libseccomp libtool-ltdl tree
(11)配置时间同步
systemctl enable ntpdate.service
systemctl enable ntpdate.service
echo '*/30 * * * * /usr/sbin/ntpdate time7.aliyun.com > /dev/null 2>&1' > /tmp/crontab2.tmp
crontab /tmp/crontab2.tmp
systemctl start ntpdate.service
(12)安装docker CE
yum-config-manager --add-repo http://download.docker.com/linux/centos/docker-ce.repo
yum clean all
yum makecache
yum install docker-ce-18.06.2.ce -y
(13)使用国内的docker镜像源
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://m30jn00e.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
(14)启动docker
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
systemctl status docker
(15)下载配置文件
(16)编辑拉取K8s镜像脚本
3、配置NFS
在所有节点安装软件:
yum install nfs-utils rpcbind -y
###在server节点上进行配置
[root@k8s-master ~]# mkdir /nfs
[root@k8s-master ~]# chmod 755 /nfs
[root@k8s-master ~]# vim /etc/exports
/nfs * (rw,syns)
[root@k8s-master ~]# systemctl start nfs
[root@k8s-master ~]# systemctl enable nfs
[root@k8s-master ~]# systemctl start rpcbind
[root@k8s-master ~]# systemctl enable rpcbind
[root@k8s-master nfs]# showmount -e localhost
Export list for localhost:
/nfs *
###在客户端安装完成后,启动服务和检测
[root@k8s-node2 ~]# systemctl start nfs
[root@k8s-node2 ~]# systemctl enable nfs
[root@k8s-node2 ~]# systemctl enable rpcbind
[root@k8s-node2 ~]# systemctl start rpcbind
[root@k8s-node1 ~]# showmount -e k8s-master
Export list for k8s-master:
/nfs *
4、安装kublet,kubeadm,kubectl
(1)在所有的节点进行安装