企业级Devops— 打造完整 CICD 实践指南(八):容器化实战

🐳 容器化实战:应用上云

前面搭建好了jenkins和K8s集群,现在我们来编写配置文件

🐳 Dockerfile文件详解

Dockerfile定义了一个构建镜像过程。

各个名词解释:

  • FROM :Dockerfile的第一条指令,用来指定基础镜像。在这里,镜像基于openjdk:17,它是一个包含JDK17的官方Docker镜像。
  • ENV:用于设置环境变量。
  • RUN:用于在镜像构建时执行命令。
  • ADD:用于将文件从宿主机复制到容器中
  • WORKDIR: 设置工作目录
  • ENTRYPOINT: 定义容器启动时默认执行命令
  • EXPOSE: 用于在容器内部声明该容器会监听的网络端口

📄 Kubernetes YAML文件详解

Kubernetes YAML文件包含两个主要部分:一个Deployment和一个Service。

各个名词解释:

  • Pod : K8S中最小调度单元,通常是一个或多个容器的集合,具有共享网络和存储。
  • Deployment : 用于管理Pod的生命周期,包括副本的自动扩缩容、滚动更新和回滚,确保应用程序的高可用性和稳定性。
  • Service : 为一组Pod提供稳定的访问入口,负责负载均衡和服务发现。它通过DNS名称和虚拟IP地址,使得客户端能够访问到对应的Pod。
  • apiVersion: 指定资源版本
  • metadata :元数据部分;name指定Deployment的名字,namespace执行Deployment部署的命名空间,label指定Deployment的标签
  • spec : 指定Deployment的详细规格,如:Pod副本数、镜像地址、端口、容器名称、容器可使用资源、凭证等。

👨‍💻 后端

在release-test根目录添加Dockerfile和k8s-releasetest.yaml两个文件并提交到远程仓库

🐳 Dockerfile

dockerfile 复制代码
FROM openjdk:17

ENV JAVA_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED"

RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone

ADD target/release-test-*.jar /data/release-test-0.0.1.jar

WORKDIR /data

ENTRYPOINT ["/bin/sh", "-c", "java ${JAVA_OPTS} -jar release-test-0.0.1.jar"]

EXPOSE 30001

📄 k8s-releasetest.yaml

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: release-test
  namespace: $NAMESPACE
  labels:
    app: release-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: release-test
  template:
    metadata:
      name: release-test
      labels:
        app: release-test
    spec:
      containers:
        - name: release-test
          image: $REGISTRY/$PROJECT/$IMAGENAME:$TAGS
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 30001
              protocol: TCP
          resources:
            requests:
              memory: "0.5G"
              cpu: "0.2"
            limits:
              memory: "1G"
              cpu: "0.5"
      imagePullSecrets:
        - name: harbor-k8s-secret
      restartPolicy: Always
      
---

apiVersion: v1
kind: Service
metadata:
  name: release-test
  namespace: $NAMESPACE
spec:
  type: NodePort
  ports:
    - port: 30001
      name: release-test
      protocol: TCP
      targetPort: 30001
      nodePort: 30001
  selector:
    app: release-test

👩‍💻 前端

在release-frontend根目录添加Dockerfile和k8s-reelasefrontend.yaml两个文件并提交到远程仓库。

🐳 Dockerfile

dockerfile 复制代码
FROM nginx:latest
ENV ENV LANG en_US.UTF-8
# 同步时区及时间
RUN ln -snf /usr/share/zoneinfo/Asia/ShangHai /etc/localtime && echo 'Asia/ShangHai' > /etc/timezone

ADD dist/ /data/www/
RUN sed -i 's/#gzip on/gzip on/g' /etc/nginx/nginx.conf
RUN sed -i '/index  index.html index.htm/a\      try_files \$uri \$uri/ \/index.html;' /etc/nginx/conf.d/default.conf
RUN sed -i 's|/usr/share/nginx/html|/data/www/|g' /etc/nginx/conf.d/default.conf

WORKDIR /data/www/
ENTRYPOINT [ "nginx", "-g", "daemon off;" ]

EXPOSE 30002

