容器 & 服务:K8s 与 Docker 应用集群 (二)

简介: 本篇介绍了kubernete的关键概念:pods 和 工作节点,描述了大概的架构和运行时结构。然后,基于上一篇的基础,重新使用k8s的kubectl命令部署我们自己的demo应用,并分析解决过程中遇到的问题。下一张将会进一步阐述原理,并对demo进行丰富。

一 概述

容器 & 服务:K8s 与 Docker 应用集群 (一)中,我们通过解决之前的一个遗留问题,初步了解了k8s的一些基础命令,做了一个应用部署。本篇将继续介绍k8s的一些原理,并优化应用demo。

二 K8s Pods与工作节点

为保证内容的准确性,本章内容主要来自kubernetes的官方文档。

2.1 kubernetes pods

与docker直接创建启动容器不同,Kubernates添加了一个Pod来托管我们的应用实例。Pod是K8s抽象出来的,用于表示一组一个,或一组多个应用程序容器(例如Docker),一级这些容器的一些共享资源。这些资源包括:

  • 共享存储,当做卷
  • 网络,作为唯一的集群IP地址
  • 有关每个容器如何运行的信息,例如容器映像版本或要使用的特定端口

Pod为特定于应用程序的『逻辑主机』建模,并且可以包含相对紧耦合的不同应用容器。例如,Pod 可能既包含带有 Node.js 应用的容器,也包含另一个不同的容器,用于提供 Node.js 网络服务器要发布的数据。Pod 中的容器共享 IP 地址和端口,始终位于同一位置并且共同调度,并在同一工作节点上的共享上下文中运行。

Pod是 Kubernetes 平台上的原子单元。 当我们在 Kubernetes 上创建 Deployment 时,该 Deployment 会在其中创建包含容器的 Pod (而不是直接创建容器)。每个 Pod 都与调度它的工作节点绑定,并保持在那里直到终止(根据重启策略)或删除。 如果工作节点发生故障,则会在群集中的其他可用工作节点上调度相同的 Pod。

几个Pods示例:

2.2 k8s 工作节点

一个 pod 总是运行在 工作节点。工作节点是 Kubernetes 中的参与计算的机器,可以是虚拟机或物理计算机,具体取决于集群。每个工作节点由主节点管理。工作节点可以有多个 pod ,Kubernetes 主节点会自动处理在群集中的工作节点上调度 pod 。 主节点的自动调度考量了每个工作节点上的可用资源。

每个 Kubernetes 工作节点至少运行:

  • Kubelet,负责 Kubernetes 主节点和工作节点之间通信的过程; 它管理 Pod 和机器上运行的容器。
  • 容器运行时(如 Docker)负责从仓库中提取容器镜像,解压缩容器以及运行应用程序。

工作节点示例:

三 k8s部署demo应用

前面容器 & 服务:Docker 应用的 Jenkins 构建 (二)中,我们在github上提交过一个demo,通过docker run 、 docker-compose up 和 docker stack deploy 命令分别部署过应用。这里我们尝试使用k8s来执行部署。

3.1 使用本地镜像

3.1.1 查看并使用本地镜像部署

bogon xxx$ docker images
REPOSITORY                           TAG                   IMAGE ID            CREATED             SIZE
dockerdemoapplication1               latest                a0ea39905467        8 days ago          122MB
nginx                                latest                f6d0b4767a6c        7 weeks ago         133MB
flamingskys/java-demo                latest                8c8971d2d351        5 months ago        406MB
k8s.gcr.io/kube-apiserver            v1.14.8               1e94481e8f30        16 months ago       209MB
k8s.gcr.io/kube-proxy                v1.14.8               849af609e0c6        16 months ago       82.1MB
k8s.gcr.io/kube-controller-manager   v1.14.8               36a8001a79fd        16 months ago       158MB
k8s.gcr.io/kube-scheduler            v1.14.8               f1e3e5f9f93e        16 months ago       81.6MB
kubernetesui/metrics-scraper         v1.0.1                709901356c11        19 months ago       40.1MB
docker/kube-compose-controller       v0.4.23               a8c3d87a58e7        21 months ago       35.3MB
docker/kube-compose-api-server       v0.4.23               f3591b2cb223        21 months ago       49.9MB
openjdk                              8u201-jdk-alpine3.9   3675b9f543c5        23 months ago       105MB
k8s.gcr.io/coredns                   1.3.1                 eb516548c180        2 years ago         40.3MB
k8s.gcr.io/etcd                      3.3.10                2c4adeb21b4f        2 years ago         258MB
k8s.gcr.io/pause                     3.1                   da86e6ba6ca1        3 years ago         742kB

