k8s 把数量众多的服务器重新抽象为一个统一的资源池,对于运维人员来说,他们面前没有服务器1、服务器2的概念,而是一个统一的资源池,增加新的服务器对运维人员来说,只是增加自资源池的可用量。不仅如此,k8s 把所有能用的东西都抽象成了资源的概念,从而提供了一套更统一,更简洁的管理方式。
1.基本概念
1.1 Pod
Pod是K8S中的最小工作单位, 和Docker中的容器类似, 不过pod是将一个或多个docker容器封装成一个统一的整体进行管理,并对外提供服务,同一个Pod内的容器可以共享网络栈、存储卷等。
例如查看本机有哪些pod: kubectl get pods
查看命名空间为kube-system下的所有pod: kubectl get pods -n kube-system
- 创建资源
k8s中所有资源都可以通过kube create
命令创建,使用create创建资源有2种方式,一种是直接使用命令指定参数,另一种是通过yaml
文件创建。例如新建一个名为kubia-pod.yaml
的文件如下:
apiVersion: v1 |
然后使用kubectl create -f kubia-pod.yaml
就可以创建一个pod
之后如果修改了配置,可以使用kubectl apply -f kubia-pod.yaml
来重新应用配置
1.2 namespace
命名空间namespace是k8s中组的概念,提供同一服务的pod应该被放置在同一命名空间下, 如果不指定,pod默认被放在命名空间default
下
1.3 ReplicationController(副本控制器)
ReplicationController(RC)是pod的复制抽象,用于解决pod的扩容缩容问题, 它会确保任何时间Kubernetes中都有指定数量的Pod在运行。在此基础上,RC还提供了一些更高级的特性,比如滚动升级、升级回滚等。
RC通过label来关联pod, 对于pod,需要设置其自身的label进行表示,label是一些列的key/value对。在创建RC的时候,需要指定标签选择器(Label Selector),生成之后,它就会通过选择器查找pod并将其纳入自己的管辖
- 标签:标签是k8s中用于分类资源而提供的一个属性,一个标签包含
标签名
和标签值
, 例如app=kubia
, k8s中绝大多数资源都是通过标签来筛选和控制pod的
一个简单的RC配置文件kubia-rc.yaml
如下:
apiVersion: v1 |
使用kubectl create -f kubia-rc.yaml
即可创建该副本控制器
此后,即使我们使用kubectl delete
删除了该副本控制器管辖的3个pod,它仍然会自动创建新的。需要注意,RC是通过标签来管理pod的,如果修改了某个pod的标签,那么它就自动脱离了RC的控制
- 存活探针
副本控制器RC是通过存活探针来讲pod的数量控制在期望数量, 存活探针的检测方式包括3种:HTTP GET请求
、TCP套接字
、Exec执行命令
一个带有存活探针的pod配置文件如下:
apiVersion: v1 |
1.4 ReplicationSet
ReplicationSet(RS)是升级版的RC,区别在于RS引入了对基于子集的selector查询条件,而RC仅支持基于值相等的selector条件查询
一个RS的配置文件kubia-rs.yaml
如下:
# 需要指定对应的 apiVersion |
1.5 Deployment
Deployment为pod和RS提供声明式的更新能力, 通过在Deployment中描述期望的集群状态, Deployment Controller会将现在的集群状态逐步更新为期望的集群状态,其职责同样是为了保证pod的数量和健康,并且提供了RS之外的新特性:
事件和状态查看:可以查看Deployment的升级详细进度和状态。
回滚:当升级pod镜像或者相关参数的时候发现问题,可以使用回滚操作回滚到上一个稳定的版本或者指定的版本。
版本记录: 每一次对Deployment的操作,都能保存下来,给予后续可能的回滚使用。
暂停和启动:对于每一次升级,都能够随时暂停和启动。
多种升级方案:Recreate—-删除所有已存在的pod,重新创建新的; RollingUpdate—-滚动升级,逐步替换的策略,同时滚动升级时,支持更多的附加参数,例如设置最大不可用pod数量,最小升级间隔时间等等。
1.6 Service
由于pod在受到RC调控时,其副本和虚拟ip的变化的,比如发生迁移或伸缩的时候。因此需要一个统一固定的ip或域名来访问,Service是pod的路由代理抽象,用于解决pod之间的路由发现问题,访问端只需要知道service的地址,由service来提供代理,Service和Pod之间同样是通过label来进行关联
接下来演示如何创建一个service:
首先使用1.4小节中的
kubia-rs.yaml
来创建3个pod:kubectl create -f kubia-rs.yaml
创建成功之后就可以看到3个pod
接下来新建service来提供对这3个pod的访问,新建
kubia-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- name: port80 # 为所有端口指定名称
port: 80 # 对外开放的服务端口
targetPort: 8080 # 后方 pod 的服务端口
selector:
app: kubia执行
kubectl create -f kubia-svc.yaml
来创建该服务,之后就可以看到它的信息:
CLUSTER-IP一栏就是该服务的ip,节点内其他pod就可以通过这个ip来访问服务,例如通过podkubia-4p45t
来访问服务:
可以看到请求被转向了kubia-k66bq
和kubia-5dlks
这2个pod,并且实现了负载均衡
1.7 Endpoints
因为svc
是通过我们事先定义好的标签选择器来查找 pod 的,所以 pod 的 ip 地址变动对于svc
毫无影响,其实在svc
和pod
之间还包含了一个资源叫做endpoint
,endpoint
(简称ep
)是一组地址及其端口的合集,如下图,只要一个svc
有标签选择器的话,他就会自动创建一个同名的ep
来标记出自己的要管理的 pod
- 通过域名访问服务
在1.6小节中我们通过ip的方式访问了服务,实际上k8s也提供了FQDN
(全限定域名)的方式访问服务:
上图中的kubia就是我们在创建service
时指定的name
属性
(这种方式可以访问同一命名空间中的服务,k8s还支持访问不同命名空间中的服务)
- 访问集群外部服务
如果一个集群内部的pod要访问外部服务器,如云数据库、公共API等,就可以利用Endpoint
来指定外部 服务的ip和端口,并将其绑定到一个服务serivce
上
新建external-service.yaml
如下,它只是提供了一个80端口供其他pod访问:
apiVersion: v1 |
然后新建external-endpoints.yaml
如下:
apiVersion: v1 |
执行创建命令: kubectl create -f external-service.yaml
kubectl create -f external-endpoints.yaml
然后查看服务详情,可以看到他已经和endpoint完成绑定
另外,也可以指定svc的类型type为ExternalName
,再通过ExternalName
字段来指定外部服务的域名,如下:
apiVersion: v1 |
2.常用命令
get |
查 | 列出某个类型的下属资源 |
---|
describe |
查 | 查看某个资源的详细信息 |
---|
logs |
查 | 查看某个 pod 的日志 |
---|
create |
增 | 新建资源 |
---|
explain |
查 | 查看某个资源的配置项 |
---|
delete |
删 | 删除某个资源 |
---|
edit |
改 | 修改某个资源的配置项 |
---|
apply |
改 | 应用某个资源的配置项 |
---|
3.对外提供服务
k8s对外提供服务通常有post-forward
、NodePort
、Ingress
几种方式
3.1 port-forward
port-forward适用于测试某个资源是否可用kubectl port-forward <资源类型>/<资源名> <本机端口>:<资源端口>
访问:
3.2 NodePort
NodePort可以将服务转发到所有k8s节点的指定端口上,其本质上也是一个Service
资源,通过指定nodePort
来将服务映射到节点的端口上,配置如下:
apiVersion: v1 |
创建后,就可以通过curl 节点ip:端口号
来访问了,节点ip可以通过kubectl describe node <节点名>
来查看
3.3 Ingress
使用NodePort已经可以满足暴露服务的需求,但是如果有多个服务,虽然可以通过nginx服务器来实现转发,但是如果服务有变更,就需要再次手动配置nginx,而k8s提供了另一种方式:Ingress
Ingress由2部分构成,服务转发服务的ingress-controller
和Ingress
资源,Ingress-controller根据Ingress资源提供的配置来转发流量, k8s本身没有自带Ingress-controller,这里我们使用官方推荐的nginx-ingress-controller
- 安装nginx-ingress-controller
官方配置文件: https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml
注意,官方的配置文件中,指定的image
镜像源无法用国内网络访问,需要替换为国内镜像源。另外,Ingress-controller
本身只是一个pod,它并不直接对外暴露端口,因此还需要新建一个NodePort将其暴露出去,完整配置文件如下:
ingress-nginx.yaml
使用kubectl create -f ingress-nginx.yaml
之后,就可以查看创建成功的Controller
- 创建ingress资源
(注意,在这一步之前需要创建一个service
及其pod
,具体可参考1.6小节中的步骤)
新建kubia-ingress.yaml
如下:
apiVersion: extensions/v1beta1 |
- 配置域名映射
在ingress-nginx.yaml
中,我们已经将nginx-ingress-controller
这个pod以30010端口暴露到主机上,接下来需要配置域名映射sudo vim /etc/hosts
加入172.17.0.3(节点ip) kubia.example.com
接下来就可以在主机上通过curl http://kubia.example.com:30010/kubia
来访问服务了
4.参考
https://www.jianshu.com/p/8d60ce1587e1
https://www.jianshu.com/p/116ce601a60f
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!