在前面的部分了解了Pod的创建删除 ,查看信息等。那么我们怎么去管理Pod呢?我们可以通过 ReplicationController 去管理维护 Pod。

Replication Controller (RC):

  A ReplicationController ensures that a specified number of pod replicas are running at any one time. In other words, a ReplicationController makes sure that a pod or a homogeneous set of pods is always up and available.

  Replication Controller 保证了在所有时间内,都有特定数量的Pod副本正在运行,如果太多了,Replication Controller就杀死几个,如果太少了,Replication Controller会新建几个,和直接创建的pod不同的是,Replication Controller会替换掉那些删除的或者被终止的pod,不管删除的原因是什么(维护阿,更新啊,Replication Controller都不关心)。基于这个理由,我们建议即使是只创建一个pod,我们也要使用Replication Controller。Replication Controller 就像一个进程管理器,监管着不同node上的多个pod,而不是单单监控一个node上的pod,Replication Controller 会委派本地容器来启动一些节点上服务(Kubelet ,Docker)。ReplicationController定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,所以RC的定义包含以下几个部分:

  • Pod期待的副本数(replicas)
  • 用于筛选目标Pod的Label Selector
  • 当Pod的副本数量小于预期数量时,用于创建新Pod的Pod模板(template)也就是说通过RC实现了集群中Pod的高可用,减少了传统IT环境中手工运维的工作。

(1) 创建名为 nginx_replication.yaml:

apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
  • kind:表示要新建对象的类型

  • spec.selector:表示需要管理的Pod的label,这里表示包含app: nginx的label的Pod都会被该RC管理

  • spec.replicas:表示受此RC管理的Pod需要运行的副本数

  • spec.template:表示用于定义Pod的模板,比如Pod名称、拥有的label以及Pod中运行的应用等

  • 通过改变RC里Pod模板中的镜像版本,可以实现Pod的升级功能 kubectl set image rc nginx-rc nginx=nginx:1.9.1

  • kubectl apply -f nginx-pod.yaml,此时k8s会在所有可用的Node上,创建3个Pod,并且每个Pod都有一个app: nginx的label,同时每个Pod中都运行了一个nginx容器。

  • 如果某个Pod发生问题,Controller Manager能够及时发现,然后根据RC的定义,创建一个新的Pod

  • 扩缩容:kubectl scale rc nginx --replicas=5

(2)根据nginx_replication.yaml创建pod:

  kubectl apply -f nginx_replication.yaml

(3)查看pod :kubectl get pods -o wide

  kubectl get rc :

(4)尝试删除一个pod :

  kubectl delete pods nginx-sfrtf

  再查看 pod 会发现有生成了一个 4q54l 。

(5)对pod进行扩缩容:

  kubectl scale rc nginx --replicas=5

  kubectl get pods

(6) 删除pod :

  kubectl delete -f nginx_replication.yaml:

ReplicaSet(RS):

  A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods.

  ReplicaSet是下一代复本控制器。ReplicaSet和 Replication Controller之间的唯一区别是现在的选择器支持。Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持新的,基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa))。在试用时官方推荐ReplicaSet。

  yaml 文件:

apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80

  一般情况下,我们很少单独使用Replica Set,它主要是被Deployment这个更高的资源对象所使用,从而形成一整套Pod创建、删除、更新的编排机制。当我们使用Deployment时,无须关心它是如何创建和维护Replica Set的,这一切都是自动发生的。同时,无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)。

Deployment :

  A Deployment provides declarative updates for Pods and ReplicaSets.

  Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:

  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment

  Deployment相对RC最大的一个升级就是我们可以随时知道当前Pod “部署”的进度。创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程。检查 Deploymnet 的状态来看部署动作是否完成(Pod副本的数量是否达到预期的值)

(1)创建nginx_deployment.yaml文件:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

(2)根据nginx_deployment.yaml文件创建pod :

  kubectl apply -f nginx_deployment.yaml

