图图
发布于 2023-11-06 / 46 阅读 / 0 评论 / 1 点赞

Jenkins+K8s发布golang应用

准备工作

  • 安装docker

  • 安装kubenets

流程演示

Jenkins使用安装

因为需要在jenkins中使用操作docker和kubectl 下面是做的挂载处理,也可以通过Jenkins的插件来操作。

挂载文件

  • docker-cli

  • docker.sock

  • kubectl

命令如下

docker run -d --name jks \
--privileged=true \
--restart=always \
-u root \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/kubectl:/usr/bin/kubectl \
-v /root/jks/jks_home:/var/jenkins_home \
--net xm-net --ip 172.19.0.11 \
-p 80:8080 -p 50000:50000 \
jenkins/jenkins:jdk11

// 等待容器启动成功
docker logs jks
// 查看初始密码
6bcdb99a826111c94b633f72550b7b63

安装问题

访问页面,会提示安装插件,安装插件这里会出现错误

方案一

直接叉掉

方案二

也可以通过一下方法解决

修改上面挂载的/root/jks/jks_home/config.xml

<useSecurity>true</useSecurity>
// 修改为
<useSecurity>false</useSecurity>

// 删除以下配置
<authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
    <denyAnonymousReadAccess>true</denyAnonymousReadAccess>
  </authorizationStrategy>
  <securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
    <disableSignup>true</disableSignup>
    <enableCaptcha>false</enableCaptcha>
  </securityRealm>


// 重启jenkins

不保证一定成功。方案一叉掉后进入Jenkins再安装插件,没有问题。

替换源
cd /root/jks/jks_home/updates

sed -i 's/https:\/\/updates.jenkins.io\/download/http:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
sed -i 's/www.google.com/www.baidu.com/g' default.json

安装插件

Jenkins -> Plugin Manager页面安装以下插件

  • Localization: Chinese (Simplified)

  • Go

其他插件,按需安装例如node,maven,ssh等,本文不作介绍

需要自动触发任务可以看我的另一篇文章,传送门

只需要配置一个webhook就可以了。

代码管理

上面一篇文章是记录gitlab的使用,本文这里使用的github,没多大差别。操作步骤如下

  1. 生成密钥对

  2. 登陆github配置公钥

  3. Jenkins中保存私钥

// 生成密钥对
ssh-keygen -t rsa -C "[email protected]"


ls /root/.ssh/
// 查看公钥
cat /root/.ssh/id_rsa.pub
// 查看私钥
cat /root/.ssh/id_rsa

配置公钥

配置私钥

Jenkins -> 系统设置 -> 安全 -> 凭证管理 -> Stores scoped to Jenkins -> System -> 全局凭据 -> Add Credentials

使用密钥

新建任务中,源码管理下面,git选项,填写仓库地址,凭证勾选刚创建的凭证。

这里会报错

jenkins status code 128: stdout: stderr: No ED25519 host key is known for github.com and you have requested strict checking. Host key verification failed. fatal: Could not read from remote repository.

只需将“主机密钥验证策略”更改为“接受第一个连接” 仪表板>管理 Jenkins >配置全局安全性> Git 主机密钥验证配置。然后在“主机密钥验证策略”中选择“接受第一个连接”。

git配置成功后保存配置我们先构建一下,运行成功,看一下构建记录

上面输出信息用我们可以在宿主机目录/root/jks/jks_home/workspace/ 下面看到成功拉取的项目代码

打包

首先需要确保自己的大包工具安装上没有,没有安装线进行插件安装,例如node,maven,本文使用go演示

Dashboard -> 系统管理 -> 全局工具配置

保存以后,进入任务配置界面

然后就是可以执行go build命令了。我们这里大包完成后需要将二进制文件再打包成镜像,推送到镜像仓库。

我这里写了个shell,只需要执行shell就行

#!/bin/bash

# 清理其他基础镜像
yes | docker image prune -a

echo "building ..."
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags=jsoniter .
  docker build --platform linux/amd64 --force-rm -t "registry-intl.cn-hongkong.aliyuncs.com/your-project/test:v1" .
  docker push "registry-intl.cn-hongkong.aliyuncs.com/your-project/test:v1"

echo "BUILD DONE"

注意:这里推送镜像,如果是私有仓库,需要先进行docker login

K8S集群

上面镜像推送成功后,就只差最后一步,发布K8S了,这里需要简单的了解下K8S。

K8S基础

K8S相关文档,传送门

# 部署应用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看 pod
kubectl get pod -o wide
# 查看 pod 详情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name
# 进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。
kubectl exec -it pod-name -- bash
# 伸缩扩展副本
kubectl scale deployment test-k8s --replicas=5
# 把集群内端口映射到节点
kubectl port-forward pod-name 8090:8080
# 查看历史
kubectl rollout history deployment test-k8s
# 回到上个版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision=2
# 删除部署
kubectl delete deployment test-k8s
# 查看全部
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
# 删除全部资源
kubectl delete all --all

工作负载分类

  • Deployment

适合无状态应用,所有pod等价,可替代

  • StatefulSet

有状态的应用,适合数据库这种类型。

  • DaemonSet

在每个节点上跑一个 Pod,可以用来做节点监控、节点日志收集等

  • Job & CronJob

Job 用来表达的是一次性的任务,而 CronJob 会根据其时间规划反复运行。

暴露IP

ClusterIP

默认的,仅在集群内可用

NodePort

暴露端口到节点,提供了集群外部访问的入口

端口范围固定 30000 ~ 32767

LoadBalancer

需要负载均衡器(通常都需要云服务商提供,裸机可以安装 METALLB 测试)

会额外生成一个 IP 对外服务

K8S 支持的负载均衡器:负载均衡器

连接集群

本文使用的是阿里的ack,自建K8S集群类似,都需要添加kube/config

连接成功后就可以看到集群里面的东西了

kubectl get pod

发布

通过上面的命令我们可以知道,发布K8S就是创建一个无状态的pod。在上文的shell后面之后需要加入命令即可

// 同名pod需要先删除,否则k8s认为没有更新,不会更新pod
if kubectl get pods test-pod &> /dev/null; then
    kubectl delete pod test-pod
fi
kubectl create -f /var/jenkins_home/workspace/test-pod/deploy/test.yaml --save-config

pod发布的yaml文件

apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
    - name: test-pod
      image: your-project/test:v1
  imagePullSecrets:
    - name: test-hub-key

注意:如果是私有仓库,时候需要配置secret的。如果是ack,可以配置免密拉取的插件。其他k8s也可以通过命令保存,上面的yaml中imagePullSecrets配置的就是已经保存的secret

kubectl create secret docker-registry your-key-name \
  --docker-server=<你的镜像仓库服务器> \
  --docker-username=<你的用户名> \
  --docker-password=<你的密码> \
  --docker-email=<你的邮箱地址>

最后如果没有问题,执行构建就可以看到已经成功发布的pod

在K8S中也能查看到pod的状态,可以通过可视化web界面查看,也可以通过get pod命令查看

网络

以上发布完成后,需要连接应用,只需要配置K8S的service和ingress即可

这里以阿里云的ack为例

也可以通过命令创建service和ingress,可以参考上文给出的文档

创建ingress,需要先创建ingress class。这里近使用的阿里的ack,其他集群无参考价值,请略过。

阿里的ack使用ingress需要先安装ingress,本文选择的是nginx ingress。

组件安装上以后,才能使用

等待ingress创建完成后

最后通过域名就可以访问应用了