Hi! 我是小小,今天是本周的第二篇,本篇主要内容是讲解k8s
前言
都9102年了,你还不知道kubernetes就真的真的真的out啦。(贩卖焦虑体) 什么是k8s,k8s这个词来自于希腊语,有主管,舵手,船长的意思,我们从图标中能看出来。在k8s的网站上,描述是这样的
生产级别的容器编排系统
从定义中可以提炼出三个关键字,分别是
生产级别
容器
编排系统
1. 生产级别
说k8s是生产级别的有如下的几个原因:
k8s 是谷歌的开源系统,基于谷歌的系统设计,并且已经在谷歌系统上平稳运行的很久。
k8s 是CNCF的首个毕业项目。
2. 容器
容器有以下几个特点
可移植性,容器可以被任何类型的操作系统安装使用。
包容性:支持多种类型的软件,这些软件都可以打包在容器内。
标准格式。
共存,多个容器可以运行在同一个物理机上。
隔离,不同的容器的软件彼此隔离。
最重要的一句话:没有容器就没有微服务。
容器和微服务化后,带来了一些好处,比如:
模块间更加独立,可以独立的部署和发布,加快了发布和更新的速度
隔离的运行环境,可以为不同模块定制不同的运行环境
3. 编排系统
容器的编排系统可以有效的管理在宿主机上的容器。
管理网络和访问
跟踪容器的状态
增大或缩小服务的规模
实现负载平衡
宿主机无响应后实现容器的重新分配
服务发现
管理容器的存储 等等…
主要功能
数据卷
pod中容器之间共享数据,可以使用数据卷。
应用程序健康检查
容器内服务可能进程阻塞无法处理请求,可以设置监控检查的策略,
复制应用程序实例
控制器维护者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 都已经删除了。
关于作者
一个生于二线,活在一线城市的程序猿,我是小小,我们下期再见。
小明菜市场
往期推荐
转载:https://blog.csdn.net/melovemingming/article/details/109193151