能看到我们之间创建的镜像还在:dockerdemoapplication1,那么根据上一篇的kubectl create命令创建pod:

bogon xxx$ kubectl create deployment dockerdemoapplication1 --image=dockerdemoapplication1
deployment.apps/dockerdemoapplication1 created

暴露端口:

bogon xxx$ kubectl expose deployment/dockerdemoapplication1 --type="NodePort" --port 8088
service/dockerdemoapplication1 exposed

查看pod:

额,又是ImagePullBackOff?什么鬼,这是一个本地镜像啊。

用docker run 简单粗暴验证一下试试:

bogon xxx$ docker run -d -t -p 18081:8080 --name dockerdemoapplication1 dockerdemoapplication1
Unable to find image 'dockerdemoapplication1:latest' locally

找不到镜像。。

3.1.2 失败原因分析

怀疑是否使用方式不对,但docker也无法运行,那么可能是数据丢失导致镜像失效。重新构建镜像试一下:

bogon xxx$ docker build -t dockerdemoapplication1 .
Sending build context to Docker daemon     17MB
Step 1/7 : FROM openjdk:8u201-jdk-alpine3.9
 ---> 3675b9f543c5
Step 2/7 : MAINTAINER flamingstar <575912990@qq.com>
 ---> Running in fe92c7cca0e8
Removing intermediate container fe92c7cca0e8
 ---> 5eb4b2e2c65e
Step 3/7 : ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
 ---> Running in d6bef87ba5c8
Removing intermediate container d6bef87ba5c8
 ---> 4bb0bc8d3bed
Step 4/7 : VOLUME /tmp
 ---> Running in 4ce6a5581444
Removing intermediate container 4ce6a5581444
 ---> c677b3d055f0
Step 5/7 : ADD target/dockerdemo-1.0.0-SNAPSHOT.jar dockerdemo.jar
 ---> 6b6bc359bc3f
Step 6/7 : ENTRYPOINT ["java","-jar","/dockerdemo.jar"]
 ---> Running in c2d3347ef496
Removing intermediate container c2d3347ef496
 ---> a656e3f3f503
Step 7/7 : EXPOSE 8080
 ---> Running in ab53e5610ead
Removing intermediate container ab53e5610ead
 ---> a9e63d4e9118
Successfully built a9e63d4e9118
Successfully tagged dockerdemoapplication1:latest

再次docker run:

bogon xxx$ docker run -d -t -p 18081:8080 --name dockerdemoapplication1 dockerdemoapplication1
53ac95a804592adc4c94688a925b905da39a5838ae0f38f95e3839499eaff367

docker运行成功。停掉docker容器,再次用k8s部署:

bogon xxx$ kubectl create deployment dockerdemoapplication1 --image=dockerdemoapplication1
deployment.apps/dockerdemoapplication1 created

再次查看pod:

还是失败。

3.1.3 再次分析

查看pod详情: kubectl describe pod dockerdemoapplication1-5549fdf7fd-zxfbx ,输出信息如下,重点在Events部分:

kubelet, docker-desktop  Failed to pull image "dockerdemoapplication1": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

 Normal   SandboxChanged  6m43s                   kubelet, docker-desktop  Pod sandbox changed, it will be killed and re-created.

kubelet, docker-desktop  Failed to pull image "dockerdemoapplication1": rpc error: code = Unknown desc = Error response from daemon: pull access denied for dockerdemoapplication1, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

由此可看到错误信息。尽管我们意图是使用本地镜像,但kubelet实际上是从仓库中拉取:https://registry-1.docker.io/v2/

repository does not exist or may require 'docker login': denied: requested access to the resource is denied

这个信息就更加明确,仓库不存在,或需要docker login,被拒绝。

3.1.4 解决

既然是打开方式不对,那么先考虑把镜像push到仓库就可以了。

3.1.4.1 推送命令

推送镜像规范
docker push 注册用户名/镜像名
1)执行推送
bogon xxx$ docker push dockerdemoapplication1:latest 
The push refers to repository [docker.io/library/dockerdemoapplication1]
62e73adb4aec: Preparing 
ee610d18148e: Preparing 
dee6aef5c2b6: Preparing 
a464c54f93a9: Preparing 
denied: requested access to the resource is denied

