Change:
Is this a request for help? Nope What keywords did you search in Kubernetes issues before filing this one? petset replicas current desired Is this a BUG REPORT or FEATURE REQUEST? BUG Kubernetes version Client Version: version.Info{Major:"", Minor:"", GitVersion:"v0.0.0-master+", GitCommit:"", GitTreeState:"not a git tree", BuildDate:"2016-09-01T10:49:36Z", GoVersion:"go1.6.2", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"", Minor:"", GitVersion:"v0.0.0-master+", GitCommit:"", GitTreeState:"not a git tree", BuildDate:"2016-09-01T10:49:36Z", GoVersion:"go1.6.2", Compiler:"gc", Platform:"linux/amd64"} Environment: Cloud provider or hardware configuration: 24 cores, 64 GB RAM OS Arch Linux Kernel (e.g. ): Linux hostname 4.4.13-1-lts SMP Wed Jun 8 16:44:31 CEST 2016 x86_64 GNU/Linux Install tools: local-cluster- Others: What happened: While creating PetSet based on this tutorial: first PetSet pod was stuck in pending state due to lack of PersistentVolumes in cluster. When getting the petset info via I expected to see "CURRENT" set to 1, while the kubectl output was as follows: While clearly shows that only one pod is created: In json and yaml output, status.replicas value was also 2. What you expected to happen: I expected that CURRENT value shown by kubectl would be due to only one pod being created. How to reproduce it (as minimally and precisely as possible): Create via on empty cluster and run and . Anything else do we need to know: Nope
CURRENT is the number of pods that have been created, not that they are READY. See for example the latest api change for replica sets where we exactly for this reason. All controllers (petsets, daemonsets, deployments, etc.) should have ReadyReplicas cc:
See also
I guess it doesn't work anyway, since only one pod was created for this PetSet, but the CURRENT says that 2 were created. I will change bug description then.
Hmm, the idea is to sync every pet periodically, but only create them one at a time. The logic that counts status.replicas is wrong. This counter shouldn't be incremented in the case where we didn't update/sync or create a pet: Today we do increment it all pet creation is blocked on the first pet becoming unhealthy. Should be an easy fix if anyone wants to jump in ( fyi) otherwise I'll get to it once 1.4 is out.
I can try to fix it if that's OK. Thanks for the pointer to the source code!
Please do, co-assigned

Discussion:
} func (f *fakePetClient) setHealthy(index int) error { <del> if len(f.pets) < index { </del> <ins> if len(f.pets) <= index { </ins> return fmt.Errorf("Index out of range, len %v index %v", len(f.pets), index) } f.pets[index].pod.Status.Phase = api.PodRunning

blockingPet *pcb } <ins> // errUnhealthyPet is returned when a we either know for sure a pet is unhealthy, // or don't know its state but assume it is unhealthy. It's used as a signal to the caller for further operations like updating status.replicas. // This is not a fatal error. type errUnhealthyPet string func (e errUnhealthyPet) Error() string { return string(e) } </ins> // Sync syncs the given pet. func (p *petSyncer) Sync(pet *pcb) error { if pet == nil {

return p.Update(realPet, pet) } if p.blockingPet != nil { <del> glog.Infof("Create of %v in PetSet %v blocked by unhealthy pet %v", pet.pod.Name, pet.parent.Name, p.blockingPet.pod.Name) return nil </del> <ins> message := errUnhealthyPet(fmt.Sprintf("Create of %v in PetSet %v blocked by unhealthy pet %v", pet.pod.Name, pet.parent.Name, p.blockingPet.pod.Name)) glog.Info(message) return message </ins> } // This is counted as a create, even if it fails. We can't skip indices // because some pets might allocate a special role to earlier indices.

case deletePet: err = petManager.Delete(pet) } <del> if err != nil { </del> <ins> switch err.(type) { case errUnhealthyPet: // We are not passing this error up, but we don't increment numPets if we encounter it, // since numPets directly translates to petset.status.replicas continue case nil: continue default: </ins> it.errs = append(it.errs, err) } }

t.Errorf("Unexpected blocking pet, err %v: %+v", err, p) } } <ins> // TODO(mkwiek): test if the petset.Status.Replicas is actually correct func TestPetSetReplicaCount(t *testing.T) { psc, fc := newFakePetSetController() ps := newPetSet(3) i, _ := psc.syncPetSet(ps, fc.getPodList()) if i != len(fc.getPodList()) { t.Errorf("syncPetSet should return actual amount of pods") } } </ins>