membuat layanan melalui kluster simpul tunggal kubernetes tidak memberi saya IP eksternal 'masuk', tetapi mesin kontainer Google memberikannya (?)

Saya mencoba menyiapkan cluster kubernetes node tunggal untuk tujuan demo dan pengujian, dan saya ingin cluster tersebut berperilaku seperti cluster k8s yang 'penuh sesak' (seperti mesin kontainer Google). Klien saya memiliki instalasi k8s sendiri, yang untuk diskusi ini kita dapat mengasumsikan tindakannya mirip dengan instalasi k8s mesin kontainer Google.

Mendapatkan IP Ingress pada K8 Full Blown

Saya membuat pod wordpress dan memaparkannya sebagai layanan, seperti yang dijelaskan dalam tutorial ini: https://cloud.google.com/container-engine/docs/tutorials/hello-wordpress

Jika Anda ingin mereplikasi masalahnya, cukup salin tempel perintah di bawah ini, yang saya ambil dari tutorial: (Ini mengasumsikan Anda memiliki proyek bernama 'stellar-access-117903'.. jika tidak silakan setel ke nama Google Anda proyek Mesin Kontainer.)

# set up the cluster  (this will take a while to provision)
#
 gcloud config set project stellar-access-117903
 gcloud config set compute/zone us-central1-b
 gcloud container clusters create hello-world \
     --num-nodes 1 \
     --machine-type g1-small

# Create the pod, and expose it as a service
#
kubectl run wordpress --image=tutum/wordpress --port=80
kubectl expose rc wordpress --type=LoadBalancer

# Describe the service
kubectl describe services wordpress

Output dari perintah deskripsikan berisi baris 'LoadBalancer Ingress: {some-ip-address}' yang persis seperti yang saya harapkan. Sekarang, ketika saya melakukan hal yang sama dengan pengaturan cluster node tunggal saya tidak mendapatkan baris itu. Saya dapat mengakses layanan wordpress di IP yang muncul di output perintah 'deskripsikan layanan'.. Namun dalam mode 'single node', IP yang dicetak adalah >cluster IP‹ layanan, yang mana biasanya (seperti yang saya pahami) tidak dapat diakses publik. Untuk beberapa alasan, ini dapat diakses publik dalam mode node tunggal. Kita dapat menirunya dengan langkah-langkah berikut.

TIDAK Mendapatkan IP Ingress pada Single Node K8

Penyiapan pertama node tunggal k8s, seperti yang dijelaskan dalam tutorial ini: https://github.com/kubernetes/kubernetes/blob/master/docs/getting-started-guides/docker.md

Agar mudah direproduksi, saya telah menyertakan semua perintah di bawah ini, jadi Anda cukup menyalin/menempel:

K8S_VERSION=1.1.1

sudo docker run --net=host -d gcr.io/google_containers/etcd:2.0.12 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data


sudo docker run \
    --volume=/:/rootfs:ro \
    --volume=/sys:/sys:ro \
    --volume=/dev:/dev \
    --volume=/var/lib/docker/:/var/lib/docker:ro \
    --volume=/var/lib/kubelet/:/var/lib/kubelet:rw \
    --volume=/var/run:/var/run:rw \
    --net=host \
    --pid=host \
    --privileged=true \
    -d \
    gcr.io/google_containers/hyperkube:v${K8S_VERSION} \
    /hyperkube kubelet --containerized --hostname-override="127.0.0.1" --address="0.0.0.0" --api-servers=http://localhost:8080 --config=/etc/kubernetes/manifests

sudo docker run -d --net=host --privileged gcr.io/google_containers/hyperkube:v${K8S_VERSION} /hyperkube proxy --master=http://127.0.0.1:8080 --v=2


# set your context to use the locally running k8s API server 
#
kubectl config set-cluster dev --server=http://localhost:8080
kubectl config set-context dev --cluster=dev  --namespace=$NS
kubectl config use-context dev

Sekarang, jalankan perintah yang sama seperti yang Anda lakukan pada k8 Google Container Engine

# Create the pod, and expose it as a service
#
kubectl run wordpress --image=tutum/wordpress --port=80
kubectl expose rc wordpress --type=LoadBalancer

# Describe the service
kubectl describe services wordpress

Output dari perintah terakhir (yang akan Anda lihat tidak memiliki informasi 'Ingress') adalah:

Name:           wordpress
Namespace:      default
Labels:         run=wordpress
Selector:       run=wordpress
Type:           LoadBalancer
IP:         10.0.0.61
Port:           <unnamed>   80/TCP
NodePort:       <unnamed>   31795/TCP
Endpoints:      172.17.0.30:80
Session Affinity:   None
No events.

Di k8s mesin kontainer Google, saya melihat peristiwa seperti 'Membuat penyeimbang beban', 'Penyeimbang beban dibuat'. Tapi hal seperti itu tidak terjadi dalam contoh node tunggal.

