
1, Pod 详解
Pod 是 Kubernetes 的最重要概念, 每一个Pod都有一个特殊的被称为 "根容器"的Pause容器。Pause容器对应的镜像属于 Kubernetes 平台的一部分,除了 Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。


Pod vs 应用
每个 Pod 都是应用的一个实例, 有专用的IP
Pod vs 容器
一个 Pod 可以有多个容器,彼此间共享网络和存储资源, 每个Pod中有一个Pause容器保存所有的容器状态,通过管理Pause容器,达到管理Pod中所有容器的效果
Pod vs 节点
同一个Pod中的容器总会被调度到相同的Node节点,不同节点间Pod的通信基于虚拟二层网络技术实现
Pod vs Pod
普通的Pod和静态Pod
1.1 Pod的定义
下面是yaml文件定义的Pod的完整内容
apiVersion: v1 // 版本
Kind: Pod // 类型: Pod
metadata: // 元数据
name: string // 元数据,pod 的名字
namespace: string // 元数据,pod 的命名空间
labels: // 元数据 标签列表
- name: string // 元数据,标签的名字
annotations: // 元数据, 自定义注解列表
- name: string // 元数据, 自定义注解名字
spec: // pod中容器的详细定义
containers: // pod中容器列表,可以有多个容器
- name: string // 容器的名称
image: string // 容器中的镜像
imagesPullPolicy: [Always|Never|IfNotPresent]
//获取镜像的策略,默认职务Always,每次都尝试重新下载镜像
command: [string] // 容器的启动命令列表(不配置的话使用镜像内部的命令)
args: [string] // 启动参数列表
workingDir: string // 容器的工作目录
volumeMounts: // 挂载到容器内部的存储卷设置
- name: string
mountPath: string // 存储卷在容器内部Mount的绝对路径
readOnly: boolean // 默认值为读写
ports: // 容器需要暴露的端口号列表
- name: string
containerPort: int // 容器要暴露的端口
hostPort: int // 容器所在主机监听的端口
// (容器暴露端口映射到宿主机的端口,设置hostPort时同一台宿主机将不能再启动该容器的第二份副本)
protocol: string // TCP 和 UDP ,默认值为 TCP
env: // 容器运行前要设置的环境列表
- name: string
value: string
resources:
limits: // 资源限制,容器的最大可用资源数量
cpu: string
memory: string
requests: // 资源限制,容器启动的初始可用资源数量
cpu: string
memory: string
livenessProbe: // pod内容器健康检查的设置
exec:
command: [string] // exec 方式需要指定的命令或脚本
httpGet: // 通过 httpget 检查健康
path: string
port: number
host: string
scheme: String
httpHeaders:
- name: String
value: string
tcpSocket: // 通过 tcpSocket 检查健康
port: number
initialDelaySeconds: 0 // 首次检查时间
timeoutSeconds: 0 // 检查超时时间
periodSeconds: 0 // 检查间隔时间
successThreshold: 0
failureThreshold: 0
securityContext: // 安全配置
privileged: false
restartPolicy: [Always|Never|OnFailure] // 重启策略,默认值为Always
nodeSelector: object //节点选择,表示将该Pod调度到包含这些label的Node上,以key:value格式指定
imagePullSecrets:
- name: string
hostNetwork: false // 是否使用主机网络模式,弃用Docker网桥,默认否
volumes: // 在该pod上定义共享存储卷列表
- name: string
emptyDir: {} // 是一种与Pod同生命周期的存储卷,是一个临时目录,内容为空
hostPath: // Pod所在主机上的目录,将被用于容器中 mount 的目录
path: string
secret: // 类型为 secret 的存储卷
secretName: string
items:
- key: string
path: string
configMap; // 类型为 configMap 的存储卷
name: string
items:
- key: string
path: string
1.2 Pod 的基本用法
在 kubernetes 中对运行容器的要求为: 容器的主程序需要一直在前台运行,而不是后台运行,应用需要改造成前台运行的方式。如果我们创建的Docker镜像的启动命令是后台执行程序,则在kuberlet创建包含这个容器的pod之后运行完该命令,即认为Pod已经结束,将立刻销毁该Pod,如果为该Pod定义了RC,则创建,销毁会陷入一个无限循环的过程中。
Pod可以由1个或多个容器组合而成。
由一个容器组成的Pod实例 vim demo1.yaml
# 一个容器组成的Pod实例
apiVersion: v1
Kind: Pod
metadata:
name: mytomcat
labels:
name: mytomcat
spec:
containers:
- name: mytomcat
image: tomcat
ports:
- containerPort: 9000
操作
~: cd /usr/local/k8s_test/
~: ls
abtmp data docker test webbench yml
~: cd test/
~: pwd
/usr/local/k8s_test/test/
~: ls
busybox-pod.yaml demo1.yaml demo2.yaml demo3.yaml demo4-deployment.yaml demo4-hpa.yaml
demo4-svc.yaml index index.html kubernetes-dashboard.yaml nginx-deployment.yaml
nginx-hpa.yaml nginx-svc.yaml
创建 mytomcat 容器命令 kubectl create -f demo1.yaml
删除 mytomcat 容器命令 kubectl delete -f demo1.yaml
查看创建的 mytomcat 容器 kubectl get pods
老师的
查看创建的 mytomcat 容器 kubectl get pods