(3)查看pod:

  kubectl get pods -o wide :

  kubectl get deployment :

  kubectl get rs :

  kubectl get deployment -o wide :当前nginx的版本

(4)更新nginx的image版本 :

  kubectl set image deployment nginx-deployment nginx=nginx:1.9.1

Labels and Selectors:

  Labels are key/value pairs that are attached to objects, such as pods.

  在前面的yaml文件中,看到很多label,顾名思义,就是给一些资源打上标签的:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas:
selector: # 匹配具有同一个label属性的pod标签
matchLabels:
app: nginx
template: # 定义pod的模板
metadata:
labels:
app: nginx # 定义当前pod的label属性,app为key,value为nginx
spec:
containers:
- name: nginx
image: nginx:1.7.
ports:
- containerPort:

  如上,表示名称为 nginx-deployment 的 Deployment,有一个label,key为app,value为nginx。我们可以将具有同一个label的pod,交给selector管理。查看pod的label标签:kubectl get pods --show-labels

Namespace:

  Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default),而node, persistentVolumes等则不属于任何namespace。Namespace常用来隔离不同的用户,比如Kubernetes自带的服务一般运行在kube-system namespace中。其实说白了,命名空间就是为了隔离不同的资源,比如:Pod、Service、Deployment等。可以在输入命令的时候指定命名空间`-n`,如果不指定,则使用默认的命名空间:default。

  查看一下当前的命名空间:kubectl get namespaces/ns

(1) 创建命名空间

  kubectl apply -f myns-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
name: myns

  查看命名空间 kubectl get ns

(2) 指定命名空间下的资源,比如创建一个pod,属于myns命名空间下

  kubectl apply -f nginx-pod.yaml

apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: myns
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort:

  查看pod:

  kubectl get pods -n myns

  kubectl get pods --all-namespaces    #查找所有命名空间下的pod

Network:

同一个Pod中的容器通信:

  在官网文档的 Pod Overview 板块这么描述道:Each Pod is assigned a unique IP address. Every container in a Pod shares the network namespace, including the IP address and network ports.我们都知道K8S最小的操作单位是Pod,先思考一下同一个Pod中多个容器要进行通信,由官网的这段话可以看出,同一个pod中的容器是共享网络ip地址和端口号的,通信显然没问题

  那如果是通过容器的名称进行通信呢?就需要将所有pod中的容器加入到同一个容器的网络中,我们把该容器称作为pod中的 pause container。就是上篇博客中提到的。

集群内Pod之间的通信:

  接下来就聊聊K8S最小的操作单元,Pod之间的通信,我们都之间Pod会有独立的IP地址,这个IP地址是被Pod中所有的Container共享的那多个Pod之间的通信能通过这个IP地址吗?我认为需要分两个维度:一是集群中同一台机器中的Pod二是集群中不同机器中的Pod

  而对于同一台机器中的Pod来说,pod之间的通信是通过 Docker的桥接网络 来完成的,这一点就不过多介绍了。

  而针对集群中不同节点的 pod 通信来说。我们需要通过一个简单demo来看一下:准备两个pod,一个nginx,一个busybox

  nginx_pod.yaml:

apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort:

  busybox_pod.yaml:

apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']

  将两个pod运行起来,并且查看运行情况

  kubectl apply -f nginx_pod.yaml

  kubectl apply -f busy_pod.yaml

  kubectl get pods -o wide :查看一下pod

  发现:nginx-pod的ip为192.168.190.95     busybox-pod的ip为192.168.80.198.

  这个时候,无论我们是通过w1去ping 192.168.80.198 还是在w2中 ping 192.168.190.95 都是没问题的。

How to implement the Kubernetes Cluster networking model--Calico:

  官网提到:https://kubernetes.io/docs/concepts/cluster-administration/networking/#the-kubernetes-network-model

  • pods on a node can communicate with all pods on all nodes without NAT(一个节点上的pod可以在没有NAT的情况下与所有节点上的pod通信)
  • agents on a node (e.g. system daemons, kubelet) can communicate with all pods on that node(一个节点上的代理(例如系统守护进程、kubelet)可以与该节点上的所有pod通信)
  • pods in the host network of a node can communicate with all pods on all nodes without NAT(在没有NAT的情况下,一个节点的主机网络中的豆荚可以与所有节点上的pod进行通信)

  所以说这一切得益于网络插件。

