k8s pod restartcount 改0_通过实例快速掌握k8s(Kubernetes)核心概念

点击上方蓝色“Go语言中文网”关注我们,设个星标,每天学习 Go 语言

本文作者:倚天码农,原创授权发布

原文链接:https://segmentfault.com/a/1190000020595811

容器技术是微服务技术的核心技术之一,并随着微服务的流行而迅速成为主流。Docker 是容器技术的先驱和奠基者,它出现之后迅速占领市场,几乎成了容器的代名词。但它在开始的时候并没有很好地解决容器的集群问题。Kubernetes[1]抓住了这个机遇,以容器编排者(Container Orchestration)的身份出现,对容器集群进行管理和调度,现在已经打败了 Docker 成为了容器技术事实上的标准。当然 K8s 内部还是需要 Docker 的,但它的功能范围被大大压缩了,只是负责底层的容器引擎和镜像(Docker Image)管理,成为了容器体系中不可缺少, 但没有存在感的一部分。而绝大部分的对外接口都是由 k8s 来负责。

K8s 核心对象:

相对于简单易学的 Docker 来说,k8s 系统庞杂而且概念众多,同一个功能有很多不同方法来完成,让你无所适从,学习起来要困难的多。对于普通码农来讲不需要建立完整的生产环境,只需要搭建一个本地开发环境,这时你只需要了解 k8s 的核心概念就够了,这样可以大大缩短学习时间。k8s 的一切都是对象(Object),它的核心概念一共只有 4 个,Pod,部署(Deployment),服务(Service)和节点(Node)。另外再加上一个容器镜像(Docker Image),这个是 Docker 引擎的核心。掌握了这五个核心概念,就对容器技术有了基本了解,打下了扎实的基础。

Windows 安装环境:

Windows10 的 Windows 10 企业版, 专业版, 和教育版是可以支持直接安装 K8s 的,但电脑是要支持 Hyper-V 的, 详见这里[2]。由于我的 Windows 是家庭版,只能先安装虚拟机(VirtualBox),再在虚拟机上安装 k8s。我用的 k8s 是Minikube[3],是 k8s 的简化版。另外还安装了 Vagrant(它是管理虚拟机的一个软件)作为界面来管理 VirtualBox。

容器镜像(Docker Image):

任何程序都在容器中运行,k8s 支持多种容器,其中Docker[4]是最流行的。容器镜像(Docker Image)是一个以文件形式存在的运行环境,它的里面是分层的,每一层都在上一层的基础上不断叠加新的功能。容器镜像是由 Dockerfile 创建的。

Dockerfile 是一个文件,里面包含一组已经定义好的 Docker 命令(与 Linux 命令比较相似)。当运行 Dockerfile 时,里面的命令被依次执行,最后生成需要的容器镜像。你再调用 Docker 命令(Docker run)运行容器镜像来生成 Docker 容器,完成之后,应用程序就已经在容器里部署好了。这种方式能够保证每次得到的环境都是一样的。容器比虚拟机强的地方在于,它占用系统资源更少,生成时间更短。创建一个容器的耗时一般是秒级的,而虚拟机是分钟级的。容器镜像的创建效率取决于它的大小,一般来讲容器镜像越小,它的生成时间越短。

下面就是一个“nginx”的 Dockerfile 示例。