创建 mytomcat 容器命令 kubectl create -f demo1.yaml

删除 mytomcat 容器命令 kubectl delete -f demo1.yaml





由两个为紧密耦合的容器组成的Pod实例 vim /usr/local/k8s_test/test/demo2.yaml
# 两个为紧密耦合的容器
apiVersion: v1
Kind: Pod
metadata:
name: myweb
labels:
name: tomcat-redis
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containerPort: 8080
- name: redis
image: redis
ports:
- containerPort: 6379
创建
~: kubectl create -f domo2.yaml
查看 demo2.yaml 文件命令 cat /usr/local/k8s_test/test/demo2.yaml
创建 myweb 容器命令 kubectl create -f demo2.yaml
查看 busybox 容器的详细信息命令 kubectl describe pod busybox
查看
kubectl get pod/po <pod_name>
kubectl get pod/po <pod_name> -o wide
kubectl describe pod/po <pod_name>
删除
kubectl delete -f pod pod_name.yaml
kubectl delete pod --all/[pod_name]
老师的
查看 busybox 容器的详细信息命令 kubectl describe pod busybox

查看 myweb 容器 kubectl get pods

创建 myweb 容器命令 kubectl create -f demo2.yaml

查看 demo2.yaml 文件命令 cat /usr/local/k8s_test/test/demo2.yaml



1.3 Pod的分类
Pod 有两种类型
普通Pod
普通Pod一旦被创建,就会被放入到etcd中存储,随后会被Kubernetes Master调度到某个具体的Node上并进行绑定,随后该Pod对应的Node上的 kubelet 进程实例化成一组相关的 Docker容器并启动起来。在默认情况下,当Pod里某个容器停止时,kubernetes 会自动检测到这个问题并且重新启动这个Pod里某个所有容器,如果Pod所在的Node宕机,则会将这个Node上的所有Pod更新调度到其他节点。
静态 Pod
静态Pod是由 kubelet进行管理的仅存在于特定Node上的Pod,他们不能通过API Server进行管理,无法与Replication Controller,Deloyment或DaemonSet进行关联,并且 kubelet也无法对他们进行健康检查。
1.4 Pod生命周期和重启策略
Pod的状态
| 状态值 | 说明 |
|---|---|
| Pending | API Server已经创建了该Pod,但Pod中的一个或多个容器的镜像还没有创建,包括镜像下载过程 |
| Running | Pod内所有容器已经创建,且至少一个人情处于运行状态,正在启动状态或正在重启状态 |
| Completed | Pod内所有容器均成功执行退出,且不会再重启 |
| Failed | Pod内所有容器均已经退出,但至少一个容器退出失败 |
| Unknown | 由于某种原因无法获取Pod状态,例如网络通信下畅 |
老师的
获取容器的状态 kubectl get pods 此时为 Running 状态

