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

전쳬 에제 소스

https://github.com/seungkyua/hello-go


Go 프로그램에서 channel 을 사용할 때 가장 중요한 부분은 channel 을 한 번만 닫아야 한다는 것이다. 그렇지 않고 닫힌 channel 을 중복해서 닫으려고 하면 panic 이 발생한다. 그래서 Discovery Go 책에서는 channel 에 값을 보내는 쪽에서 닫는 패턴을 추천한다.


프로젝트로 완성하는 Go 프로그래밍(Go Programming Blueprints Second Edition) 의 chat 예제를 보면 client 가 종료되어도 client 가 가지고 있는 채널을 닫지 않는 에러가 있어 이를 간단히 수정했다.


client.go 의 client struct 에 필요없는 room 변수는 삭제했다. (나중에 필요하면 추가할지도)

대신 read 메소드에 root 의 forward channel 을 인자로 받는다. 

type client struct {
socket *websocket.Conn
send chan []byte
}


read 메소드에는 socket close 하는 부분이 있는데 socket 에러가 나면 read 가 에러가 날 것이고 이 때 defer 로 channel 닫는 부분을 추가한다. write 메소드에는 중복을 피하기 위해서 channel 닫는 부분을 넣지 않았다.


func (c *client) read(forward chan<- []byte) {
defer func() {
c.socket.Close()
log.Println("Client socker read closed.")
close(c.send)
log.Println("Client send channel closed.")
}()
for {
_, msg, err := c.socket.ReadMessage()
if err != nil {
log.Println("Client Socket ReadMaessage error")
return
}
forward <- msg
}
}

 

 root.go 에서는 쓰이고 있지는 않지만 client 에 leave 할 경우 기존 client channel 닫는 소스 대신 client socket 을 닫는 부분으로 변경했다. range 로 모든 client channel 에 값을 보내고 있기 때문에 여기는 보내는 channel 이지만 channel 을 닫기가 어렵다. 그래서 client 에서 channel 을 닫는 로직을 추가했다.

 

root struct 에서 생성한 forward, join, leave channel 은 처리하지 않았다. 나중에 room 에 client 가 아무도 없을 때의 로직에 추가되면 그 때 닫는 부분을 추가해야 한다.


func (r *room) run() {
go func() {
for {
select {
case client := <-r.join:
r.clients[client] = true
case client := <-r.leave:
delete(r.clients, client)
client.socket.Close()
case msg := <-r.forward:
for client := range r.clients {
client.send <- msg
}
}
}
}()
}








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

Helm chart

OpenStack 2018.03.23 10:33



# ingress.yaml 


images:

      tags:

        entrypoint: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        ingress: registry.cicd.stg.taco/nginx-ingress-controller:0.9.0

        error_pages: registry.cicd.stg.taco/defaultbackend:1.0

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

      pull_policy: Always

    config:

      worker-processes: "8"

    pod:

      replicas:

        ingress: 1

        error_page: 1




# openstack-ceph-config.yaml


images:

      tags:

        ks_user: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_service: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_endpoints: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ceph_bootstrap: registry.cicd.stg.taco/ceph-daemon:tag-build-master-jewel-ubuntu-16.04

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        ceph_daemon: registry.cicd.stg.taco/ceph-daemon:tag-build-master-jewel-ubuntu-16.04

        ceph_config_helper: registry.cicd.stg.taco/ceph-config-helper:v1.7.5

        ceph_rbd_provisioner: registry.cicd.stg.taco/rbd-provisioner:v0.1.1

        ceph_cephfs_provisioner: registry.cicd.stg.taco/cephfs-provisioner:v0.1.1

      pull_policy: IfNotPresent 

    deployment:

      storage_secrets: true

      client_secrets: true

      rbd_provisioner: false

      cephfs_provisioner: false

      rgw_keystone_user_and_endpoints: false

    conf:

      ceph:

        global:

          mon_host: 192.168.51.20

    storageclass:

      rbd:

        provision_storage_class: false

        user_id: cinder

        admin_secret_namespace: openstack

      cephfs:

        provision_storage_class: false

        dmin_secret_namespace: openstack

    manifests:

      configmap_bin_clients: true

      configmap_bin_ks: true

      configmap_bin: true

      configmap_etc: true

      configmap_templates: true

      daemonset_mon: false

      daemonset_osd: false

      deployment_mds: false

      deployment_moncheck: false

      deployment_rbd_provisioner: false

      deployment_cephfs_provisioner: false

      deployment_rgw: false

      deployment_mgr: false

      job_bootstrap: false

      job_cephfs_client_key: false

      job_keyring: false

      job_ks_endpoints: false

      job_ks_service: false

      job_ks_user: false

      job_namespace_client_key_cleaner: true

      job_namespace_client_key: true

      job_rbd_pool: false

      job_storage_admin_keys: true

      secret_keystone_rgw: false

      secret_keystone: false

      service_mgr: false

      service_mon: false

      service_rgw: false

      service_mon_discovery: false

      storageclass: false

    dependencies:

      rbd_provisioner:

        jobs:

        services:




# mariadb.yaml


images:

      tags:

        mariadb: registry.cicd.stg.taco/mariadb:10.1.23

        test: registry.cicd.stg.taco/ocata/ubuntu-source-kolla-toolbox:develop

      pull_policy: Always

    pod:

      replicas:

        server: 3

    volume:

      enabled: true

      class_name: ceph



# etcd.yaml


images:

      tags:

        etcd: registry.cicd.stg.taco/etcd:v3.2.5 

        test: registry.cicd.stg.taco/ocata/ubuntu-source-kolla-toolbox:develop

      pull_policy: IfNotPresent

    pod:

      replicas:

        etcd: 1



# rabbitmq.yaml


images:

      tags:

        rabbitmq: registry.cicd.stg.taco/rabbitmq:3.7

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        test: registry.cicd.stg.taco/ocata/ubuntu-source-keystone:2.2.0

      pull_policy: IfNotPresent

    pod:

      replicas:

        server: 3

    volume:

      class_name: ceph




# memcached.yaml


images:

      tags:

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        memcached: registry.cicd.stg.taco/memcached:1.5.5 

      pull_policy: IfNotPresent

    pod:

      replicas:

        server: 1





# libvirt.yaml


images:

      tags:

        libvirt: registry.cicd.stg.taco/ocata/ubuntu-source-nova-libvirt:2.2.0

      pull_policy: Always

    ceph:

      enabled: true

      cinder_user: "cinder"

      cinder_keyring: "xxxxx=="

    libvirt:

      listen_addr: 0.0.0.0

      log_level: 3

    manifests:

      configmap_bin: true

      configmap_etc: true

      daemonset_libvirt: true




# openvswitch.yaml


images:

      tags:

        openvswitch_db_server: registry.cicd.stg.taco/ocata/ubuntu-source-openvswitch-db-server:2.2.0

        openvswitch_vswitchd: registry.cicd.stg.taco/ocata/ubuntu-source-openvswitch-vswitchd:2.2.0

      pull_policy: Always

    network:

      external_bridge: br-ex

      interface:

        external: bond1.52

      auto_bridge_add: {}




# keystone.yaml


images:

      tags:

        bootstrap: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        test: registry.cicd.stg.taco/ocata/ubuntu-source-rally:2.2.0

        db_init: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        keystone_db_sync: registry.cicd.stg.taco/ocata/ubuntu-source-keystone:2.2.0

        db_drop: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        keystone_fernet_setup: registry.cicd.stg.taco/ocata/ubuntu-source-keystone:2.2.0

        keystone_fernet_rotate: registry.cicd.stg.taco/ocata/ubuntu-source-keystone:2.2.0

        keystone_credential_setup: registry.cicd.stg.taco/ocata/ubuntu-source-keystone:2.2.0

        keystone_credential_rotate: registry.cicd.stg.taco/ocata/ubuntu-source-keystone:2.2.0

        keystone_api: registry.cicd.stg.taco/ocata/ubuntu-source-keystone:2.2.0

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        rabbit_init: registry.cicd.stg.taco/rabbitmq:3.7-management

      pull_policy: Always

    conf:

      keystone:

        DEFAULT:

          debug: true

    pod:

      replicas:

        api: 3




# glance.yaml