FROM alpine:3.2
EXPOSE 80 443
RUN apk add --update nginx && \
rm -rf /var/cache/apk/* && \
mkdir -p /tmp/nginx/client-body
COPY ./nginx.conf /etc/nginx/nginx.conf
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d"]
CMD ["nginx", "-g", "daemon off;"]

任何 Dockerfile 的第一句总是“FROM 。。。”,就是要创建一个 Linux 的运行环境。一般有以下几种:

  • FROM ubuntu:18.04:按照 Linux 的具体版本来创建镜像,这样的 Linux 运行环境是比较完整的,镜像的大小是百兆级别的。

  • FROM alpine:latest : alpine 是一个 精简了的 Linux 运行环境,它的大小是十兆级别的。

  • FROM scratch : scratch 是最小 Linux 运行环境,创建非常快,但它的问题是你不能通过 shell 登录到容器内部,因此我一般不用它。

当用 Vagrant 管理虚拟机时,可以先用 Vagrant 命令启动虚拟机,然后敲入 vagrant ssh,进入虚拟机,系统显示:

PS E:\app2\kub> vagrant ssh
Last login: Sat Sep 28 06:56:11 2019 from 10.0.2.2

然后键入“docker run --name docker-nginx -p 8001:80 nginx”运行 Nginx 镜像。"docker-nginx"是容器的名字,“--name”是名字的参数选项。“-p”表示端口映射,把虚拟机的“8001”端口映射到容器的“80”端口(Nginx 的缺省端口)。“nginx”是镜像的名字,如果本地没有找到“Nginx”镜像,系统会自动从 Docker 镜像库里下载 Nginx 镜像到本地,然后再运行,这个镜像有比较完整的 Linux 系统,因此文件比较大(100M),但也可以凑活着用。命令运行之后,显示:

vagrant@ubuntu-xenial:~$ docker run --name docker-nginx -p 8001:80 nginx

这时 Nginx 已经运行,但还没有任何请求,控制台没有输出。如果名字为“docker-nginx”的容器以前已经被运行,那么你需要删除原来的,再运行上面命令。可以先敲入“docker ps -a”找到所有运行过的容器,再敲入“docker rm 1ec2e3d63537”进行删除,其中“ 1ec2e3d63537”是容器 ID.

切换到另一个虚拟机窗口,敲入 curl localhost:8001,显示:

vagrant@ubuntu-xenial:/usr/bin$ curl localhost:8001
...

Welcome to nginx!


...

这时就出现了 Nginx 的首页,表示 Docker 容器中的 Nginx 已经正常运行。

换回原容器显示窗口,这时有了请求,控制台输出 Nginx 日志。

vagrant@ubuntu-xenial:~$ docker run --name docker-nginx -p 8001:80 nginx
172.17.0.1 - - [28/Sep/2019:07:02:25 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"

这时已验证 Docker 镜像是好的,敲入“CTRL-C”退出。

Pod:

Pod 是 k8 是的最基本概念,你可以把它看成是对容器(container)的一个封装,用来管理容器。一个 Pod 里可以管理有一个或多个容器,但一般是一个。Pod 里的所有容器都共享 Pod 的资源和网络。当一个 Pod 不能满足用户需求时,你可以把 Pod 作为复制的最小单元来复制出一个同样的 Pod 来处理用户请求。Pod 支持多种容器,不过一般是用 Docker。你可以用单独的 Pod 配置文件创建 Pod, 也可以把 Pod 的配置信息放在其他的对象(例如 Deployment)的配置文件里面,并与其他对象一起创建,后者更为常见。每一个 Pod 都有一个唯一的 IP 地址,Pod 一旦生成就可以通过 IP 地址进行访问。但一般不这么做,而是通过服务(Service)去间接地去访问。下面就是 Pod 的配置文件。它的解释放在后面的 Deployment 里面。

kind: Pod
apiVersion: v1
metadata:
labels:
app: nginx-app
spec:
containers:
- name: nginx-container
image: nginx:latest
restartPolicy: Never

Pod 模板(Pod Templates)

Pod 模板是嵌入在其他 K8s 对象(Object)中的 Pod 的配置说明,例如 Replication Controllers, Jobs, 和 DaemonSets. 这时,Pod 不是单独创建的,而是由其它对象来创建,其中最常用的是 Deployment。

部署(Deployment):

Deployment 是比 Pod 更高一层的对象,它的主要作用是管理 Pod 集群,它里面可以有一个或多个 Pod, 每一个 Pod 在功能上都是等同的。一般在 Deployment 里配置多个 Pod 以实现负载均衡和容错。在配置 Deployment 时,你需要指定 Pod 拷贝的个数,Deployment 会自动管理它里面的 Pod。当某个 Pod 宕机时,Deployment 能自动复制一个新的 Pod 并替换宕机的 Pod,

下面就是 Deployment 的配置文件(nginx-deployment.yaml)。在正方形灰框内(从 template 开始)的是嵌入在 Deployment 里的 Pod 的设置,灰框上面的是部署(Deployment)的设置。当你运行这个配置文件时,它会创建一个 Deployment,同时也会创建嵌入在里面的 Pod。这就是为什么我们一般不需要单独的 Pod 的配置文件,因为已经把它嵌入在了 Deployment 里了。

446e0b0a59501a55e1b2db104c1bf57a.png
file

键入“kubectl create -f nginx-deployment.yaml”来运行这个部署,显示:

vagrant@ubuntu-xenial:~/dockerimages/kubernetes/nginx$ kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created

这时部署已经成功,现在就可以访问它了。每个 Pod 都有自己的 k8s 集群内部 IP 地址,我们这时只能在 K8s 内部用 IP 地址进行访问。键入下面命令查看 Pod 地址,里面有两个“Nginx”Pod,因为 Deployment 里面是两个 Pod 的集群。

vagrant@ubuntu-xenial:~/nginx$ kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP
NAME IP
hello-minikube-856979d68c-74c65 172.17.0.3
nginx-deployment-77fff558d7-bhbbt 172.17.0.10
nginx-deployment-77fff558d7-v6zqw 172.17.0.9

打开另一个窗口,连入虚拟机,然后键入以下命令“kubectl exec -ti hello-minikube-856979d68c-74c65 -- /bin/sh”登录到 k8s 集群内部,就能访问 Nginx 了。这里“hello-minikube-856979d68c-74c65”是"Minikube"Pod 的名字。“172.17.0.10”是其中一个 Pod 的内部 IP 地址。

vagrant@ubuntu-xenial:~$ kubectl exec -ti hello-minikube-856979d68c-74c65 -- /bin/sh
# curl 172.17.0.10

服务(Service):

Service 是最上层的 k8s 的对象,可以看成我们平常说的微服务。对服务来讲最重要的就是服务注册和发现。在 k8s 中,Service 就是用来实现这个功能的。下面就是 Service 的配置文件(nginx-service.yaml)。一般来说调用服务需要知道三个东西,IP 地址,协议和端口,例如"http://10.0.2.1:80". 但我们不想用 IP,而是用名字来寻址,这就需要 DNS。DNS 在 k8s 集群内部实现了基于服务名的寻址。下面是 Service 的配置文件。Service 通过“selector”来与 Pod 进行绑定,这里它把请求转发给标签“app”是“nginx-app”的 Pod。“nodePort”给服务创建了一个外部可以访问的端口,这样在虚拟机上就可以直接访问服务,而不必登录到 k8s 集群里。

1055afd929455ba2789a980dee8723d3.png
file

运行以下命令“kubectl create -f nginx-service.yaml”创建服务。


服务创建完成之后,调用以下命令显示当前的所有服务, 现在就有了“nginx-service”服务。“80”是服务的内部端口,“30163”是服务的外部端口。

vagrant@ubuntu-xenial:~/$ kubectl create -f nginx-service.yaml
service/nginx-service created

因为已经通过“NodePort”对外开放了端口,现在不必登录到 k8s 内部,在虚拟机上就可以访问服务了. 你可以键入“localhost”

vagrant@ubuntu-xenial:~/$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 35d
nginx-service NodePort 10.109.7.249 80:30163/TCP 18s

Service 和 Deployment 的区别:

Deployment 是用来管理集群的,与 Pod 绑定,但你不能直接访问 Deployment。服务(Service)是为了方便用名字(而不是 IP 地址)访问。但这也只是在集群内部。你可以登录 k8s 集群内部,然后键入下面命令访问服务,但在虚拟机上(k8s 外面)就不行, 这时只能用 IP 地址。因为 DNS 只是在 k8s 内部才起作用。

# curl nginx-service

节点(Node):

Node 刚开始接触时容易和 Pod 搞混,但它相当于虚拟机或物理机,而 Pod 相当于容器。所有的的 Pod 或容器都是部署在 Node 上面。Minikube 只支持单 Node,但你可以在它里面部署多个 Pod。下面是 Node 示意图。

5e02762ce529bdc7a571dab6999b2245.png
file

k8s 核心概念之间的关系:

对象间关系:

下面是 k8s 的一个简单结构图:

412fd5f5736ae434f747f7b6df75bd55.png
file

图中每个菱形是一个 Node,中间的 Node 是 Master Node,其余三个是 Worker Node。Master Node 负责管理 Worker Node。Worker Node 是真正干活的 Node。Master Node 里有各种控制器,Deployment 就是由控制器来管理的,它在中间的管理 Node 里,他里面有两个部署,A 和 B,分别对应服务 A 和服务 B。“服务 A”部署在最下面的 Node 里,它里面只有一个 Pod。“服务 B”部署在上面的两个 Node 里,左边的 Node 只有一个 Pod,右边的 Node 有两个 Pod,这是一个有三个 Pod 的集群。当一个部署里有多个 Pod 时,一般是把它们部署在不同的 Node 上,这样即使一个 Node 宕机,Deployment 仍然可用。

对象绑定:

下图是介绍对象之间如何绑定的关系图。

e46fd2ae0717df2130b6edf7120f2c1f.png
file

每个对象都有多个标签(Label),“app”就是一个用来标识 Pod 对象的标签。图里有两个 Pod,它们的“app”标签的值分别为“A”和“B”,其中 Pod “B”是集群,而 Pod “A”不是。服务(Service)和部署(Deployment)都通过标签选择器(Label Selector)来绑定与之匹配的 Pod。

附录:

你最好是已经安装了 k8s 和 Docker 环境,那就可以依次运行本文中的示例。如果你没有环境,新建一个也不难。如果你不愿意创建环境, k8s 的官网有一个练习环境,可以直接用来运行命令,详见这里[5]

推荐阅读

  • 『GCTT 出品』Go 语言中的包装一个微服务样板

317f7b6c40c2b024b1aacf8ddf425fa6.png

参考资料

[1]

Kubernetes: https://kubernetes.io/

[2]

详见这里: https://minikube.sigs.k8s.io/docs/start/windows/

[3]

Minikube: https://github.com/kubernetes/minikube

[4]

Docker: https://www.docker.com/

[5]

详见这里: https://kubernetes.io/docs/tutorials/kubernetes-basics/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/498980.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

div垂直居中的方法_【CSS】8种常见的垂直水平居中方法

1.比较传统的方式 absolutemargin负值偏移特点:父容器要设置宽高,需要知道子容器宽高,偏移量是子容器宽高的一半且是负值,兼容性好/* absolutemargin负值偏移布局 */.layout.absolute {position: relative;}.layout.absolute art…