Pod重启策略
Pod的重启策略包括Always, OnFailure 和Never,默认值是Always
| 重启策略 | 说明 |
|---|---|
| Always | 当容器失效时,由 kubelet自动重启该容器 |
| OnFailure | 当容器终止运行且退出码下为0时,由kubelet自动重启该容器 |
| Never | 不论容器运行状态如何,kubelet都不会重启该容器 |
常见状态转换
| Pod包含的容器数 | Pod当前的状态 | 发生事件 | Pod的结果状态 | ||
|---|---|---|---|---|---|
| RestartPolicy=Always | RestartPolicy=OnFailure | RestartPolicy=Never | |||
| 包含一个容器 | Running | 容器成功退出 | Running | Succeeded | Succeeded |
| 包含一个容器 | Running | 容器失败退出 | Running | Running | Failure |
| 包含两个容器 | Running | 1个容器失败退出 | Running | Running | Running |
| 包含两个容器 | Running | 容器被OOM杀掉 | Running | Running | Failure |

1.5 Pod资源配置
每个Pod都可以对其能使用的服务器上的计算资源设置限额, Kubernetes中可以设置限额的计算资源有CPU与Memory两种,其中CPUd的资源单位为CPU数量是一个绝对值而非相对值,Memory配额也是一个绝对值,他的单位是内存字节数。
Kubernetes 里,一个计算资源进行配额限定需要设定以下两个参数:
Requests 该资源最小申清数量,系统必须满足要求
Limits 该资源最大允许使用的量,不能突破,当容器试图使用超过这个量的资源时,可能会被Kubernetes Kill并重启

spec:
containers:
- name: db
image: mysql
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
上述代码表明MySQL容器申请最少 0.25个CPU以及64MIB内存,在运行过程中容器所能使用的资源配额为0.5个CPU以及128MIB内存。
2 Label详解
Label 是 Kubernetes 系统中另一个核心概念,一个Label是一个key=value的键值对,其中key与value由用户自己指定。Label可以附加到各种资源对象上,如Node,Pod,Service,RC,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上,Label通常在资源对象定义时确定,也可以在对象创建后动态添加或删除。
Label的最常见的用法是使用metadata.label字段,来为对象添加Label,通过spec.selector来引用对象(选择模板)
apiVersion: v1
Kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
Kind: Service
metadata:
name: nginx
spec:
type: NodePort
ports:
- port: 80
nodePort: 33333
selector:
app: nginx
Label 附加到 Kubernetes 集群中的各种资源对象上,目前就是对这些资源对象进行分组管理,而分组管理的核心就是Label Selector. Label与Label Selector都是不能单独定义,必须附加在一些资源对象的定义文件上,一般附加在RC和Service的资源定义文件中。
vim /usr/local/k8s_test/test/demo3.yaml
apiVersion: extensions/vibeta1
Kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: app-demo
tier: frontend
spec:
containers:
- name: tomcat-demo
image: tomcat
ports:
- containerPort:8080
删除 demo3.yaml 再查看 容器
~: kubectl delete -f demo3.yaml
~:kubectl get pods
先创建 demo3.yaml 再查看 容器
~: kubectl create -f demo3.yaml
~: kubectl describe -f demo3.yaml
老师的
先创建 demo3.yaml 再查看 容器

删除 demo3.yaml 再查看 容器

查看容器 kubectl get pods

查看 yaml 文件 cat /usr/local/k8s_test/test/demo3.yaml


vim /usr/local/k8s_test/test/demo5-rc.yaml
apiVersion: v1
Kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
~: cat /usr/local/k8s_test/test/demo5-rc.yaml
查看创建的容器 kubectl get pods 可以看到创建了3个nginx
通过命令 kubectl scale rc nginx --replicas=5 可以动态扩缩Pod数量
老师的
通过 kubectl get svc 查看服务