storage: rbd

    images:

      tags:

        test: registry.cicd.stg.taco/ocata/ubuntu-source-rally:2.2.0

        glance_storage_init: registry.cicd.stg.taco/ceph-daemon:tag-build-master-jewel-ubuntu-16.04

        db_init: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        glance_db_sync: registry.cicd.stg.taco/ocata/ubuntu-source-glance-api:2.2.0

        db_drop: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_user: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_service: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_endpoints: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        glance_api: registry.cicd.stg.taco/ocata/ubuntu-source-glance-api:2.2.0

        glance_registry: registry.cicd.stg.taco/ocata/ubuntu-source-glance-registry:2.2.0

        bootstrap: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        rabbit_init: registry.cicd.stg.taco/rabbitmq:3.7-management

      pull_policy: Always

    pod:

      replicas:

        api: 3

        registry: 3

      user:

        glance:

          uid: 42415

    network:

      api:

        ingress:

          proxy_body_size: 102400M

    conf:

      ceph:

        monitors: ["192.168.51.20"]

        admin_keyring: "xxxx=="

      glance:

        glance_store:

          rbd_store_user: glance

          rbd_store_pool: images

        DEFAULT:

          show_image_direct_url: true

    bootstrap:

      enabled: true

      images:

        cirros:

          id: 201084fc-c276-4744-8504-cb974dbb3610

          private: false




# nova.yaml


images:

      tags:

        bootstrap: registry.cicd.stg.taco/ocata/ubuntu-source-nova-api:2.2.0

        db_init: registry.cicd.stg.taco/ocata/ubuntu-source-nova-api:2.2.0

        db_drop: registry.cicd.stg.taco/ocata/ubuntu-source-nova-api:2.2.0

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        rabbit_init: registry.cicd.stg.taco/rabbitmq:3.7-management

        ks_user: registry.cicd.stg.taco/ocata/ubuntu-source-kolla-toolbox:2.2.0

        ks_service: registry.cicd.stg.taco/ocata/ubuntu-source-kolla-toolbox:2.2.0

        ks_endpoints: registry.cicd.stg.taco/ocata/ubuntu-source-kolla-toolbox:2.2.0

        nova_api: registry.cicd.stg.taco/ocata/ubuntu-source-nova-api:2.2.0

        nova_cell_setup: registry.cicd.stg.taco/ocata/ubuntu-source-nova-api:2.2.0

        nova_compute: registry.cicd.stg.taco/ocata/ubuntu-source-nova-compute:2.2.0

        nova_compute_ironic: registry.cicd.stg.taco/ocata/ubuntu-source-nova-compute-ironic:2.2.0

        nova_compute_ssh: registry.cicd.stg.taco/ocata/ubuntu-source-nova-ssh:2.2.0

        nova_conductor: registry.cicd.stg.taco/ocata/ubuntu-source-nova-conductor:2.2.0

        nova_consoleauth: registry.cicd.stg.taco/ocata/ubuntu-source-nova-consoleauth:2.2.0

        nova_db_sync: registry.cicd.stg.taco/ocata/ubuntu-source-nova-api:2.2.0

        nova_novncproxy: registry.cicd.stg.taco/ocata/ubuntu-source-nova-novncproxy:2.2.0

        nova_novncproxy_assets: registry.cicd.stg.taco/ocata/ubuntu-source-nova-novncproxy:2.2.0

        nova_placement: registry.cicd.stg.taco/ocata/ubuntu-source-nova-placement-api:2.2.0

        nova_scheduler: registry.cicd.stg.taco/ocata/ubuntu-source-nova-scheduler:2.2.0

        nova_spiceproxy: registry.cicd.stg.taco/ocata/ubuntu-source-nova-spicehtml5proxy:2.2.0

        nova_spiceproxy_assets: registry.cicd.stg.taco/ocata/ubuntu-source-nova-spicehtml5proxy:2.2.0

        test: registry.cicd.stg.taco/ocata/ubuntu-source-rally:2.2.0

      pull_policy: Always

    bootstrap:

      enabled: true

      flavors:

        m1_tiny:

          id: 0c84e220-a258-439f-a6ff-f8e9fd980025

    network:

      novncproxy:

        name: "nova-novncproxy"

        node_port:

          enabled: true

          port: 30608

        port: 6080

        targetPort: 6080

    ceph:

      enabled: true

      cinder_user: "cinder"

      cinder_keyring: "xxxx=="

      secret_uuid: "582393ff-9a5c-4a2e-ae0d-86ec18c36afc"

    conf:

      nova:

        DEFAULT:

          force_config_drive: true

          scheduler_default_filters: "RetryFilter,AvailabilityZoneFilter,RamFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter"

          debug: true

        vnc:

          novncproxy_base_url: http://ctrl01-stg:30608/vnc_auto.html

        libvirt:

          rbd_user: "cinder"

          rbd_secret_uuid: "582393ff-9a5c-4a2e-ae0d-86ec18c36afc"

        scheduler:

          discover_hosts_in_cells_interval: 60

    endpoints:

      oslo_db_cell0:

        path: /nova_cell0

    pod:

      user:

        nova:

          uid: 42436

      replicas:

        api_metadata: 3

        osapi: 3

        conductor: 3

        consoleauth: 3

        scheduler: 3

        novncproxy: 3




# neutron.yaml


images:

      tags:

        bootstrap: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        neutron_test: registry.cicd.stg.taco/ocata/ubuntu-source-rally:2.2.0

        db_init: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        neutron_db_sync: registry.cicd.stg.taco/ocata/ubuntu-source-neutron-server:2.2.0

        db_drop: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_user: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_service: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_endpoints: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        neutron_server: registry.cicd.stg.taco/ocata/ubuntu-source-neutron-server:2.2.0

        neutron_dhcp: registry.cicd.stg.taco/ocata/ubuntu-source-neutron-dhcp-agent:2.2.0

        neutron_metadata: registry.cicd.stg.taco/ocata/ubuntu-source-neutron-metadata-agent:2.2.0

        neutron_l3: registry.cicd.stg.taco/ocata/ubuntu-source-neutron-l3-agent:2.2.0

        neutron_openvswitch_agent: registry.cicd.stg.taco/ocata/ubuntu-source-neutron-openvswitch-agent:2.2.0

        neutron_linuxbridge_agent: registry.cicd.stg.taco/ocata/ubuntu-source-neutron-linuxbridge-agent:2.2.0

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        rabbit_init: registry.cicd.stg.taco/rabbitmq:3.7-management

      pull_policy: Always

    pod:

      replicas:

        server: 3

      user:

        neutron:

          uid: 42435

    labels:

      agent:

        dhcp:

          node_selector_key: openstack-network-node

        l3:

          node_selector_key: openstack-network-node

    manifests:

      daemonset_metadata_agent: false

      daemonset_ovs_agent: true

      daemonset_lb_agent: false

    network:

      backend: ovs

      external_bridge: br-ex

      interface:

        tunnel: bond1

    conf:

      neutron_sudoers:

        override: |

          # This sudoers file supports rootwrap-daemon for both Kolla and LOCI Images.

          Defaults !requiretty

          Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin:/var/lib/kolla/venv/bin"

          neutron ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/neutron-rootwrap /etc/neutron/rootwrap.conf *, /var/lib/openstack/bin/neutron-rootwrap /etc/neutron/rootwrap.conf *, /var/lib/kolla/venv/bin/neutron-rootwrap-daemon /etc/neutron/rootwrap.conf, /var/lib/openstack/bin/neutron-rootwrap-daemon /etc/neutron/rootwrap.conf

      neutron:

        DEFAULT:

          debug: True

          core_plugin: ml2

          l3_ha: True

          global_physnet_mtu: 9000

          service_plugins: router

          interface_driver: openvswitch

        agent:

          root_helper_daemon: sudo neutron-rootwrap-daemon /etc/neutron/rootwrap.conf

      plugins:

        ml2_conf:

          ml2:

            mechanism_drivers: openvswitch,l2population

            type_drivers: flat, vlan, vxlan

            tenant_network_types: vxlan

        openvswitch_agent:

          agent:

            tunnel_types: vxlan

            l2_population: True

            arp_responder: True

          ovs:

            bridge_mappings: "external:br-ex"

          securitygroup:

            firewall_driver: openvswitch






# cinder.yaml