websocket 导致大量apache进程_Swoole 服务端主动向websocket推送消息

在之前的博文中,我们已经学完了如果使用swoole搭建websocket长连接,也学会了swoole的多进程数据共享操作。但在一个完整的websocket长连接日常操作链中,服务端往往会主动给在线的用户单独推送消息,会群发一些消息。在Swoole-webso…

python因子分析法_python——因子分析

因子分析用Python做的一个典型例子 一、实验目的 采用合适的数据分析方法对下面的题进行解答二、实验要求 采用因子分析方法,根据48位应聘者的15项指标得分,选出6名最优秀的应聘者。 三、代码 importpandas aspd importnumpy asnp importmath asmath imp…

polycom安卓手机客户端_三款免费「游戏串流」APP,在手机/电视上玩PC游戏

以前想把电脑游戏输出到电视机上玩,得用HDMI线输出,如果电脑主机和电视机离太远,HDMI线不够长,还得抱电脑主机到电视机旁边,非常不方便。随着技术的发展,现在已经有「串流」功能,只要电视机和电…

python获取返回值_python如何获取函数的返回值

函数需要先定义后调用,函数体中 return 语句的结果就是返回值。如果一个函数没有 reutrn 语句,其实它有一个隐含的 return 语句,返回值是 None,类型也是 NoneType。return 语句的作用:结束函数调用、返回值 指定返回值…