通过命令 kubectl scale rc nginx --replicas=5 可以动态扩缩Pod数量

查看创建的容器 kubectl get pods 可以看到创建了3个nginx

3 Replication Controller详解
Replication Controller(RC)是Kubernetes系统中核心概念之一,当我们定义了一个RC并提交到 Kubernetes集群中以后,Master节点上的 Controller Manager组件就得到通知,定期检查系统中存活的Pod并确保目标Pod实例的数量刚好等于RC的预期值,如果有过多或过少的Pod运行,系统就好停掉或创建一些Pod,此外我们也可以通过修改RC的副本数量,来实现Pod的动态缩放功能。
kubectl scale rc nginx --replicas=5
由于Replication Controller与kubernetes代码中的模块Replication Controller同名,所以在Kubernetes v1.2时,他就升级成了另外一个新的概念Replica Sets,官方解释为下一代的RC,他与区别是: Replica Sets 支援基于集合的 Label selector,而RC只支援基于等式的Label Selector.我们很少单独使用Replica Sets,他主要被Deployment这个梗高层面的资源对象所使用,从而形成一整套Pod创建,删除,更新的编排机制,最好不要越过RC直接创建Pod,因为Replication Controller会通过RC管理Pod副本,实现自动创建,补足,替换,删除Pod副本。这样就能提高应用的容灾能力,减少用于节点崩溃等意外状况造成的损失。即使应用程序只有一个Pod副本,也强烈建议使用RC来定义Pod.
4 Replica Sets详解
ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的selector(ReplicationController仅支持等式), Kubernetes官方强烈建议避免直接使用ReplicaSet, 而应该通过Deployment来创建RS和Pod.由于ReplicaSet是ReplicationController的代替物,因此用法基本相同,,唯一的区别在于ReplicaSet支持集合式的selector
5 Deployment详解
Deployment是Kubernetesv1.2引入的新概念,引入的目的是为了更好的解决Pod的编排问题,Deployment内部使用了Replica Set来实现。Deployment的定义与Replica Set的定义很类似,除了API声明与Kind类型有所区别:
apiVersion: extension/v1beta1
Kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: app-demo
tier: frontend
spec:
controllers:
- name: tomcat-demo
image: tomcat
ports:
- containerPort: 8080
vim /usr/local/k8s_test/test/demo4-deployment.yaml
apiVersion: apps/v1beta1
Kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
template:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: 50m
ports:
- containerPort: 80
老师的
查看容器具体详情 kubectl describe deployments nginx-deployment

查看 kubectl get deployments

查看yaml文件

6 Horizontal Pod Autoscaler
Horizontal Pod Autoscaler(Pod横向扩容 简称 HPA)与RC,Deployment一样,也属于一种 Kubernetes 资源对象。通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
Kubernetes对Pod扩容与缩容提供了手动和自动两种模式,手动模式通过 kubectl scale命令对一个 Deployment/RC进行Pod副本数量的设置,自动模式则需要用户根据某个性能指标或者自定义业务指标,并指定Pod副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整。
手动扩容和缩容
kubectl scale deployment frontend --replicas=1
自动扩容和缩容
HPA控制器基本Master的kube-controller-manager服务启动参数 --horizontal-pod-autoscaler-sync-period定义的时长(默认值为30s)周期性地监测Pod的CPU使用率,并在满足条件时对RC或Deployment中的Pod副本数量进行调整,以符合用户定义的平均Pod CPU使用率。
根据cpu去调整应用的扩缩容的yaml文件
apiVersion: extensions/v1beta1
Kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 1
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: 50m
ports:
- containerPort: 80
---
apiVersion: v1
Kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
selector:
app: nginx
---
apiVersion: autoscaling/v1
Kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: app/v1beta1
Kind; Deployment
name: nginx-deployment
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 50
黑色为 Pod 模板定义


