系列文章
第一章:✨ k8s入门:裸机部署 k8s 集群
第二章:✨ k8s入门:部署应用到 k8s 集群
第三章:✨ k8s入门:service 简单使用
第四章:✨ k8s入门:StatefulSet 简单使用
第五章:✨ k8s入门:存储(storage)
第六章:✨ K8S 配置 storageclass 使用 nfs 动态申领本地磁盘空间
第七章:✨ k8s入门:配置 ConfigMap & Secret
第八章:✨ k8s入门:k8s入门:Helm 构建 MySQL
第九章:✨ k8s入门:kubernetes-dashboard 安装
第十章:✨ k8s入门:kube-prometheus-stack 全家桶搭建(Grafana + Prometheus)
文章目录
- 系列文章
- 一、简介
- 二、pod 和 deployment 关系
- 三、k8s 使用本地镜像部署
- 四、上传镜像到仓库
- 五、公共镜像部署
- 六、私人镜像部署
- 1、创建阿里云验证
- 2、私人镜像创建 pod
- ①、kubectl port-forward 临时暴露端口访问测试
- ②、错误: open /run/flannel/subnet.env: no such file or directory`
- ③、创建 pod 暴露端口
- 3、创建 Deployment
- 4、历史版本控制
- 5、其他命令
- 七、小妙招
- 八、遗留问题
参考文章: https://k8s.easydoc.net/
一、简介
接上篇裸机部署 k8s 集群:https://blog.csdn.net/qq_41538097/article/details/124869179
基础环境:
- 系统⭐Linux、centos 7.9 、3 台虚拟机
- 虚拟机IP⭐master:192.168.25.100,node1:192.168.25.101,node2:192.168.25.102
- k8s 版本⭐1.23.1
- docker 版本⭐20.10.16
官方文档
- Kubernetes 官方文档:https://kubernetes.io/zh/docs/setup/
- Kubernetes 中文社区 | 中文文档:http://docs.kubernetes.org.cn/
- spring-cloud-kubernetes:https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/
- kubectl 命令:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
二、pod 和 deployment 关系
- pod
- Pod 是 k8s 的最小调度单位
- 一个 Pod 代表集群上正在运行的一个进程
- Pod 中运行一个容器,可以将 Pod 视为单个封装的容器,但是 K8s 是直接管理 Pod 而不是容器
- Pod 中运行多个容器,这些容器可以形成一个单一的内部service单位,可以相互通信,共享数据
- 一个 Pod 被分配一个独立的IP地址,Pod中的每个容器共享 IP 地址和网络端口,Pod 内的容器可以使用 localhost 相互通信。
- Pod 中的容器与Pod 外部通信时,他们必须协调如何使用共享网络资源(如端口)。
- deployment
- 创建 deployment 的时候一定会创建Pod
- Deployment 可以新建及管理多副本应用(即多个副本 Pod)
- deployment 可以部署多个Pod,所有 Pod 的名字后面会随机带一串随机数避免重复
- Deployement 会配合 RC 调度保障定量的 Pod 数量。
三、k8s 使用本地镜像部署
使用 Dockerfile 在本地生成的镜像,不用上传到仓库,该方法不常用
k8s默认会从远端拉取镜像,其默认配置参数 imagePullPolicy 为 Always,我们可以将该参数设置为Never 或者 IfNotPresent,k8s 就会从本地拉取镜像了。
master 节点 pod 配置
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:containers:- name: test-k8s # 容器名字image: k8s-test:1.0 # 镜像imagePullPolicy: Never # 本地获取镜像,不从远程拉取ports:- name: httpcontainerPort: 8080 # 容器端口hostPort: 8080 # 暴露端口protocol: TCP
注意:
本地拉去镜像:指的是如果有一个 master 节点、两个 node1、node2 节点,如果 kubectl 选择将 pod 运行在 node2 节点,则 node2 本地必须有 yaml 指定的镜像,否则会报错
这种方法节点少还可以用,节点多不适用
四、上传镜像到仓库
将准备好的 jar 制作成镜像上传到私人仓库,可参考我另一篇博客 https://blog.csdn.net/qq_41538097/article/details/106861717
上传成功可以拉取镜像测试一下,jar 包中接口如下
五、公共镜像部署
对于公共镜像可以直接使用 kubectl run 创建 pod
# 使用 nginx:latest 镜像创建一个名为 nginx 的 pod
kubectl run nginx --image nginx:latest
使用公共镜像创建 pod,公共镜像可以直接 docker pull 拉取,不需要登陆
在可以使用 kubectl 工具的节点(一般建议 master 节点)新建 k8s-pod-dockerhub-public.yaml 文件,添加如下内容
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:# 定义容器,可以多个containers:- name: test-k8s # 容器名字# DockerHub仓库 image: yelingyun/k8s-test:1.0 # 镜像版本# 阿里云仓库 #image: registry.cn-zhangjiakou.aliyuncs.com/k8s-private/k8s-csdn:1.0 # 镜像版本
使用 kubectl apply -f k8s-pod-dockerhub-public.yaml
部署 pod
-
kubectl get pod -o wide 查看 pod 状态以及部署详情
-
kubectl describe pod nginx 查看 pod 部署日志
-
kubectl logs -f test-pod 查看 pod 中指定容器启动日志
-
kubectl exec -it test-pod /bin/sh 进入容器
六、私人镜像部署
dockerhub 和阿里云仓库操作类似
1、创建阿里云验证
登陆阿里云仓库docker login --username=xxxxxxx registry.cn-zhangjiakou.aliyuncs.com
,登陆成功会生成 ~/.docker/config.json 验证文件
k8s 集群中通过 ~/.docker/config.json 文件制作 secret 凭证
cat ~/.docker/config.json | base64 -w 0
保存好下面的信息
新建一个 secret 的 yaml 文件,就叫 registry-secret.yaml
apiVersion: v1
kind: Secret
metadata:name: mysecretnamespace: default
type: kubernetes.io/dockerconfigjson
data:.dockerconfigjson: ewoJImF1dGh*************************************************************************************************gkJfQoJfQp9
创建并检查 secret 凭证
kubectl apply -f registry-secret.yaml # 创建secretkubectl get secret # 查看全部
kubectl get secret mysecret # 查看指定的secret
如下创建成功
2、私人镜像创建 pod
新建 aliyun-private-springboot-pod.yaml 文件,添加 secret 验证拉取私人镜像
apiVersion: v1
kind: Pod
metadata:name: springboot-pod
spec:# 定义容器,可以多个containers:- name: springboot # 容器名字image: registry.cn-zhangjiakou.aliyuncs.com/k8s-private/springboot:1.0 # 阿里云私人镜像imagePullSecrets:- name: mysecret # 名字保持和创建的验证保持一致
创建并查看 pod 信息
kubectl apply -f aliyun-private-springboot-pod.yaml # 创建 pod
查看 pod 状态已启动,部署到了 node1 节点,拉去镜像用时 14 s,查看 pod 启动日志发现端口 8080
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 74m
springboot-pod 1/1 Running 0 24s
test-pod 1/1 Running 0 147m[root@master ~]# kubectl describe pod springboot-pod
.......
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 46s default-scheduler Successfully assigned default/springboot-pod to node1Normal Pulling 44s kubelet Pulling image "registry.cn-zhangjiakou.aliyuncs.com/k8s-private/springboot:1.0"Normal Pulled 29s kubelet Successfully pulled image "registry.cn-zhangjiakou.aliyuncs.com/k8s-private/springboot:1.0" in 14.659996621sNormal Created 29s kubelet Created container springbootNormal Started 29s kubelet Started container springboot
[root@master ~]# kubectl logs -f springboot-pod. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.5.13)2022-06-07 08:14:27.799 INFO 1 --- [ main] com.ye.test.TestApplication : Starting TestApplication v0.0.1-SNAPSHOT using Java 1.8.0_212 on springboot-pod with PID 1 (/root/test-0.0.1.jar started by root in /root)
2022-06-07 08:14:27.804 INFO 1 --- [ main] com.ye.test.TestApplication : No active profile set, falling back to 1 default profile: "default"
2022-06-07 08:14:30.977 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-06-07 08:14:31.005 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-06-07 08:14:31.006 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.62]
2022-06-07 08:14:31.378 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-06-07 08:14:31.379 INFO 1 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3459 ms
2022-06-07 08:14:33.002 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-06-07 08:14:33.024 INFO 1 --- [ main] com.ye.test.TestApplication : Started TestApplication in 6.397 seconds (JVM running for 7.625)
2022-06-07 08:54:39.922 INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-06-07 08:54:39.923 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-06-07 08:54:39.929 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms
①、kubectl port-forward 临时暴露端口访问测试
把集群内 8080 端口映射到节点 8090,在 master 节点执行(在可以使用 kubectl 命令的节点都可以执行)
-
本机访问
默认只能本地访问 127.0.0.1(IPv4) 和 ::1 (IPv6)[root@master ~]# kubectl port-forward springboot-pod 8090:8080 Forwarding from 127.0.0.1:8090 -> 8080 Forwarding from [::1]:8090 -> 8080
重新打开一个 master 连接,因为使用 kubectl port-forward 是临时的,不能关闭,关闭即不起作用
[root@master ~]# curl 192.168.25.100:8090/k8s/test curl: (7) Failed connect to 192.168.25.100:8090; 拒绝连接 [root@master ~]# curl 127.0.0.1:8090/k8s/test {"msg":"ok","code":200,"record":{"请求方式:":"GET","耗时:":"0ms","接口:":"http://127.0.0.1:8090/k8s/test"}}
-
所有地址
使用 --address 0.0.0.0 指定所有地址都可访问[root@master ~]# kubectl port-forward springboot-pod --address 0.0.0.0 8080:8080 Forwarding from 0.0.0.0:8080 -> 8080
在宿主机使用虚拟机 master IP地址访问 http://192.168.25.100:8090/k8s/test
②、错误: open /run/flannel/subnet.env: no such file or directory`
报错:如果你运行 kubectl describe pod [pod-name]
报错错误 networkPlugin cni failed to set up pod "test-pod_default" network: open /run/flannel/subnet.env: no such file or directory
解决问题:先查看master节点有无 /run/flannel/subnet.env 文件,有则复制到其他节点,没有则新建文件添加如下内容,保证每个节点都有该文件
cat <<EOF >> /run/flannel/subnet.env
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
EOF
③、创建 pod 暴露端口
使用 DockerHub 镜像 redis:latest,创建一个 redis,暴露节点 6379 端口
apiVersion: v1
kind: Pod
metadata:name: redis
spec:# 指定 pod 到 node1 节点nodeName: node1containers:- name: redis # 容器名字image: redis:latestports:- containerPort: 6379hostPort: 6379
创建 pod
[root@master redis]# kubectl apply -f redis.yaml
pod/redis created
[root@master redis]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 47h 10.244.1.3 node1 <none> <none>
redis 1/1 Running 0 68s 10.244.1.16 node1 <none> <none>
测试:pod/redis 创建在 node1 192.168.25.101 节点,暴露端口为 6379,如下连接成功
3、创建 Deployment
Deployment 示例,新建 aliyun-private-springboot-deployment.yaml 文件添加如下内容,使用阿里云私人镜像部署三个 pod
apiVersion: apps/v1
kind: Deployment
metadata:# 部署名字name: test-k8s-deployment
spec:replicas: 3# 用来查找关联的 Pod,所有标签都匹配才行selector:matchLabels:app: test-k8s-deployment# 定义 Pod 相关数据template:metadata:labels:app: test-k8s-deploymentspec:# 定义容器,可以多个containers:- name: springboot-deployment # 容器名字image: registry.cn-zhangjiakou.aliyuncs.com/k8s-private/springboot:1.0 # 阿里云私人镜像imagePullSecrets:- name: mysecret
创建 Deployment 查看运行状态
# 创建 Deployment
kubectl apply -f aliyun-private-springboot-deployment.yaml
# 查看创建详情
kubectl describe deployment test-k8s-deployment
# 查看 pod 状态
kubectl get pod
kubectl get pod -o wide
# 获取 deployment 状态
kubectl get deployment
可以看到三个 pod 部署成功,两个在 node2 节点,一个在 node1 节点
命令行指定 pod 副本数量,可用于伸缩扩展副本
# 伸缩扩展副本
kubectl scale deployment test-k8s-deployment --replicas=5
可以看到副本由原来的三个变为五个,新增了两个
如果想访问测试可以使用 kubectl port-forward test-k8s-deployment-6d764f4b45-4hh6p --address 0.0.0.0 8888:8080
4、历史版本控制
- 新增一个镜像版本 registry.cn-zhangjiakou.aliyuncs.com/k8s-private/springboot:1.1
- 修改 aliyun-private-springboot-deployment.yaml 文件指定镜像版本为 1.1
- 重新使用 kubectl apply -f aliyun-private-springboot-deployment.yaml 部署
可以看到为灰度更新,一边销毁一边创建,始终保证有运行的 pod
查看部署详情 kubectl describe pod test-k8s-deployment-6c8c7d5b78-m55v5
,可以看到拉取 1.1版本
查看历史版本:kubectl rollout history deployment test-k8s-deployment
,可以发现有两个版本
版本回滚可以使用如下命令
# 回到上个版本
kubectl rollout undo deployment test-k8s-deployment
# 回到指定版本
kubectl rollout undo deployment test-k8s-deployment --to-revision=2
# 删除部署
kubectl delete deployment test-k8s-deployment
5、其他命令
# 强制删除资源
kubectl delete pod/speaker-n2jf2 pod/speaker-r8c7s --force --grace-period=0
# 查看全部
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
# 删除全部资源,pod 和 deployment
kubectl delete all --all
七、小妙招
在使用vim进行文档操作时,粘贴多行时,会出现错位、错乱(行注释极为明显)
解决办法:
vim进入文件后,先 ESC 再输入 :set paste
回车后再按下 i /a 之后进行粘贴集不会乱码
八、遗留问题
- 每次只能访问一个 pod,没有负载均衡自动转发到不同 pod
- 访问还需要端口转发
- Pod 重新创建后 IP 变了,名字也变了
下一篇使用 Service 解决这些问题