images:

      tags:

        test: registry.cicd.stg.taco/ocata/ubuntu-source-rally:2.2.0

        db_init: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        cinder_db_sync: registry.cicd.stg.taco/ocata/ubuntu-source-cinder-api:2.2.0

        db_drop: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_user: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_service: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_endpoints: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        cinder_api: registry.cicd.stg.taco/ocata/ubuntu-source-cinder-api:2.2.0

        bootstrap: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        cinder_scheduler: registry.cicd.stg.taco/ocata/ubuntu-source-cinder-scheduler:2.2.0

        cinder_volume: registry.cicd.stg.taco/ocata/ubuntu-source-cinder-volume:2.2.0

        cinder_volume_usage_audit: registry.cicd.stg.taco/ocata/ubuntu-source-cinder-volume:2.2.0

        cinder_storage_init: registry.cicd.stg.taco/ceph-daemon:tag-build-master-jewel-ubuntu-16.04

        cinder_backup: registry.cicd.stg.taco/ocata/ubuntu-source-cinder-backup:2.2.0

        cinder_backup_storage_init: registry.cicd.stg.taco/ceph-daemon:tag-build-master-jewel-ubuntu-16.04

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        rabbit_init: registry.cicd.stg.taco/rabbitmq:3.7-management

      pull_policy: Always

    pod:

      user:

        cinder:

          uid: 42407

      replicas:

        api: 3

        backup: 1

        scheduler: 3

        volume: 1

    conf:

      ceph:

        admin_keyring: "xxxxx=="

        monitors: ["192.168.51.20"]

      cinder:

        DEFAULT:

          debug: true

          backup_ceph_user: "cinder"

          backup_ceph_pool: "backups"

      backends:

        rbd1:

          volume_driver: cinder.volume.drivers.rbd.RBDDriver

          volume_backend_name: rbd1

          rbd_ceph_conf: "/etc/ceph/ceph.conf"

          rbd_flatten_volume_from_snapshot: false

          rbd_max_clone_depth: 5

          rbd_store_chunk_size: 4

          rados_connect_timeout: -1

          rbd_user: "cinder"

          rbd_pool: "volumes"





# heat.yaml


images:

      tags:

        bootstrap: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        db_init: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        heat_db_sync: registry.cicd.stg.taco/ocata/ubuntu-source-heat-api:2.2.0

        db_drop: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_user: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_service: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        ks_endpoints: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        heat_api: registry.cicd.stg.taco/ocata/ubuntu-source-heat-api:2.2.0

        heat_cfn: registry.cicd.stg.taco/ocata/ubuntu-source-heat-api:2.2.0

        heat_cloudwatch: registry.cicd.stg.taco/ocata/ubuntu-source-heat-api:2.2.0

        heat_engine: registry.cicd.stg.taco/ocata/ubuntu-source-heat-engine:2.2.0

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        rabbit_init: registry.cicd.stg.taco/rabbitmq:3.7-management

      pull_policy: Always

    pod:

      user:

        heat:

          uid: 42418

      replicas:

        api: 3

        cfn: 3

        cloudwatch: 3

        engine: 3



# horizon.yaml


images:

      tags:

        db_init: registry.cicd.stg.taco/ocata/ubuntu-source-horizon:2.2.0

        horizon_db_sync: registry.cicd.stg.taco/ocata/ubuntu-source-horizon:2.2.0

        horizon: registry.cicd.stg.taco/ocata/ubuntu-source-horizon:2.2.0

        dep_check: registry.cicd.stg.taco/kubernetes-entrypoint:v0.2.1

        test: registry.cicd.stg.taco/ocata/ubuntu-source-horizon:develop

      pull_policy: Always

    pod:

      replicas:

        server: 3

    network:

      external_policy_local: false

      node_port:

        enabled: true

        port: 32000

    local_settings:

      openstack_neutron_network:

        enable_router: "True"

        enable_quotas: "True"

        enable_ipv6: "False"

        enable_distributed_router: "False"

        enable_ha_router: "True"

        enable_lb: "True"

        enable_firewall: "False"

        enable_vpn: "False"

        enable_fip_topology_check: "True"




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

OpenStack 발표자료 (From Kubernetes to OpenStack)





Posted by Kubernetes Korea co-leader seungkyua@gmail.com
## /etc/mysql/my.cnf 설정 파일

[mysqld]
# base directory
datadir=/var/lib/mysql
tmpdir=/tmp

# Charset
character_set_server=utf8
collation_server=utf8_unicode_ci
skip-character-set-client-handshake

# Logging
slow_query_log=on
slow_query_log_file=/var/log/mysql/mariadb-slow.log
log_warnings=2

# General logging has huge performance penalty therefore is disabled by default
general_log=off
general_log_file=/var/log/mysql/mariadb-error.log

long_query_time=3
log_queries_not_using_indexes=on

# Networking
bind_address=0.0.0.0
port=3306

# When a client connects, the server will perform hostname resolution,
# and when DNS is slow, establishing the connection will become slow as well.
# It is therefore recommended to start the server with skip-name-resolve to
# disable all DNS lookups. The only limitation is that the GRANT statements
# must then use IP addresses only.
skip_name_resolve

# Tuning
user=mysql
max_allowed_packet=256M
open_files_limit=10240
max_connections=8192
max-connect-errors=1000000
join_buffer_size = 192K
tmp_table_size = 16M
max_heap_table_size = 16M

## Generally, it is unwise to set the query cache to be larger than 64-128M
## as the costs associated with maintaining the cache outweigh the performance
## gains.
## The query cache is a well known bottleneck that can be seen even when
## concurrency is moderate. The best option is to disable it from day 1
## by setting query_cache_size=0 (now the default on MySQL 5.6)
## and to use other ways to speed up read queries: good indexing, adding
## replicas to spread the read load or using an external cache.
query_cache_size=0
query_cache_type=0

sync_binlog=0
thread_cache_size=16
table_open_cache=2048
table_definition_cache=1024

#
# InnoDB
#
# The buffer pool is where data and indexes are cached: having it as large as possible
# will ensure you use memory and not disks for most read operations.
# Typical values are 50..75% of available RAM.
# TODO(tomasz.paszkowski): This needs to by dynamic based on available RAM.
innodb_buffer_pool_size=10G
innodb_log_file_size=128M
innodb_file_per_table=1
innodb_doublewrite=0
innodb_file_format=Barracuda
innodb_flush_method=O_DIRECT
innodb_io_capacity=500
innodb_old_blocks_time=1000
innodb_read_io_threads=8
innodb_write_io_threads=8

# Clustering
binlog_format=ROW
default-storage-engine=InnoDB
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=2
innodb_locks_unsafe_for_binlog=1
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name=mariadb
wsrep_node_name=mariadb-0.mariadb-discovery
wsrep_node_address=172.16.10.252
wsrep_cluster_address="gcomm://mariadb-1.mariadb-discovery:4567,mariadb-2.mariadb-discovery:4567"
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=root:password
wsrep_provider_options="gcache.size=512M; gcache.name=/tmp/galera.cache; gcache.page_size=128M; gmcast.listen_addr=tcp://0.0.0.0:4567"
wsrep_slave_threads=16
wsrep_on=1

[mysqldump]
max-allowed-packet=16M

[client]
default_character_set=utf8
protocol=tcp
port=3306
connect_timeout=10




