kubernetes的学习
Posted F3nGaoXS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kubernetes的学习相关的知识,希望对你有一定的参考价值。
kubernetes的学习
本篇学习笔记总结自https://k8s.easydoc.net/,https://www.bilibili.com/video/BV1Tg411P7EB/
安装k8s集群
主节点需要的组件
- docker(也可以是其他容器运行时)
- kubectl 集群命令行交互工具
- kubeadm 集群初始化工具
工作节点需要的组件
- docker(也可以是其他容器运行时)
- kubelet 管理 Pod 和容器,确保他们健康稳定运行。
- kube-proxy 网络代理,负责网络相关的工作
部署应用到集群
使用pod
快速创建
--image=镜像地址
kubectl run <pod_name> --image==<image_url>
通过yaml文件创建单个pod
apiVersion: v1
kind: Pod
metadata:
# pod名称
name: test-k8s
spec:
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
然后
kubectl apply -f <file_path.<yaml>>
通过yaml文件创建多个pod(deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: test-k8s
spec:
replicas: 5
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: test-k8s
# 定义 Pod 相关数据
template:
metadata:
labels:
app: test-k8s
spec:
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v1 # 镜像
然后
kubectl apply -f <file_path.<yaml>>
称之为development(部署),并且可以使用
kubectl get deployment
查询当前的部署情况
Tips
运行单个pod的yaml文件的kind为
Pod
,运行多个pod的yaml文件的kind为Deployment
进入pod的bash
kubectl exec -it <pod_name> -- bash
资源类型
常见的资源类型有
类型名称 | 描述 | 简写 |
---|---|---|
pod | po | |
deployment | deploy | |
service | svc | |
statefulset | sts | |
storage class | sc | |
presistent volume | pv | |
presistent volume claim | pvc | |
config map | cm | |
sercet | ||
name space | ns |
可以使用如下命令查看所有资源,资源名称及其简写
kubectl api-resources
命令
apply
运行资源
kubectl apply [-f] <file_path>
# -f:读取文件,然后运行
示例1,启用service资源:
service.yaml
apiVersion: v1
kind: Service
metadata:
name: test-k8s
...
运行:
kubectl apply -f service.yaml # 读取该文件,然后运行资源
示例2:启动pod资源:
pod.yaml
apiVersion: v1
kind: Pod
metadata:
# pod名称
name: test-k8s
...
运行:
kubectl apply -f pod.yaml
同理,还可以运行更多资源,如deployment、statefulset等,具体资源类型由文件的kind决定。
get
可以列出该类型的所有资源
kubectl get [资源类型] [-o wide|name|yaml|json]
# all:列出所有资源,包括pod、deployment、service等
# -o wide:详细信息
# -o name:仅输出资源名称
# -o yaml:YAML格式化输出
# -o json:JSON格式化输出
示例:
kubectl get pod # 列出所有pod
kubectl get pod -o wide # 以详细的方式列出所有pod
describe
查看资源的详细描述
kubectl describe [资源类型] <name> # 第一种写法:资源类型(如pod、svc)+空格+具体名称
kubectl describe [资源类型]/<name> # 第二种写法:资源类型+/+具体名称
kubectl describe [资源类型] # 第三种写法:资源类型,不加具体名称。查看所有该资源的详细描述
示例:
kubectl describe pod test-pod
kubectl describe pod/test-pod
kubectl describe pod
logs
查看资源的日志
kubectl logs [资源类型]/<name> [-f] [-tail 100] # 只能这种写法
# -f:循环读取,即可以读取不断改变的log
# -tail:读取最尾部xx行
示例:
kubectl logs pod/test-k8s
delete
删除资源
kubectl delete [资源类型] <name>
kubectl delete [资源类型]/<name>
示例:
kubectl delete pod/test-k8s
rollout
查看资源的变更历史history
kubectl rollout history [资源类型] <name>
kubectl rollout history [资源类型]/<name>
重新部署restart(仅适用于deployment)
kubectl rollout restart deployment/<name>
回退到上一版本undo
kubectl rollout undo deployment/<name>
回退到指定版本
kubectl rollout undo deployment/<name> --to-revision=2
port-forward
将资源转发到本地
kubectl port-forward [资源类型] <name> [local_port]:[remote_port]
kubectl port-forward [资源类型]/<name> [local_port]:[remote_port]
示例:
将资源的8090的端口转发到本地的8080
kubectl port-forward svc/test-k8s 8080:8090
其他命令
# 命令修改镜像,--record 表示把这个命令记录到操作历史中
kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record
# 暂停运行,暂停后,对 deployment 的修改不会立刻生效,恢复后才应用设置
kubectl rollout pause deployment test-k8s
# 恢复
kubectl rollout resume deployment test-k8s
# 重启
kubectl rollout restart deployment test-k8s
# 删除全部资源
kubectl delete all --all
service
特性
- Service 通过 label 关联对应的 Pod
- Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重创改变 IP
- 提供了负载均衡功能,自动转发流量到不同 Pod
- 可对集群外部提供访问端口
- 集群内部可通过服务名字访问
Tips
service一共有四种type:
ClusterIP
默认的,仅在集群内可用
NodePort
暴露端口到节点,提供了集群外部访问的入口
端口范围固定 30000 ~ 32767LoadBalancer
需要负载均衡器(通常都需要云服务商提供,裸机可以安装 METALLB 测试)
会额外生成一个 IP 对外服务
K8S 支持的负载均衡器:负载均衡器Headless
适合数据库
clusterIp 设置为 None 就变成 Headless 了,不会再分配 IP
示例
service.yaml:
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: ClusterIP
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
# nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
运行:
kubectl apply -f <service_path>
statefulset
StatefulSet 是用来管理有状态的应用,例如数据库。StatefulSet 会固定每个 Pod 的名字
特性
- Service 的
ClusterIP
是空的,Pod 名字也是固定的。 - Pod 创建和销毁是有序的,创建是顺序的,销毁是逆序的。
- Pod 重建不会改变名字,除了IP,所以不要用IP直连
访问时,如果直接使用 Service 名字连接,会随机转发请求
要连接指定 Pod,可以这样pod-name.service-name
示例
mongo.yaml
# StatefulSet: mongodb
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 3
serviceName: mongodb
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
---
# Service: mongodb
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
targetPort: 27017
运行:
kubectl apply -f <file_path>
pod、deployment、service、statefulset四者的关系
这四者在yaml文件中通过指定不同的kind
来区分,pod是deployment和statefulset运行的最小单元,deployment和statefulset可以通过指定spec.replicas
来扩展多个pod,deployment启动的pod默认的名称为deploy名称+无序字符
,而statefulset启动的pod的默认名称为statefulset名称+有序数字
,如
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
mongodb-0 1/1 Running 1 (20h ago) 3d17h
test-k8s-75bd6fbdbc-72rxc 1/1 Running 1 (20h ago) 3d17h
test-k8s-75bd6fbdbc-ns5h2 1/1 Running 1 (20h ago) 3d17h
启动service并不会创建pod,只是service会通过label来关联pod或者deploy或者statefulset,可以随之进行端口转发,供外部访问。由于service是通过label关联pod的,所以pod销毁service也不会销毁的。
数据持久化
k8s集群并不会为你处理数据的存储,我们可以为数据库挂载一个磁盘来确保数据的持久化。可以选择云存储、本地磁盘、NFS。
- 本地磁盘:可以挂载某个节点上的目录,但是这需要限定 pod 在这个节点上运行
- 云存储:不限定节点,不受集群影响,安全稳定;需要云服务商提供,裸机集群是没有的。
- NFS:不限定节点,不受集群影响
hostPath
把节点上的一个目录挂载到 Pod,但是已经不推荐使用了,文档
配置方式简单,需要手动指定 Pod 跑在某个固定的节点。
仅供单节点测试使用;不适用于多节点集群。
minikube 提供了 hostPath 存储,文档
将容器卷的挂载路径(volumeMounts
)指向节点的卷路径(volumes
)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
serviceName: mongodb
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent 仅本地没有镜像时才远程拉,Always 永远都是从远程拉,Never 永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /data/db # 容器里面的挂载路径
name: mongo-data # 卷名字,必须跟下面定义的名字一致
volumes:
- name: mongo-data # 卷名字
hostPath:
path: /data/mongo-data # 节点上的路径
type: DirectoryOrCreate # 指向一个目录,不存在时自动创建
# - name: mongo-data
# persistentVolumeClaim:
# claimName: mongodata
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
protocol: TCP
targetPort: 27017
ConfigMap
yaml文件的kind是ConfigMap
,官方文档
示例
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
# config-map的名称
name: mongo-config
data:
# key-value
mongo-address: mongodb-0.mongodb:27017
运行:
kubectl apply -f configmap.yaml
通过get查看并且输出为yaml格式
kubectl get cm mongo-config -o yaml
接下来就可以在其他地方被读取了,这里以一个App的环境变量为例:
app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
# 部署名字
name: test-k8s
spec:
replicas: 2
# 用来查找关联的 Pod,所有标签都匹配才行
selector:
matchLabels:
app: test-k8s
# 定义 Pod 相关数据
template:
metadata:
labels:
app: test-k8s
spec:
# 等待 mongodb 起来后才启动
initContainers:
- name: wait-mongo
image: busybox:1.28
command: ['sh', '-c', "until nslookup mongodb; do echo waiting for mongo; sleep 2; done"]
# 定义容器,可以多个
containers:
- name: test-k8s # 容器名字
image: ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v4-configmap # 镜像
env:
- name: MONGO_USERNAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-username
- name: MONGO_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
- name: MONGO_ADDRESS
valueFrom:
# 从config map资源中取
configMapKeyRef:
# 资源名称
name: mongo-config
# 取资源中对应的key的value
key: mongo-address
---
apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIp 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: NodePort
ports:
- nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
可以看到env[2].name的valueFrom中是configMapKeyRef,则代表使用ConfigMap资源中取,并且指定ConfigMap资源的名称和key,即可以读取到内容了。
这里的env:MONGO_ADDRESS
是从名叫mongo-config
的ConfigMap资源中读取key为mongo-address
对应的value,即mongodb-0.mongodb:27017
。
Secret
yaml文件的kind是Secret
,官方文档
示例
secret.yaml
apiVersion: v1
kind: Secret
metadata:
# secret的名称
name: mongo-secret
# 默认的type是Opaque
type: Opaque
data:
# key-value
# 需要进行base64加密处理
mongo-username: bW9uZ291c2Vy
mongo-password: bW9uZ29wYXNz
运行
kubectl apply -f secret.yaml
以yaml文件格式查看
kubectl get secret mongo-secret -o yaml
接下来就可以被其他地方读取了,这里mongo的statefulset为例
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
serviceName: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongo
image: mongo:4.4
# IfNotPresent:仅本地没有镜像时才远程拉,Always:永远都是从远程拉,Never:永远只用本地镜像,本地没有则报错
imagePullPolicy: IfNotPresent
# 该container的环境变量列表
env:
# 环境变量名称
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
# 'secretKeyRef'表示从secret资源中取
secretKeyRef:
# 指定secret的名称
name: mongo-secret
# 取secret中的key对应的value
key: mongo-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
---
apiVersion: v1
kind: Service
metadata:
name: mongodb
spec:
selector:
app: mongodb
type: ClusterIP
# HeadLess
clusterIP: None
ports:
- port: 27017
protocol: TCP
targetPort: 27017
可以看到env[0].name的valueFrom中是secretKeyRef,则代表使用Secret资源中取,并且指定Secret资源的名称和key,即可以读取到内容了。
这里的env:MONGO_INITDB_ROOT_USERNAME
是从名叫mongo-secret
的ConfigMap资源中读取key为mongo-username
对应的value,即bW9uZ291c2Vy
,env:MONGO_INITDB_ROOT_PASSWORD
同理。
可以看到,configMap和secret读取的方式是差不多的。
Tips
如果type是Opaque的话,那么data需要进行base64处理
Helm
Helm
类似 npm,pip,docker hub, 可以理解为是一个软件库,可以方便快速的为我们的集群安装一些第三方软件。
使用 Helm 我们可以非常方便的就搭建出来 MongoDB / mysql 副本集群,YAML 文件别人都给我们写好了,直接使用。官网,应用中心
我们可以在应用中心搜索集群,然后添加源并且安装就可以快速创建集群了,不需要自己手动写配置文件,并且我们可以在安装集群的时候手动指定一些参数。
示例:安装mongodb
1、添加源
helm repo add bitnami https://charts.bitnami.com/bitnami
2、安装
# 默认安装
helm install first-mongo bitnami/mongodb
# 指定参数安装
helm install my-mongo bitnami/mongodb --set architecture="replicaset",auth.rootPassword="mongopass"
具体可以手动指定的参数可以在应用中心中查看
3、查看密码
kubectl get secret my-mongo-mongodb -o yaml
# 查看密码并且写入文件
kubectl get secret my-mongo-mongodb -o yaml > secret.yaml
4、查看
可以查看到通过helm,已经自动安装好了包含可以扩展的pod、service、statefulset的集群。
kubectl get all
5、测试
临时运行一个包含 mongo client 的 debian 系统
kubectl run mongodb-client --rm --tty -i --restart='Never' --image docker.io/bitnami/mongodb:4.4.10-debian-10-r20 --command -- bash
在client中利用url、username、password连接mongo server
mongo --host my-mongo-mongodb-0.my-mongo-mongodb-headless.default.svc.cluster.local:27017 -u root -p mongopass
6、转发集群端口到宿主机
此时可以通过宿主机的工具来尝试连接mongo server,如Navicat、DateGrip等。
kubectl port-forward svc/my-mongo-mongodb-headless 27018:27017
7、删除集群
helm delete first-mongo
namespace
列出所有命名空间
kubectl get ns
查看默认的命名空间
kubectl get all
查看指定的命名空间
kubectl get all -n <namespace>
示例
查看k8s系统的命名空间
kubectl get all -n kube-system
创建命名空间
每次部署或者查询时候都需要指定命名空间
kubectl create namespace testns
部署应用到指定命名空间
kubectl apply -f app.yml [-n|--namespace] <namespace>
然后查询
kubectl get pod [-n|--namespace] <namespace>
每次部署应用或者查询时候都需要指定命名空间
kubens
每次部署或者查询时候都需要指定命名空间有点麻烦,可以利用kubens
快速切换命名空间,后续的命令就不需要再利用-n|--namespace
指定命名空间了。
查看所有命名空间
高亮显示当前所位于的命名空间
kubens
切换到指定命名空间
kubens <namespace>
切换回上一命名空间
kubens -
kubectx
快速切换集群
Ingress
yaml文件的kind是Ingress
,官方文档,是一个作用类似于nginx的,能够提供对集群中的服务的外部访问进行管理的API对象
示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-example
spec:
ingressClassName: nginx
rules:
- host: tools.fun
http:
paths:
# 匹配'/easydoc'转发到service1
- path: /easydoc
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
# 匹配'/svnbucket'转发到service2
- path: /svnbucket
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
其他
Service中type为ClusterIP和NodePort的区别
ClusterIP
:通过集群内部的IP暴露服务,选择该值的时候服务只能在集群内部访问。是service
默认的type。
NodePort
:通过每个节点上的IP和静态端口暴露服务。NodePort
服务会路由到自动创建的ClusterIP
服务,通过请求 <节点 IP>:<节点端口>
,你可以从集群的外部访问一个 NodePort
服务。
ConfigMap和Secret的区别
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。
注意:
ConfigMap 并不提供保密或者加密功能。 如果你想存储的数据是机密的,请使用 Secret, 或者使用其他第三方工具来保证你的数据的私密性,而不是用 ConfigMap。
Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。
使用dashboard可视化管理
默认情况下不会部署 Dashboard。可以通过以下命令部署:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml
使用
kubectl proxy
输入网址:
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
以上是关于kubernetes的学习的主要内容,如果未能解决你的问题,请参考以下文章
二进制安装kubernetes kubectl命令行工具使用详解
Docker&Kubernetes ❀ Kubernetes集群Service资源配置清单
Docker&Kubernetes ❀ Kubernetes集群Service资源配置清单