Kubernetes Jenkins插件 - 奴隶总是离线

时间:2016-07-20 17:15:34

标签: jenkins docker kubernetes

我试图使用Jenkins / Kubernetes插件与Jenkins协调docker奴隶。

我正在使用此插件:https://github.com/jenkinsci/kubernetes-plugin

我的问题是所有从属设备都处于脱机状态,因此作业无法执行:

Slave status

enter image description here

我在使用minikube的本地方框上以及由我们的操作组托管的K8群集上尝试了此操作。我已经尝试过Jenkins 1.9和Jenkins 2.我总是得到相同的结果。屏幕截图来自Jenkins 1.642.4,K8 v1.2.0

这是我的配置...请注意,当我点击“测试连接”时我获得了成功。另请注意,我不需要任何凭据(这是我可以看到的与记录的示例之间的唯一区别)。

Jenkins System Configuration

Jenkins日志反复显示以下内容:

    Waiting for slave to connect (11/100): docker-6b55f1b7fafce
Jul 20, 2016 5:01:06 PM INFO org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud$ProvisioningCallback call
Waiting for slave to connect (12/100): docker-6b55f1b7fafce
Jul 20, 2016 5:01:07 PM INFO org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud$ProvisioningCallback call
Waiting for slave to connect (13/100): docker-6b55f1b7fafce
Jul 20, 2016 5:01:08 PM INFO org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud$ProvisioningCallback call

当我运行kubectl get events时,我看到了这一点:

24s         24s        1         docker-6b3c2ff27dad3   Pod                                Normal    Scheduled           {default-scheduler }      Successfully assigned docker-6b3c2ff27dad3 to 96.xxx.xx.159
24s         23s        2         docker-6b3c2ff27dad3   Pod                                Warning   MissingClusterDNS   {kubelet 96.xxx.xx.159}   kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy.
23s         23s        1         docker-6b3c2ff27dad3   Pod       spec.containers{slave}   Normal    Pulled              {kubelet 96.xxx.xx.159}   Container image "jenkinsci/jnlp-slave" already present on machine
23s         23s        1         docker-6b3c2ff27dad3   Pod       spec.containers{slave}   Normal    Created             {kubelet 96.xxx.xx.159}   Created container with docker id 82fcf1bd0328
23s         23s        1         docker-6b3c2ff27dad3   Pod       spec.containers{slave}   Normal    Started             {kubelet 96.xxx.xx.159}   Started container with docker id 82fcf1bd0328

有什么想法吗?

更新:csanchez建议的更多日志信息

 ➜  docker git:(master) ✗ kubectl get pods --namespace default -o wide
NAME                   READY     STATUS    RESTARTS   AGE       NODE
docker-6bb647254a2a4   1/1       Running   0          1m        96.x.x.159

➜  docker git:(master) ✗ kubectl log docker-6bafbac10b392

    Jul 20, 2016 6:45:10 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Connecting to 96.x.x.159:50000 (retrying:10)
java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)

我必须查看这个端口50000用于什么?

6 个答案:

答案 0 :(得分:3)

在Kubernetes中运行jenkins时,服务名称可由jenkins master和slave解析。

配置此方法的最佳方法是使用内部DNS并将jenkins网址设置为:

http://jenkins:8080

(假设您调用了服务jenkins,并且服务上的端口是8080)

不需要隧道。

这种方法的好处是它可以在没有重新配置的情况下重新启动jenkins。

次要的好处是您不必将Jenkins暴露给外界,从而限制了安全风险。

答案 1 :(得分:2)

我只是想为上述新手的答案添加更多解释。

在公开jenkins UI时,您还需要公开内部端口50000 以下是jenkins部署的简单服务:

apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: jenkins
spec:
  type: NodePort
  ports:
    - port: 8080
      name: "http"
      nodePort: 30000
      targetPort: 8080
    - port: 50000
      name: "slave"
      nodePort: 30010
      targetPort: 50000
  selector:
    app: jenkins

对于Jenkins UI的外部访问,nodePort正在上述配置中使用。我将端口8080暴露给nodePort 30000(jenkins UI现在将在node_ip:30000处可用)并将pod端口50000暴露给nodeport 30010。

创建svc后:

$ kubectl get svc -n jenkins
NAME      CLUSTER-IP    EXTERNAL-IP   PORT(S)                          AGE
jenkins   10.233.5.94   <nodes>       8080:30000/TCP,50000:30010/TCP   23m

现在将jenkins_ip:30010添加为Jenkins Tunnel

答案 2 :(得分:1)

