Kubernetes pause infra container 는 기존의 golang 에서 c 로 변경되었다.


main 함수를 보면 다음과 같다.

int main(int argc, char **argv) {
int i;
for (i = 1; i < argc; ++i) {
if (!strcasecmp(argv[i], "-v")) {
printf("pause.c %s\n", VERSION_STRING(VERSION));
return 0;
}
}

if (getpid() != 1)
/* Not an error because pause sees use outside of infra containers. */
fprintf(stderr, "Warning: pause should be the first process\n");

if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
return 1;
if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
return 2;
if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap,
.sa_flags = SA_NOCLDSTOP},
NULL) < 0)
return 3;

for (;;)
pause();
fprintf(stderr, "Error: infinite loop terminated\n");
return 42;
}


pause 는 infra container 이므로 getpid() 가 1 인 최상의 프로세스가 되는 것이 Security 측면에서 바람직하다.


sigaction 은 signal 이 SIGINT (키보드 ctrl + c 로 종료), SIGTERM (종료) 가 들어오면 sigdown 함수를 handler 로 등록해서 수행한다.

자식 프로세스가 종료되거나 정지/재시작 될 때 SIGCHLD signal 이 발생하는데, SA_NOCLDSTOP flag 는 자식 프로세스가 정지되는 4가지의 signal - SIGSTOP(프로세스 정지), SIGTSTP(키보드 ctrl + z 로 발생한 프로세스 정지), SIGTTIN(백그라운드에서 제어터미널 읽기를 시도해서 정지), SIGTTOU(백그라운드에서 제어터미널 쓰기를 시도해서 정지) 등을 받아서 정지되거나 CONTINUE signal 을 받아서 재시작되어도 이를 통지 받지 않겠다는 의미이다. 즉, pause 가 부모 프로세스가 이지만 SIGCHLD signal 을 통보받을 필요가 없다고 생각하는 것이다.  하지만 그 나머지인 경우인 자식 프로세스가 종료되는 경우에는 signal 을 받을 수 밖에 없다. 이 때는 waitpid 함수를 통해서 혹시라도 자식 프로세스가 좀비가 되었을 때 좀비 프로세스를 제거할 수 있다.


sigaction 함수는 에러가 발생하면 -1 을 정상 처리되면 0을 리턴한다.


static void sigdown(int signo) {
psignal(signo, "Shutting down, got signal");
exit(0);
}

psignal 함수는 두번째 인자로 들어온 string 을 stderr 로 출력한다.



static void sigreap(int signo) {
while (waitpid(-1, NULL, WNOHANG) > 0)
;
}

자식 프로세스가 왜 종료 되었는지는 관심이 없고 단순히 자식 프로세스가 종료될 때 좀비 프로세스를 막고자 한다면 waitpid 함수를 위와 같이 사용한다.


첫번재 인자로 전달된 pid 값이 -1 이면 모든 자식 프로세스가 종료될 때 까지 기다린다. 하지만 마지막 인자로 WNOHANG 이 입력되면 부모 프로세스는 기다리지 않고 바로 리턴된다. 하나의 SIGCHLD 에 대해서 while 문으로 처리한 이유는 여러 자식 프로세스가 종료될 수 있는 가능성이 있기 때문이다. 즉, SIGCHLD signal 이전에 좀비 프로세스가 있으면 그것을 처리한다. 


그럼 결과적으로는 SIGCHLD signal 이 발생할 때 pause 프로세스는 아무것도 기다리지 않고 좀비 프로세스가 있으면 처리하고 바로 리턴한다.

그리고 마지막에 pause() 함수에 의해서 잠시 정지 상태가 된다. 



* 좀비 프로세스 : 자식 프로세스가 종료되어 사용하는 리소스는 모두 해제된 상태지만, 부모 프로세스가 자식 프로세스의 종료를 확인하지 못한 상태로 커널의 프로세스 테이블에는 관리되고 있는 상태