## sync 상태 보기 (각 mariadb 서버에서)
MariaDB [(none)]> show status like 'wsrep_%';
+------------------------------+-------------------------------------------------------------+
| Variable_name                | Value                                                       |
+------------------------------+-------------------------------------------------------------+
| wsrep_apply_oooe             | 0.007694                                                    |
| wsrep_apply_oool             | 0.000000                                                    |
| wsrep_apply_window           | 1.014445                                                    |
| wsrep_causal_reads           | 0                                                           |
| wsrep_cert_deps_distance     | 25.653383                                                   |
| wsrep_cert_index_size        | 67                                                          |
| wsrep_cert_interval          | 0.007814                                                    |
| wsrep_cluster_conf_id        | 3                                                           |
| wsrep_cluster_size           | 3                                                           |
| wsrep_cluster_state_uuid     | 86cf6166-d00b-11e7-92f6-bf254b8a19b3                        |
| wsrep_cluster_status         | Primary                                                     |
| wsrep_commit_oooe            | 0.000000                                                    |
| wsrep_commit_oool            | 0.000000                                                    |
| wsrep_commit_window          | 1.006594                                                    |
| wsrep_connected              | ON                                                          |
| wsrep_desync_count           | 0                                                           |
| wsrep_evs_delayed            |                                                             |
| wsrep_evs_evict_list         |                                                             |
| wsrep_evs_repl_latency       | 0.000495221/0.000788639/0.00164732/0.00034555/19            |
| wsrep_evs_state              | OPERATIONAL                                                 |
| wsrep_flow_control_paused    | 0.000000                                                    |
| wsrep_flow_control_paused_ns | 0                                                           |
| wsrep_flow_control_recv      | 0                                                           |
| wsrep_flow_control_sent      | 0                                                           |
| wsrep_gcomm_uuid             | f14761b1-d026-11e7-a9c6-43e9a12bd841                        |
| wsrep_incoming_addresses     | 192.168.236.97:3306,192.168.28.197:3306,192.168.105.20:3306 |
| wsrep_last_committed         | 12525                                                       |
| wsrep_local_bf_aborts        | 0                                                           |
| wsrep_local_cached_downto    | 6127                                                        |
| wsrep_local_cert_failures    | 0                                                           |
| wsrep_local_commits          | 970                                                         |
| wsrep_local_index            | 2                                                           |
| wsrep_local_recv_queue       | 0                                                           |
| wsrep_local_recv_queue_avg   | 0.143574                                                    |
| wsrep_local_recv_queue_max   | 40                                                          |
| wsrep_local_recv_queue_min   | 0                                                           |
| wsrep_local_replays          | 0                                                           |
| wsrep_local_send_queue       | 0                                                           |
| wsrep_local_send_queue_avg   | 0.000978                                                    |
| wsrep_local_send_queue_max   | 2                                                           |
| wsrep_local_send_queue_min   | 0                                                           |
| wsrep_local_state            | 4                                                           |
| wsrep_local_state_comment    | Synced                                                      |
| wsrep_local_state_uuid       | 86cf6166-d00b-11e7-92f6-bf254b8a19b3                        |
| wsrep_protocol_version       | 7                                                           |
| wsrep_provider_name          | Galera                                                      |
| wsrep_provider_vendor        | Codership Oy <info@codership.com>                           |
| wsrep_provider_version       | 25.3.20(r3703)                                              |
| wsrep_ready                  | ON                                                          |
| wsrep_received               | 5579                                                        |
| wsrep_received_bytes         | 4241688                                                     |
| wsrep_repl_data_bytes        | 441822                                                      |
| wsrep_repl_keys              | 4283                                                        |
| wsrep_repl_keys_bytes        | 56574                                                       |
| wsrep_repl_other_bytes       | 0                                                           |
| wsrep_replicated             | 970                                                         |
| wsrep_replicated_bytes       | 560476                                                      |
| wsrep_thread_count           | 13                                                          |

+------------------------------+-------------------------------------------------------------+ 


wsrep_cluster_conf_id : 모든 db 에 똑같은 id 로 설정되어야 함

wsrep_cluster_size : 클러스터의 노드 갯수

wsrep_cluster_state_uuid : 고유 클러스터 ID 로 클러스터의 노드는 같은 값을 가져야 함

wsrep_cluster_status : 노드의 역할

wsrep_incoming_addresses : 클러스터 멤버의 ip 

wsrep_local_state_comment : 해당 노드가 클러스터의 멤버인지를 확인

wsrep_ready : 노드가 준비된 상태



## docker 내에서 클러스터 시작 (첫번째 클러스터)

$ sed -i 's/^safe_to_bootstrap:.*/safe_to_bootstrap: 1/' /var/lib/mysql/grastate.dat || :

$ docker-entrypoint.sh mysqld --wsrep-new-cluster


## docker 내에서 클러스터 시작 (두번째, 세번째 클러스터)

$ sed -i 's/^safe_to_bootstrap:.*/safe_to_bootstrap: 1/' /var/lib/mysql/grastate.dat || :

$ docker-entrypoint.sh mysqld







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

https://www.ted.com/talks/joy_buolamwini_how_i_m_fighting_bias_in_algorithms?utm_campaign=tedspread--b&utm_medium=referral&utm_source=tedcomshare





00:12

안녕하세요. 코드의 시인, 조이입니다. 저는 보이지 않는 힘이 일어나는 것을 막기 위한 사명을 띠고 있어요. 제가 '코드화된 시선'이라 부르는 힘인데요. 다른 사람은 알고리즘의 편견이라 부르죠.

Hello, I'm Joy, a poet of code, on a mission to stop an unseen force that's rising, a force that I called "the coded gaze," my term for algorithmic bias.


00:27

알고리즘의 편견은 인간의 편견처럼 불평등을 초래하지만 알고리즘은 바이러스처럼 대규모의 편견을 빠른 속도로 퍼뜨릴 수 있어요. 또한, 알고리즘의 편견은 자신이 배제되는 경험이나 차별적인 대우로 이어질 수 있어요. 자세히 설명해 드리죠.

Algorithmic bias, like human bias, results in unfairness. However, algorithms, like viruses, can spread bias on a massive scale at a rapid pace. Algorithmic bias can also lead to exclusionary experiences and discriminatory practices. Let me show you what I mean.


00:48

(비디오) 안녕, 카메라야. 이게 내 얼굴이야. 내 얼굴이 보이니? 안경을 벗으면 보이니? 이 친구의 얼굴은 보이잖아. 내 얼굴은 보여? 그럼 가면을 쓸게. 내 가면이 보이니?

(Video) Hi, camera. I've got a face. Can you see my face? No-glasses face? You can see her face. What about my face? I've got a mask. Can you see my mask?



01:08

이런 일이 왜 일어난 걸까요? 제가 왜 컴퓨터 앞에 앉아서 하얀 가면을 쓰고 싸구려 웹캠에 인식이 되도록 노력하고 있을까요? 제가 코드의 시인으로서 '코드화된 시선'과 싸우기 전에 저는 MIT 미디어랩의 대학원생이었어요. 그곳에서 많은 기발한 프로젝트에 참여할 수 있었는데 염원의 거울도 있었습니다. 제가 참여한 프로젝트로, 거울에 비친 제 모습에 디지털 가면을 씌우는 프로젝트였죠. 아침에 힘찬 느낌을 원하면 사자 가면을 씌울 수 있고 희망찬 느낌을 받고 싶다면 명언을 띄울 수 있었죠. 저는 일반적인 얼굴 인식 소프트웨어를 사용하여 시스템을 만들었지만 제가 흰 가면을 쓰지 않으면 굉장히 테스트하기 어려웠어요.

So how did this happen? Why am I sitting in front of a computer in a white mask, trying to be detected by a cheap webcam? Well, when I'm not fighting the coded gaze as a poet of code, I'm a graduate student at the MIT Media Lab, and there I have the opportunity to work on all sorts of whimsical projects, including the Aspire Mirror, a project I did so I could project digital masks onto my reflection. So in the morning, if I wanted to feel powerful, I could put on a lion. If I wanted to be uplifted, I might have a quote. So I used generic facial recognition software to build the system, but found it was really hard to test it unless I wore a white mask.



01:56

불행하게도, 저는 전에도 이런 문제에 부딪힌 적이 있어요. 제가 조지아 공대에서 컴퓨터 공학 전공생이었을 때 저는 사회적 로봇을 연구했어요. 과제들 중 하나는 까꿍놀이하는 로봇을 만들기였죠. 간단한 순서 교대 게임으로, 얼굴을 가렸다가 보이며 "까꿍!"이라고 말하는 게임이죠. 문제는, 까꿍 놀이는 제가 여러분의 얼굴을 볼 수 있어야 하는데 로봇이 저를 보지 못했어요. 하지만 저는 룸메이트의 얼굴을 빌려서 프로젝트를 끝냈고 과제를 제출한 다음 다른 누군가가 이 문제를 해결하겠지 라고 생각했어요.

Unfortunately, I've run into this issue before. When I was an undergraduate at Georgia Tech studying computer science, I used to work on social robots, and one of my tasks was to get a robot to play peek-a-boo, a simple turn-taking game where partners cover their face and then uncover it saying, "Peek-a-boo!" The problem is, peek-a-boo doesn't really work if I can't see you, and my robot couldn't see me. But I borrowed my roommate's face to get the project done, submitted the assignment, and figured, you know what, somebody else will solve this problem.