📄 k8s-reelasefrontend.yaml

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: release-frontend
  namespace: $NAMESPACE
  labels:
    app: release-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: release-frontend
  template:
    metadata:
      name: release-frontend
      labels:
        app: release-frontend
    spec:
      containers:
        - name: release-frontend
          image: $REGISTRY/$PROJECT/$IMAGENAME:$TAGS
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80 # nginx端口号
              protocol: TCP
          resources:
            requests:
              memory: "0.5G"
              cpu: "0.2"
            limits:
              memory: "1G"
              cpu: "0.5"
      imagePullSecrets:
        - name: harbor-k8s-secret
      restartPolicy: Always
      
---

apiVersion: v1
kind: Service
metadata:
  name: release-frontend
  namespace: $NAMESPACE
spec:
  type: NodePort
  ports:
    - port: 30002
      name: release-frontend
      protocol: TCP
      targetPort: 80
      nodePort: 30002
  selector:
    app: release-frontend

📝 创建命名空间

🖥️ 机器B中创建

前面的配置文件中可以看到namespace为:$NAMESPACE。

$NAMESPACE变量的值根据不同环境(开发、测试、生产)不同,这里我们以开发环境为例,在k8s集群服务器中执行下面命令:

bash 复制代码
kubectl create namespace develop

🛠️ 配置 Kubernetes Secret 以访问私有 Harbor

🖥️ 机器B中创建

前面的配置文件中可以看到imagePullSecrets的name为:harbor-k8s-secret, kubelet拉取镜像时需要验证是否有权限拉取。 当没有配时,拉取镜像会报:pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials。

  • 创建 Kubernetes Secret : 使用 kubectl create secret docker-registry 命令创建Secret,确保提供正确的Harbor服务器地址、用户名和密码。

    bash 复制代码
    kubectl create secret docker-registry harbor-k8s-secret \
      --docker-server=https://xxx \
      --docker-username=<your-username> \
      --docker-password=<your-password> \
      --docker-email=<your-email> \
      -n develop

    这个命令会在develop命名空间下创建一个名为 harbor-k8s-secret 的Secret。 ⚠️ 注意 :xxx必须和k8s yaml文件中镜像地址一致,如:images: xxx/test:2024110215014382。

  • 在 Pod 或 Deployment 中引用 Secret : 在你的Pod或Deployment的YAML文件中,需要指定 imagePullSecrets,以便Kubernetes在拉取镜像时使用该Secret。

🔒 配置服务器安全组规则

  • k8s所在服务器的ip地址需要添加到harbor(https一般为443端口)所在服务器的安全组规则中
  • jenkins所在服务器的ip地址需要 添加到harbor(https一般为443端口)所在服务器的安全组规则中
相关推荐
Ikalus198810 小时前
假成功有四种形状:给 AI 写自动化工具的自检清单
自动化运维
johnsmithCA10 小时前
给搜索的法规条文做了个「版本核验」流程:怎么确认手上的条文还是现行有效版
人工智能·自动化运维
liangshanbo12152 天前
面试题:AI 对话上下文超限怎么办?
面试·webpack·devops
海海不掉头发4 天前
软件项目管理学习笔记-从软件危机到敏捷与DevOps
笔记·学习·devops
效率工作实验室4 天前
AI Agent 管理平台如何与现有 DevOps 和 ITSM 体系集成?
ai·agent·devops·集成·管理平台
极小狐5 天前
CI 作业里 kubectl 连不上集群?用 Kubernetes Agent 打通部署链路的 7 个步骤
ci/cd·kubernetes·gitlab·devops·k8s部署
天天喝旺仔5 天前
CI/CD 实战:GitHub Actions 自动化构建、测试与发布流水线
ci/cd·自动化·github·devops·持续集成
小稀土1235 天前
内网私有化部署 DevOps 软件落地指南:8 个坑、6 个步骤,一次讲清
devops
cakeism8255 天前
金融行业 DevOps 平台推荐:2026年主流方案对比与 Gitee 选型解析
金融·gitee·devops
智能运维指南5 天前
研发效能平台建设路径:从工具堆砌到价值流驱动的效能革命
devops·研发效能度量·嘉为蓝鲸·研发效能平台