Service:

  官网:https://kubernetes.io/docs/concepts/services-networking/service/

  An abstract way to expose an application running on a set of Pods as a network service.With Kubernetes you don’t need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them.(一种将运行在一组pod上的应用程序公开为网络服务的抽象方法。使用Kubernetes,您不需要修改应用程序来使用不熟悉的服务发现机制。Kubernetes为Pods提供它们自己的IP地址和一组Pods的单个DNS名称,并且可以在它们之间实现负载平衡。)

(1)创建whoami-deployment.yaml文件,并且 kubectl apply -f whoami-deployment.yaml :

apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami-deployment
labels:
app: whoami
spec:
replicas:
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: jwilder/whoami
ports:
- containerPort:

(2)查看pod以及service :

  kubectl get pods -o wide

  kubectl get svc  :可以发现目前并没有关于whoami的service

  通过 curl 192.168.190.96:8000/192.168.190.97:8000/192.168.80.199:8000 访问都是没问题的。

(4)创建whoami的service :

  kubectl expose deployment whoami-deployment  创建

  kubectl get svc   查看

  删除svc   kubectl delete service whoami-deployment

  可以发现有一个Cluster IP类型的service,名称为whoami-deployment,IP地址为10.101.42.200

(5)通过Service的Cluster IP访问

(6)具体查看一下whoami-deployment的详情信息,发现有一个Endpoints连接了具体3个Pod

  kubectl describe svc whoami-deployment

(7)不妨对whoami扩容成5个

  kubectl scale deployment whoami-deployment --replicas=5

(8):其实对于Service的创建,不仅仅可以使用kubectl expose,也可以定义一个yaml文件

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port:
targetPort:
type: Cluster

  其实Service存在的意义就是为了Pod的不稳定性,而上述探讨的就是关于Service的一种类型Cluster IP,只能供集群内访问, 以Pod为中心,已经讨论了关于集群内的通信方式,接下来就是探讨集群中的Pod访问外部服务,以及外部服务访问集群中的Pod

  Pod访问外部服务,比较简单,没太多好说的内容,直接访问即可。Service的类型包括

  • ClusterIP:使用一个集群固定IP,这个是默认选项
  • NodePort:使用一个集群固定IP,但是额外在每个POD上均暴露这个服务,端口
  • LoadBalancer:使用集群固定IP,和NODEPord,额外还会申请申请一个负载均衡器来转发到服务(load balancer )

  注意:NodePort 支持TCP和UDN,但是LoadBalancers在1.0版本只支持TCP

外部服务访问集群中的Pod (Service-NodePort):

  也是Service的一种类型,可以通过NodePort的方式,说白了,因为外部能够访问到集群的物理机器IP,所以就是在集群中每台物理机器上暴露一个相同的IP,比如32008

(1)根据上面的 whoami-deployment.yaml创建pod 。

(2)创建NodePort类型的service,名称为 whoami-deployment,注意这里的类型

  kubectl expose deployment whoami-deployment --type=NodePort

(3)注意上述的端口30778,实际上就是暴露在集群中物理机器上的端口,浏览器通过物理机器的IP访问

  NodePort虽然能够实现外部访问Pod的需求,但是真的好吗?其实不好,占用了各个物理主机上的端口

