文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Docker 是什么?K8s又是什么?如何从 0 到 1 实战 Docker 与 K8s 全流程部署?

2024-11-28 14:08

关注

一、原理部分

1. Docker

Docker是一个容器化平台,它允许开发者将应用及其依赖项打包到一个称为容器的标准化单元中,以便可以在不同环境中快速、可靠地运行这些应用。它的本质是利用操作系统的Cgroups和Namespace机制创建出来的隔离环境。更多详情参考我以往的文章:容器 = Namespace + Cgroups + rootfs

Docker核心概念包括以下几个:

(1) Kubernetes核心概念

① 镜像:Docker(Image)镜像是一个轻量级、独立、可执行的软件包,其中包含运行某个应用程序所需的所有内容,包括代码、运行时、库、环境变量和配置文件。镜像是不可变的,基于镜像可以创建容器。

② 容器:容器(Container)是镜像的运行实例,它是一个轻量级、独立的环境,可以在任何支持 Docker的机器上运行。容器与主机系统共享操作系统内核,但在进程空间上是隔离的。

③ Dockerfile:Dockerfile是一个文本文件,包含构建 Docker镜像的所有命令,可以通过 Dockerfile来自动化镜像的创建过程。

④ Docker Hub:Docker Hub是一个云端的 Docker镜像存储库,用户可以在上面发布和获取镜像,它提供了一个平台来共享和管理镜像。

⑤ 容器编排:Docker Compose是一种定义和运行多容器 Docker应用程序的工具,通过一个docker-compose.yml文件,用户可以定义一个应用包含的所有服务,并使用简单的命令启动或停止它们。

Docker容器可以描述成以下全景图(图片来自极客张磊):

(2) Docker的优点

Docker的优点可以用一句话总结:一次打包,到处部署。这个和 JVM一次编译,到处运行的设计有着异曲同工之妙,所以说,计算机领域很多思维是相通的!

下图对比了使用与不使用 Docker的场景:

2. Kubernetes

Kubernetes(K8s) 一词源自希腊,意为“舵手”或“掌舵者”,用于指导和管理船只的航行。它是一个容器编排平台,负责自动化容器的部署、扩展(水平扩展)、负载均衡、以及故障恢复等工作。

Kubernetes的核心概念包括以下几个:

(1) Kubernetes核心概念

① 节点:节点(Node)是 Kubernetes集群中的一台物理机或虚拟机,负责运行应用程序的工作负载。每个节点运行一个Kubelet(用于管理节点上的容器)和一个容器运行时(例如Docker)。

② Pod:Pod是 Kubernetes中最小的可部署单元,通常包含一个或多个容器。Pod中的容器共享网络和存储,可以协同工作。

③ 控制器:控制器(Controller)负责管理和维护集群中的Pod和相关的服务。常见的控制器有 ReplicaSet(确保指定数量的Pod副本在运行)、Deployment(管理无状态应用)和 StatefulSet(管理有状态应用)。

④ 服务:服务(Service)是一个抽象的方式,用于定义一组Pod的逻辑集合以及访问这些 Pod的策略。Kubernetes中的服务提供了负载均衡和服务发现功能。

⑤ 命名空间:命名空间(Namespace)用于在同一个 Kubernetes集群中将资源进行逻辑上的隔离。它允许多个团队或项目共享一个集群而不会相互影响。

⑥ 配置管理:配置管理包含 ConfigMap 和 Secret。ConfigMap 用于存储非机密的数据,类似配置文件。Secret用于存储机密数据,如密码、OAuth令牌和SSH密钥。

⑦ Ingress:Ingress是一个 API对象,管理外部访问到集群中服务的 HTTP和 HTTPS路由。它提供负载均衡、SSL终止和基于名称的虚拟托管等功能。

⑧ Deployment:Deployment是一个用于管理无状态应用程序的核心组件。它提供了一种声明式的方法来管理 Pod和 ReplicaSet,从而实现应用程序的部署、升级和扩缩。

Kubernetes可以描述成以下全景图(图片来自极客张磊):

(2) Kubernetes 的工作流程

Kubernetes 的整体工作流程可以总结成下面 6个步骤:

整个流程如下图:

3. 两者关系

