
Hi! 我是小小,今天是本周的第二篇,本篇主要内容是讲解k8shtml
前言
都9102年了,你还不知道kubernetes就真的真的真的out啦。(贩卖焦虑体) 什么是k8s,k8s这个词来自于希腊语,有主管,舵手,船长的意思,咱们从图标中能看出来。在k8s的网站上,描述是这样的node
生产级别的容器编排系统linux
从定义中能够提炼出三个关键字,分别是nginx
-
生产级别 -
容器 -
编排系统
1. 生产级别
说k8s是生产级别的有以下的几个缘由:web
-
k8s 是谷歌的开源系统,基于谷歌的系统设计,而且已经在谷歌系统上平稳运行的好久。 -
k8s 是CNCF的首个毕业项目。
2. 容器
容器有如下几个特色面试
-
可移植性,容器能够被任何类型的操做系统安装使用。 -
包容性:支持多种类型的软件,这些软件均可以打包在容器内。 -
标准格式。 -
共存,多个容器能够运行在同一个物理机上。 -
隔离,不一样的容器的软件彼此隔离。

最重要的一句话:没有容器就没有微服务。docker
容器和微服务化后,带来了一些好处,好比:数据库
-
模块间更加独立,能够独立的部署和发布,加快了发布和更新的速度 -
隔离的运行环境,能够为不一样模块定制不一样的运行环境
3. 编排系统
容器的编排系统能够有效的管理在宿主机上的容器。后端
-
管理网络和访问 -
跟踪容器的状态 -
增大或缩小服务的规模 -
实现负载平衡 -
宿主机无响应后实现容器的从新分配 -
服务发现 -
管理容器的存储 等等…
主要功能
数据卷
pod中容器之间共享数据,可使用数据卷。api
应用程序健康检查
容器内服务可能进程阻塞没法处理请求,能够设置监控检查的策略,
复制应用程序实例
控制器维护者pod副本数量,保证一个pod或一组同类prod数量始终可用
弹性伸缩
根据设定的指标,自动缩放pod副本数
服务发现
使用环境变量或DNS插件保证容器中程序发现pod入口访问地址。
负载均衡
一组pod副本分配一个私有的集群ip地址,负载均衡转发请求到后端容器,在集群类其余pod能够经过clusterIP访问应用。
滚动更新
更新服务不中断,一次更新一个pod,而不是同时删除整个服务。
服务编排
经过文件描述部署服务,使得应用程序部署变得高效。
资源监控
Node节点组件集成cAdvisor资源收集工具,经过Heapster汇总,并保存到influxDB时序数据库,最后由Grafana展现。
提供认证受权
支持RBAC认证受权机制。
设计架构
功能组件
k8s 集群中有管理节点,Master与工做节点,Node两种类型。
-
管理节点Master主要负责k8s集群管理,集群中各个节点之间信息交互,任务调度,还负责容器,pod, namespaces , pv 等生命周期的管理。 -
工做节点node主要为容器和pod提供计算资源,pod及其容器所有运行在工做节点上,工做节点经过kubelet服务与管理节点通讯以管理容器的生命周期,并与集群其余节点进行通讯。
master组件
kube-apiserver
kubernetes api 资源操做的惟一入口,各类组件的协调者,以HTTP API 提供接口服务,并提供相关的认证,受权等机制,
kube-controller-manager
处理集群中常规的后台任务,一个资源对应一个控制器,而ControllerManager负责管理这些控制器,并维护集群的状态。
kube-scheduler
负责资源的调度,按照预约的策略把pod调度到对应的Node节点上。
Node组件
kubelet
kubelet是Master在Node节点上的agent,管理本机运行容器的生命周期,同时也负责Volume和网络的管理。例如建立容器,挂载数据卷,下载secret,获取容器和节点的状态等工做。
kube-proxy
在Node节点上实现Pod/serviced网络代理,提供cluster内部的服务发现和四层负载均衡。
docker
真正运行容器的地方
etcd集群
分布式键值对储存系统,用于保存集群状态,好比pod,service等对象信息。
分层架构
核心层:最核心的功能,对外提供api 应用层,部署无状态应用,等,和路由。管理层:系统度量,自动化,以及RBAC等 接口层:kubectl命令行工具,以及客户端sdk 生态系统:分为外部的日志,监控等,内部的镜像仓库等。
安装
建立集群
首先,查看所使用的 minikube 版本:
$ minikube version
minikube version: v0.25.0
启动 minikube:
$ minikube start
Starting local Kubernetes v1.9.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.
minikube 启动以后,会建立一个单节点 Kubernetes 集群。
查看集群版本:
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.0", GitCommit:"925c127ec6b946659ad0fd596fa959be43f0cc05", GitTreeState:"clean", BuildDate:"2017-12-15T21:07:38Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"", Minor:"", GitVersion:"v1.9.0", GitCommit:"925c127ec6b946659ad0fd596fa959be43f0cc05", GitTreeState:"clean", BuildDate:"2018-01-26T19:04:38Z", GoVersion:"go1.9.1", Compiler:"gc", Platform:"linux/amd64"}
这里有两个版本,client version 指的是 kubectl 命令行工具的版本,而 server version 才是 Kubernetes 的版本。
查看更详细的版本信息:
$ kubectl cluster-info
Kubernetes master is running at https://172.17.0.77:8443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
集群所在主机的 ip 为 172.17.0.77。
注意:这里的 master 指的是 Kubernetes 集群的 master 节点(在 Kubernetes 集群中,节点分为两类,一类是 master 节点,一类是 node 节点)。那怎么看到 node 节点呢?
$ kubectl get node
NAME STATUS ROLES AGE VERSION
host01 Ready <none> 20m v1.9.0
host01 就是 node 节点,在当前环境中,实际上只有一台主机。这台主机既做为 master 节点,也做为 node 节点。
部署应用
下面以部署一个 nginx 为例来演示部署应用的过程:
$ kubectl run first-app --image=nginx --port=80
deployment "first-app" created
经过 run 命令建立一个名为 first-app 的 deployment,使用的是 docker hub 上最新的 nginx 镜像,并指定了应用端口为 80。deployment 是干吗的呢?别急,往下看:
查看当前的 deployment:
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
first-app 1 1 1 1 1m
查看当前的 pod:
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
first-app-6db44b474-dbbtp 1/1 Running 0 4m
查看更详细的 pod 内容:
$ kubectl describe pod first-app-6db44b474-dbbtp
Name: first-app-6db44b474-dbbtp
Namespace: default
Node: host01/172.17.0.77
Start Time: Fri, 02 Mar 2018 06:48:02 +0000
Labels: pod-template-hash=286006030
run=first-app
Annotations: <none>
Status: Running
IP: 172.18.0.4
Controlled By: ReplicaSet/first-app-6db44b474
Containers:
first-app:
Container ID: docker://54eacc7ff536d7181fa366883f7ed4cf632492ad6ed391207fea436d22d219a9
Image: nginx
Image ID: docker-pullable://nginx@sha256:4771d09578c7c6a65299e110b3ee1c0a2592f5ea2618d23e4ffe7a4cab1ce5de
Port: 80/TCP
State: Running
Started: Fri, 02 Mar 2018 06:48:14 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-zkqw6 (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-zkqw6:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-zkqw6
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 7m default-scheduler Successfully assigned first-app-6db44b474-dbbtp to host01
Normal SuccessfulMountVolume 7m kubelet, host01 MountVolume.SetUp succeeded for volume "default-token-zkqw6"
Normal Pulling 7m kubelet, host01 pulling image "nginx"
Normal Pulled 7m kubelet, host01 Successfully pulled image "nginx"
Normal Created 7m kubelet, host01 Created container
Normal Started 7m kubelet, host01 Started container
对外发布服务
已经部署好了一个 nginx 应用,那么要怎么去访问呢?这时候就须要用到 service。建立一个 service:
$ kubectl expose deployment/first-app --type="NodePort" --port=80
service "first-app" exposed
查看建立好的名为 first-app 的 service :
$ kubectl get svc first-app
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
first-app NodePort 10.102.0.12 <none> 80:30491/TCP 1m
在 PORT(S) 一栏中,除了 80 端口,后面还有一个 30491 端口。这是使用了“NodePort”类型建立 service 分配的端口,经过主机 ip 和这个端口,就能够访问到这个 service 了。可使用 curl 工具进行访问:
$ curl 172.17.0.77:30491
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
扩缩应用
刚刚已经成功访问到 nginx 应用,但有些时候,可能须要多个 nginx 来横向扩展,那么在 Kubernetes 中怎么实现呢?
$ kubectl scale deployment/first-app --replicas=3
deployment "first-app" scaled
再查看当前的 pod,能够看到当前已经有了 3 个 first-app 了。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
first-app-6db44b474-6vlrj 1/1 Running 0 39s
first-app-6db44b474-dbbtp 1/1 Running 0 19m
first-app-6db44b474-gjzgg 1/1 Running 0 39s
若是以为 3 个太浪费资源了,想减小 pod 的数量,那么可使用一样的命令,把 replicas 参数的值改成须要的值就能够了。
更新应用
最经常使用的就是更新镜像。以前使用的是 docker hub 上最新的 nginx,如今用 1.10.3 这个比较老的版原本替代最新版本。先查看当前使用的 nginx 版本。这里有一个很简单的方法,访问一个不存在的页面,以下:
$ curl 172.17.0.77:30491/abc
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.13.9</center>
</body>
</html>
当前使用的 nginx 版本是 1.13.9,接下来进行更新操做:
$ kubectl set image deployment/first-app first-app=nginx:1.10
deployment "first-app" image updated
再查看当前 nginx 的版本:
$ curl 172.17.0.77:30491/abc
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>
nginx 版本已经成功更新为 1.10.3。
删除应用
最后来说讲删除应用,以前是经过 deployment 来建立应用,因此只须要删除 deployment 就能够删除对应的应用了。
$ kubectl delete deployment/first-app
deployment "first-app" deleted
再查看一下当前的 pod:
$ kubectl get pod
No resources found.
全部的 pod 都已经删除了。
关于做者
一个生于二线,活在一线城市的程序猿,我是小小,咱们下期再见。

小明菜市场
往期推荐
本文分享自微信公众号 - 小明菜市场(fileGeek)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。