Ingress:

  官网:https://kubernetes.io/docs/concepts/services-networking/ingress/

  An API object that manages external access to the services in a cluster, typically HTTP.(管理对集群中的服务(通常是HTTP)的外部访问的API对象。)

  Ingress can provide load balancing, SSL termination and name-based virtual hosting.(Ingress可以提供负载平衡,SSL终止和基于名称的虚拟主机。)

  可以发现,Ingress就是帮助我们访问集群内的服务的。不过在看Ingress之前,我们还是先以一个案例出发。很简单,在K8S集群中部署tomcat浏览器想要访问这个tomcat,也就是外部要访问该tomcat,用之前的Service-NodePort的方式是可以的,比如暴露一个32008端口,只需要访问192.168.0.61:32008即可。显然,Service-NodePor t的方式生产环境不推荐使用,那接下来就基于上述需求,使用Ingress实现访问tomcat的需求。

  我们使用熟悉的 Nginx Ingress Controller : https://kubernetes.github.io/ingress-nginx/

  我们可以来看一下这个案例的架构图:

(1) 创建my-tomcat.yaml文件,同时一起创建Service 。并且 kubectl apply -f my-tomcat.yaml ,创建tomcat的pod和service ,记得将之前的tomcat删除:kubectl delete -f my-tomcat.yaml。

  然后查看tomcat 跟service : kubectl get svc   , kubectl get pods 。

apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
labels:
app: tomcat
spec:
replicas:
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containerPort:
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
ports:
- port:
protocol: TCP
targetPort:
selector:
app: tomcat

(2) 以Deployment方式创建Pod,该Pod为Ingress Nginx Controller,官网提到了怎么创建Ingress Nginx Controller:

  kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

  执行这个命令就可以生成对应的 pod 。要想让外界访问,可以通过Service的NodePort或者HostPort方式,这里选择HostPort,还有比如指定 w1 节点上运行

  确保nginx-controller运行到w1节点上,在w1上打标签:kubectl label node w1 name=ingress

  使用HostPort方式运行,需要增加配置 ,所以我们先把 https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml 下载下来修改配置,在名字为 nginx-ingress-controller 的 Deployment 下增加如下配置:

hostNetwork: true
nodeSelector:
name: ingress
kubernetes.io/os: linux

(3) 创建 Ingress Nginx Controller 的pod :kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

  要确保w1节点上的80和443端口没有被占用,镜像拉取需要较长的时间,这块注意一下哦

  查看其进度:kubectl get pods -n ingress-nginx -o wide

  然后可以进而查看其进度信息:kubectl describe pod nginx-ingress-controller-7c66dcdd6c-qcmbx -n ingress-nginx

  我们发现拉去镜像失败,所以这里我们可以手动的去拉镜像  docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1.我这里由于网络问题直接报错。

  所以我这边替换成阿里云的镜像 registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.26.1 ,下载完记得修改一下 mandatory.yaml ,因为我是想部署到w1节点上,这里的镜像应该到w1节点去下。然后apply

  kubectl get pods -n ingress-nginx

  kubectl describe pod nginx-ingress-controller-66949687d4-5g8ws -n ingress-nginx :看到启动成功就OK了

  等构建完进入下一步。

(4)创建Ingress以及定义转发规则 :kubectl apply -f nginx-ingress.yaml

  kubectl get ingress

#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: tomcat.wuzz.com
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort:

  kubectl describe ingress nginx-ingress :

(5)修改win的hosts文件,由于我这里 nginx-ingress-controller 是在 w1 节点上,所以要w1的IP 映射3添加dns解析:192.168.1.102 tomcat.wuzz.com

(6)打开浏览器,访问tomcat.wuzz.com.

  总结:如果以后想要使用Ingress网络,其实只要定义ingress,service和pod即可,前提是要保证nginx ingress controller已经配置好了。