失败,报了denied。 一般是没有在本地终端执行docker login导致,所以进行

2)登录操作
bogon xxx$ docker login
Authenticating with existing credentials...
Login did not succeed, error: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (flamingskys): flamingskys
Password: 
Login Succeeded
3)登录成功后再次执行1)

4)重新构建镜像

错误不意外,因为按照规范,我们push要指定仓库,这点和github类似。而上面的镜像没有指定默认仓库(账号),直接裸传出错是正常的。所以重新构建镜像(注意别忘了,在工程所在的目录下执行):

docker build -t flamingskys/dockerdemoapplication1 .
5)正式push镜像
bogon xxx$ docker push flamingskys/dockerdemoapplication1:latest 
The push refers to repository [docker.io/flamingskys/dockerdemoapplication1]
62e73adb4aec: Pushed 
ee610d18148e: Pushed 
dee6aef5c2b6: Pushed 
a464c54f93a9: Pushed 
latest: digest: sha256:afed6ab41808512962a50b0521ca9f5d870f4c6281114656e396f44d85c0019f size: 1159
6)kubectl部署

有了远程镜像,我们再次尝试创建deployment(记得要先删除之前创建失败的deployment):

然后查看pod状态,终于成功了! ————————这只是内心OS,然而并没有。。。查看pod详情,发现报错信息如下:

关键错误信息:

Get https://registry-1.docker.io/v2/flamingskys/dockerdemoapplication1/manifests/latest: net/http: TLS handshake timeout

Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout

网络TLS握手超时,看起来是网络的问题,但可以确定,是从我们指定的位置拉取镜像了,只是家里的破网不够给力。ok,删掉deployment再重试一次:

容器还在创建中,describe一下pod详情:

bogon xxx$ kubectl describe pod dockerdemoapplication1-648f767cff-dd5t7
Name:               dockerdemoapplication1-648f767cff-dd5t7
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               docker-desktop/192.168.65.3
Start Time:         Fri, 05 Mar 2021 22:02:27 +0800
Labels:             app=dockerdemoapplication1
                    pod-template-hash=648f767cff
Annotations:        <none>
Status:             Pending
IP:                 
Controlled By:      ReplicaSet/dockerdemoapplication1-648f767cff
Containers:
  dockerdemoapplication1:
    Container ID:   
    Image:          flamingskys/dockerdemoapplication1
    Image ID:       
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-62ccr (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  default-token-62ccr:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-62ccr
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                     Message
  ----    ------     ----  ----                     -------
  Normal  Scheduled  20s   default-scheduler        Successfully assigned default/dockerdemoapplication1-648f767cff-dd5t7 to docker-desktop
  Normal  Pulling    19s   kubelet, docker-desktop  Pulling image "flamingskys/dockerdemoapplication1"

最后Events 中的Successfully,终于成功。

别高兴过早,还有一个步骤没做呢。

7)暴露服务

使用18081端口吧,避免冲突:

bogon xxx$ kubectl expose deployment/dockerdemoapplication1 --type="NodePort" --port 18081
Error from server (AlreadyExists): services "dockerdemoapplication1" already exists

services已存在,是之前发布的遗留问题,先执行删除后再暴露一次:

bogon xxx$ kubectl delete service dockerdemoapplication1
service "dockerdemoapplication1" deleted
bogon xxx$ kubectl expose deployment/dockerdemoapplication1 --type="NodePort" --port 18081
service/dockerdemoapplication1 exposed

至此,应用部署成功。

四 总结

   本篇介绍了kubernete的关键概念:pods 和 工作节点,描述了大概的架构和运行时结构。然后,基于上一篇的基础,重新使用k8s的kubectl命令部署我们自己的demo应用,并分析解决过程中遇到的问题。下一张将会进一步阐述原理,并对demo进行丰富。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