黑色部位为Service

黑色部分就是我们定义的HPA

7 Volume详解
Volume 是 Pod 中能够被多个容器访问的共享目录.Kubernetes的Volume定义在Pod上,他被一个Pod中的多个容器挂载到具体的文件目录下,Volume与Pod的生命周期相同,但与容器的生命周期不相关,当容器终止或重启时,Volume中的数据也不会丢失。要使用Volume,pod需要指定volume的类型和内容(spec.volume字段),和映射到容器的位置(spec.containers.volumeMount字段)。
Kubernetes 支持多种类型的Volume包括:
emptyDir,hostPath,gcePersistentDisk,awsElasticBlockStore,nfs,iscsi,
flocker,glusterfs,rbd,cephfs,gitRepo,secret,persistentVolumeClaim,
downwardAPI,azureFileVolume,azureDisk,vsphereVolume,Quobyte,PortworxVolume,ScaleIO
emptyDir
emptyDir类型的Volume创建于pod被调度到某个宿主机上的时候,而同一个pod内的容器都能读写EmptyDir中的同一个文件,一旦这个pod离开这个宿主机,EmptyDir中的数据就会被永久删除。所以目前EmptyDir类型的volume主要用作临时空间,比如web服务器写日志或者tmp文件需要的临时目录。yaml实例如下:
apiVersion: v1
Kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: docker.io/nazarpc/webserver
name: cache-volume
volumes:
- name: cache-volume
emptyDir; {}

hostPath
HostPath属性是volume使得对应的容器能够访问当前宿主机上的指定目录。例如,需要运行一个访问Docker系统目录的容器宿,那么就使用/var/lib/docker目录作为HostDir类型的volume;或者要在一个容器内部运行CAdvisor,那么就使用/dev/cgroups目录作为一个HostDir类型的volume.一旦这个离开了这个宿主机,HostDir中的数据虽然不会被永久删除,但数据也不会随pod迁移到其他宿主机上。因此,需要注意的是,由于各个主机上的文件系统结构和内容并不一定完全相同,所以相同pod的HostDir可能会在不同的宿主机上表现出不同的行为。yaml实例如下:
apiVersion: v1
Kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: docker.io/nazarpc/webserver
name: test-container
volumeMounts: # 指定容器中挂载路径
- mountPath: /test-pd
name: test-volume
volumes: # 指定所提供的存储卷
- name: test-volume
hostPath: # 宿主机上的目录
# directory location on host
path: /data

nfs
NFS类型的volume,允许一块现有的网络硬盘在同一个pod内的容器间共享。yaml实例如下:
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
Kind: Deployment
metadata:
name: redis
spec:
selector:
matchLabels:
app: redis
revisionHistoryLimit: 2
template:
metadata:
labels:
app: redis
spec:
containers:
- image: redis # 应用的镜像
name: redis
imagePullPolicy: IfNotPresent
ports: # 应用的内部端口
- containerPort: 6379
name: redis6379
env:
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
- name: REDIS_PASSWORD
value: "redis"
volumeMounts: # 持久化挂载位置,在docker中
- name: redis-persistent-storage
mountPath: /data
volumes: # 宿主机上的目录
- name: redis-persistent-storage
nfs:
path: /k8s-nfs/redis/data
server: 192.168.126.112



8 Namespace详解
Namespace在很多情况下用于实现多用户的资源隔离,通过将集群内部的资源对象分配到不同的Namespace中,形成逻辑上的分组,便于不同的分组在共享使用整个集群的资源同时还能被分别管理,Kubernetes集群在启动后,会创建一个名为"default"的Namespace,如果不特别指明Namespace则用户创建的Pod,RC,Service都将被系统创建到这个名为default的Namespace中。
Namespace创建
apiVersion: v1
Kind: Namespace
metadata:
name: development
---
apiVersion: v1
Kind: Pod
metadata:
name: busybox
namespace: development
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox

