Kubernetes组件及网络基础
在前面的部分了解了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组件及网络基础的更多相关文章
- Kubernetes组件与架构
转载请标明出处: 文章首发于>https://www.fangzhipeng.com/kubernetes/2018/09/30/k8s-basic1/ 本文出自方志朋的博客 Kubernete ...
- Kubernetes【K8S】(一):Kubernetes组件
什么是Kubernetes Kubernetes 是一个可移植的.可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化.Kubernetes拥有一个庞大且快速增长的生态系统. ...
- Kubernetes(K8s)基础概念 —— 凿壁偷光
Kubernetes(K8s)基础概念 -- 凿壁偷光 K8s是什么:全称 kubernetes (k12345678s) 作用:用于自动部署,扩展和管理"容器化应用程序"的 ...
- C#学习笔记——面向对象、面向组件以及类型基础
C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...
- kubernetes组件
kubernetes组件 @(马克飞象)[k8s] 组件 kubernetes除了必备的dns和网络组件外,官方推出大量的cluster-monitoring,dashboard,fluentd-el ...
- centos7下kubernetes(4.kubernetes组件)
Kubenetes cluster 由master和node组成 Master是kubenetes的大脑.运行着以下进程:kube-apiserver.kube-scheduler.kube-cont ...
- Linux网络基础-总
目录 Linux网络基础 一.网卡和数据包的转发 1.收包流程 二.多网卡bonding 三.SR-IOV 四.DPDK 五.TUN/TAP 六.Linux bridge 和VLAN 七.TCP/IP ...
- Linux运维笔记(一)网络基础知识
网络基础知识 一.基本概念 1.ARPANET & TCP/IP:以“软件”技术将网络硬件整合,使得不同的计算机或者数据可以通过这个软件达成数据沟通(TCP/IP技术也被称为Internet) ...
- QQ和微信凶猛成长的背后:腾讯网络基础架构的这些年
本文来自腾讯资深架构师杨志华的分享. 1.前言 也许没有多少人记得2004年发生的事情.但对于老腾讯来说,14年前的那个日子,2004年6月16日永远难以忘怀.这一天,QQ诞生5年后的腾讯在香港联交所 ...
随机推荐
- springboot 配置quart多数据源
Springboot版本为2.1.6 多数据源配置使用druid进行配置,数据库使用的为Oracle11g,如果使用的是MySQL,直接将数据库的地址和驱动改一下即可 <parent> & ...
- 轻松学习JVM——垃圾回收器
原文链接:https://www.cnblogs.com/leefreeman/p/7402695.html 上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某 ...
- 【leetcode】1221. Split a String in Balanced Strings
题目如下: Balanced strings are those who have equal quantity of 'L' and 'R' characters. Given a balanced ...
- 浅谈Android的资源编译过程
转载自 http://www.cnblogs.com/dyllove98/p/3144950.html 好长,记录下,一次看完感觉像没看一样 Android APK 一.APK的结构以及生成 APK是 ...
- codevs 1126 数字统计 2010年NOIP全国联赛普及组 x
题目描述 Description 请统计某个给定范围[L, R]的所有整数中,数字2出现的次数. 比如给定范围[2, 22],数字2在数2中出现了1次,在数12中出现1次,在数20中出现1次,在数21 ...
- Android字体设置,Roboto字体使用
一.自定义字体 1.android Typeface使用TTF字体文件设置字体 我们可以在程序中放入ttf字体文件,在程序中使用Typeface设置字体.第一步,在assets目录下新建fonts目录 ...
- Java数据结构之排序---快速排序
快速排序是对冒泡排序的一种改进. 快速排序的基本思想: 假设我们以升序为例,它的执行流程可以概括为,每一趟选择当前所有子序列中的一个关键字(通常我们选择第一个,下述代码实现选择的也是第一个数)作为枢纽 ...
- http三次握手,四次挥手
本文经过借鉴书籍资料.他人博客总结出的知识点,欢迎提问 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上序号后 ...
- Chrome 66 新增异步剪贴板 API
在过去的几年里我们只能使用 document.execCommand 来操作剪贴板.不过,这种操作剪贴板的操作是同步的,并且只能读取和写入 DOM. 现在 Chrome 66 已经支持了新的 Asyn ...
- Java 使用反射给属性赋值
package com.nf147.manage.spring; import java.lang.reflect.Field; public class Cat { private String n ...