您需要按照插件示例config https://github.com/jenkinsci/kubernetes-plugin/blob/master/src/main/kubernetes/jenkins.yml

中的说明公开端口8080和50000

答案 3 :(得分:1)

感谢@csanchez我有解决方案。

enter image description here

问题是我在k8中运行jenkins服务器而我没有在k8中指定固定端口(我让k8选择端口)。因此,更改jenkins隧道的配置解决了它。

更好的解决方案是按照建议修复端口,然后进行更改。

答案 4 :(得分:0)

我知道这是一篇过时的文章,但是以上答案均未解决离线Jenkins代理的问题 无论如何,我已经设法自己解决了这个问题,我将把解决方案留在这里!

注1::我的Kubernetes群集通过Hyper-V在本地3个VM上运行,而我不使用Nginx!

注意2: Jenkins主服务器正在Kubernetes吊舱上运行!

注意3::您可以在此处检出我的git存储库:https://github.com/RazvanSebastian/Kubernetes_Cluster/tree/master/3_jenkins_setup

  1. 为詹金斯创建一个命名空间

$ kubectl create namespace jenkins

  1. 创建服务帐户,因为Jenkins主用户将需要权限来创建/删除资源,例如Jenkins-Slave Pod。
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: jenkins
  namespace: jenkins
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
  resources: ["pods/exec"]
  verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get","list","watch"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: jenkins
  namespace: jenkins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
- kind: ServiceAccount
  name: jenkins
  1. 我们必须创建两个服务;

NodePort 将允许从Kubernetes集群外部访问Jenkins主服务器

apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: jenkins
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      nodePort: 30123
      name: ui
  selector:
    app: master
  type: NodePort

ClusterIp ,它将像内部Jenkins-Slaves的发现服务一样工作。 默认情况下,主服务器在端口5000上监听入站代理!

apiVersion: v1
kind: Service
metadata:
  name: jenkins-discovery
  namespace: jenkins
spec:
  selector:
    app: master
  ports:
    - protocol: TCP
      port: 50000
      targetPort: 50000
      name: slaves
  1. 现在我们必须为Jenkins master创建一个部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
       app: master
  template:
    metadata:
      labels:
        app: master
    spec:
      serviceAccountName: jenkins
      containers:
        - image: jenkins/jenkins:lts
          name: jenkins
          ports:
            - containerPort: 8080
              name: http-port
            - containerPort: 50000
              name: jnlp-port
          env:
            - name: JAVA_OPTS
              value: -Djenkins.install.runSetupWizard=false

观察1: Jenkins主容器必须公开两个端口:8080(UI Jenkins端口)和50000(对于入站代理)。如果您不公开5000端口,您将收到Jenkins-Slaves的离线状态

观察2: 部署模板中的serviceAccountName: jenkins行将绑定到Jenkins创建/删除Kubernetes资源的权限

  1. 检查在jenkins命名空间中创建的资源

$ kubectl get all -o wide --namespace=jenkins

注意 从Jenkins窗格中复制IP;我们将需要它来设置詹金斯

  1. 获取Kubernetes主节点地址

$ kubectl cluster-info | grep master

  1. 现在,我们必须从UI配置Jenkins。我将附加图像,但您也可以检查git repo :)

    7.1。安装软件包(管理Jenkins->管理插件->可用): Kubernetes SSH代理

    7.2。设置主节点(管理詹金斯->管理节点和云->工具图标): enter image description here

    7.3。设置Kubernetes插件(管理Jenkins->配置系统->在页面底部,单击Cloud部分) enter image description here

enter image description here

7.4。确保在创建Jenkins作业时存在如下限制: enter image description here

答案 5 :(得分:0)

因为kubectl -n jenkins-namespace get services显示为:

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
cicd-jenkins         ClusterIP   172.20.120.227   <none>        8080/TCP    128d
cicd-jenkins-agent   ClusterIP   172.20.105.189   <none>        50000/TCP   128d

您必须转到Jenkins>管理Jenkins>配置系统(http://jenkins:8080/configure)。 然后,相应地配置 Jenkins URL jenkins隧道(请参见下面的屏幕截图)

信用https://youtu.be/MkzCVvlpiaM

enter image description here

如果您使用的是Jenkins代码配置(JCasC)插件,则可以通过jenkinsUrljenkinsTunnel键进行配置:

jenkins:
  clouds:
  - kubernetes:
      name: cluster
      serverUrl: https://kubernetes.default
      # ....
      jenkinsUrl: http://cicd-jenkins:8080/
      jenkinsTunnel:  cicd-jenkins-agent:50000
      # ....