kubernetes 基础
k8s基础概念
pod分类
自助式pod
自我管理的pod,创建以后仍然需要提交给apiserver,由apiserver接收以后借助于调度器将其调度至指定的node节点,由node启动此pod
如果此pod出现故障,需要重启容器则由kubelet来完成
如果node节点故障了,那么此pod将会消失。其无法实现全局调度。所以不推荐使用此种pod
控制器管理的pod
常见的pod控制器:
- ReplicationController(复制控制器)
当启动一个pod时,这个pod如果不够用可以再启一个副本,而后由控制器来管理同一类pod的各种副本与对象。一旦副本少了就会自动增加。采取多退少补的规则,精确符合我们所定义的期望。
支持滚动更新 - ReplicaSet
由一个名叫Deployment的声明式更新的控制器来管理 - Deployment
Deployment只能管理无状态的应用 - StateFulSet
有状态副本集,可以管理有状态的应用 - DaemonSet
如果需要在每个node上运行一个副本的时候可以用DaemonSet - Job
- Cronjob
- 以上每种控制器都是用来实现一种特定的应用管理的
核心组件
HPA
Deployment还支持二级控制器
HPA(HorizontalPodAutoscaler,水平pod自动伸缩控制器)
一般情况下我们可以确保一个node上有2个pod在运行,万一用户访问流量增加,2个pod不足以承载这么多访问量怎么办?此时我们就应该要增加pod资源,那么到底应该加几个?
HPA控制器可自动监控pod、自动进行扩展。
service
假如有2个pod,pod有其生命周期,万一pod所在的节点宕机,那么此pod将应该要在其他的节点上重建,而重建完的pod与原来的pod已经不是同一个pod了,只是两者都是运行的同一个服务而已。且每个容器都有其IP地址,重建的pod中的容器其IP地址与之前的pod中容器的IP地址是不一样的,如此—来就会存在一个问题,客户端如何访问这些pod中的容器呢?
服务发现 (集贸市场例子:注册摊位、声明地址)
pod是有生命周期的,一个pod随时都有可能离去,随时都有可能会有其他pod加进来,假如它们提供的是同一种服务,客户端是无法通过固定的手段来访问这些pod的,因为pod本身是不固定的,它们随时可能被替换掉,无论使用主机名还是IP地址,都随时会被替换掉。
为了尽可能的降低客户端与pod间协调的复杂度,k8s为每一组提供同类服务的pod和其客户端之间添加了一个中间层,这个中间层是固定的,这个中间层就叫service
service只要不被删除,其地址与名称皆是固定的,当客户端需要在其配置文件中写*问某个服务时,它不再需要自动发现,只需要在配置文件中写明service的名称即可,而这个service是个调度器,其不但能够提供一个稳定的访问入口,还可以做反向代理,当service接收到客户端的请求后,会将其代理到后端的pod之上,一旦pod宕机了会立即新建一个pod,这个新建的pod会立即被service关联上,作为service后端的可用pod之一
客户端程序访问服务都是通过IP+端口或者主机名+端口的方式来实现的。而service关联后端的pod不是靠它的IP和主机名,而是靠pod的标签选择器。只要创建的pod的label是统一的,无论P地址和主机如何改变,其都能被service所识别。如此一来,只要pod属于标签选择器,只要其在service的管理范围之内,则其就会被关联到service中,当这个动态的pod关联到service中之后,再进行动态的探测此pod的IP地址、端口,再将其作为自己后端可调度的可用服务器主机对象。因此,客户端的请求发送到service,然后由service代理到后端真实的pod中的容器进行响应。
service不是一个程序,也不是一个组件,它只是一个iptables的dnat规则
service作为k8s的对象,有其自身的名称,而service的名称相当于服务的名称,而这个名称可以被解析。
AddOne附件
dns pod
- 装完k8s后第一件事就需要在k8s集群上部署一个dns pod,以确保各service的名称能够被解析
- 可以动态改变,包括动态创建、动态删除、动态修改
- 比如把service的名称改了,dns pod会自动触发,将dns解析记录中的名称也给改掉;假如我们手动把service的ip地址给改了,改完以后会自动触发,将dns服务中的解析记录给改掉
- 如此一来,客户端去访问pod资源的时候可以直接访问service的名称,然后由集群中专用的dns服务来负责解析
这种pod是k8s自身的服务就需要用到的pod,所以我们把它称为基础性的系统架构级的pod对象,而且它们也被称为集群附件
k8s网络模型
- 节点网络
- service集群网络
- pod网络
- k8s的三种网络模型分属于三个网段,由此延伸出来三个问题
- 同一pod内的多个容器间如何通信?
- lop网卡
- 各pod之间如何通信?
- 物理桥桥接,规模大的情况下会产生广播风暴(很少用这种方式)
- Overlay Network,通过隧道的方式转发报文(基本上都会用这个方式)
- pod与service之间如何通信?
- 同一pod内的多个容器间如何通信?
Kubectl管理工具
kuberconfig配置文件
kubectl使用kubeconfig认证文件连接k8s集群,使用kubectl config指令生成kubeconfig文件。
kubeconfig连接k8s认证文件:
- 集群
apiVersion:v1
kind:Config
clusters:
- cluster:
certificate-authority-data:
server:https://192.168.31.61:6443
name:kubernetes
- 上下文
contexts:
- context:
cluster:kubernetes
user:kubernetes-admin
name:kubernetes-admin@kubernetes
- 当前上下文
currnet-context:kubernetes-admin@kubernetes
- 客户端认证
users:
- name:kubernetes
user:
client-certificate-data:
client-key-data:
kubectl管理命令概述
类型 | 命令 | 概述 |
基础命令 | create | 通过文件名或标准输入创建资源 |
expose | 为Deployment,Pod创建Service | |
run | 在集群中运行一个特定的镜像 | |
set | 在对象上设置特定的功能 | |
explain | 文档参考资料 | |
get | 显示一个或多个资源 | |
edit | 使用系统编辑一个资源 | |
delete | 通过文件名、标准输入、资源名称或标签选择器来删除资源 | |
部署命令 | rollout | 管理Deployment,Daemonset资源的发布(例如状态、发布记录、回滚等) |
rolling-update | 滚动升级,仅限ReplicationController | |
scale | 对Deployment、ReplicaSet、RC或Job资源扩容或收缩Pod数量 | |
autoscale | 为Deploy,RS,RC配置自动伸缩规则(依赖metrics-server和hpa) | |
集群管理命令 | certificate | 修改证书资源 |
cluster-info | 显示集群信息 | |
top | 查看资源利用率(依赖metrics-server) | |
cordon | 标记节点不可调度 | |
uncordon | 标记节点可调度 | |
drain | 驱逐节点上的应用,准备下线维护 | |
taint | 修改节点taint标记 |
Kubectl命令的使用
Kubectl命令入门
create
创建一个来源一个文件或标准输入的资源
[root@master ~]# kubectl create deployment b1 --image busybox
deployment.apps/b1 created
创建好后查看,发现b1状态是ContainerCreating
,表示正在拉镜像,如果你的镜像早早拉下来了,那它就直接启动了
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
b1-68578fbb6c-gzhn2 0/1 ContainerCreating 0 10s
过了一会再查看b1,发现是CrashLoopBackOff
,表示已经退掉了,退掉了并不代表没运行,它是运行了,运行之后退出了;因为busybox默认是打开/bin/sh程序,而/bin/sh一执行就退出了,跟容器里面一样的,一启动就退出了。
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
b1-68578fbb6c-gzhn2 0/1 CrashLoopBackOff 3 102s
再创建一个b2,在命令后面加上一个-- date
,过一会查看状态,发现也挂掉了,因为-- date命令也是一样的一执行就没了
[root@master ~]# kubectl create deployment b2 --image busybox -- date
deployment.apps/b2 created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
b1-68578fbb6c-gzhn2 0/1 CrashLoopBackOff 7 14m
b2-75d5678b7f-76zpc 0/1 CrashLoopBackOff 7 12m
再创建一个b3,还是在创建b1的命令后,加上-- sleep 6000
,过了一会发现,运行起来了
[root@master ~]# kubectl create deployment b3 --image busybox -- sleep 6000
deployment.apps/b3 created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
b1-68578fbb6c-gzhn2 0/1 CrashLoopBackOff 7 14m
b2-75d5678b7f-76zpc 0/1 CrashLoopBackOff 7 13m
b3-84d7f7d4bf-lbcnh 1/1 Running 0 47s
由此发现b3里面有任务,就可以运行的,而前面两个是没有任务的,或者说任务一执行就没了,就会挂掉
一下启动三个pods,用kubectl create <TYPE NAME> <POD NAME>--image <镜像> --replicas <启动pod的数量>
,这里我们创建的是deployment无状态)类型的,replicas是用来设置要启动多少pods
[root@master ~]# kubectl create deployment myapp --image nginx --replicas 3
deployment.apps/myapp created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-6d8d776547-chght 1/1 Running 0 4m1s
myapp-6d8d776547-dc7jb 1/1 Running 0 4m1s
myapp-6d8d776547-qb7pt 1/1 Running 0 4m1s
nginx-6799fc88d8-kwd2b 1/1 Running 0 24h
暴露端口号,用-- port <端口号>
[root@master ~]# kubectl create deployment myapp1 --image nginx --port 80
deployment.apps/myapp1 created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-6d8d776547-chght 1/1 Running 0 8m18s
myapp-6d8d776547-dc7jb 1/1 Running 0 8m18s
myapp-6d8d776547-qb7pt 1/1 Running 0 8m18s
myapp1-677f4bf9bf-cf8ln 1/1 Running 0 102s
get
获取node节点、pod、service信息
列出所有的pod,在ps终端中打印出来
[root@master ~]# kubectl get pods
显示pods的详细信息
[root@master ~]# kubectl get pods -o wide
列出单replication的控制器的指定名称
[root@master ~]# kubectl get deployment myapp
NAME READY UP-TO-DATE AVAILABLE AGE
myapp 3/3 3 3 15m
一起列出replication的控制器和服务显示
[root@master ~]# kubectl get svc
[root@master ~]# kubectl get service
expose
暴露端口号,--target-port
表示暴露目标端口号
创建一个服务,这个服务在它的80端口号连接它的时候用容器的8000,用外面的80访问容器里的8000
## 把80映射到8000,因为它的类型是ClusterIP,表示这个service只能在集群中能访问到;NodePort则表示是在真机上可以访问的
[root@master ~]# kubectl expose deployment myapp --port 80 --target-port 8000
service/myapp exposed
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp ClusterIP 10.110.171.169 <none> 80/TCP 3s
nginx NodePort 10.111.4.86 <none> 80:30859/TCP 41h
delete
删除pod和service相同的名字,删除的时候指定你要删除的类型,你用哪个类型创建的就用哪个类型来删除
## 因为b1属于deployment类型的控制器,我们是通过控制器来管理的,而不是通过pod自身,而pod有两种类型,一种是自助式pod,一种是控制器管理的pod;我们现在用的是控制器管理的pod,所有要用控制器来管理它
[root@master ~]# kubectl delete deployment b1
deployment.apps "b1" deleted
[root@master ~]# kubectl get pods
No resources found in default namespace.
[root@master ~]# kubectl delete svc myapp
service "myapp" deleted
[root@master ~]# kubectl delete pods nginx
pod "nginx" deleted
[root@master ~]# kubectl get pods
No resources found in default namespace.
run
启动一个nginx pod
[root@master ~]# kubectl run nginx --image nginx
pod/nginx created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 2m52s
[root@master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 3m43s 10.244.2.11 node2.example.com <none> <none>
暴露端口号
[root@master ~]# kubectl run nginx --image nginx --port 80
pod/nginx created
加标签
[root@master ~]# kubectl run nginx --image nginx --labels "app=nginx,env=prod"
pod/nginx created
干跑模式(只是干跑一下,不会真的去跑)
[root@master ~]# kubectl run nginx --image nginx --dry-run server
W1219 20:00:28.790987 1379634 helpers.go:553] --dry-run is deprecated and can be replaced with --dry-run=client.
pod/nginx created (dry run)
[root@master ~]# kubectl get pods
No resources found in default namespace.
describe
描述pod信息
[root@master ~]# kubectl describe pod nginx