java模拟器百度_Java模拟实现百度文档在线浏览

这个思路是我参考网上而来,代码是我实现。采用Apache下面的OpenOffice将资源文件转化为pdf文件,然后将pdf文件转化为swf文件,用FlexPaper浏览。ok,A、下载OpenOffice (转换资源文件)B、下载JodConverter(调用OpenOffice)C、下载Sw…

body click js 委托_JS 事件循环

进程 线程CPU 分配资源的最小单位是进程,同一个时间内单个 CPU 只能运行一个进程,单个 CPU 一次只能运行一个任务CPU 调度的最小单位是线程,一个进程里面包含多个线程。可以看看阮老师的这篇文章,进程与线程的一个简单解释浏览器的…

django jsonresponse_利用 Django 动态展示 Pyecharts 图表数据的几种方法

本文将介绍如何在 web 框架 Django 中使用可视化工具 Pyecharts, 看完本教程你将掌握几种动态展示可视化数据的方法!Django 模板渲染1. 新建一个 Django 项目命令行中输入以下命令django-admin startproject pyecharts_django_demo创建一个应用程序python manage.py startapp d…

python网页登录验证码不显示_进网页需要验证码?不好意思,Python从来不惧各种验证码!...

今天要来说说滑动验证码了大家应该都很熟悉点击滑块然后移动到图片缺口进行验证现在越来越多的网站使用这样的验证方式为的是增加验证码识别的难度那么,对于这种验证码应该怎么破呢接下来就是见证神奇的时刻打开 b 站的登录页面可以看到登录的时候需要进行滑块验证按…