Saya bertanya-tanya ... apakah ada konfigurasi yang perlu saya lakukan agar mereka berfungsi secara identik? Sangat penting bahwa mereka bekerja secara identik... hanya berbeda dalam skalabilitasnya, karena kami ingin menjalankan pengujian terhadap versi node tunggal, dan akan sangat membingungkan jika berperilaku berbeda.

Terima kasih sebelumnya atas bantuan Anda -chris


person Chris Bedford    schedule 03.01.2016    source sumber


Jawaban (2)


Inilah solusi yang kami temukan. Saat kami menjalankan Kubernetes node tunggal, kami menyadari melalui trial and error bahwa saat Anda mengekspos suatu layanan, IP eksternal tidak kembali melalui IngressIP; sebaliknya, ia kembali melalui clusterIP, yang seperti disebutkan di atas dapat dilihat oleh publik. Jadi, kami baru saja memodifikasi kode kami agar berfungsi dengan itu. Kami menggunakan clusterIP dalam kasus node tunggal. Berikut adalah kode yang kami gunakan untuk membuat jam tangan pada layanan untuk mengetahui kapan k8s telah mengalokasikan IP kami yang terlihat secara eksternal:

Pertama kita menggunakan API fabric8 untuk membuat konfigurasi layanan:

            case "Service" =>
              val serviceConf = mapper.readValue(f, classOf[Service])
              val service = kube.services().inNamespace(namespaceId).create(serviceConf)
              watchService(service)

Metode 'watchService' didefinisikan di bawah ini:

  private def watchService(service: Service) = {
    val namespace = service.getMetadata.getNamespace
    val name = service.getMetadata.getName
    logger.debug("start -> watching service -> namespace: " + namespace + " name: " + name)
    val kube = createClient()
    try {
      @volatile var complete = false
      val socket = kube.services().inNamespace(namespace).withName(name).watch(new Watcher[Service]() {
        def eventReceived(action: Action, resource: Service) {
          logger.info(action + ":" + resource)
          action match {
            case Action.MODIFIED =>
              if (resource.getMetadata.getName == name) {
                complete = isServiceComplete(resource)
              }
            //            case Action.DELETED =>
            //              complete = true
            case _ =>
          }
        }
      })
      while (!complete) {
        Thread.sleep(5000)
        complete = isServiceComplete(kube.services().inNamespace(namespace).withName(name).get)
      }
      logger.info("Closing socket connection")
      socket.close()
    } finally {
      logger.info("Closing client connection")
      kube.close()
    }

    logger.debug("complete -> watching services , namespace: " + namespace + " name: " + name)
  }

Peretasan kunci yang kami perkenalkan ada pada metode 'isServiceComplete' .. saat menggunakan node tunggal k8s, nilai 'isUsingMock' adalah benar. sehingga membuat kita menggunakan clusterIP untuk mengetahui apakah konfigurasi layanan sudah selesai atau belum.

  private def isServiceComplete(service: Service) = {
    !service.getStatus.getLoadBalancer.getIngress.isEmpty  || mockServiceComplete(service)
  }

  def mockServiceComplete(service: Service): Boolean = {
    val clusterIP  = service.getSpec.getClusterIP
    logger.trace(s"mockServiceComplete:   $isUsingMock /  $clusterIP / $KUBE_SERVER" )
    isUsingMock && ! clusterIP.isEmpty
  }

Maaf jika tidak banyak konteks tambahan di sini. Akhirnya proyek kami harus menjadi sumber terbuka dan kami dapat memposting solusi lengkap.

-Kris

person Chris Bedford    schedule 13.01.2016

LoadBalancer adalah fitur yang diterapkan oleh penyedia cloud backend, sehingga Anda tidak melihatnya dibuat di pengaturan lokal Anda

(lihat penyedia cloud: https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers)

person uvgroovy    schedule 03.01.2016
comment
Terima kasih.. ya, saya memang membaca tentang itu. Apa yang saya harapkan adalah semacam pengaturan konfigurasi, plugin, skrip, peretasan apa pun, yang memungkinkan pengaturan node tunggal untuk meniru perilaku penyedia cloud yang menawarkan penyeimbangan beban. Jika saya dapat mengetahui cara menghubungkan ke kubernetes dan melakukan ini, saya akan memposting solusinya di sini.. Tapi mudah-mudahan ada yang sudah melakukan ini. Pokoknya terima kasih sekali lagi atas tanggapan Anda. - person Chris Bedford; 04.01.2016
comment
Anda dapat mengatur layanan dengan NodePort dan menggunakan nginx untuk memuat keseimbangan melalui RC lain (Anda berpotensi menemukan node melalui api dan mengonfigurasi nginx secara otomatis) mega hack dan tidak yakin bagaimana port node bekerja dalam penerapan mesin tunggal... - person uvgroovy; 04.01.2016
comment
juga jika Anda hanya ingin mengakses layanan yang diterapkan, Anda dapat mencoba menggunakan fitur proxy kubelet - person uvgroovy; 04.01.2016