02:33

그로부터 오래 지나지 않아 창업 대회 참가를 위해 홍콩에 갔어요. 주최 측은 참여자들이 그 지역의 스타트업 기업들을 방문하도록 했어요. 한 스타트업에 사회적 로봇이 있었고 시범을 보여주기로 했어요. 로봇은 모두에게 잘 작동했죠. 저만 빼고요. 아마 짐작하셨을 거예요. 제 얼굴을 인식하지 못했어요. 저는 개발자들에게 무슨 일이냐고 물었고 제가 썼던 그 얼굴 인식 소프트웨어를 쓴 게 문제였어요. 지구 반대편에서 저는 알고리즘의 편견이 인터넷에서 파일을 다운로드받는 것처럼 빠르게 퍼질 수 있다는 걸 알았어요.

Not too long after, I was in Hong Kong for an entrepreneurship competition. The organizers decided to take participants on a tour of local start-ups. One of the start-ups had a social robot, and they decided to do a demo. The demo worked on everybody until it got to me, and you can probably guess it. It couldn't detect my face. I asked the developers what was going on, and it turned out we had used the same generic facial recognition software. Halfway around the world, I learned that algorithmic bias can travel as quickly as it takes to download some files off of the internet.



03:15

어떻게 된 걸까요? 왜 제 얼굴은 인식되지 않죠? 자, 우리가 어떻게 기계가 볼 수 있게 하는지 알아보세요. 컴퓨터의 시야는 머신 러닝 기술을 사용해 얼굴을 인식해요. 우리는 여러 예시 얼굴들로 이루어진 연습 세트를 만들어 놓죠. 이건 얼굴이다. 이건 얼굴이다. 이건 얼굴이 아니다. 그리고 시간이 지나면, 컴퓨터에게 얼굴 인식을 가르칠 수 있어요. 하지만, 연습 세트가 그렇게 다양하지 않다면 규정된 표준에서 너무 벗어나는 얼굴들은 인식하기 어려울 거예요. 저한테 일어났던 일과 같죠.

So what's going on? Why isn't my face being detected? Well, we have to look at how we give machines sight. Computer vision uses machine learning techniques to do facial recognition. So how this works is, you create a training set with examples of faces. This is a face. This is a face. This is not a face. And over time, you can teach a computer how to recognize other faces. However, if the training sets aren't really that diverse, any face that deviates too much from the established norm will be harder to detect, which is what was happening to me.



03:49

하지만 걱정하지 마세요. 좋은 소식도 있어요. 연습 세트는 하늘에서 뚝 떨어지지 않아요. 우리가 직접 만들 수 있죠. 따라서 전 영역을 아울러 다양한 인류의 얼굴을 반영하는 연습 세트를 만들 기회가 있어요.

But don't worry -- there's some good news. Training sets don't just materialize out of nowhere. We actually can create them. So there's an opportunity to create full-spectrum training sets that reflect a richer portrait of humanity.



04:04

여러분은 방금 사회적 로봇이 어떤지 제가 어떻게 알고리즘의 편견에 의한 배제에 대해 알게되었는지 보셨어요. 하지만 알고리즘의 편견은 차별적 관행으로 이어질 수도 있습니다. 미국 전역에서 경찰서들이 범죄 근절의 무기로 얼굴 인식 소프트웨어를 사용하기 시작했어요. 조지타운대 법학센터에 따르면 총 1억1천7백만명에 달하는 미국 성인 둘 중 한 명의 얼굴이 얼굴 인식 네트워크에 올려져 있어요. 경찰은 현재 이 네트워크를 제한 없이 살펴볼 수 있어요. 정확성이 검증되지 않은 알고리즘을 사용하면서요. 우리는 얼굴 인식이 잘못될 수 있다는 것을 알고 있고 얼굴을 일관되게 표시하는 것은 과제로 남아있어요. 아마 페이스북에서 보셨을 거예요. 저와 제 친구들은 다른 사람의 이름이 우리 사진에 표시된 것을 보고 매번 웃어요. 하지만 범죄 용의자를 잘못 파악하는 것은 웃을 일이 아니며 시민의 자유를 침해하죠.

Now you've seen in my examples how social robots was how I found out about exclusion with algorithmic bias. But algorithmic bias can also lead to discriminatory practices. Across the US, police departments are starting to use facial recognition software in their crime-fighting arsenal. Georgetown Law published a report showing that one in two adults in the US -- that's 117 million people -- have their faces in facial recognition networks. Police departments can currently look at these networks unregulated, using algorithms that have not been audited for accuracy. Yet we know facial recognition is not fail proof, and labeling faces consistently remains a challenge. You might have seen this on Facebook. My friends and I laugh all the time when we see other people mislabeled in our photos. But misidentifying a suspected criminal is no laughing matter, nor is breaching civil liberties.



05:12

머신러닝은 현재 얼굴인식에 사용되지만 컴퓨터 시각을 넘어선 곳까지 확장되고 있어요. '대량살상무기 (WMD)'라는 책에서 데이터 과학자 캐시 오닐은 새로운 대량살상무기에 대해서 말해요. 널리 퍼진, 알 수 없는 파괴적인 알고리즘이죠. 이들은 우리 삶에 큰 영향을 미치는 선택에 점점 많이 사용되고 있어요. 누가 고용되고 누가 해고되는가? 빚을 질까? 보험에 가입할까? 원하는 대학에 합격하는가? 여러분과 당신이 같은 상품에 대해서 같은 가격을 지불하는가?

Machine learning is being used for facial recognition, but it's also extending beyond the realm of computer vision. In her book, "Weapons of Math Destruction," data scientist Cathy O'Neil talks about the rising new WMDs -- widespread, mysterious and destructive algorithms that are increasingly being used to make decisions that impact more aspects of our lives. So who gets hired or fired? Do you get that loan? Do you get insurance? Are you admitted into the college you wanted to get into? Do you and I pay the same price for the same product purchased on the same platform?



05:55

법 집행에서도 예방적 치안을 위해 머신 러닝 사용을 시작했어요. 몇몇 판사들은 기계가 만든 위험 점수를 사용하여 사람들의 형량을 결정하기도 해요. 그래서 우린 이런 선택에 대해 생각해 봐야 해요. 이 선택이 공정한가? 게다가 우리는 알고리즘의 선택이 매번 공정하지는 않다는 걸 봤어요.

Law enforcement is also starting to use machine learning for predictive policing. Some judges use machine-generated risk scores to determine how long an individual is going to spend in prison. So we really have to think about these decisions. Are they fair? And we've seen that algorithmic bias doesn't necessarily always lead to fair outcomes.



06:19

그럼 어떻게 해야 할까요? 우리는 포괄적인 코드를 만들고 포괄적인 코딩 선례를 도입해야 해요. 이것은 사람들로부터 시작됩니다. 따라서, 누가 코딩을 하는지가 중요하죠. 우리는 지금 다양한 개인들로 이루어져 서로의 맹점을 볼 수 있는 팀을 만들고 있나요? 기술적인 면에서 우리가 어떻게 코딩을 하는지가 중요해요. 지금 우리는 시스템을 개발하면서 공정함을 염두에 두고 있나요? 마지막으로, 우리가 왜 코딩을 하는지가 중요해요. 우리는 엄청난 부를 위하여 컴퓨터를 도구로 사용했어요. 이제 우리에겐 더 큰 평등을 얻을 기회가 있어요. 우리가 사회적 변화를 미루지 않고 우선순위에 둔다면요. 이 세 가지 요소가 '인코딩' 운동을 구성합니다. 누가 코딩을 하는지 어떻게 코딩을 하는지 왜 코딩을 하는지가 중요해요.

So what can we do about it? Well, we can start thinking about how we create more inclusive code and employ inclusive coding practices. It really starts with people. So who codes matters. Are we creating full-spectrum teams with diverse individuals who can check each other's blind spots? On the technical side, how we code matters. Are we factoring in fairness as we're developing systems? And finally, why we code matters. We've used tools of computational creation to unlock immense wealth. We now have the opportunity to unlock even greater equality if we make social change a priority and not an afterthought. And so these are the three tenets that will make up the "incoding" movement. Who codes matters, how we code matters and why we code matters.



07:15