* 고아 프로세스 : 자식 프로세스 보다 부모 프로세스가 죽었을 경우 자식 프로세스가 pid 1 인 init 프로세스에 속하게 된 경우




 



 
















Posted by Kubernetes Korea co-leader seungkyua@gmail.com


2018년 3월 26일 CNC & Kubernetes Meetup 발표 자료


 facebook group : https://www.facebook.com/groups/k8skr/


• 일시: 2018년 3월 26일(월) 오후 7시 30분 - 9시 30분

• 장소: 역삼역 7번 출구 GS타워 12층 AWS코리아 (강남구 논현로 508)

• 세션 내용:


19:30-20:10 Kubernetes 를 이용한 Cloud native platform 개발 (어형부형)



20:10-20:50 Helm chart 를 활용한 App 배포 방법 (안승규)








Posted by Kubernetes Korea co-leader seungkyua@gmail.com


[ dynamic volume 사용법 ]
1. pvc 에 storageclass 를 지정하여 pvc 만 생성하면 pv 가 다이너믹하게 생성되고 pvc 도 생성된다.
2. 이 때 rbd 이미지도 자동으로 생성된다.

$ vi jenkins-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins
  namespace: ci-infra
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 100Gi
  storageClassName: ceph




[ static volume 사용법 ]
1. rbd 이미지를 수동으로 생성해야 한다.
2. pv 에 storageclass 와 rbd 값을 모두 넣어야 한다.
    pv 에 pvc 에서 pv 를 selector 로 찾을 수 있게 label 값을 넣어야 한다.
    (keyring 값은 안넣어도 됨, storageclass의 secret 이용)
3. pvc 에 storageclass 와 selector 나 volumeName 둘 중에 하나를 사용하여 pv 와 연결한다.
    (storageclass 는 값은 없어도 됨.  없으면 default 인 storageclass 값을 활용함)


$ vi jenkins-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: jenkins
  labels:
    app: jenkins
spec:
  capacity:
    storage: 100Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ceph
  rbd:
    image: jenkins
    monitors:
    - 192.168.30.23:6789
    - 192.168.30.24:6789
    - 192.168.30.25:6789
    pool: kubes
    secretRef:
      name: ceph-secret-user
    user: kube


$ vi jenkins-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins
  namespace: ci-infra
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 100Gi
  storageClassName: ceph
  selector:
    matchLabels:
      app: jenkins
# volumeName: jenkins


$ vi jenkins-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jenkins
  namespace: ci-infra
  labels:
    app: jenkins
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: cicd-services
                operator: In
                values:
                - enabled
      securityContext:
        runAsUser: 1000
        fsGroup: 1000
      containers:
      - name: master
        env:
        - name: JENKINS_OPTS
          value: "--httpsPort=0 --http2Port=0"
        - name: JAVA_OPTS
          value: "-Xms8G -Xmx8G -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent -XX:+ParallelRefProcEnabled -XX:+UseStringDeduplication -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:+UnlockDiagnosticVMOptions -XX:G1SummarizeRSetStatsPeriod=1 -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Seoul"
        image: jenkins/jenkins:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        - containerPort: 50000
          name: jnlp
          protocol: TCP
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 2
          failureThreshold: 5
        volumeMounts:
        - mountPath: /var/jenkins_home
          name: jenkins
#        resources:
#          limits:
#            cpu: 4000m
#            memory: 8000Mi
#          requests:
#            cpu: 1000m
#            memory: 8000Mi
      volumes:
      - name: jenkins
        persistentVolumeClaim:
          claimName: jenkins




## 생성
$ rbd create kubes/jenkins -s 100G
$ kubectl create -f jenkins-pv.yaml
$ kubectl create -f jenkins-pvc.yaml

$ kubectl create -f jenkins-deployment.yaml 


Posted by Kubernetes Korea co-leader seungkyua@gmail.com






Posted by Kubernetes Korea co-leader seungkyua@gmail.com