Namespace 查看(查看命名空间为development下的pods)
kubectl get pods --namespace=development
查看默认命名空间的pod命令 kubectl get pods
查看指定命名空间的pod命令 kubectl get pods --namespace=development
vim /usr/local/k8s_test/test/demo6-namespace.yaml
apiVersion: v1
Kind: Namespace
metadata:
name: development
vim /usr/local/k8s_test/test/demo6-pod.yaml
apiVersion: v1
Kind: Pod
metadata:
name: busybox
namespace: development
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
name: busybox
老师的
查看命名空间和Pod容器创建


查看默认命名空间的pod命令 kubectl get pods

查看指定命名空间的pod命令 kubectl get pods --namespace=development

9 Service详解
Service是Kubernetes最核心概念,通过创建 Service 可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。
9.1 Service的定义
yaml格式的Service定义文件
apiVersion: v1
Kind: Service
metadata:
name: string
namespace: string
labels:
- name: string
annotations:
- name: string
spec:
selector: []
type: string
clusterIP: string
sessionAffinity: string
ports:
- name: string
protocol: string
port: int
targetPort: int
nodePort: int
status:
leadBalancer:
ingress:
ip: string
hostname: string

| 属性名称 | 取值类型 | 是否必选 | 取值说明 |
|---|---|---|---|
| version | string | Required | v1 |
| kind | string | Required | Service |
| metadata | object | Required | 元数据 |
| metadata.name | string | Required | Service名称 |
| metadata.namespace | string | Required | 命名空间,默认值为default |
| metadata.labels\[\] | list | 自定义标签列表 | |
| metadata.annotation\[\] | list | 自定义注解列表 | |
| spec | object | Required | 详细描述 |
| spec.selector\[\] | list | Required | Label Selector配置,将选择具有指定label标签的Pod作为管理范围 |
| spec.type | string | Required | Service类型,指定Service的访问方式,默认值为ClusterIP,取值范围如下: ClusterIP虚拟服务的IP,用于k8s集群内部的Pod访问,在Node上kube-proxy通过设置的iptables规则进行转发。NodePort: 使用宿主机的端口,使用能够访问各Node的外部客户端通过Node的IP地址和端口就能访问服务。loadBalancer使用外接负载均衡器完成到服务的负载均衡器的IP地址,并同时定义nodePort和ClusterIP,用于公有云环境。 |
| spec.clusterIP | string | 虚拟服务的IP地址,当type=clusterIP时,如果不指定,则系统进行自动分配,也可以手工指定,当type=LoadBalancer时,则需指定。 | |
| spec.session.Affinity | string | 是否支持Session,可选值为ClientIP,表示将用一个源IP地址的客户端访问请求都转发到同一个后端Pod,默认值为空 | |
| spec.ports\[\] | list | Service需要暴露的端口列表 | |
| spec.ports\[\].name | string | 端口名称 | |
| spec.ports\[\].protocol | string | 端口协议,支持TCP/UDP,默认值为TCP | |
| spec.ports\[\].port | int | 服务监听的端口号 | |
| spec.ports\[\].targetPort | int | 需要转发到后端Pod的端口号 | |
| spec.ports\[\].nodePort | int | 当spec.type=loadBalancer时,设置外部负载均衡器地址,用于公有云环境 | |
| status.loadBalance | object | 外部负载均衡器 | |
| status.loadBalance.Ingress | object | 外部负载均衡器 | |
| status.loadBalance.Ingress.ip | string | 外部负载均衡器的IP地址 | |
| status.loadBalance.Ingress.hostname | string | 外部负载均衡器的主机名 |