Kubernetes组件及网络基础的更多相关文章

  1. Kubernetes组件与架构

    转载请标明出处: 文章首发于>https://www.fangzhipeng.com/kubernetes/2018/09/30/k8s-basic1/ 本文出自方志朋的博客 Kubernete ...

  2. Kubernetes【K8S】(一):Kubernetes组件

    什么是Kubernetes ​ Kubernetes 是一个可移植的.可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化.Kubernetes拥有一个庞大且快速增长的生态系统. ...

  3. Kubernetes(K8s)基础概念 —— 凿壁偷光

    Kubernetes(K8s)基础概念  --  凿壁偷光 K8s是什么:全称 kubernetes  (k12345678s) 作用:用于自动部署,扩展和管理"容器化应用程序"的 ...

  4. C#学习笔记——面向对象、面向组件以及类型基础

    C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...

  5. kubernetes组件

    kubernetes组件 @(马克飞象)[k8s] 组件 kubernetes除了必备的dns和网络组件外,官方推出大量的cluster-monitoring,dashboard,fluentd-el ...

  6. centos7下kubernetes(4.kubernetes组件)

    Kubenetes cluster 由master和node组成 Master是kubenetes的大脑.运行着以下进程:kube-apiserver.kube-scheduler.kube-cont ...

  7. Linux网络基础-总

    目录 Linux网络基础 一.网卡和数据包的转发 1.收包流程 二.多网卡bonding 三.SR-IOV 四.DPDK 五.TUN/TAP 六.Linux bridge 和VLAN 七.TCP/IP ...

  8. Linux运维笔记(一)网络基础知识

    网络基础知识 一.基本概念 1.ARPANET & TCP/IP:以“软件”技术将网络硬件整合,使得不同的计算机或者数据可以通过这个软件达成数据沟通(TCP/IP技术也被称为Internet) ...

  9. QQ和微信凶猛成长的背后:腾讯网络基础架构的这些年

    本文来自腾讯资深架构师杨志华的分享. 1.前言 也许没有多少人记得2004年发生的事情.但对于老腾讯来说,14年前的那个日子,2004年6月16日永远难以忘怀.这一天,QQ诞生5年后的腾讯在香港联交所 ...

随机推荐

  1. python tkinter菜单

    python3中,Tkinter编写菜单界面案例 from tkinter import * top=Tk() top.wm_title("菜单") top.geometry(&q ...

  2. The GuidRepresentation for the reader is CSharpLegacy, which requires the binary sub type to be Uuid

    使用客户端链接MongoDb报错 The GuidRepresentation for the reader is CSharpLegacy, which requires the binary su ...

  3. Selenium 警告框处理

    警告框分三种类型: alert:显示带有一条指定消息和一个 OK 按钮的警告框. confirm:显示一个带有指定消息和 OK 及取消按钮的对话框. prompt:显示可提示用户进行输入的对话框. 我 ...

  4. Python3学习笔记(八):集合

    集合(set)是一种可变的无序的不重复的数据类型 要创建集合,需要将所有项(元素)放在花括号({})内,以逗号(,)分隔. >>> s = {'p','y','t','h','o', ...

  5. JMS学习七(ActiveMQ之Topic的持久订阅)

    非持久化订阅持续到它们订阅对象的生命周期.这意味着,客户端只能在订阅者活动时看到相关主题发布的消息.如果订阅者不活动,它会错过相关主题的消息.如果花费较大的开销,订阅者可以被定义为durable(持久 ...

  6. Oracle报Ora01522

    应用服务报错截图 数据库后台日志报错截图 从日志分析应该是回滚异常造成表空间无法使用回滚段,而回滚涉及的表空间为undo表空间 尝试新建UNDO表空间,再将UNDO_TABLESPACE切换到新建的U ...

  7. sqli-labs(31)

    0x01找闭合 这里是WAF的jsp调到php的同样 第二个参数构造 偷看源码 闭合是") 我们尝试一下构造爆破数据库名 login.php?id=&id=-") unio ...

  8. js,正则实现金钱格式化

    https://blog.csdn.net/qq_36279445/article/details/78889305 https://github.com/jawil/blog/issues/30

  9. Vue v-if以及 v-else 的使用

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. linux cut sort wc sed>vi awk (文本处理)

    cut: 显示切割的行数据 -f: 选择显示的列 (1: 显示第一列; 1,3: 显示第一列.第三列; 1-3: 显示第一列到第三列) -s: 不显示没有分隔符的行 -d: 自定义分隔符(' '空格 ...