그리고 인코딩을 향해 가며 우리는 편견을 분별하는 플랫폼을 구축할 수 있어요. 제가 공유한 것과 같은 다른 사람들의 경험을 모으고 현존하는 소프트웨어를 검사하면서 말이죠. 우리는 또한 더욱 포용적인 연습 세트를 만들기 시작할 수 있어요. "포괄적인 셀카" 캠페인을 상상해 보세요. 여러분과 제가 더욱 포용적인 연습 세트를 만드는 데 셀카를 보내면서 도움을 줄 수 있는 거예요. 그리고 우리가 개발하는 기술의 사회적 영향에 대해 보다 양심적으로 생각할 수 있어요.

So to go towards incoding, we can start thinking about building platforms that can identify bias by collecting people's experiences like the ones I shared, but also auditing existing software. We can also start to create more inclusive training sets. Imagine a "Selfies for Inclusion" campaign where you and I can help developers test and create more inclusive training sets. And we can also start thinking more conscientiously about the social impact of the technology that we're developing.



07:49

인코딩 운동을 시작하기 위해서 저는 알고리즘 정의 연합을 창설했어요. 공정함을 중요시 여기는 사람 누구든 '코딩된 시선'에 맞서 싸우는 걸 도와줍니다. codedgaze.com에서 편견을 보고하거나 검사를 요청하거나 테스터가 될 수 있으며 진행되는 대화에 참여할 수도 있어요. 해시태그 codedgaze입니다.

To get the incoding movement started, I've launched the Algorithmic Justice League, where anyone who cares about fairness can help fight the coded gaze. On codedgaze.com, you can report bias, request audits, become a tester and join the ongoing conversation, #codedgaze.



08:12

그래서 저는 여러분이 저와 함께 기술이 일부만이 아닌 모두를 위해 쓰이는 세상을 포용성을 중요시여기고 사회적 변화를 중시하는 세상을 만드는데 동참하셨으면 합니다.

So I invite you to join me in creating a world where technology works for all of us, not just some of us, a world where we value inclusion and center social change.



08:25

감사합니다.

Thank you.



08:26

(박수)

(Applause)



08:32

하지만 여러분에게 질문이 하나 있어요. 여러분은 이 싸움에 동참하실 건가요?

But I have one question: Will you join me in the fight?



08:37

(웃음)

(Laughter)



08:38

(박수)

(Applause)






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

## Install OpenVPN

# apt-get update
# apt-get install openvpn easy-rsa

## Set Up the CA Directory (using easy-rsa)
# make-cadir /etc/openvpn/ease-rsa
# cd /etc/openvpn/ease-rsa

## Configure the CA Variables
# vi vars
export KEY_COUNTRY="KR"
export KEY_PROVINCE="Seoul"
export KEY_CITY="Jongno"
export KEY_ORG="OpenStackKR"
export KEY_EMAIL="root@localhost"
export KEY_OU="OpenStack KR"
export KEY_NAME="server"