9.2 Service 的基本用法
一般来说,对外提供服务的应用程序要通过某中机制来实现,对于容器应用最便的方式就是通过TCP/IP机制及监听IP和端口号来实现。创建一个基本功能的Service
apiVersion: v1
Kind: ReplicationController
metadata:
name: mywebapp
spec:
replicas: 2
template:
metadata:
name: mywebapp
labels:
app: mywebapp
spec:
containers:
- name: mywebapp
image: tomcat
ports:
- containerPort: 8080
我们可以通过
kubectl get pods -l app=mywebapp -o yaml | grep podIP
来获取Pod的IP地址和端口号来访问Tomcat服务,但是直接通过Pod的IP地址和端口服务应用服务是不可靠的,因为当 Pod所在的Node发生故障时,Pod将会被 Kubernetes 重新调度到领一个 Node 节点,Pod的地址会发生改变,我们可以通过配置文件来定义 Service,再通过 kubectl create 来创建,这样可以通过Service的地址来访问后端的Pod.
apiVersion: v1
Kind: Service
metadata:
name: mywebAppService
spec:
ports:
- port: 8081
targetPort: 8080
selector:
app: mywebapp
9.2.1 多端口 Service
有时一个容器应用也可能纯净度为提供多个端口的服务,那么在Service的定义中也可以相应地设置为将多个端口对应到多个应用服务。
apiVersion: v1
Kind: Service
metadata:
name: mywebAppService
spec:
ports:
- port: 8080
targetPort: 8080
name: web
- port: 8005
targetPort: 8005
name: management
selector:
app: mywebapp
9.2.2 外部服务 Service
在某些特殊环境中,应用系统需要将一个外部数据库作为后端服务进行连接,或将领一个集群或Namespace中的服务作为服务的后端,这时可以通过创建一个无 Lable Selector的Service来实现
apiVersion: v1
Kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: v1
Kind: Endpoints
metadata:
name: my-service
subsets:
- address:
- IP: 10.254.24.3
PORTS:
- PORT: 8080

黑色代码就是创建一个最基本的Service的代码

vim /usr/local/k8s_test/test/demo7-rc.yaml
apiVersion: v1
Kind: ReplicationController
metadata:
name: mywebapp
spec:
replicas: 1
template:
metadata:
name: mywebapp
labels:
app: mywebapp
spec:
containers:
- name: mywebapp
image: 192.168.126.112:5000/docker.io/tomcat
ports:
- containerPort: 8080
查看容器和RC命令 kubectl get pods / kubectl get rc
老师的


查看我们创建的mywebapp

查看容器和RC命令 kubectl get pods / kubectl get rc

通过命令kubectl get pods -l app=mywebapp -o yaml | grep podIP来获取当前Pod容器的IP地址

我们通过 curl 10.254.74.3:8080 服务应用 我们可以得到tomcat的页面 直接访问Pod是不合适的。

通过 kubectl get svc 获取到 mywebapp-svc 服务

通过 curl 10.254.163.4:8081 访问应用,也可以访问到我们刚才的Pod,我们原来可以去通过IP直接访问,但是这种访问一个问题:如果我们的pod失效了,我们的kubernetes重新把Pod迁移到另外一个Node上时,他的IP地址就失效了,但是我们可以通过一个Server来做一个统一的入口,无论你后台的IP是否失效,只要你的Service与Pod对应上,我们可以访问我们的Service,来达到我们访问后端Pod的效果

我们创建一个Service,他没有指定label,也就说你不知道他真正要访问具体哪个Pod,我们怎么办呢?我们可以创建一个Endpoints,通过指定一个相同名字,这个名字必须与Service里面的名字一致,来去映射我们的Endpoints,去重新映射一下他的IP地址

查看 服务 kubectl get svc

查看容器详细信息命令 kubectl describe svc mywebapp-svc

vim /usr/local/k8s_test/test/demo8-endpoints.yaml
# 我们创建一个Endpoints,用来解决无Label Selector 的问题
apiVersion: v1
Kind: Endpoints
metadata:
name: my-service
subsets:
- address:
- ip: 10.254.74.3
ports:
- port: 8080
vim /usr/local/k8s_test/test/demo8-svc.yaml
# 这是创建一个Service,他没有指定label,也就是说,你不知道他还要访问具体是哪个Pod
apiVersion: v1
Kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
