k8s简介
文档:/fairy-era/yg511q/hg3u04
学习视频是b站的黑马视频。
前言
现在基本部署都是容器化部署,虽说容器化部署很方便,但也会有一些问题,比如:
- 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器
- 当并发访问量变大的时候,怎么样做到横向扩展容器数量
这些容器管理的问题统称为容器编排问题,为了解决编排问题,就产生一些容器编排软件。其中最常见的就是k8s。
k8s的优点:k8s组成部分,组件
一个K8s集群主要是由控制节点(master),工作节点(node)构成,每个节点会安排不同的组件。
master需要的的组件:
- Kublet: k8s的后端程序,用来启动对应容器。
- Apiserver是资源操作的唯一入口,接受用户输入的命令,提供认证授权等等。
- Scheduler:负责集群资源调度,按照调度策略,将pod调度到相应的node节点。
- ControllerManager: 负责维护集群的状态,比如程序部署安排,故障检测,自动扩展,滚动更新等。
- Etcd组件:负责存储集群中各种资源对象的信息,也是保证集群中信息的同步。
node需要的的组件
- 1 Kublet: 负责维护容器的生命周期,通过控制dokcer,创建,更新,销毁容器,相当于node节点的对接人,接受调度的命令。
- kubeProxy: 负责提供集群内部的服务发现和负载均衡。跟apiServer的区别,apiServer是控制入口,而kubeProxy可以访问pod中的容器。
- Dokcer 负责节点上容器的各种操作。
以部署一个nginx服务来说明k8s各个组建的调用关系。
k8s重要概念
Service跟apiServer不一样,Service是对外服务的统一入口,可以实现负载均衡,通过label堆pod进行分类,然后控制流量访问到哪个pod。
NameSpace,隔离pod,即不同NameSpace的pod无法互相访问。
集群搭建
使用kubeadm,这里使用三台虚拟机,自己配置ipv4地址。
环境搭建
- 2主机解析
具体其他操作可以观看/weicunqi/p/
当我们搭建好环境之后,可以启动一个ngxin试一下:
启动成功。
资源管理
在k8s中,一切皆资源。
* k8s是一个集群系统,用户可以在集群中部署各种服务,而部署服务就是在k8s集群中,运行一个一个容器。
- k8s最小单元是pod,pod也是一个资源,容器一般放在pod中,k8s不直接管理pod,而是通过 pod控制器(也是一资源),如Deployment, ReplicaSet等来管理pod
- pod在提供服务之后,提供了 Service 资源来访问pod中的服务,Service跟apiService是两码事。
学习k8s,就是要学习如何对集群上的pod, pod控制器,sService,存储等各种资源进行操作。
###资源管理方式
三种: - 命令时对象管理,直接操作k8s的资源。
kubectl run nginx-pod --image=nginx:1.17.1 --port=80
- 命令时对象配置,通过命令和配置文件,操作k8s资源,参数不再命令行写了,转到配置文件中了。
kubectl create/patch -f
- 声明式对象配置,通过apply和配置文件操作操作k8s资源。一般用于创建和更新资源。
kubectl apply -f
优缺点:
命令式对象管理
kubectl是kubernetes集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。
kubectl [command] [type] [name] [flags]
kubectl get pod xxxx --namespace xxx
查看xxx命名空间内的xxx pod情况
comand:指定要对资源执行的操作,例如create、get、delete
type:指定资源类型,比如deployment、pod、service
name:指定资源的名称,名称大小写敏感
flags:指定额外的可选参数
资源类型
kubernetes中所有的内容都抽象为资源,可以通过下面的命令进行查看: kubectl api-resources
命令式配置对象管理
命令式对象配置就是使用命令配合配置文件一起来操作kubernetes资源。
命令式对象配置的方式操作资源,可以简单的认为:命令 + yaml配置文件(里面是命令需要的各种参数)
声明式对象配置
声明式对象配置就是使用apply描述一个资源最终的状态(在yaml中定义状态)
使用apply操作资源:
如果资源不存在,就创建,相当于 kubectl create
如果资源已存在,就更新,相当于 kubectl patch
总结
创建/更新资源 使用声明式对象配置 kubectl apply -f
删除资源 使用命令式对象配置 kubectl delete -f
查询资源 使用命令式对象管理 kubectl get(describe) 资源名称
YML语言
YAML是一个类似 XML、JSON 的标记性语言。它强调以数据为中心,并不是以标识语言为重点。因而YAML本身的定义比较简单,号称"一种人性化的数据格式语言"。
像.yml文件的编写等等都是用这种语法。
实战入门
Namespace
记住一点:Namespace可以将Pod隔离(跟label的区别),让其不可以互相访问。
不同组互相隔离,比如开发者看不到测试组。
[root@master ~]# kubectl get namespace
NAME STATUS AGE
default Active 45h # 所有未指定Namespace的对象都会被分配在default命名空间
kube-node-lease Active 45h # 集群节点之间的心跳维护,v1.13开始引入
kube-public Active 45h # 此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system Active 45h # 所有由Kubernetes系统创建的资源都处于这个命名空间
Pod
k8s的最小单元是pod,容器必须跑在pod,k8s通过pod控制器控制pod。
k8s在集群启动之后,各个组件也是通过pod的方式运行的。
corends,集群内通信。
etcd,存储对象资源。
apiserver,控制器入口。
controller-manage:决定pod在哪台运行。
scheduler,调度,
还有flannel网络,
以及proxy代理访问Pod等等。
一个Pod里面一般至少有两个容器,一个跟容器,不会计算在内。这个的意思 就是pod里面全部有一个容器,准备完毕的有1个。根容器不会计算在内。
kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace dev
/nginx created
kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 2m15s
kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-64777cd554-vvhdf 1/1 Running 0 3m4s 10.244.1.17 node1 <none> <none>
- 创建一个nginx的pod控制器,并且启动一个nginx服务,端口为80,namespace为dev
- -o wide表示详细删除,可以看到nginx服务器准备完成,并且抛在了node1服务器上。
- 这里查找的时候需要指定命名空间,因为不加就默认查找命名空间为default的
- curl 10.244.1.17:80就能在内部访问nginx,但是这个只是内部访问的,而且他是跟随pod的变化而变化的,也就是说当pod重建之后,ip就变了,所以就需要service提供一个稳定的ip进行访问。
- 删除pod不能直接删除pod,得直接删除pod控制器,否则pod控制器会当你删除pod的时候立马重启了一个pod。
label
- 在资源上添加标识,用他们来进行区分和选择。
- 如,一个网站的前台应用,和后台应用。我们想让他们分组,如果使用namespace的话,那么他们之间无法通信,显然不合常规,所以可以使用label来进行区分,分组(这也是跟namespace的本质区别)。
标签定义完毕之后,就需要选择标签。
Label Selector用于查询和筛选拥有某些标签的资源对象
pod控制器 Deployment
k8s中。pod是最小的控制单元,但是k8s不直接控制pod,而是通过一些pod控制器,如deployment,他会生成级联对象descrplate,由级联对象来控制pod.
- 当Pod资源出错的时候,pod控制器会尝试进行重启或者重建pod。
- deployment跟Pod的关系也是通过label来管理的
kubectl run nginx --image=nginx:1.17.1 --prot=80 --replicas=5 -n dev
[root@master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-64777cd554-2hcgb 1/1 Running 0 10s 10.244.2.29 node2 <none> <none>
nginx-64777cd554-6btr6 1/1 Running 0 10s 10.244.2.28 node2 <none> <none>
nginx-64777cd554-dtbff 1/1 Running 0 10s 10.244.1.21 node1 <none> <none>
nginx-64777cd554-qpdcm 1/1 Running 0 10s 10.244.1.19 node1 <none> <none>
nginx-64777cd554-rwxbk 1/1 Running 0 10s 10.244.1.20 node1 <none> <none>
[root@master ~]# kubectl get pod -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-64777cd554-2hcgb 1/1 Running 0 37s pod-template-hash=64777cd554,run=nginx
nginx-64777cd554-6btr6 1/1 Running 0 37s pod-template-hash=64777cd554,run=nginx
nginx-64777cd554-dtbff 1/1 Running 0 37s pod-template-hash=64777cd554,run=nginx
nginx-64777cd554-qpdcm 1/1 Running 0 37s pod-template-hash=64777cd554,run=nginx
nginx-64777cd554-rwxbk 1/1 Running 0 37s pod-template-hash=64777cd554,run=nginx
[root@master ~]#
- 可以看到,通过nginx的deploiyment管理器创建的pod,label都有一个run=nginx。
Service资源
- Pod创建完之后,我们需要对其访问,在集群内部可以通过pod ID来访问,但是pod ID不是固定不变的,如果pod出错重新创建了,那么pod Id就会变了。不固定。
- 这时候就需要通过service资源来访问,我们可以通过固定的Service Id来访问pod,service id是固定的,访问service id, server找到对应的pod访问。
[root@master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-64777cd554-22jzc 1/1 Running 0 9s 10.244.2.30 node2 <none> <none>
nginx-64777cd554-2dlfh 1/1 Running 0 9s 10.244.1.23 node1 <none> <none>
nginx-64777cd554-c9wmw 1/1 Running 0 9s 10.244.2.31 node2 <none> <none>
nginx-64777cd554-fbfpm 1/1 Running 0 9s 10.244.1.22 node1 <none> <none>
nginx-64777cd554-tx29r 1/1 Running 0 9s 10.244.1.24 node1 <none> <none>
[root@master ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 5/5 5 5 21s nginx nginx:1.17.1 run=nginx
pod在重建过程中,Pod IP是会改变的。并且集群外部无法访问Pod Ip
Service可以看作是一组同类pod对外的访问接口。
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx exposed
[root@master ~]# kubectl get service -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx ClusterIP 10.110.68.30 <none> 80/TCP 9s run=nginx
- 这里使用ClusterIp,仅在集群内访问service的ip
- 创建集群外访问的:
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx exposed
[root@master ~]# kubectl get service -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx NodePort 10.109.27.97 <none> 80:30692/TCP 2s run=nginx
- NodePort表示创建集群外访问的service
访问成功。