Docker提供容器化机制,用于封装和打包应用,并利用 CI/CD管道将容器镜像推送至中央容器注册中心(如 Docker Hub 或 Harbor),而 Kubernetes是一个强大的容器编排平台,负责调度、扩展和管理 Docker容器化应用,保证系统高可用、故障自动恢复。

从宏观上看,两者关系可以通过下图来形象的表达:

好了,理论部分讲解完后,我们正式进入代码实战部分,俗话说:说起来容易做起来难,对于 Kubernetes集群还真有点难度,来,上干货!!!

二、代码实战

1. 目的

开发一个简单的 Java Web应用,并将其 Docker容器化部署到 Kubernetes集群中,然后在浏览器访问,展示:Hello world, This is my docker running in Kubernetes!。

2. 步骤

整体流程核心步骤有下面几个:

(1) 安装环境

首先,需要确保我们安装了以下环境:JDK(Java Development Kit), Gradle(Maven),Docker, Kubernetes,下面是我安装的版本:

JDK 版本:

Gradle版本:

Docker 版本:我使用的是 Mac Pro 电脑,直接使用 brew安装:

brew install --cask docker

Kubernetes 版本:

我使用的是 Mac Pro电脑,直接使用 brew安装:

brew install kubectl

注意:Gradle 和 Maven 是项目管理工具,只要安装一个就OK,自己熟悉哪个就安装哪个。

(2) 创建Java Web应用

① 创建Gradle(Maven)项目

创建一个 Springboot 项目,整个目录结构如下:

在src/main/cloud/com/yuanjava/docker目录下创建一个新的 Java类,如HelloController.java:

package com.yuanjava.docker;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
   @GetMapping("/test")
   public String test() {
      return "Hello world, This is my docker running in Kubernetes!";
   }
}

② Gradle(Maven)打包项目:

Gradle打包指令如下:

gradle build

这里在 build/libs 目录下就就会看到打包后的 jar包:

(3) 容器化 Java Web应用

① 编写Dockerfile:

在项目根目录下创建一个Dockerfile:

FROM openjdk:17-jdk-slim
COPY build/libs/yuanjava-1.0.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

② 构建Docker镜像:

在当前目录,运行以下命令就可以构建 Docker镜像,-t的作用是给这个镜像加一个Tag,也就是起一个好听的名字。

docker build -t yuanjava:1.0 .

运行完上面的指令之后,就可以在 Docker镜像库看到刚才打的镜像了,可以使用docker images指令查看镜像:

docker images

也可以通过 Docker的可视化工具查看镜像:

③ 运行Docker容器

我们可以通过下面的命令来启动 Docker容器:

docker run -p 9999:9999 yuanjava:1.0

然后,在浏览器中访问http://localhost:9999/test来测试 Docker是否启动完成。访问结果如下图:

④ 推送 Docker镜像到远程仓库

这一步是为了下面将 Docker镜像部署到 Kubernetes集群做准备,推送命令如下:

docker push yuanjava:1.0

推送完之后,远程仓库就多了一个镜像,如下图所示:

注意:如果没有 Docker账号,需要先创建账号。

(4) 部署到Kubernetes集群

① 启动 Kubernetes集群

通常来说,我们会使用minikube命令来启动和管理 Kubernetes 集群,安装和启动命令如下:

# 安装 minikube
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
chmod +x minikube
sudo mv minikube /usr/local/bin/

# 启动 Kubernetes集群
minikube start

② 编写Kubernetes Deployment配置

创建一个deployment.yaml文件,内容如下:

apiVersion: apps/v1 # 定义了 Kubernetes API 的版本
kind: Deployment    # 声明这个 Kubernetes 资源的类型
metadata:
 name: yuanjava     # 包含资源的元数据,Kubernetes 通过 metadata 字段中的各类信息来跟踪和管理资源
spec:
 replicas: 2       # Pod的副本数量,即 Deployment将运行 2个相同的 Pod
 selector:
   matchLabels:
     app: yuanjava # 告诉 Deployment 如何找到它管理的 Pod
 template:
   metadata:
     labels:
       app: yuanjava # 定义 Pod 的模板
   spec:
     containers:
     - name: yuanjava
       image: yuanjava/yuanjava:1.0 #定义容器使用的镜像,Kubernetes 会从容器镜像仓库中拉取它
       ports:
       - containerPort: 9999     # 指定容器内部监听的应用端口

