K8S的资源管理
k8s编排资源介绍
回顾:
Master:
- APIServer: 6443端口
- 用户认证: 双向认证
- Scheduler:调度任务给Node运行POD
- Controller:确保指定数量的POD处于运行状态
Node:
- Pod: 运行pod;Pod是名称空间(namespace)级别的资源
- Kube-Proxy: 监视apiserver的资源变动,然后反应在当前节点
K8S上最重要的基本组件: POD,POD Controller,Service,Volume
POD
1. 创建POD有两种方式:
- 直接创建POD
- 使用POD Contrller创建(如下是控制器)
- Deployment:nginx-deploy `--->` nginx Pod
- DaemonSet
- Stateful
- Service: nginx-svc `----->` nginx Pod 调度用户请求到POD
2. POD是名称空间(namespace)级别的资源
[root@centos7-node1 ~]# kubectl get namespaces #查看namespace
NAME STATUS AGE
default Active 84m
kube-node-lease Active 84m
kube-public Active 84m
kube-system Active 84m
[root@centos7-node1 ~]# kubectl get pods -n kube-system #查看系统级别的pods有哪些
NAME READY STATUS RESTARTS AGE
coredns-5644d7b6d9-6tlxm 1/1 Running 0 84m
coredns-5644d7b6d9-vnn2h 1/1 Running 0 84m
[root@centos7-node1 ~]# kubectl api-resources #查看资源
[root@centos7-node1 ~]# kubectl get deployments -n kube-system #查看kube-system下的Deployments控制器
名称空间
Namespace:对应POD资源,资源的逻辑组合
操作:CURD
简写: ns
展示类型: -o
: json ;wide;yaml
实例如下:
[root@centos7-node1 ~]# kubectl create namespace develop
[root@centos7-node1 ~]# kubectl create namespace testing
[root@centos7-node1 ~]# kubectl create namespace prod
[root@centos7-node1 ~]# kubectl get ns #查看名称空间
[root@centos7-node1 ~]# kubectl delete namespace develop #删除develop的ns,如果有pod也会被删除[危险操作]
[root@centos7-node1 ~]# kubectl delete ns/testing ns/prod #批量删除
[root@centos7-node1 ~]# kubectl get ns/default -o yaml #按照指定格式展示
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2019-11-10T05:01:59Z"
name: default
resourceVersion: "150"
selfLink: /api/v1/namespaces/default
uid: 32bb80ce-f2d2-4d6a-a157-ad0dfe680729
spec:
finalizers:
- kubernetes
status:
phase: Active
[root@centos7-node1 ~]# kubectl describe ns/default #打印描述信息
Name: default
Labels: <none>
Annotations: <none>
Status: Active
No resource quota.
No resource limits.
控制器
Deployment:组合POD资源
操作:CURD
简写: ds
展示类型: -o
: json ;wide;yaml
实例如下:
[root@centos7-node1 ~]# kubectl create deploy ngx-dep --image=nginx:1.14-alpine #在default的名称空间创建
[root@centos7-node1 ~]# kubectl get all
[root@centos7-node1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ngx-dep-d554574bd-crx88 1/1 Running 0 62s 10.244.1.2 centos7-node2 <none> <none>
在node2执行如下命令,即可访问nginx
[root@centos7-node2 ~]# curl 10.244.1.2
[root@centos7-node1 ~]# kubectl delete pods/ngx-dep-d554574bd-crx88 #删除pod,这样会自动创建,除非删掉deploy
[root@centos7-node1 ~]# kubectl get deploy
[root@centos7-node1 ~]# kubectl delete deploy ngx-dep
[root@centos7-node1 ~]# kubectl get pods #POD此时就被删除了
Service
Service:组合deploy,实现负载均衡
操作:CURD
简写: svc
展示类型: -o
: json ;wide;yaml
实例如下:
[root@centos7-node1 ~]# kubectl create service -h
Create a service using specified subcommand.
Aliases:
service, svc
Available Commands:
clusterip Create a ClusterIP service. #常见的方式
externalname Create an ExternalName service.
loadbalancer Create a LoadBalancer service.
nodeport Create a NodePort service.
[root@centos7-node1 ~]# kubectl create service clusterip ngx-dep --tcp=80:80 #指定端口(节点的端口:Deployment POD的端口),名称为ngx-dep,这样是为了自动关联deploy的ngx-dep
[root@centos7-node1 ~]# kubectl get svc/ngx-dep -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2019-11-10T06:56:19Z"
labels:
app: ngx-dep
name: ngx-dep
namespace: default
resourceVersion: "10458"
selfLink: /api/v1/namespaces/default/services/ngx-dep
uid: 25673ead-98b1-4693-a305-c7d2a543ddc2
spec:
clusterIP: 10.101.154.250
ports:
- name: 80-80
port: 80
protocol: TCP
targetPort: 80
selector:
app: ngx-dep
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
[root@centos7-node1 ~]# kubectl describe svc/ngx-dep #展示关联信息
Name: ngx-dep
Namespace: default
Labels: app=ngx-dep #名称必须爆出一直
Annotations: <none>
Selector: app=ngx-dep
Type: ClusterIP
IP: 10.101.154.250
Port: 80-80 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.4:80 ##此处就是关联信息
Session Affinity: None
Events: <none>
[root@centos7-node1 ~]# kubectl delete pods ngx-dep-d554574bd-wmjf2 #删除当前的svc对应的POD,然后会自动重建POD,重建的POD有可能会被调度到其他NODE
[root@centos7-node1 ~]# kubectl get pods -o wide #查看结果
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ngx-dep-d554574bd-7pnkf 1/1 Running 0 16s 10.244.2.2 centos7-node3 <none> <none>
[root@centos7-node1 ~]# kubectl get svc -n kube-system #查看DNS
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 124m
[root@centos7-node1 ~]# vim /etc/resolv.conf #修改DNS
# Generated by NetworkManager
search localdomain
nameserver 192.168.48.2
nameserver 10.96.0.10
[root@centos7-node1 ~]# curl ngx-dep.default.svc.cluster.local.
service结合deploy控制器练习
[root@centos7-node1 ~]# kubectl create deploy myapp --image=ikubernetes/myapp:v1
[root@centos7-node1 ~]# kubectl get pods
[root@centos7-node1 ~]# kubectl get deploy
[root@centos7-node3 ~]# curl 10.244.2.3
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@centos7-node3 ~]# curl 10.244.2.3/hostname.html
myapp-5c6976696c-vdhgt
[root@centos7-node1 ~]# kubectl create svc clusterip myapp --tcp=80:80 #创建SVC
[root@centos7-node1 ~]# kubectl scale --replicas=3 deployment myapp #将myapp扩容到三个副本
[root@centos7-node1 ~]# kubectl describe svc/myapp
Name: myapp
Namespace: default
Labels: app=myapp
Annotations: <none>
Selector: app=myapp
Type: ClusterIP
IP: 10.108.198.219
Port: 80-80 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.5:80,10.244.2.3:80,10.244.3.2:80
Session Affinity: None
Events: <none>
[root@centos7-node2 ~]# kubectl delete svc/myapp #删除svc
[root@centos7-node2 ~]# kubectl create svc nodeport myapp --tcp=80:80 #创建nodeport形式的svc
k8s的资源类型
简单总结
ApiServer是K8S的集线器;整个集群的Gateway;数据支持json/yaml;
- Api接口中的资源可以分为多个逻辑组合
- 每个组合: API,Group,api群组
- 每个组可以独立演进
- 每个组可以多版本并存
[root@centos7-node1 ~]# kubectl api-versions #查看aip 版本
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
authentication.k8s.io/v1
authentication.k8s.io/v
资源对象的配置格式
1. API Server接受和返回的所有JSON对象都遵循同一个模式,他们都具有“Kind”和“apiVersion”字段,用于标识对象所属的资源类型,API群组以及相关的版本
2. 大多数的对象或列表类型的资源还需要具有三个嵌套性的字段: metadata
,spec
,status
- metadata: 提供元数据信息;例如名称,隶属的名称空间,标签等
- spec: 用于定义用户期望的状态,不同的资源类型,其状态的意义各有不同;例如pod资源最为核心的功能在于运行容器
- status:记录互动对象当前的状态,他有kubernetes系统自行维护,对用户来说是只读字段
3. kubectl api-resources
命令获取的是集群支持的所有资源类型
和解循环
客户端向API Server提交POST请求以创建对象
- 通过json格式的body提交
- Yaml格式需要事先完成向json格式的转化
- 对象信息存储在ETCD中,其定义出的状态也叫做“期望的状态(SPEC)”
控制器负责将其创建为Kubernetes集群上的具体对象(活动对象),并确保其当前状态(status)与用户自定义的期望状态相同
- status由控制器自行维护,而spec由用户进行提交
- 活动对象在运行过程中因节点故障等原因可能会在某一时刻导致其status不在吻合与spec
- 控制器和解循环不间断的监控着相关对象的当前状态,在对象的当前状态发生改变是运行合适的操作使其当前的状态无限的接近spec定义的期望状态
管理资源对象的流程
资源对象的管理方式
kubectl的命令可分为三类:
- 陈述式命令: 用到的run,expose,delete和get等命令,他们直接操作于k8s系统上的活动对象,简单易用;但不支持代码服用,修改以及日志审计等功能,这些功能的实现要通过依赖于资源配置文件中,这些文件称为资源清单。
- 陈述式对象配置
- 声明式对象配置: apply完成增和改的操作 [推荐使用]
Namespace
- 使用资源清单创建namespace实例
[root@centos7-node1 ~]# mkdir /root/manifests/basic/ -p
[root@centos7-node1 ~]# vim /root/manifests/basic/develop-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: develop
[root@centos7-node1 ~]# kubectl create -f /root/manifests/basic/develop-ns.yaml #创建
[root@centos7-node1 ~]# kubectl get ns # 查看ns创建状态
[root@centos7-node1 ~]# vim /root/manifests/basic/prod-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: prod
[root@centos7-node1 basic]# kubectl apply -f prod-ns.yaml #更新或创建,可以多次执行
POD
- 手动创建自主式POD小例子:
[root@centos7-node1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-5c6976696c-vdhgt 1/1 Running 0 6h31m
myapp-5c6976696c-vvhs2 1/1 Running 0 6h24m
ngx-dep-d554574bd-7pnkf 1/1 Running 0 6h43m
[root@centos7-node1 ~]# kubectl get pods/myapp-5c6976696c-vdhgt -o yaml --export >> /root/manifests/basic/pod-demo.yaml
[root@centos7-node1 ~]# vim /root/manifests/basic/pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: pod-demo
namespace: develop
spec:
containers:
- image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
name: myapp
resources: {}
dnsPolicy: ClusterFirst
enableServiceLinks: true
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
[root@centos7-node1 ~]# kubectl apply -f manifests/basic/pod-demo.yaml #声明式对象配置
[root@centos7-node1 ~]# kubectl get pods -n develop -o wide #查看
其中imagePullPolicy有三种选项:
- IfNotPresent: 如果本地不存在,才向远端仓库下载镜像
- Always: 不管镜像本地是否存在,都要去远端镜像仓库下载镜像
- Never: 本地没有这个镜像就不启动(不下载)
文档查看:
逐层解释(对象)
[root@centos7-node1 ~]# kubectl explain pods
[root@centos7-node1 ~]# kubectl explain pods.metadata
[root@centos7-node1 ~]# kubectl explain pods.spec.containers
- 单个Pod里面跑多个container实例
此时的container之间是共享网络名称空间的,相当于是join
[root@centos7-node1 ~]# vim /root/manifests/basic/pod-demo-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo-2
namespace: prod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
- name: bbox
image: busybox:latest
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","sleep 86400"]
[root@centos7-node1 ~]# kubectl apply -f /root/manifests/basic/pod-demo-2.yaml
[root@centos7-node1 ~]# kubectl get pods -n prod
[root@centos7-node1 ~]# kubectl get pods -n prod -o yaml
[root@centos7-node2 ~]# kubectl exec pod-demo-2 -c bbox -n prod -it -- /bin/sh #进入其中一个container
/ # wget -O -q -S 127.0.0.1
[root@centos7-node2 ~]# kubectl logs pod-demo-2 -c myapp -n prod #查看日志
127.0.0.1 - - [10/Nov/2019:14:43:01 +0000] "GET / HTTP/1.1" 200 65 "-" "Wget" "-
- hostpod网络下的POD
此状态下的POD共享了宿主机的网络,但是不大安全
[root@centos7-node1 ~]# vim /root/manifests/basic/host-pod.yaml
apiVersion: v1
kind: pod
metadata:
name: mypod
namespace: default
spec:
containers:
- name: myapp
image: ikuvernetes/myapp:v1
hostNetwork: true
[root@centos7-node1 ~]# kubectl apply -f /root/manifests/basic/host-pod.yaml #创建
[root@centos7-node1 ~]# kubectl get pods -o wide #查看
mypod 1/1 Running 0 7s 192.168.56.12 centos7-node2 <none> <none>
- ports下的单一映射
[root@centos7-node1 ~]# vim /root/manifests/basic/host-pod-2.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- protocol: TCP
containerPort: 80
name: http
hostPort: 8080
[root@centos7-node1 ~]# kubectl apply -f /root/manifests/basic/host-pod-2.yaml #应用配置
[root@centos7-node1 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-5c6976696c-vdhgt 1/1 Running 0 7h39m 10.244.2.3 centos7-node3 <none> <none>
myapp-5c6976696c-vvhs2 1/1 Running 0 7h32m 10.244.1.5 centos7-node2 <none> <none>
mypod 1/1 Running 0 28s 10.244.1.7 centos7-node2 <none> <none>
ngx-dep-d554574bd-7pnkf 1/1 Running 0 7h51m 10.244.2.2 centos7-node3 <none> <none>
[root@centos7-node1 ~]# curl centos7-node2:8080 #访问宿主机所在的POD 8080映射端口
[root@centos7-node1 ~]# curl 10.244.1.7 #查看POD IP(这个定义的是80端口)
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
思考
当POD是在10.244.0.0/16的网段内,那么k8s集群之外的机器能否访问?如不能,如何时期访问?
显然是不能访问的
-
要能访问的话需要在:
- service,Nodeport
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2019-11-10T07:25:38Z"
labels:
app: myapp
name: myapp
namespace: default
resourceVersion: "13328"
selfLink: /api/v1/namespaces/default/services/myapp
uid: c4638ec6-c25f-4756-b1ad-4f5cfa3a8577
spec:
clusterIP: 10.107.19.50
externalTrafficPolicy: Cluster
ports:
- name: 80-80
nodePort: 31800
port: 80
protocol: TCP
targetPort: 80
selector:
app: myapp
sessionAffinity: None
type: NodePort
- HostPort
- HostNetwork