## Build the Certificate Authority
# source vars
# ./clean-all
# ./build-ca
Generating a 2048 bit RSA private key
.....................................................+++
...................+++
writing new private key to 'ca.key'
-----
Country Name (2 letter code) [KR]:
State or Province Name (full name) [Seoul]:
Locality Name (eg, city) [Jongno]:
Organization Name (eg, company) [OpenStackKR]:
Organizational Unit Name (eg, section) [OpenStackKR]:
Common Name (eg, your name or your server's hostname) [OpenStackKR CA]:
Name [server]:
Email Address [root@localhost]:


## Create the Server Certificate, Key, and Encryption Files
# ./build-key-server server

A challenge password []:               --> 그냥 엔터
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated


# ./build-dh
# openvpn --genkey --secret keys/ta.key


## Generate a Client Certificate and Key Pair
# cd /etc/openvpn/ease-rsa
# source vars
./build-key seungkyua
Generating a 2048 bit RSA private key
.....+++
.................+++
writing new private key to 'seungkyua.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [KR]:
State or Province Name (full name) [Seoul]:
Locality Name (eg, city) [Jongno]:
Organization Name (eg, company) [OpenStackKR]:
Organizational Unit Name (eg, section) [OpenStackKR]:
Common Name (eg, your name or your server's hostname) [seungkyua]:
Name [server]:
Email Address [root@localhost]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:password
An optional company name []: OpenStackKR
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'KR'
stateOrProvinceName   :PRINTABLE:'Seoul'
localityName          :PRINTABLE:'Jongno'
organizationName      :PRINTABLE:'OpenStackKR'
organizationalUnitName:PRINTABLE:'OpenStackKR'
commonName            :PRINTABLE:'seungkyua'
name                  :PRINTABLE:'server'
emailAddress          :IA5STRING:'root@localhost'
Certificate is to be certified until Aug 29 01:42:22 2027 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated



## Configure the OpenVPN Service
# cd /etc/openvpn/ease-rsa/keys
# cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn
# gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf

# vi /etc/openvpn/server.conf
32 port 1194
35 proto tcp
78 ca ca.crt
79 cert server.crt
80 key server.key

141 push "route 192.168.30.0 255.255.255.0"
142 push "route 192.168.230.0 255.255.255.0"
143 push "route 192.168.130.0 255.255.255.0"
144 push "route 192.168.49.0 255.255.255.0"
145 push "route 192.168.51.0 255.255.255.0"
146 push "route 192.168.54.0 255.255.255.0"

205 push "dhcp-option DNS 192.168.30.26"    # 사설 DNS 서버가 설치될 서버 IP
206 push "dhcp-option DNS 8.8.8.8"
208 push "dhcp-option DOMAIN cicd.seungkyua"   # 사설 DNS 도메인

250 tls-auth ta.key 0
256 cipher AES-128-CBC   # AES
259 auth SHA256
275 user nobody
276 group nogroup


## Adjust the Server Networking Configuration
# vi /etc/sysctl.conf
28 net.ipv4.ip_forward=1

# sysctl -p

# ip route | grep default
# iptables -t nat -A POSTROUTING -s 10.8.0.0/8 -o br-ex -j MASQUERADE



## Start and Enable the OpenVPN Service
# systemctl start openvpn@server
# systemctl status openvpn@server
# systemctl enable openvpn@server


## Create Client Configuration Infrastructure
# cd /etc/openvpn
# mkdir -p /etc/openvpn/client-configs/files
# chmod 700 /etc/openvpn/client-configs/files
# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/client-configs/base.conf

# vi client-configs/base.conf
36 proto tcp
42 remote server_ip 1194
61 user nobody
62 group nogroup
88 #ca ca.crt
89 #cert client.crt
90 #key client.key
113 cipher AES-128-CBC
114 auth SHA256
115 key-direction 1


# vi client-configs/make_config.sh
#!/bin/bash

# First argument: Client identifier

KEY_DIR=/etc/openvpn/ease-rsa/keys
OUTPUT_DIR=/etc/openvpn/client-configs/files
BASE_CONFIG=/etc/openvpn/client-configs/base.conf

cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn


# chmod 700 client-configs/make_config.sh

# cd /etc/openvpn/client-configs

## seungkyua.ovpn 파일이 /etc/openvpn/client-configs/files 디렉토리 밑에 생성됨
# ./make_config.sh seungkyua



## 사용자 추가 시 클라이언트 파일 만드는 법

# cd /etc/openvpn/ease-rsa
# source vars
# ./build-key seungkyua

# cd /etc/openvpn/client-configs
# ./make_config.sh seungkyua


## server reboot 시 체크
# ip route | grep default

# iptables -t nat -A POSTROUTING -s 10.8.0.0/8 -o br-ex -j MASQUERADE



출처 : https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04






## Install Bind on the DNS Server
# sudo apt-get update
# apt-get install unbound


## config 설정
# cd /etc/unbound
# vi unbound.conf.d/root-auto-trust-anchor-file.conf
server:
    verbosity: 1
    statistics-interval: 0
    statistics-cumulative: no
    extended-statistics: yes
    num-threads: 2

        interface: 192.168.30.26
        interface: 127.0.0.1

    outgoing-range: 4096
    outgoing-port-permit: 40000-44096
    cache-max-ttl: 3600
    do-ip4: yes
    do-ip6: no

    access-control: 10.8.0.0/24 allow
    access-control: 192.168.30.0/24 allow
    access-control: 192.168.54.0/24 allow

    chroot: ""
    username: "unbound"
    directory: "/etc/unbound"
    log-time-ascii: yes
    pidfile: "/var/run/unbound/unbound.pid"
    hide-identity: yes
    hide-version: yes
    harden-short-bufsize: yes
    harden-large-queries: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    harden-below-nxdomain: yes
    harden-referral-path: yes
    use-caps-for-id: yes
    unwanted-reply-threshold: 10000000
    prefetch: yes
    prefetch-key: yes
    rrset-roundrobin: yes
    minimal-responses: yes
#    trusted-keys-file: /etc/unbound/keys.d/*.key
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    val-clean-additional: yes
    val-permissive-mode: no
    val-log-level: 1
    key-cache-size: 512m

    include: /etc/unbound/local.d/*.conf

# Remote control config section.
remote-control:
    control-enable: yes
    server-key-file: "/etc/unbound/unbound_server.key"
    server-cert-file: "/etc/unbound/unbound_server.pem"
    control-key-file: "/etc/unbound/unbound_control.key"
    control-cert-file: "/etc/unbound/unbound_control.pem"

# Stub and Forward zones
# include: /etc/unbound/conf.d/*.conf



## dns 설정
# mkdir -p local.d
# vi local.d/cicd.seungkyua.conf
local-zone: "cicd.stg.taco." static
local-data: "master01.cicd.seungkyua. IN A 192.168.30.13"
local-data: "node01.cicd.seungkyua. IN A 192.168.30.12"
local-data: "node02.cicd.seungkyua. IN A 192.168.30.17"
local-data: "node03.cicd.seungkyua. IN A 192.168.30.18"
local-data: "node04.cicd.seungkyua. IN A 192.168.30.21"

local-data: "centos-repo.cicd.seungkyua. IN A 192.168.30.12"
local-data: "dashboard.cicd.seungkyua. IN A 192.168.30.12"
local-data: "grafana.cicd.seungkyua. IN A 192.168.30.12"
local-data: "horizon.cicd.seungkyua. IN A 192.168.30.12"
local-data: "jenkins.cicd.seungkyua. IN A 192.168.30.12"
local-data: "keystone.cicd.seungkyua. IN A 192.168.30.12"
local-data: "kibana.cicd.seungkyua. IN A 192.168.30.12"
local-data: "minio.seungkyua. IN A 192.168.30.12"
local-data: "pypi-repo.cicd.seungkyua. IN A 192.168.30.12"
local-data: "registry.cicd.seungkyua. IN A 192.168.30.12"
local-data: "scope.cicd.seungkyua. IN A 192.168.30.12"
local-data: "prometheus.cicd.seungkyua. IN A 192.168.30.12"
local-data: "ubuntu-repo.cicd.seungkyua. IN A 192.168.30.12"



## start unbound
# systemctl restart unbound.service

# systemctl enable unbound.service 



출처 : https://calomel.org/unbound_dns.html



## reload unbound server with new configuration

# unbound-control reload






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

Youtube 동영상

영문 스트립트


지금부터 나와 주변 사람들에게 물어야 할 인생의 다섯 가지 중요한 질문을 소개합니다.

My final suggestion is that there are five truly essential questions that you should regularly ask yourself and others.

거창할지 모르지만 이해해주길 바랍니다. 졸업 축사이니까.

My claim is that, this is slightly outlandish as a claim but this is a graduation speech.

이 질문을 하는 습관을 들이면 성공적이고 행복한 삶을 살며 마지막의 보너스 질문에 '네'라고 자신 있게 답할 수 있습니다.

if you get in the habit of asking these questions, you have a very good chance of being both successful and happy,

and you will be in a good position to answer “I did” to the bonus question at the end.


1.잠깐만요, 뭐라고요? (Wait, What?)

첫 번째 질문은 우리 아이가 좋아하는 질문이자 십대들이 특히 자주 하고 우리들도 곧잘 하는 질문입니다.

The first is a question my own kids are fond of asking, and it’s one you may have heard other teenagers pose — or maybe you still pose it yourself.

질문이 고전적입니다. '잠깐만요, 뭐라고요?'

The question is the classic, 'Wait, what?'

'잠깐만, 뭐라고?' 또는 '잠깐만요, 뭐?'라고 하기도 합니다.

It could be asked is 'Wait, What?' or 'Wait, What?' (둘의 억양이 다름)

우리 아이들은 보통 내가 집안일을 시키려 할 때 이 질문을 합니다.

My kids typically pose this question when I get to the point in a conversation where I’m asking them to do a chore or two.

아이들 입장에선 내 말이 이렇게 들립니다. "어쩌구... 저쩌구... 내일 아침에 방 좀 치워라!"

From their perspective, they hear me saying something like: "blah, blah, blah, blah, and then I’d like you to clean your room."

바로 그 순간에 아이들은 묻습니다. "잠깐만요, 뭐라고요, 뭘 치우라고요?"

And at that precise moment, the question inevitably comes: "Wait, what? Clean what?"

'잠깐만, 뭐라고?'는 사실 무언가를 명확히 하기위한 매우 효과적인 질문으로, 이해를 위해 필수적입니다.

"Wait what" is actually a very effective way of asking for clarification, which is crucial to understanding.

결론을 내리기 전과 결정을 하기 전에 물어야만 하는 질문입니다.

It’s the question you should ask before drawing conclusions or before making a decision.

하바드 학장인 라케시 쿠라나는 훌륭한 마스터클래스를 진행하며 지지에 앞서 질의의 중요성을 강조했습니다.

The Dean of Harvard College, Rakesh Khurana, gave a great master class this year, where he emphasized the importance of inquiry before advocacy.

어떤 의견을 반대하거나 지지하기 전에 상황과 개념을 이해하는 것이 중요합니다.

It’s important to understand an idea before you advocate for or against it.

'뭐라고요?' 전에 오는 '잠깐만요'는 진정으로 이해할 수 있도록 잠시 시간을 갖게 하는 좋은 알람입니다.

The wait, which precedes the what, is also a good reminder that it pays to slow down to make sure you truly understand.


2. 나는 궁금한데요? (I wonder...)

두 번째 질문은 '나는 궁금한데요?'입니다. 이 질문은 왜 그런지(wonder why)와 할 수 있는지(wonder if)가 이어집니다.

The second question is "I wonder" which can be followed by "why" or "if". So I wonder why, or I wonder if.

'왜 그런지'라는 질문은 이 세상에 호기심을 갖게 합니다. '할 수 있는지'라는 질문은 세상이 더 나아지도록 하는 방법을 생각하게 합니다.

Asking 'I wonder why' is the way to remain curious about the world, and asking 'I wonder if' is the way to start thinking about how you might improve the world.

다음과 같이, 나는 왜 미국의 학교가 인종적으로 분리되어 있는지 궁금했습니다. 우리가 이 상황을 바꿀 수 있을 지 궁금했습니다.

As in, I wonder why our schools are so segregated, and I wonder if we could change this?

나는 왜 학생들이 학교생활을 지루해 하는지 궁금했습니다. 학생들이 집중할 수 있는 수업을 만들 수 있는지 궁금했습니다.

Or I wonder why students often seem bored in school, and I wonder if we could make their classes more engaging?


3. 적어도... 할 수 있지 않을까? (Couldn't we at least?)

세 번째 질문은 '적어도... 할 수 있지 않을까요?'입니다.

The third question is: "Couldn’t we at least...?"

이 질문은 보통 우리가 꽉 막힌 곳에서 빠져나올 때 유용합니다. 의견 차를 넘어 합의에 도달할 때 유용합니다.

This is the question to ask that will enable you to get unstuck, as they say. It’s what enables you to get past disagreement to some consensus,

다음과 같이, 우리가 주장하는 교육 전략은 다르다 해도 학생들의 복지가 최우선이라는 건 동의하지 않나요?

as in, couldn’t we at least agree that we all care about the welfare of students, even if we disagree about strategy?

또한 일의 결과를 확신하지 못하더라도 일단 무언가를 시작할 때 유용합니다.

It’s also a way to get started when you’re not entirely sure where you will finish,

다음과 같이, 적어도 모든 학생들이 잘 먹고 건강하게 학교에 다닐 수 있는 기회를 주는 것을 시작해야 하지 않나요?

as in, couldn’t we at least begin by making sure that all kids have the chance to come to school healthy and well-fed?


4. 내가 어떻게 도울까? (How can I help?)

내 번째 질문은 '내가 어떻게 도울까?'입니다.

The fourth question is: "How can I help?"

여러분은 누군가를 돕고 싶어 교육대학원에 들어왔을 겁니다.

You are at HGSE, I presume, because you are interested in helping others.

하지만 여기서 구원자 증후군, 당신이 누군가를 구원하는 전문가이고 영웅이라는 태도에 대해 인식하게 되었을 겁니다.

But you also know, from your time here, to be aware of the savior complex, of the stance where you are the expert or hero who swoops in to save others.

우리는 구원자 증후군 때문에 가장 인간적인 본능인 타인에게 손을 내미는 본능을 버려서는 안 됩니다.

We shouldn’t let the real pitfalls of the savior complex extinguish one of the most humane instincts there is — the instinct to lend a hand.

하지만 어떻게 돕느냐가 더 중요할 수 있습니다.

But how we help matters as much as that we do help,

"어떻게 도울까?"라고 묻는 것은 도움의 방향을 겸손하게 묻는 것이며,

and if you ask "how you can help", you are asking, with humility, for direction.

그들이 자기 삶의 전문가이자 당신이 돕는 만큼 그들도 당신을 도울 수 있다는 사실을 깨닫게 합니다.

And you are recognizing that others are experts in their own lives and that they will likely help you as much as you help them.


5. 무엇이 가장 중요한가? (What truly matters?)

다섯 번째 질문은 '무엇이 가장 중요한가?'입니다.

The fifth question is this: "What truly matters?"

여러분도 적절한 질문이라 생각할 것입니다.

You can tack on "to me" as appropriate.

이 질문은 문제의 핵심과 믿음과 신념의 핵심으로 들어가게 해주는 질문입니다.

This is the question that forces you to get to the heart of issues and to the heart of your own beliefs and convictions.

매년 새해 결심에 추가하거나 대신할 수도 있는 질문입니다.

Indeed, it’s a question that you might add to, or substitute for, New Year’s resolutions.

새해 첫날 내게 무엇이 진정 중요한가 물을 수 있습니다.

You might ask yourself, in other words, at least every new year: what truly matters to me?

이것이 다섯 개의 중요한 필수 질문입니다.

So these are the five essential questions.


'잠깐만요, 뭐라고요?'는 모든 이해의 근원입니다.

"Wait, what" is at the root of all understanding.

'궁금해'는 모든 호기심의 근원입니다.

"I wonder" is at the heart of all curiosity.

'우리가 적어도... 할 수 있지 않을까?'는 모든 진전의 시작입니다.

"Couldn’t we at least" is the beginning of all progress.

'어떻게 도울 수 있을까?'는 모든 좋은 관계의 기본입니다.

"How can I help" is at the base of all good relationships.

'무엇이 가장 중요한가?'는 삶의 핵심으로 들어가게 해줍니다.

And "what really matters" gets you to the heart of life.

이 질문을 정기적으로, 특히 마지막 질문을 자주 한다면 보너스 질문에 답할 좋은 위치에 서게 됩니다.

If you ask these questions regularly, especially the last one, you will be in a great position to answer the bonus question,

이것은 생의 마지막에서 여러분이 만나게 될 가장 중요한 질문입니다.

which is, at the end of the day, the most important question you’ll ever face.

이 보너스 질문은 여러 버전이 있으며, 이전에 한 버전은 확실히 들었을 것입니다.

This bonus question is posed in many ways, and you have surely heard a version of it before.

나에게 가장 강렬한 한 문장으로 다가온 것은 레이먼드 카버의 시 <만년의 조각글>에서 였습니다.

To me, the single best phrasing of this question is in a poem by Raymond Carver, called "Late Fragments".

그가 쓴 마지막 시입니다.

It’s one of the last poems he wrote.

지난 9월 나의 법대 동기이자 가장 사랑하는 친구였던 더그 켄들의 장례식에서 이 문장을 만났습니다.

I came across it recently on the very sad occasion of a memorial service for one of my dearest and closest friends, my former law school roommate Doug Kendall,

51세라는 너무 젊은 나이에 세상을 떠난 친구입니다.

who died in September at the far too young age of 51.

이 시는 그의 장례식 식순 뒤에 적혀 있었습니다. 시는 질문으로 시작하는데 이것이 바로 나의 보너스 질문에 해당합니다.

The poem was printed on the back of the program for his memorial and it starts with this question, what I’m calling the bonus question.

'그럼에도 불구하고 당신은 이 삶에서 원하는 것을 얻었습니까?'

"And did you get what you wanted out of life, even so?"


그럼에도 불구하고 이 부분이, 나에게는, 긴 인생과 삶의 희망에서 피할 수 없는 고통과 실망을 완벽하게 잡아냈다고 생각합니다.

The "even so" part of this, to me, captures perfectly the recognition of the pain and disappointment that inevitably make up a full life, but also the hope that life,

또한 '그럼에도 불구하고' 우리 인생에 행복과 만족의 가능성이 함께 함을 이야기합니다.

even so, offers the possibility of joy and contentment.

당신이 '잠깐만요, 뭐라고요?, 나는 궁금한데요?, 적어도 할 수 있지 않을까?, 어떻게 도울까?, 무엇이 가장 중요한가?' 이 질문을 주기적으로 한다면,

My claim is that if you regularly ask: wait, what, I wonder, couldn’t we at least, how can I help, and what really matters,

'마지막 그럼에도 불구하고 당신은 삶에서 원하는 것을 얻었는가?'라는 질문에 '네'라고 대답할 수 있을 것입니다.

when it comes time to ask yourself "And did you get what you wanted out of life, even so", your answer will be "I did".

이 시는 '그럼에도 불구하고 원하는 것을 얻었는가?'라는 질문에 '그렇다'라고,

So the poem asks "And did you get what you wanted out of life, even so",

또 "당신은 무엇을 원했습니까?"에 "이 지상에서, 나를 사랑받는 사람이라 부를 수 있고, 사랑받고 있다고 느끼는 것"이라고 답합니다.

and then continues: "I did. And what did you want?", "To call myself beloved. To feel beloved on the earth.".

사랑을 받는다는 건 지극히 사랑받는다는 것 뿐 아니라 소중히 여겨지고 존경받는 것입니다.

The word "beloved" is important here as it not only means dearly loved, but also cherished and respected.


이제 나의 축사가 거의 끝나가고 있으니 한 가지만 당부합니다.

And while I promise I’m very near the end of my speech, let me just say that

이 시를 읽으며 학생들을 생각할 수밖에 없었습니다.

when I read these lines, it’s hard for me not to think about students.

우리는 이곳은 물론 다른 곳에서 우리가 가르치는 학생들의 실력을 어떻게 향상시킬까를 항상 고민해야 합니다.

We spend a lot of time, here and elsewhere, thinking about how we might improve student performance, which is how it should be.

학생들이 공부를 잘할 뿐만 아니라 사랑받고 있다고 느낀다면 모든 학교와 이 세상은 보다 나은 곳이 될 것입니다.

Yet I can’t help but think that schools, and indeed, the world, would be better places if students didn’t simply perform well but also felt beloved

모든 학생들은 선생님께 사랑받고 친구들에게 사랑받아야 합니다.

- beloved by their teachers and by their fellow classmates.

이제 축사를 마무리하며 여러분에게 마지막 인사를 전합니다.

To tie this all together into one slightly misshapen package, and to bid you a final farewell.

이제 대학원을 떠나 여러분을 절실히 필요로 하는 넓은 세상에 나아갈 여러분에게 나의 소망과 신념을 꼭 전하고 싶습니다.

As you leave Appian Way and head into a world that desperately needs you, let me express my sincere hope and belief that

좋은 질문을 하고, 듣기를 멈추지 않는다면 여러분 자신이 이 지상에서 사랑받고 있다고 느낄 것이며,

if you never stop asking and listening for good questions, you will feel beloved on this earth,

마찬가지로, 다른 사람들 특히 여러분의 학생들이 사랑받는다고 느끼게 해줄 수 있습니다.

and, just as importantly, you will help others, especially students, feel the same.

감사합니다.

Thank you very much.





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