③ 编写Kubernetes Service配置

创建一个service.yaml文件,内容如下:

apiVersion: v1
kind: Service # 用于描述和管理向外部或者内部暴露应用的网络访问方式
metadata:
  name: yuanjava # 包含资源的元数据信息
spec:
  type: LoadBalancer # 定义了服务的类型,LoadBalancer 类型会将服务暴露给外部网络
  ports:
  - port: 80  # 这是对外暴露的端口,表示外部客户端访问服务时使用的端口号
    targetPort: 9999 # 这是集群内部目标 Pod 上运行的容器所监听的端口
  selector:
    app: yuanjava

④ 部署到Kubernetes

我们可以使用kubectl命令应用配置,命令说明如下:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

⑤ 验证部署

使用以下命令检查 Pods和 Service状态:

kubectl get pods
kubectl get services

如下图,2个 Pod都处于 Running 状态:

(5) 浏览器验证

最后,我们可以在浏览器中访问,验证应用是否成功部署到 Kubernetes 集群,访问地址是:http://EXTERNAL-IP/hello ,如下图:

因为,我是本地部署,所以EXTERNAL-IP地址为,即未分配,但是可以通过minikube service yuanjava查看 IP地址,如下图所示:

最后,打开地址http://192.168.49.2:63213/test, 见证奇迹的时刻到了:

因为是本地环境,所以链接最终会跳转到http://127.0.0.1:63213/test 。

到此,我们就成功地手动将 Docker镜像部署到 Kubernetes集群,并且通过 URL能够访问,过程很艰辛,结果还是比较美好。

但是,如果要部署大量的机器,这样手动操作肯定是不行,因此,我们需要结组一些 CI/CD工具(如 GitHub Actions、GitLab CI/CD 或 Jenkins)实现自动化 Docker镜像构建和 Kubernetes 部署。

这里以 GitHub Actions为例,创建 .github/workflows/auto-deploy.yaml:

name: Auto Deploy Application to Kubernetes

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    # Step 1: 检出代码
    - name: Checkout code
      uses: actions/checkout@v3

    # Step 2: 登录 Docker Registry
    - name: Log in to Docker Hub
      run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

    # Step 3: 构建并推送 Docker 镜像
    - name: Build and push Docker image
      run: |
        docker build -t ${{ secrets.DOCKER_USERNAME }}/yuanjava:latest .
        docker push ${{ secrets.DOCKER_USERNAME }}/yuanjava:latest

    # Step 4: 设置 kubectl
    - name: Set up kubectl
      uses: azure/setup-kubectl@v3
      with:
        version: 'latest'

    # Step 5: 配置 kubeconfig 文件
    - name: Configure kubeconfig
      run: |
        echo "${{ secrets.KUBECONFIG }}" > kubeconfig
        export KUBECONFIG=kubeconfig

    # Step 6: 部署到 Kubernetes
    - name: Apply Kubernetes manifests
      run: |
        kubectl apply -f deployment.yaml
        kubectl apply -f service.yaml

关键说明:

三、总结

本文,我们先从理论上分析了 Docker 和 Kubernetes的核心概念以及它们之间的关系。

接着,我们从代码实战的角度,带大家一步一步实操了如何编写一个简单的 Java Web应用,并将其 Docker容器化,最后部署到 Kubernetes集群中,然后在浏览器访问。在实操的期间,因为所有的环境都是本地环境临时搭建,所以遇到了很多的问题,但最终还是成功了。

通过这次实操,再次说明了做技术不能只停留在理论,实操很重要,实操期间我们可能遇到很多问题,但是,当我们通过各种方式去解决问题的时候,这个过程其实就是对技术更深入的学习和掌握。

个人建议:

Docker是云原生很重要相对简单的一个技术基础,强烈建议掌握并且一定要去实战。Kubernetes的难度系统会比 Docker大,它为大量容器提供调度、资源管理、弹性伸缩等功能,如果使用的机器数量比较少,Kubernetes其实很难用上,但是,如果可以,还是建议我们创造条件在实际生产环境中去使用和学习 Kubernetes。相信我,这种有压力的学习效果贼棒!

来源:猿java内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