怎么调用新建模型里文章的内容_优雅地进行Tensorflow Lite模型转换

初涉知乎江湖,知道大佬很多,请温柔以待!!!七日凌晨,谷歌连夜发布了有关于Tensorflow最新成果和技术,这应该是贾扬清离开脸书后另一个深度学习界令人惊呼的事件了吧!(旁白…

git add后取消_Git常用命令-总结

创建git用户$ git config --global user.name "Your Name"$ git config --global user.email "emailexample.com"初始化一个Git仓库,使用git init命令。添加文件到Git仓库,分两步:使用命令git add ,注意&…

查看csv编码_[小O地图-数据] - 坐标转地址文字(逆地理编码)

小O地图是一款基于互联网地图进行地理数据处理、分析、图表的软件。致力为广大科研人员提供专业地图数据,用于科研及学习。小O地图提供将【经纬度坐标转换为地址】的功能,例如:将“116.359861, 39.917225” 转换为 “北京市西城区…

python自动化办公源码_python自动化办公:文件篇(自动整理文件,一键完成)

import os list_all[]#初始化一个空列表 for root ,dirs,files in os.walk(rC:UsersShineionDesktop新建文件夹): for name in files: file_pathos.path.join(root,name)#包含路径的文件 file_nameos.path.split(file_path)[-1] list_all.append(file_name) print(list_all)如果…

ocr中文数据集_CNOCR:测试集准确率最高98%,自带识别模型的中文OCR包

今天 Gitee 为大家介绍的是一款中文 OCR 包。大家都知道,训练模型是一件非常费时费力的事情,但今天这款项目已经自带训练好的识别模型,我们只需要下载下来使用即可,可以说是非常方便了,那么下面我们就去看看这个项目的…

sha算法源代码java_SHA算法Java实现

一 简介安全散列算法固定长度摘要信息二 SHA算法SHA-1、SHA-2(SHA-224、SHA-256、SHA384、SHA-512)三 SHA算法实现package com.imooc.security.sha; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Security; impo…

arraylist remove() java_执行ArrayList的remove(object)方法抛异常?

简介或许有很多小伙伴都尝试过如下的代码:然后会发现抛出java.util.ConcurrentModificationException异常,这是一个并发异常。那么这个到底是什么情况?首先需要介绍一下增强for循环增强for循环增强for循环是Java1.5后,Collection实…

centos gdb调试_gdb-miss-debuginfo

使用gdb调试core时候,提示Missing separate debuginfos的解决办法。错误提示错误提示信息如下:Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64 libaio-0.3.109-13.el7.x86_64 libgcc-4.8.5-4.el7.x86_64 libstdc-4…

怎么判断自己启动的线程是否执行完成 java_多线程?怎么用?

Java线程:概念与原理操作系统中线程和进程的概念现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中&…

mysql设置中文_Flask中MySQL预热

Flask和MySQL导读现在Flask已经学习到了类视图,它其实是这样一个关系FLask高级视图视图函数app.route\add_url_rule类视图蓝图blueprint(这个接下来要讲)结束蓝图后,接着就是Flask数据库的结合SQLAlchemy.在学习SQLAlchemy之前,希望和大家一起了解学习一下mysql这篇文章不涉及理…

html首行缩进2字符怎么设置_Word如何设置首行缩进2字符

在使用Word编写书籍或者文稿时,我们都会有个习惯将每个段落前面空两个字符,这样可以很好的方便读者阅读时分辨段落。有的人习惯用几个空格来代替,有的人习惯用空白字符V1来代替(像Word联盟网站上的每篇教程就是用V1来标记段落的)。其实在Word…