Kubernetes是什么
官网
https://kubernetes.io/
中文版:https://kubernetes.io/zh/
Kubernetes是谷歌十几年大规模容器管理经验的成果
是Borg的一个开源版本
基于容器技术的分布式架构方案
Service简介
Kubernetes以Service为核心,Service有如下特征
唯一名称
拥有一个虚拟ip和端口
提供某种远程服务能力
被映射到提供这种服务能力的一组容器应用上
Pod简介
Pod运行在Node主机中
Pod是Kubernetes管理的最小运行单元
通常一个Node运行上百个Pod
每个Pod有一个特殊的Pause容器,负责网络栈和Volume挂载卷
只有提供服务的那组Pod才会被映射为一个服务
为什么要使用Kubernetes
一旦搭建好Kubernetes环境后,后续对于应用的部署与运维,使用Kubernetes就非常方便了
Hello World
Kubernetes的安装先不讲了
现在要做的事情是
使用Kubernetes部署MySQL与JavaWeb程序
JavaWeb可以访问Kubernetes
基本步骤
MySQL副本集
MySQL Service
JavaWeb副本集
JavaWeb Service
下面的几个yaml文件在
https://github.com/nbcoolkid/learning/tree/master/k8s
MySQL RC
mysql-rc.yaml
apiVersion: v1
# 表名这是一个副本集
kind: ReplicationController
metadata:
# RC的名称,全局唯一
name: mysql
spec:
# 期待的Pod数量
replicas: 1
selector:
app: mysql
# 根据此模板创建Pod副本
template:
metadata:
labels:
# Pod副本拥有的标签,对应RC的Selector
app: mysql
spec:
containers:
- name: mysql
image: registry.cn-hangzhou.aliyuncs.com/sherry/mysql:5.7
ports:
# 容器应用监听的端口号
- containerPort: 3306
# 注入容器内的环境变量
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
注意这里的yaml文件,不可以有制表符,我们一律使用空格键代替
编写完文件后,使用apply命令做个文件格式检查
➜ k8s git:(master) ✗ kubectl apply -f mysql-rc.yaml
replicationcontroller/mysql created
创建RC
➜ k8s git:(master) ✗ kubectl create -f mysql-rc.yaml
replicationcontroller/mysql created
查看创建结果
➜ k8s git:(master) ✗ kubectl get rc
NAME DESIRED CURRENT READY AGE
mysql 1 1 1 4m17s
查看创建的Pod情况
➜ k8s git:(master) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-wg9sp 1/1 Running 0 5m16s
dashboard
其实通过dashboard,也能看到启动情况
MySQL Service
mysql-svc.yaml
apiVersion: v1
kind: Service # 表名这是一个Kubernetes Service
metadata:
name: mysql # Service全局名称
spec:
ports:
- port: 3306 # Service对外提供的端口
selector:
app: mysql # Service对应的Pod拥有此标签,所有拥有此标签的pod都归我管
创建Service
➜ k8s git:(master) ✗ kubectl create -f mysql-svc.yaml
service/mysql created
查看创建结果
➜ k8s git:(master) ✗ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 175m
mysql ClusterIP 10.105.55.185 <none> 3306/TCP 84s
可以发现,MySQL服务被分配了一个值为10.105.55.185
的CLUSTER-IP
,端口为3306
此时,Kubernetes集群中其他创建的Pod就可以通过这个ip+端口进行连接和访问了
这里的ip,是Service创建后由Kubernetes系统自动分配的,
其他Pod无法余弦知道,所以需要有一个服务发现机制来找到这个服务。
现在,我们根据Service的唯一名称获取到ip和端口
JavaWeb RC
myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
在Tomcat容器内部,应用将使用环境变量MYSQL_SERVICE_HOST的值连接MySQL,更安全的做法是使用服务的名称mysql进行访问
创建RC
➜ k8s git:(master) ✗ kubectl create -f myweb-rc.yaml
replicationcontroller/myweb created
验证
➜ k8s git:(master) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-ck4j5 1/1 Running 0 164m
myweb-8dhr9 1/1 Running 0 3m11s
myweb-nm75w 1/1 Running 0 3m11s
JavaWeb Service
myweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
type: NodePort
和nodePort: 30001
,表明此Service开启了NodePort
方式的外网访问模式
启动
➜ k8s git:(master) ✗ kubectl create -f myweb-svc.yaml
service/myweb created
验证
➜ k8s git:(master) ✗ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h47m
mysql ClusterIP 10.105.55.185 <none> 3306/TCP 174m
myweb NodePort 10.101.31.133 <none> 8080:30001/TCP 41s
验证
经过上述步骤,我们通过dashbaord查看到底启动了哪些服务
Service
RC
Pod
我们可以使用 http://虚拟机ip:30001/demo/
的方式来进行验证访问
那么怎么获取这个虚拟机的ip呢?
我这里使用的是minikube安装的Kubernetes环境,安装后,在虚拟机中的Linux,账号是root,密码为空
然后使用ipconfig|more
命令就能看到ip
ok,至此,我们的hello world完毕
基本概念与术语
Kubernetes中的大部分概念,包括Node、Pod、Replication Controller、Service,都可以被看做一种资源对象
几乎所有的资源对象都可以通过kubectl进行增删改查操作,并持久化到etcd中
apiVersion:v1
声明当前这个资源对象归属于v1这个核心API
大部分的资源对象都归属于v1这个核心API
Master
Kubernetes集群的控制节点,一般在生产环境至少部署3台作为高可用
所有的Kubernetes指令都是发给Master,由Master去管理集群中的节点
Master上运行着以下核心进程
Kubernetes API Server:kube-apiserver,集群控制入口
Kubernetes Controller Manager:kube-controller-manager,资源对象管理
Kubernetes Scheduler:kube-scheduler,资源调度
Master上通常还部署etcd服务,因为Kubernetes里的所有资源对象数据都保存在etcd中
Node
工作节点,运行应用程序
Node上运行着以下核心进程
kubelet:负责Pod对应容器的创建、启停,与Master的协作,实现集群管理
kube-proxy:实现Kubernetes Service的通信,负载均衡的重要组件
docker
Node可以在Kubernetes运行期间动态加入集群
前提是Node节点已经安装好了上述核心进程
默认情况下,kubelet会向Master注册自己
如果某个Node失联,Master会触发“工作负载大转移”的自动流程
Pod
Pod运行在Node上
Pod有一个Pause根容器
Pod内容器可以和Kubernetes集群中任意的Pod内的容器进行直接通信
PodIP+容器端口=Endpoint,代表此Pod内的某个服务的对外通信地址
一般一个应用会暴露两个Endpoint,一个服务端口,一个管理端口
可以配置Pod对资源期望的最低要求和最高要求(CPU、内存)
resources:
# 设置一个较小的值,符合容器平时工作负载下的资源需求
requests:
# 内存占用,默认单位为字节,一般我们使用Mi,表示兆
memory: "64Mi"
# 以1/1000为最小单位,100m表示0.1个CPU
# 不管是在一个1Core的机器还是8Core的机器上,100m代表的含义都是一样的
cpu: "250m"
# 设置一个较大的值,符合容器峰值负载下的资源需求
# 当容器试图使用超过这个量的资源时,可能被Kubernetes杀掉并重启
limits:
memory: "128Mi"
cpu: "500m"
Label
Label是键值对,key和value均由用户自定义
一个Label可以被附加到多个资源上,一个资源可以定义任意数量的Label
Label通常在资源定义时确定,也可以在对象创建后动态添加与删除
Label定义后,通过 Label Selector(标签选择器)进行查询和筛选
Selector有基于等式与基于集合两种
name=redis-slave,匹配所有具备
name!=redis-slave,匹配所有不具备
name in (redis-master,redis-slave)
name not in (pho-frontend)
多个表达式之间用,
分割
多个表达式之间是AND
关系
matchLabels与matchExpressions
Replication Controller/Replica Set
RC定义内容包括
期待Pod的数量
删选Pod的Label Selector
Pod数量不满足时用于创建新Pod的template
一个完整的RC定义案例
确保拥有tier=frontend
标签的Pod在Kubernetes集群中始终只有一个副本
删除RC,并不会删除通过该RC创建好的Pod
如果要删除RC对于的Pod,可以设置replicas值为0,然后更新RC
kubectl提供stop、delete命令,来一次性删除RC及其对应的Pod
在应用升级的时候
其实就是一个新的容器镜像替代旧版本的过程
通过改变RC中Pod模板的镜像版本,实现滚动升级
Deployment
为了更好的解决Pod的编排问题,Deployment内部使用Replica Set
我们把Deployment当做一次RC的升级即可
Horizontal Pod Autoscaler
HPA用于实现Pod的横向自动扩容
StatefulSet
Service
Kubernetes内部的服务,最终是通过Service暴露出去的
Service整个生命周期内,拥有唯一不变的ip
Job
Volume
Volume是Pod中能够被多个容器访问的共享目录
Kubernetes中的Volume概念、用途、目的,与Docker中的Volume类似,但又有不同
Kubernetes中的Volume定义在Pod中
Kubernetes中的Volume与Pod的生命周期相同,与容器不同
Kubernetes支持多种文件系统的Volume,如:GlusterFS、Ceph等
Persistent Volume
Namespace
命名空间,一般用于实现多租户的资源个例
Annotation
ConfigMap
本文由博客一文多发平台 OpenWrite 发布!