kind部署 fedora-dev

在完成 Fedora镜像 制作之后,将镜像推送到 kind集群本地Registry 部署个人开发环境:

准备工作

  • 将制作完成的 Fedora镜像 fedora-dev 打上tag并推送Local Registry:

fedora-dev 镜像tag后推送Local Registry
docker tag fedora-dev localhost:5001/fedora-dev:latest
docker push localhost:5001/fedora-dev

部署

简单部署

部署到kind集群的fedora-dev-deployment.yml
---
apiVersion: v1
kind: Service
metadata:
  name: fedora-dev-service
  labels:
    app: fedora-dev
spec:
  #type: LoadBalancer
  ports:
    - name: ssh
      protocol: TCP
      port: 22
      targetPort: 22
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
    - name: https
      protocol: TCP
      port: 443
      targetPort: 443
  selector:
    app: fedora-dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fedora-dev-origin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fedora-dev
  template:
    metadata:
      labels:
        app: fedora-dev
    spec:
      containers:
      - name: fedora-dev
        image: localhost:5001/fedora-dev:latest
        ports:
          - containerPort: 22
            name: ssh
            protocol: TCP
  • 部署:

fedora-dev 部署到kind集群(初始简化配置)
kubectl apply -f fedora-dev-deployment-origin.yml

此时你会发现,部署的 fedora-dev 并没有像 Fedora镜像 非常轻松地运行起来,而是不断的 CrashLoopBackOff :

通过 kubectl describe pods fedora-dev-origin-64f5b9bb44-f5gw8 可以看到:

Warning  BackOff    4s (x6 over 56s)   kubelet            Back-off restarting failed container

强制启动和排查

既然Kubernetes根据端口判断容器服务不正常,那很有可能在 Fedora镜像 能够正常工作在docker的镜像在Kubernetes中存在问题。由于我为了部署开发环境,采用的是非常规的富容器,包含了 Systemd进程管理器 ,这在 Docker systemd进程管理器 也是需要特殊配置的,所以首先怀疑是Kubernetes环境 systemd 异常:

  • 既然服务无法启动(端口不通),那么修改Kuternetes的 Probe 侦测,改为无论如何都能够成功的模式,这样就可以先启动容器再进行下一步排查。创建 fedora-dev-deployment-forceup.yml :

修订probe方式,强制pod运行以便检查异常 fedora-dev-deployment-forceup.yml
---
apiVersion: v1
kind: Service
metadata:
  name: fedora-dev-service
  labels:
    app: fedora-dev
spec:
  #type: LoadBalancer
  ports:
    - name: ssh
      protocol: TCP
      port: 22
      targetPort: 22
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
    - name: https
      protocol: TCP
      port: 443
      targetPort: 443
  selector:
    app: fedora-dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fedora-dev-forceup
spec:
  replicas: 1
  selector:
    matchLabels:
      app: fedora-dev
  template:
    metadata:
      labels:
        app: fedora-dev
    spec:
      containers:
      - args:
        - date; sleep 10; echo 'Hello from fedora-dev'; touch /tmp/healthy; sleep 1; while
          true; do sleep 120; done;
        command:
        - /bin/bash
        - -ec
        name: fedora-dev
        image: localhost:5001/fedora-dev:latest
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          failureThreshold: 8
          initialDelaySeconds: 15
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 15
        ports:
          - containerPort: 22
            name: ssh
            protocol: TCP
  • 运行强制启动:

强制启动pod: fedora-dev-forceup
kubectl apply -f fedora-dev-deployment-forceup.yml

现在我们有2个pod:

% kubectl get pods
NAME                                 READY   STATUS             RESTARTS      AGE
fedora-dev-forceup-b9ccb477-qk7rd    1/1     Running            0             36s
fedora-dev-origin-64f5b9bb44-f5gw8   0/1     CrashLoopBackOff   4 (76s ago)   2m47s
  • 登陆到 fedora-dev-forceup-b9ccb477-qk7rd 检查为何 ssh服务 服务无法正常工作:

    kubectl exec -it fedora-dev-forceup-b9ccb477-qk7rd -- /bin/bash
    

检查 sshd 服务:

# systemctl status sshd
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

可以看到 Systemd进程管理器 没有作为 init 启动启动,也就无法启动后续的 sshd 服务

之前在 Fedora镜像 运行 fedora-devdocker run 命令 添加了 --privileged=true 才能实现 Docker systemd进程管理器 ,但是在 Kubernetes 上没有这个运行参数传递。那么,就需要 systemd container interface 传递到容器内部环境变量 container=docker 来告知 Systemd进程管理器 运行在容器内部

在Kubernetes,需要使用 使用ConfigMap配置Pod ,我添加如下环境变量:

向pod容器传递 container=docker 环境变量
...
    spec:
      containers:
      - name: fedora-dev
        image: localhost:5001/fedora-dev:latest
        env:
          - name: container
            value: "docker"
        ports:
          - containerPort: 22
            name: ssh
            protocol: TCP

但是还是不行

之前在探索 Docker systemd进程管理器 时发现 How to run systemd in a container 使用 Podman 在容器中运行 systemd ,我Google了很久也没有找到 Systemd进程管理器 作为 Kubernetes pods 的 init 方法。似乎只有 Podman 才建议使用 Systemd进程管理器 ,而 Docker Atlas 默认则采用 Docker tini进程管理器 作为init。

我暂时改为 Docker tini进程管理器 来重新构建 Fedora镜像(采用tini替代systemd) ,有关 Systemd进程管理器 作为init的Kubernets pod,我后续再探索…