k8s入门:部署应用到 k8s 集群

系列文章

第一章:✨ 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)



参考文章: 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

官方文档

二、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: http
          containerPort: 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: mysecret
  namespace: default
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ewoJImF1dGh*************************************************************************************************gkJfQoJfQp9

创建并检查 secret 凭证

kubectl apply -f registry-secret.yaml  # 创建secret

kubectl 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 node1
  Normal  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.659996621s
  Normal  Created    29s   kubelet            Created container springboot
  Normal  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
networkPlugin cni failed to set up pod "test-k8s-68bb74d654-mc6b9_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: node1
  containers:
    - name: redis # 容器名字
      image: redis:latest
      ports:
        - containerPort: 6379
          hostPort: 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-deployment
    spec:
      # 定义容器,可以多个
      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 解决这些问题

  • 5
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值