9天前
|
监控 Linux 开发者
Docker服务systemd配置文件详解
Docker服务systemd配置文件详解
18 0
|
2天前
|
存储 安全 开发者
【Docker 专栏】Docker 与云存储服务的集成
【5月更文挑战第9天】在数字化时代,Docker和云存储服务的结合为企业和开发者提供了强大工具。Docker的高效性、可移植性和隔离性,加上云存储的扩展性、高可靠性和高可用性,通过集成可以实现数据持久化、便捷部署和资源优化。常见的集成包括AWS S3、Azure Blob Storage和Google Cloud Storage。集成时需注意安全、性能和兼容性问题,未来集成将更加紧密和智能化,助力企业创造更大价值。
【Docker 专栏】Docker 与云存储服务的集成
|
2天前
|
机器学习/深度学习 监控 Kubernetes
【Docker 专栏】Docker 容器内服务的自动扩展与缩容
【5月更文挑战第9天】本文探讨了Docker容器服务的自动扩展与缩容原理及实践,强调其在动态业务环境中的重要性。通过选择监控指标(如CPU使用率)、设定触发条件和制定扩展策略,实现资源的动态调整。方法包括云平台集成和使用Kubernetes等框架。实践中,电商平台和实时数据处理系统受益于此技术。注意点涉及监控数据准确性、扩展速度和资源分配。未来,智能算法将提升扩展缩容的效率和准确性,成为关键技术支持。
【Docker 专栏】Docker 容器内服务的自动扩展与缩容
|
2天前
|
Kubernetes Java API
Kubernetes详解(三)——Kubernetes集群组件
Kubernetes详解(三)——Kubernetes集群组件
12 1
|
3天前
|
监控 Docker 容器
【Docker 专栏】Docker Swarm 集群的扩展与缩容策略
【5月更文挑战第8天】本文探讨了Docker Swarm集群的扩展与缩容策略。集群扩展可提高性能、增强可用性和适应业务发展,可通过手动或自动方式实现。缩容则需考虑业务需求、资源利用率和节点状态,可手动或按策略执行。关键步骤包括添加/移除节点及任务迁移。注意数据同步、监控评估和测试验证。案例分析和总结强调了灵活管理对保持集群最佳状态的重要性。
【Docker 专栏】Docker Swarm 集群的扩展与缩容策略
|
3天前
|
存储 关系型数据库 Linux
CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件
CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件
26 4
|
7天前
|
运维 监控 Kubernetes
Kubernetes 集群的监控与维护策略
【5月更文挑战第4天】 在当今微服务架构盛行的时代,容器化技术已成为软件开发和部署的标准实践。Kubernetes 作为一个开源的容器编排平台,因其强大的功能和灵活性而广受欢迎。然而,随着 Kubernetes 集群规模的扩大,集群的监控和维护变得日益复杂。本文将探讨 Kubernetes 集群监控的重要性,分析常见的监控工具,并提出一套有效的集群维护策略,以帮助运维人员确保集群的健康运行和高可用性。
39 10
|
8天前
|
存储 运维 监控
Kubernetes 集群的持续监控与优化策略
【5月更文挑战第3天】在微服务架构和容器化部署日益普及的背景下,Kubernetes 已成为众多企业的首选容器编排平台。然而,随着集群规模的增长和业务复杂度的提升,有效的集群监控和性能优化成为确保系统稳定性和提升资源利用率的关键。本文将深入探讨针对 Kubernetes 集群的监控工具选择、监控指标的重要性解读以及基于数据驱动的性能优化实践,为运维人员提供一套系统的持续监控与优化策略。
|
11天前
|
运维 Kubernetes 监控
Kubernetes 集群的监控与维护策略
【4月更文挑战第30天】 在现代云计算环境中,容器化技术已成为应用程序部署和管理的重要手段。其中,Kubernetes 作为一个开源的容器编排平台,以其强大的功能和灵活性受到广泛欢迎。然而,随之而来的是对 Kubernetes 集群监控和维护的复杂性增加。本文将探讨针对 Kubernetes 集群的监控策略和维护技巧,旨在帮助运维人员确保集群的稳定性和高效性。通过分析常见的性能瓶颈、故障诊断方法以及自动化维护工具的应用,我们将提供一套实用的解决方案,以优化 Kubernetes 环境的性能和可靠性。
|
11天前
|
运维 Kubernetes 监控
Kubernetes集群的持续性能优化策略
【4月更文挑战第30天】 在动态且不断扩展的云计算环境中,保持应用性能的稳定性是一个持续的挑战。本文将探讨针对Kubernetes集群的持续性能优化策略,旨在为运维工程师提供一套系统化的性能调优框架。通过分析集群监控数据,我们将讨论如何诊断常见问题、实施有效的资源管理和调度策略,以及采用自动化工具来简化这一过程。