一. 常用命令
含义 | 命令 |
---|---|
部署应用 | kubectl apply -f app.yaml |
查看 pod | kubectl get pod -o wide |
查看 pod 详情 | kubectl describe pod pod-name |
查看 log | kubectl logs pod-name |
查看 | kubectl get deployment |
查看 | kubectl get svc |
查看service详情 | kubectl describe svc test-k8s |
获取service的endpoints的信息 | kubectl get endpoints |
获取service的endpoints的详细信息 | kubectl get endpoints service-name -o yaml |
查看 | kubectl get statefulsets |
| kubectl delete all --all |
删除部署 | kubectl delete deployment test-k8s |
删除service | kubectl delete svc test-k8s |
进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。 | kubectl exec -it pod-name -- bash |
伸缩扩展副本 | kubectl scale deployment test-k8s --replicas=5 |
把集群内端口映射到节点 | kubectl port-forward pod-name 8090:8080 |
其他命令
含义 | 命令 |
---|---|
| kubectl get all |
重新部署 | kubectl rollout restart deployment test-k8s |
命令修改镜像,--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 get deployment test-k8s -o yaml >> app2.yaml |
查看历史 | kubectl rollout history deployment test-k8s |
回到上个版本 | kubectl rollout undo deployment test-k8s |
回到指定版本 | kubectl rollout undo deployment test-k8s --to-revision=2 |
二. Service
1. 集群内访问
代码语言:txt复制apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
type: ClusterIP
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
应用配置 kubectl apply -f service.yaml
查看服务 kubectl get svc
查看服务详情 kubectl describe svc test-k8s
,可以发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点。
服务的默认类型是 ClusterIP
,只能在集群内部访问,我们可以进入到 Pod 里面访问:
kubectl exec -it pod-name -- bash
curl http://test-k8s:8080
如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 8888:8080
2. 集群外访问
代码语言:txt复制apiVersion: v1
kind: Service
metadata:
name: test-k8s
spec:
selector:
app: test-k8s
# 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
type: NodePort
ports:
- port: 8080 # 本 Service 的端口
targetPort: 8080 # 容器端口
nodePort: 31000 # 节点端口,范围固定 30000 ~ 32767
应用配置 kubectl apply -f service.yaml
在节点上,我们可以 curl http://localhost:31000/hello/easydoc
访问到应用
并且是有负载均衡的,网页的信息可以看到被转发到了不同的 Pod
代码语言:txt复制hello easydoc
IP lo172.17.0.8, hostname: test-k8s-68bb74d654-962lh
如果你是用 minikube,因为是模拟集群,你的电脑并不是节点,节点是 minikube 模拟出来的,所以你并不能直接在电脑上访问到服务
Loadbalancer
也可以对外提供服务,这需要一个负载均衡器的支持,因为它需要生成一个新的 IP 对外服务,否则状态就一直是 pendding,这个很少用了,后面我们会讲更高端的 Ingress 来代替它。
3. 总结
ClusterIP
默认的,仅在集群内可用
NodePort
暴露端口到节点,提供了集群外部访问的入口
端口范围固定 30000 ~ 32767
三. YAML关键字
字段名 | 字段类型 | 说明 |
---|---|---|
version | string | RESTFul API的版本,目前基本上是v1,可以通过kubectl api-versions命令去查询所有的API的version |
kind | string | 定义的资源类型和角色,例如Pod |
metadata | object | 元数据对象,固定值就写metadata |
metadata.name | string | 元数据对象的名字,例如Pod的名字 |
metadata.namespace | string | 元数据对象的命名空间,不指定则默认是default空间 |
spec | objec | 详细定义对象,固定值就写Spec |
spec.containers[] | list容器列表 | |
spec.containers[].name | string | 这里定义容器的名字 |
spec.containers[].image | string | 这里定义容器要用到的镜像名称 |
spec.containers[].imagePullPolicy | string | 镜像拉取策略,有Always/Never/IfNotPresent三个可选,默认是Always |
spec.containers[].command[] | list | 指定容器启动命令,不指定则使用镜像打包时的启动命令 |
spec.containers[].args[] | list | 指定容器启动命令参数,因为是数组所以可以指定多个 |
spec.containers[].workingDir | string | 指定容器的工作目录 |
spec.containers[].volumeMounts[] | list | 存储卷配置 |
spec.containers[].volumeMounts[].name | string | |
spec.containers[].volumeMounts[].mountPath | string | |
spec.containers[].volumeMounts[].readOnly | string | |
spec.containers[].ports[] | list | 容器需要的端口列表 |
spec.containers[].ports[].name | string | 端口名称 |
spec.containers[].ports[].containerPort | string | 容器需要监听的端口号 |
spec.containers[].ports[].hostPort | string | 主机需要监听的端口号,默认跟上面的containersPort一致,设置了以后不能在同一台宿主机上启动第二个副本 |
spec.containers[].ports[].protocol | string | 端口协议,TCP/UDP,默认是TCP |
spec.containers[].env[] | list | 环境变量 |
spec.containers[].env[].name | string | 环境变量名称 |
spec.containers[].env[].value | string | 环境变量值 |
spec.containers[].resources | object | 限制资源的使用上限,后面详细讲 |
spec.restartPolicy | string | Pod的重启策略,可选Always/OnFailure/Never,默认值为Always |
spec.nodeSelector | object | 定义Node的label过滤标签,键值对格式指定 |
spec.imagePullSecrets | object | 定义pull镜像时使用的密钥,键值对格式指定 |
spec.hostNetwork | Boolean | 定义是否使用主机网络。默认为false表示不使用宿主机网络,只用docker网桥。设置了true将无法在同一台宿主机上启动第二个副本 |
举例:
四. yaml文件的固定结构
代码语言:txt复制COPY每个文件必须的结构如下:
apiVersion: apps/v1 # api版本
kind: xxxx # 要创建的资源类型,如Deployment/Pod/ReplicaSet/StatefulSet/DaemonSet/Job/Cronjob/Service/Ingress...
metadata: # 元数据对象,该资源的基本属性和信息
name: xxx # 定义该资源的名称
namespace: xxx # 命名空间,默认放到default空间
lables: # 标签,在下一行定义键值对,可以是多对键值对
xxx: xxxx
xxx: xxxx
annotations # 资源注解
xxx: xxxx
spec: # 定义期望状态,详细的创建信息
containers: # 容器列表
- name: xxx # 容器名
image: xxxx # 容器镜像
status: # 当前状态,由k8s集群维护,不可以自定义
1. Controller定义部分
代码语言:txt复制COPY必须定义名字
------------------------------------------
apiVersion: apps/v1 # api版本(必须的)
kind: Deployment # 表示要创建的Controller资源类型
metadata: # 元数据对象,该资源的基本属性和信息(必须的)
name: nginx-deployment # 定义该资源的名称(必须的),同一命名空间内,必须唯一
namespace: xxxx # 命名空间,默认放到default空间(可选)
labels: # 标签,用来定位一个或多个资源,键值对方式进行定义,下方使用的selector会与这里的键值对对应,作为selector的挑选条件
app: nginx # 设置key为app,value为nginx
------------------------------------------
2. 资源的特点
也就是kind所创建的资源的信息
代码语言:txt复制COPY------------------------------------------
spec: # 描述该资源的创建信息,对应kind资源类型的信息
revisionHistoryLimit: 10 # 回滚时会用到,用来保留最近10的版本
replicas: 2 # 创建2个应用实例
selector:
# 标签选择器,与上面的标签共用,这个部分是17版本开始加的,必须与上面的labels对应
matchLabels: # 选择包含标签app:nginx的资源
# 正确的Deployment,让matchLabels 和template.metadata.lables完全匹配才能不报错
# 直接不写spec.mathlabels创建直接报错缺少缺少必要字段selector
# 当把matchLables匹配的和下面pod模板不相对应,也会直接报错:选择的标签和模板标签不匹配
# matchLabel是pod的标签选择器。 由此选择其pod的现有ReplicaSet(副本集)将受此部署影响的副本。
app: nginx
------------------------------------------
matchLabels总结
1、在Deployment中必须写matchLabels
2、在定义模板的时候必须定义labels,因为Deployment.spec.selector是必须字段,而又必须和template.labels对应
3、templdate里面定义的内容会应用到下面所有的副本集里面,在template.spec.containers里面不能定义labels标签
3. Pod的模板
代码语言:txt复制COPY必须定义labels
------------------------------------------
template: # 选择或创建的Pod模板
metadata: # Pod的元数据,Pod的信息
labels: # Pod标签
app: nginx
------------------------------------------
4. Container的模板
代码语言:txt复制COPY------------------------------------------
spec: # 期望Pod实现的功能(在Pod中部署什么)
strategy: # 在滚动更新Pod时的启动Pod数量比值
rollingUpdate:
maxSurge: 35%
maxUnavailable: 35%
nodeSelector: # 指定pod运行在哪个集群节点
restartPolicy: # 容器重启策略(Never/Always/OnFailure)
hostNetwork: true # 表示直接使用节点中的主机网络,相当于docker的host网络
containers: # 在Pod中生成容器,容器列表,可写入多个镜像的实例
- name: xxxx # 定义容器名
image: xxxx # 容器使用的镜像
- name: xxxx
image: xxxx
imagePullPolicy:
# 镜像下载策略(IfNotPresent/Never/Always)
# 分别代表,没有镜像时下载,从不下载,总是下载
command: # 运行程序==dockerfile中的ENTRYPOINT,或者docker run时最后跟的/bin/bash等命令,会替代dockerfile中cmd和ENTRYPOINT执行的命令
- echo
- 'hello world'
args: # 向docker镜像中传递命令,通常用来给command传参,也可以单独使用,与dockerfile中的CMD作用一样,如果yml中只写了args,将会给dockerfile中的ENTRYPOINT传参,dockerfile中的CMD会失效。
- xxx
- xxx
ports: # 用来暴露端口,并不是端口映射,仅仅为了可以看到容器中使用了哪两个端口
- name: xxx
containerPort: 80 # 容器中提供服务的端口
protocol: TCP/UDP # 默认是tcp
- name: xxx
containerPort: 443
volumeMounts: # 用来指定容器内的路径
- name: nginxconf
mountPath: /usr/local/nginx/conf
- name: nginxhtml
mountPath: /usr/local/nginx/html
readOnly: True # 设置容器内只读,默认是读写
volumes: # 指定对应name的物理机路径,缩进与上方的containers对齐
- name: nginxconf
hostPath:
path: /nginx/conf
- name: nginxhtml
hostPath:
path: /nginx/html
- name: xxx
emptyDir: {}
- name: xxx
persistentVolumeClaim: # 使用PVC存储资源
claimName: xxxxx-xxx
LivenessProbe: # 存活检测,判断文件是否存在,检测失败重启容器
exec:
command:
- cat
- /tmp/healthy
readinessProbe: # 读取检测,判断文件是否存在,检测失败,标记为不可用,将不会被Service所负载
exec:
command:
- cat
- /tmp/healthy
------------------------------------------
五. 常见问题
如果你运行 kubectl describe pod/pod-name
发现 Events 中有下面这个错误
networkPlugin cni failed to set up pod "test-k8s-68bb74d654-mc6b9_default" network: open /run/flannel/subnet.env: no such file or directory
在每个节点创建文件 /run/flannel/subnet.env
写入以下内容,配置后等待一会就好了
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
参考文章
- 【Kubernetes 004】用yaml文件创建自己的第一个pod
- Kubernetes之yaml文件详解(汇总-详细)